diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d257ce37..c978729f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,7 +42,7 @@ jobs: run: | eval `opam env` export LD_LIBRARY_PATH=`opam config var z3:lib` - ./coverage.sh test + scripts/coverage.sh test - name: Upload new coverage results if: always() diff --git a/.gitignore b/.gitignore index 184db933..36d30805 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ scripts/result.txt scripts/output.txt scripts/cntlm.bir scripts/total.txt + +mra_tools diff --git a/cntlm.bir b/cntlm.bir deleted file mode 100644 index 9b3858c7..00000000 --- a/cntlm.bir +++ /dev/null @@ -1 +0,0 @@ -000daeb9: program diff --git a/cpus/armv8.6.cpu b/cpus/armv8.6.cpu new file mode 100644 index 00000000..63394171 Binary files /dev/null and b/cpus/armv8.6.cpu differ diff --git a/mra_tools/arch/arch.asl b/mra_tools/arch/arch.asl deleted file mode 100644 index 95a51bef..00000000 --- a/mra_tools/arch/arch.asl +++ /dev/null @@ -1,17699 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// Proprietary Notice -// -// This document is protected by copyright and other related rights -// and the practice or implementation of the information contained in -// this document may be protected by one or more patents or pending -// patent applications. No part of this document may be reproduced in any -// form by any means without the express prior written permission of -// Arm. No license, express or implied, by estoppel or otherwise to -// any intellectual property rights is granted by this document unless -// specifically stated. -// -// Your access to the information in this document is conditional upon -// your acceptance that you will not use or permit others to use the -// information for the purposes of determining whether implementations -// infringe any third party patents. -// -// THIS DOCUMENT IS PROVIDED "AS IS". ARM PROVIDES NO REPRESENTATIONS -// AND NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT -// LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY -// QUALITY, NON-INFRINGEMENT OR FITNESS FOR A PARTICULAR PURPOSE WITH -// RESPECT TO THE DOCUMENT. For the avoidance of doubt, Arm makes no -// representation with respect to, and has undertaken no analysis to -// identify or understand the scope and content of, patents, copyrights, -// trade secrets, or other rights. -// -// This document may include technical inaccuracies or typographical -// errors. -// -// TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL ARM BE -// LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION ANY DIRECT, -// INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES, -// HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT -// OF ANY USE OF THIS DOCUMENT, EVEN IF ARM HAS BEEN ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGES. -// -// This document consists solely of commercial items. You shall be -// responsible for ensuring that any use, duplication or disclosure of -// this document complies fully with any relevant export laws and -// regulations to assure that this document or any portion thereof is not -// exported, directly or indirectly, in violation of such export -// laws. Use of the word "partner" in reference to Arm's customers is not -// intended to create or refer to any partnership relationship with any -// other company. Arm may make changes to this document at any time and -// without notice. -// -// If any of the provisions contained in these terms conflict with -// any of the provisions of any click through or signed written agreement -// covering this document with Arm, then the click through or signed -// written agreement prevails over and supersedes the conflicting -// provisions of these terms. This document may be translated into other -// languages for convenience, and you agree that if there is any conflict -// between the English version of this document and any translation, the -// terms of the English version of the Agreement shall prevail. -// -// The Arm corporate logo and words marked with (R) or (TM)(TM) -// are registered trademarks or trademarks of Arm Limited (or its -// subsidiaries) in the US and/or elsewhere. All rights reserved. Other -// brands and names mentioned in this document may be the trademarks of -// their respective owners. Please follow Arm's trademark usage -// guidelines at -// http://www.arm.com/company/policies/trademarks. -// -// Copyright (C) 2019 Arm Limited (or its affiliates). All rights reserved. -// -// Arm Limited. Company 02557590 registered in England. -// -// 110 Fulbourn Road, Cambridge, England CB1 9NJ. -// -// LES-PRE-20349 -//////////////////////////////////////////////////////////////////////// - -enumeration VBitOps {VBitOps_VBIF, VBitOps_VBIT, VBitOps_VBSL}; -enumeration VBitOps {VBitOps_VBIF, VBitOps_VBIT, VBitOps_VBSL}; -enumeration VFPNegMul {VFPNegMul_VNMLA, VFPNegMul_VNMLS, VFPNegMul_VNMUL}; -enumeration VCGEtype {VCGEtype_signed, VCGEtype_unsigned, VCGEtype_fp}; -enumeration VFPNegMul {VFPNegMul_VNMLA, VFPNegMul_VNMLS, VFPNegMul_VNMUL}; -enumeration VCGTtype {VCGTtype_signed, VCGTtype_unsigned, VCGTtype_fp}; -enumeration VFPNegMul {VFPNegMul_VNMLA, VFPNegMul_VNMLS, VFPNegMul_VNMUL}; -enumeration VBitOps {VBitOps_VBIF, VBitOps_VBIT, VBitOps_VBSL}; -enumeration Constraint {// General - Constraint_NONE, // Instruction executes with - // no change or side-effect to its described behavior - Constraint_UNKNOWN, // Destination register has UNKNOWN value - Constraint_UNDEF, // Instruction is UNDEFINED - Constraint_UNDEFEL0, // Instruction is UNDEFINED at EL0 only - Constraint_NOP, // Instruction executes as NOP - Constraint_TRUE, - Constraint_FALSE, - Constraint_DISABLED, - Constraint_UNCOND, // Instruction executes unconditionally - Constraint_COND, // Instruction executes conditionally - Constraint_ADDITIONAL_DECODE, // Instruction executes with additional decode - // Load-store - Constraint_WBSUPPRESS, Constraint_FAULT, - // IPA too large - Constraint_FORCE, Constraint_FORCENOSLCHECK}; - -enumeration InstrSet {InstrSet_A64, InstrSet_A32, InstrSet_T32}; - -// HaveAnyAArch32() -// ================ -// Return TRUE if AArch32 state is supported at any Exception level - -boolean HaveAnyAArch32() - return boolean IMPLEMENTATION_DEFINED; - -// HighestELUsingAArch32() -// ======================= -// Return TRUE if configured to boot into AArch32 operation - -boolean HighestELUsingAArch32() - if !HaveAnyAArch32() then return FALSE; - return boolean IMPLEMENTATION_DEFINED; // e.g. CFG32SIGNAL == HIGH - -// UsingAArch32() -// ============== -// Return TRUE if the current Exception level is using AArch32, FALSE if using AArch64. - -boolean UsingAArch32() - boolean aarch32 = (PSTATE.nRW == '1'); - if !HaveAnyAArch32() then assert !aarch32; - if HighestELUsingAArch32() then assert aarch32; - return aarch32; - -// CurrentInstrSet() -// ================= - -InstrSet CurrentInstrSet() - - if UsingAArch32() then - result = if PSTATE.T == '0' then InstrSet_A32 else InstrSet_T32; - // PSTATE.J is RES0. Implementation of T32EE or Jazelle state not permitted. - else - result = InstrSet_A64; - return result; - -constant bits(2) EL3 = '11'; -constant bits(2) EL2 = '10'; -constant bits(2) EL1 = '01'; -constant bits(2) EL0 = '00'; - -// HaveEL() -// ======== -// Return TRUE if Exception level 'el' is supported - -boolean HaveEL(bits(2) el) - if el IN {EL1,EL0} then - return TRUE; // EL1 and EL0 must exist - return boolean IMPLEMENTATION_DEFINED; - -// HighestEL() -// =========== -// Returns the highest implemented Exception level. - -bits(2) HighestEL() - if HaveEL(EL3) then - return EL3; - elsif HaveEL(EL2) then - return EL2; - else - return EL1; - -// HaveAArch32EL() -// =============== - -boolean HaveAArch32EL(bits(2) el) - // Return TRUE if Exception level 'el' supports AArch32 in this implementation - if !HaveEL(el) then - return FALSE; // The Exception level is not implemented - elsif !HaveAnyAArch32() then - return FALSE; // No Exception level can use AArch32 - elsif HighestELUsingAArch32() then - return TRUE; // All Exception levels are using AArch32 - elsif el == HighestEL() then - return FALSE; // The highest Exception level is using AArch64 - elsif el == EL0 then - return TRUE; // EL0 must support using AArch32 if any AArch32 - return boolean IMPLEMENTATION_DEFINED; - -constant bits(5) M32_User = '10000'; -constant bits(5) M32_FIQ = '10001'; -constant bits(5) M32_IRQ = '10010'; -constant bits(5) M32_Svc = '10011'; -constant bits(5) M32_Monitor = '10110'; -constant bits(5) M32_Abort = '10111'; -constant bits(5) M32_Hyp = '11010'; -constant bits(5) M32_Undef = '11011'; -constant bits(5) M32_System = '11111'; - -// BadMode() -// ========= - -boolean BadMode(bits(5) mode) - // Return TRUE if 'mode' encodes a mode that is not valid for this implementation - case mode of - when M32_Monitor - valid = HaveAArch32EL(EL3); - when M32_Hyp - valid = HaveAArch32EL(EL2); - when M32_FIQ, M32_IRQ, M32_Svc, M32_Abort, M32_Undef, M32_System - // If EL3 is implemented and using AArch32, then these modes are EL3 modes in Secure - // state, and EL1 modes in Non-secure state. If EL3 is not implemented or is using - // AArch64, then these modes are EL1 modes. - // Therefore it is sufficient to test this implementation supports EL1 using AArch32. - valid = HaveAArch32EL(EL1); - when M32_User - valid = HaveAArch32EL(EL0); - otherwise - valid = FALSE; // Passed an illegal mode value - return !valid; - -enumeration ArchVersion { - ARMv8p0 - , ARMv8p1 - , ARMv8p2 - , ARMv8p3 - , ARMv8p4 - , ARMv8p5 - , ARMv8p6 -}; - -// HasArchVersion() -// ================ -// Return TRUE if the implemented architecture includes the extensions defined in the specified -// architecture version. - -boolean HasArchVersion(ArchVersion version) - return version == ARMv8p0 || boolean IMPLEMENTATION_DEFINED; - -// HaveSecureEL2Ext() -// ================== -// Returns TRUE if Secure EL2 is implemented. - -boolean HaveSecureEL2Ext() - return HasArchVersion(ARMv8p4); - -type SCRType; - -// SCR_GEN[] -// ========= - -SCRType SCR_GEN[] - // AArch32 secure & AArch64 EL3 registers are not architecturally mapped - assert HaveEL(EL3); - bits(64) r; - if HighestELUsingAArch32() then - r = ZeroExtend(SCR); - else - r = ZeroExtend(SCR_EL3); - return r; - -// IsSecureBelowEL3() -// ================== -// Return TRUE if an Exception level below EL3 is in Secure state -// or would be following an exception return to that level. -// -// Differs from IsSecure in that it ignores the current EL or Mode -// in considering security state. -// That is, if at AArch64 EL3 or in AArch32 Monitor mode, whether an -// exception return would pass to Secure or Non-secure state. - -boolean IsSecureBelowEL3() - if HaveEL(EL3) then - return SCR_GEN[].NS == '0'; - elsif HaveEL(EL2) && (!HaveSecureEL2Ext() || HighestELUsingAArch32()) then - // If Secure EL2 is not an architecture option then we must be Non-secure. - return FALSE; - else - // TRUE if processor is Secure or FALSE if Non-secure. - return boolean IMPLEMENTATION_DEFINED "Secure-only implementation"; - -// IsSecure() -// ========== -// Returns TRUE if current Exception level is in Secure state. - -boolean IsSecure() - if HaveEL(EL3) && !UsingAArch32() && PSTATE.EL == EL3 then - return TRUE; - elsif HaveEL(EL3) && UsingAArch32() && PSTATE.M == M32_Monitor then - return TRUE; - return IsSecureBelowEL3(); - -bits(32) SP_mon; -bits(32) LR_mon; - -Unreachable() - assert FALSE; - -// RBankSelect() -// ============= - -integer RBankSelect(bits(5) mode, integer usr, integer fiq, integer irq, - integer svc, integer abt, integer und, integer hyp) - - case mode of - when M32_User result = usr; // User mode - when M32_FIQ result = fiq; // FIQ mode - when M32_IRQ result = irq; // IRQ mode - when M32_Svc result = svc; // Supervisor mode - when M32_Abort result = abt; // Abort mode - when M32_Hyp result = hyp; // Hyp mode - when M32_Undef result = und; // Undefined mode - when M32_System result = usr; // System mode uses User mode registers - otherwise Unreachable(); // Monitor mode - - return result; - -// LookUpRIndex() -// ============== - -integer LookUpRIndex(integer n, bits(5) mode) - assert n >= 0 && n <= 14; - - case n of // Select index by mode: usr fiq irq svc abt und hyp - when 8 result = RBankSelect(mode, 8, 24, 8, 8, 8, 8, 8); - when 9 result = RBankSelect(mode, 9, 25, 9, 9, 9, 9, 9); - when 10 result = RBankSelect(mode, 10, 26, 10, 10, 10, 10, 10); - when 11 result = RBankSelect(mode, 11, 27, 11, 11, 11, 11, 11); - when 12 result = RBankSelect(mode, 12, 28, 12, 12, 12, 12, 12); - when 13 result = RBankSelect(mode, 13, 29, 17, 19, 21, 23, 15); - when 14 result = RBankSelect(mode, 14, 30, 16, 18, 20, 22, 14); - otherwise result = n; - - return result; - -enumeration Unpredictable {// Writeback/transfer register overlap (load) - Unpredictable_WBOVERLAPLD, - // Writeback/transfer register overlap (store) - Unpredictable_WBOVERLAPST, - // Load Pair transfer register overlap - Unpredictable_LDPOVERLAP, - // Store-exclusive base/status register overlap - Unpredictable_BASEOVERLAP, - // Store-exclusive data/status register overlap - Unpredictable_DATAOVERLAP, - // Load-store alignment checks - Unpredictable_DEVPAGE2, - // Instruction fetch from Device memory - Unpredictable_INSTRDEVICE, - // Reserved CPACR value - Unpredictable_RESCPACR, - // Reserved MAIR value - Unpredictable_RESMAIR, - // Reserved TEX:C:B value - Unpredictable_RESTEXCB, - // Reserved PRRR value - Unpredictable_RESPRRR, - // Reserved DACR field - Unpredictable_RESDACR, - // Reserved VTCR.S value - Unpredictable_RESVTCRS, - // Reserved TCR.TnSZ value - Unpredictable_RESTnSZ, - // Reserved SCTLR_ELx.TCF value - Unpredictable_RESTCF, - // Out-of-range TCR.TnSZ value - Unpredictable_OORTnSZ, - // IPA size exceeds PA size - Unpredictable_LARGEIPA, - // Syndrome for a known-passing conditional A32 instruction - Unpredictable_ESRCONDPASS, - // Illegal State exception: zero PSTATE.IT - Unpredictable_ILZEROIT, - // Illegal State exception: zero PSTATE.T - Unpredictable_ILZEROT, - // Debug: prioritization of Vector Catch - Unpredictable_BPVECTORCATCHPRI, - // Debug Vector Catch: match on 2nd halfword - Unpredictable_VCMATCHHALF, - // Debug Vector Catch: match on Data Abort or Prefetch abort - Unpredictable_VCMATCHDAPA, - // Debug watchpoints: non-zero MASK and non-ones BAS - Unpredictable_WPMASKANDBAS, - // Debug watchpoints: non-contiguous BAS - Unpredictable_WPBASCONTIGUOUS, - // Debug watchpoints: reserved MASK - Unpredictable_RESWPMASK, - // Debug watchpoints: non-zero MASKed bits of address - Unpredictable_WPMASKEDBITS, - // Debug breakpoints and watchpoints: reserved control bits - Unpredictable_RESBPWPCTRL, - // Debug breakpoints: not implemented - Unpredictable_BPNOTIMPL, - // Debug breakpoints: reserved type1 - Unpredictable_RESBPTYPE, - // Debug breakpoints: not-context-aware breakpoint - Unpredictable_BPNOTCTXCMP, - // Debug breakpoints: match on 2nd halfword of instruction - Unpredictable_BPMATCHHALF, - // Debug breakpoints: mismatch on 2nd halfword of instruction - Unpredictable_BPMISMATCHHALF, - // Debug: restart to a misaligned AArch32 PC value - Unpredictable_RESTARTALIGNPC, - // Debug: restart to a not-zero-extended AArch32 PC value - Unpredictable_RESTARTZEROUPPERPC, - // Zero top 32 bits of X registers in AArch32 state - Unpredictable_ZEROUPPER, - // Zero top 32 bits of PC on illegal return to AArch32 state - Unpredictable_ERETZEROUPPERPC, - // Force address to be aligned when interworking branch to A32 state - Unpredictable_A32FORCEALIGNPC, - // SMC disabled - Unpredictable_SMD, - // FF speculation - Unpredictable_NONFAULT, - // Zero top bits of Z registers in EL change - Unpredictable_SVEZEROUPPER, - // Load mem data in NF loads - Unpredictable_SVELDNFDATA, - // Write zeros in NF loads - Unpredictable_SVELDNFZERO, - // Access Flag Update by HW - Unpredictable_AFUPDATE, - // Consider SCTLR[].IESB in Debug state - Unpredictable_IESBinDebug, - // Bad settings for PMSFCR_EL1/PMSEVFR_EL1/PMSLATFR_EL1 - Unpredictable_BADPMSFCR, - // Zero saved BType value in SPSR_ELx/DPSR_EL0 - Unpredictable_ZEROBTYPE, - // Timestamp constrained to virtual or physical - Unpredictable_EL2TIMESTAMP, - Unpredictable_EL1TIMESTAMP, - // Clearing DCC/ITR sticky flags when instruction is in flight - Unpredictable_CLEARERRITEZERO}; - -array bits(64) _R[0..30]; - -// Rmode[] - non-assignment form -// ============================= - -bits(32) Rmode[integer n, bits(5) mode] - assert n >= 0 && n <= 14; - - // Check for attempted use of Monitor mode in Non-secure state. - if !IsSecure() then assert mode != M32_Monitor; - assert !BadMode(mode); - - if mode == M32_Monitor then - if n == 13 then return SP_mon; - elsif n == 14 then return LR_mon; - else return _R[n][31:0]; - else - return _R[LookUpRIndex(n, mode)][31:0]; - -// Rmode[] - assignment form -// ========================= - -Rmode[integer n, bits(5) mode] = bits(32) value - assert n >= 0 && n <= 14; - - // Check for attempted use of Monitor mode in Non-secure state. - if !IsSecure() then assert mode != M32_Monitor; - assert !BadMode(mode); - - if mode == M32_Monitor then - if n == 13 then SP_mon = value; - elsif n == 14 then LR_mon = value; - else _R[n][31:0] = value; - else - // It is CONSTRAINED UNPREDICTABLE whether the upper 32 bits of the X - // register are unchanged or set to zero. This is also tested for on - // exception entry, as this applies to all AArch32 registers. - if !HighestELUsingAArch32() && ConstrainUnpredictableBool(Unpredictable_ZEROUPPER) then - _R[LookUpRIndex(n, mode)] = ZeroExtend(value); - else - _R[LookUpRIndex(n, mode)][31:0] = value; - - return; - -// R[] - assignment form -// ===================== - -R[integer n] = bits(32) value - Rmode[n, PSTATE.M] = value; - return; - -// R[] - non-assignment form -// ========================= - -bits(32) R[integer n] - if n == 15 then - offset = (if CurrentInstrSet() == InstrSet_A32 then 8 else 4); - return _PC[31:0] + offset; - else - return Rmode[n, PSTATE.M]; - -// SP - assignment form -// ==================== - -SP = bits(32) value - R[13] = value; - return; - -// SP - non-assignment form -// ======================== - -bits(32) SP - return R[13]; - -type ProcState is ( - bits (1) N, // Negative condition flag - bits (1) Z, // Zero condition flag - bits (1) C, // Carry condition flag - bits (1) V, // oVerflow condition flag - bits (1) D, // Debug mask bit [AArch64 only] - bits (1) A, // SError interrupt mask bit - bits (1) I, // IRQ mask bit - bits (1) F, // FIQ mask bit - bits (1) PAN, // Privileged Access Never Bit [v8.1] - bits (1) UAO, // User Access Override [v8.2] - bits (1) DIT, // Data Independent Timing [v8.4] - bits (1) TCO, // Tag Check Override [v8.5, AArch64 only] - bits (2) BTYPE, // Branch Type [v8.5] - bits (1) SS, // Software step bit - bits (1) IL, // Illegal Execution state bit - bits (2) EL, // Exception Level - bits (1) nRW, // not Register Width: 0=64, 1=32 - bits (1) SP, // Stack pointer select: 0=SP0, 1=SPx [AArch64 only] - bits (1) Q, // Cumulative saturation flag [AArch32 only] - bits (4) GE, // Greater than or Equal flags [AArch32 only] - bits (1) SSBS, // Speculative Store Bypass Safe - bits (8) IT, // If-then bits, RES0 in CPSR [AArch32 only] - bits (1) J, // J bit, RES0 [AArch32 only, RES0 in SPSR and CPSR] - bits (1) T, // T32 bit, RES0 in CPSR [AArch32 only] - bits (1) E, // Endianness bit [AArch32 only] - bits (5) M // Mode field [AArch32 only] -) - -ProcState PSTATE; - -// ConstrainUnpredictable() -// ======================== -// Return the appropriate Constraint result to control the caller's behavior. The return value -// is IMPLEMENTATION DEFINED within a permitted list for each UNPREDICTABLE case. -// (The permitted list is determined by an assert or case statement at the call site.) - -// NOTE: This version of the function uses an Unpredictable argument to define the call site. -// This argument does not appear in the version used in the Armv8 Architecture Reference Manual. -// The extra argument is used here to allow this example definition. This is an example only and -// does not imply a fixed implementation of these behaviors. Indeed the intention is that it should -// be defined by each implementation, according to its implementation choices. - -Constraint ConstrainUnpredictable(Unpredictable which) - case which of - when Unpredictable_WBOVERLAPLD - return Constraint_WBSUPPRESS; // return loaded value - when Unpredictable_WBOVERLAPST - return Constraint_NONE; // store pre-writeback value - when Unpredictable_LDPOVERLAP - return Constraint_UNDEF; // instruction is UNDEFINED - when Unpredictable_BASEOVERLAP - return Constraint_NONE; // use original address - when Unpredictable_DATAOVERLAP - return Constraint_NONE; // store original value - when Unpredictable_DEVPAGE2 - return Constraint_FAULT; // take an alignment fault - when Unpredictable_INSTRDEVICE - return Constraint_NONE; // Do not take a fault - when Unpredictable_RESCPACR - return Constraint_TRUE; // Map to UNKNOWN value - when Unpredictable_RESMAIR - return Constraint_UNKNOWN; // Map to UNKNOWN value - when Unpredictable_RESTEXCB - return Constraint_UNKNOWN; // Map to UNKNOWN value - when Unpredictable_RESDACR - return Constraint_UNKNOWN; // Map to UNKNOWN value - when Unpredictable_RESPRRR - return Constraint_UNKNOWN; // Map to UNKNOWN value - when Unpredictable_RESVTCRS - return Constraint_UNKNOWN; // Map to UNKNOWN value - when Unpredictable_RESTnSZ - return Constraint_FORCE; // Map to the limit value - when Unpredictable_OORTnSZ - return Constraint_FORCE; // Map to the limit value - when Unpredictable_LARGEIPA - return Constraint_FORCE; // Restrict the inputsize to the PAMax value - when Unpredictable_ESRCONDPASS - return Constraint_FALSE; // Report as "AL" - when Unpredictable_ILZEROIT - return Constraint_FALSE; // Do not zero PSTATE.IT - when Unpredictable_ILZEROT - return Constraint_FALSE; // Do not zero PSTATE.T - when Unpredictable_BPVECTORCATCHPRI - return Constraint_TRUE; // Debug Vector Catch: match on 2nd halfword - when Unpredictable_VCMATCHHALF - return Constraint_FALSE; // No match - when Unpredictable_VCMATCHDAPA - return Constraint_FALSE; // No match on Data Abort or Prefetch abort - when Unpredictable_WPMASKANDBAS - return Constraint_FALSE; // Watchpoint disabled - when Unpredictable_WPBASCONTIGUOUS - return Constraint_FALSE; // Watchpoint disabled - when Unpredictable_RESWPMASK - return Constraint_DISABLED; // Watchpoint disabled - when Unpredictable_WPMASKEDBITS - return Constraint_FALSE; // Watchpoint disabled - when Unpredictable_RESBPWPCTRL - return Constraint_DISABLED; // Breakpoint/watchpoint disabled - when Unpredictable_BPNOTIMPL - return Constraint_DISABLED; // Breakpoint disabled - when Unpredictable_RESBPTYPE - return Constraint_DISABLED; // Breakpoint disabled - when Unpredictable_BPNOTCTXCMP - return Constraint_DISABLED; // Breakpoint disabled - when Unpredictable_BPMATCHHALF - return Constraint_FALSE; // No match - when Unpredictable_BPMISMATCHHALF - return Constraint_FALSE; // No match - when Unpredictable_RESTARTALIGNPC - return Constraint_FALSE; // Do not force alignment - when Unpredictable_RESTARTZEROUPPERPC - return Constraint_TRUE; // Force zero extension - when Unpredictable_ZEROUPPER - return Constraint_TRUE; // zero top halves of X registers - when Unpredictable_ERETZEROUPPERPC - return Constraint_TRUE; // zero top half of PC - when Unpredictable_A32FORCEALIGNPC - return Constraint_FALSE; // Do not force alignment - when Unpredictable_SMD - return Constraint_UNDEF; // disabled SMC is Unallocated - when Unpredictable_NONFAULT - return Constraint_FALSE; // Speculation enabled - when Unpredictable_SVEZEROUPPER - return Constraint_TRUE; // zero top bits of Z registers - when Unpredictable_SVELDNFDATA - return Constraint_TRUE; // Load mem data in NF loads - when Unpredictable_SVELDNFZERO - return Constraint_TRUE; // Write zeros in NF loads - when Unpredictable_AFUPDATE // AF update for alignment or permission fault - return Constraint_TRUE; - when Unpredictable_IESBinDebug // Use SCTLR[].IESB in Debug state - return Constraint_TRUE; - when Unpredictable_BADPMSFCR // Bad settings for PMSFCR_EL1/PMSEVFR_EL1/PMSLATFR_EL1 - return Constraint_TRUE; - when Unpredictable_ZEROBTYPE - return Constraint_TRUE; // Save BTYPE in SPSR_ELx/DPSR_EL0 as '00' - when Unpredictable_CLEARERRITEZERO // Clearing sticky errors when instruction in flight - return Constraint_FALSE; - -// ConstrainUnpredictableBool() -// ============================ - -// This is a simple wrapper function for cases where the constrained result is either TRUE or FALSE. - -// NOTE: This version of the function uses an Unpredictable argument to define the call site. -// This argument does not appear in the version used in the Armv8 Architecture Reference Manual. -// See the NOTE on ConstrainUnpredictable() for more information. - -boolean ConstrainUnpredictableBool(Unpredictable which) - - c = ConstrainUnpredictable(which); - assert c IN {Constraint_TRUE, Constraint_FALSE}; - return (c == Constraint_TRUE); - -// HaveVirtHostExt() -// ================= - -boolean HaveVirtHostExt() - return HasArchVersion(ARMv8p1); - -// ELStateUsingAArch32K() -// ====================== - -(boolean,boolean) ELStateUsingAArch32K(bits(2) el, boolean secure) - // Returns (known, aarch32): - // 'known' is FALSE for EL0 if the current Exception level is not EL0 and EL1 is - // using AArch64, since it cannot determine the state of EL0; TRUE otherwise. - // 'aarch32' is TRUE if the specified Exception level is using AArch32; FALSE otherwise. - if !HaveAArch32EL(el) then - return (TRUE, FALSE); // Exception level is using AArch64 - elsif secure && el == EL2 then - return (TRUE, FALSE); // Secure EL2 is using AArch64 - elsif HighestELUsingAArch32() then - return (TRUE, TRUE); // Highest Exception level, and therefore all levels are using AArch32 - elsif el == HighestEL() then - return (TRUE, FALSE); // This is highest Exception level, so is using AArch64 - - // Remainder of function deals with the interprocessing cases when highest Exception level is using AArch64 - - boolean aarch32 = boolean UNKNOWN; - boolean known = TRUE; - - aarch32_below_el3 = HaveEL(EL3) && SCR_EL3.RW == '0' && (!secure || !HaveSecureEL2Ext() || SCR_EL3.EEL2 == '0'); - aarch32_at_el1 = (aarch32_below_el3 || (HaveEL(EL2) && - ((HaveSecureEL2Ext() && SCR_EL3.EEL2 == '1') || !secure) && HCR_EL2.RW == '0' && - !(HCR_EL2.E2H == '1' && HCR_EL2.TGE == '1' && HaveVirtHostExt()))); - if el == EL0 && !aarch32_at_el1 then // Only know if EL0 using AArch32 from PSTATE - if PSTATE.EL == EL0 then - aarch32 = PSTATE.nRW == '1'; // EL0 controlled by PSTATE - else - known = FALSE; // EL0 state is UNKNOWN - else - aarch32 = (aarch32_below_el3 && el != EL3) || (aarch32_at_el1 && el IN {EL1,EL0}); - - if !known then aarch32 = boolean UNKNOWN; - return (known, aarch32); - -// ELStateUsingAArch32() -// ===================== - -boolean ELStateUsingAArch32(bits(2) el, boolean secure) - // See ELStateUsingAArch32K() for description. Must only be called in circumstances where - // result is valid (typically, that means 'el IN {EL1,EL2,EL3}'). - (known, aarch32) = ELStateUsingAArch32K(el, secure); - assert known; - return aarch32; - -// ELUsingAArch32() -// ================ - -boolean ELUsingAArch32(bits(2) el) - return ELStateUsingAArch32(el, IsSecureBelowEL3()); - -// DebugTargetFrom() -// ================= - -bits(2) DebugTargetFrom(boolean secure) - if HaveEL(EL2) && (!secure || (HaveSecureEL2Ext() && - (!HaveEL(EL3) ||SCR_EL3.EEL2 == '1'))) then - if ELUsingAArch32(EL2) then - route_to_el2 = (HDCR.TDE == '1' || HCR.TGE == '1'); - else - route_to_el2 = (MDCR_EL2.TDE == '1' || HCR_EL2.TGE == '1'); - else - route_to_el2 = FALSE; - - if route_to_el2 then - target = EL2; - elsif HaveEL(EL3) && HighestELUsingAArch32() && secure then - target = EL3; - else - target = EL1; - - return target; - -// DebugTarget() -// ============= -// Returns the debug exception target Exception level - -bits(2) DebugTarget() - secure = IsSecure(); - return DebugTargetFrom(secure); - -// IsSecureEL2Enabled() -// ==================== -// Returns TRUE if Secure EL2 is enabled, FALSE otherwise. - -boolean IsSecureEL2Enabled() - if HaveEL(EL2) && HaveSecureEL2Ext() then - if HaveEL(EL3) then - if !ELUsingAArch32(EL3) && SCR_EL3.EEL2 == '1' then - return TRUE; - else - return FALSE; - else - return IsSecure(); - else - return FALSE; - -// ELIsInHost() -// ============ - -boolean ELIsInHost(bits(2) el) - return ((IsSecureEL2Enabled() || !IsSecureBelowEL3()) && HaveVirtHostExt() && !ELUsingAArch32(EL2) && - HCR_EL2.E2H == '1' && (el == EL2 || (el == EL0 && HCR_EL2.TGE == '1'))); - -// S1TranslationRegime() -// ===================== -// Stage 1 translation regime for the given Exception level - -bits(2) S1TranslationRegime(bits(2) el) - if el != EL0 then - return el; - elsif HaveEL(EL3) && ELUsingAArch32(EL3) && SCR.NS == '0' then - return EL3; - elsif HaveVirtHostExt() && ELIsInHost(el) then - return EL2; - else - return EL1; - -// S1TranslationRegime() -// ===================== -// Returns the Exception level controlling the current Stage 1 translation regime. For the most -// part this is unused in code because the system register accessors (SCTLR[], etc.) implicitly -// return the correct value. - -bits(2) S1TranslationRegime() - return S1TranslationRegime(PSTATE.EL); - -// VBAR[] - non-assignment form -// ============================ - -bits(64) VBAR[bits(2) regime] - bits(64) r; - case regime of - when EL1 r = VBAR_EL1; - when EL2 r = VBAR_EL2; - when EL3 r = VBAR_EL3; - otherwise Unreachable(); - return r; - -// VBAR[] - non-assignment form -// ============================ - -bits(64) VBAR[] - return VBAR[S1TranslationRegime()]; - -// ExcVectorBase() -// =============== - -bits(32) ExcVectorBase() - if SCTLR.V == '1' then // Hivecs selected, base = 0xFFFF0000 - return Ones(16):Zeros(16); - else - return VBAR[31:5]:Zeros(5); - -// AArch32.VCRMatch() -// ================== - -boolean AArch32.VCRMatch(bits(32) vaddress) - - if UsingAArch32() && ELUsingAArch32(EL1) && IsZero(vaddress[1:0]) && PSTATE.EL != EL2 then - // Each bit position in this string corresponds to a bit in DBGVCR and an exception vector. - match_word = Zeros(32); - - if vaddress[31:5] == ExcVectorBase()[31:5] then - if HaveEL(EL3) && !IsSecure() then - match_word[UInt(vaddress[4:2]) + 24] = '1'; // Non-secure vectors - else - match_word[UInt(vaddress[4:2]) + 0] = '1'; // Secure vectors (or no EL3) - - if HaveEL(EL3) && ELUsingAArch32(EL3) && IsSecure() && vaddress[31:5] == MVBAR[31:5] then - match_word[UInt(vaddress[4:2]) + 8] = '1'; // Monitor vectors - - // Mask out bits not corresponding to vectors. - if !HaveEL(EL3) then - mask = '00000000':'00000000':'00000000':'11011110'; // DBGVCR[31:8] are RES0 - elsif !ELUsingAArch32(EL3) then - mask = '11011110':'00000000':'00000000':'11011110'; // DBGVCR[15:8] are RES0 - else - mask = '11011110':'00000000':'11011100':'11011110'; - - match_word = match_word AND DBGVCR AND mask; - match = !IsZero(match_word); - - // Check for UNPREDICTABLE case - match on Prefetch Abort and Data Abort vectors - if !IsZero(match_word[28:27,12:11,4:3]) && DebugTarget() == PSTATE.EL then - match = ConstrainUnpredictableBool(Unpredictable_VCMATCHDAPA); - else - match = FALSE; - - return match; - -signal DBGEN; -signal NIDEN; -signal SPIDEN; -signal SPNIDEN; - -// AArch32.SelfHostedSecurePrivilegedInvasiveDebugEnabled() -// ======================================================== - -boolean AArch32.SelfHostedSecurePrivilegedInvasiveDebugEnabled() - // The definition of this function is IMPLEMENTATION DEFINED. - // In the recommended interface, AArch32.SelfHostedSecurePrivilegedInvasiveDebugEnabled returns - // the state of the (DBGEN AND SPIDEN) signal. - if !HaveEL(EL3) && !IsSecure() then return FALSE; - return DBGEN == HIGH && SPIDEN == HIGH; - -// ConstrainUnpredictableBits() -// ============================ - -// This is a variant of ConstrainUnpredictable for when the result can be Constraint_UNKNOWN. -// If the result is Constraint_UNKNOWN then the function also returns UNKNOWN value, but that -// value is always an allocated value; that is, one for which the behavior is not itself -// CONSTRAINED. - -// NOTE: This version of the function uses an Unpredictable argument to define the call site. -// This argument does not appear in the version used in the Armv8 Architecture Reference Manual. -// See the NOTE on ConstrainUnpredictable() for more information. - -// This is an example placeholder only and does not imply a fixed implementation of the bits part -// of the result, and may not be applicable in all cases. - -(Constraint,bits(width)) ConstrainUnpredictableBits(Unpredictable which) - - c = ConstrainUnpredictable(which); - - if c == Constraint_UNKNOWN then - return (c, Zeros(width)); // See notes; this is an example implementation only - else - return (c, bits(width) UNKNOWN); // bits result not used - -// ConstrainUnpredictableInteger() -// =============================== - -// This is a variant of ConstrainUnpredictable for when the result can be Constraint_UNKNOWN. If -// the result is Constraint_UNKNOWN then the function also returns an UNKNOWN value in the range -// low to high, inclusive. - -// NOTE: This version of the function uses an Unpredictable argument to define the call site. -// This argument does not appear in the version used in the Armv8 Architecture Reference Manual. -// See the NOTE on ConstrainUnpredictable() for more information. - -// This is an example placeholder only and does not imply a fixed implementation of the integer part -// of the result. - -(Constraint,integer) ConstrainUnpredictableInteger(integer low, integer high, Unpredictable which) - - c = ConstrainUnpredictable(which); - - if c == Constraint_UNKNOWN then - return (c, low); // See notes; this is an example implementation only - else - return (c, integer UNKNOWN); // integer result not used - -// EL2Enabled() -// ============ -// Returns TRUE if EL2 is present and executing -// - with SCR_EL3.NS==1 when Non-secure EL2 is implemented, or -// - with SCR_EL3.NS==0 when Secure EL2 is implemented and enabled, or -// - when EL3 is not implemented. - -boolean EL2Enabled() - return HaveEL(EL2) && (!HaveEL(EL3) || SCR_EL3.NS == '1' || IsSecureEL2Enabled()); - -// Halted() -// ======== - -boolean Halted() - return !(EDSCR.STATUS IN {'000001', '000010'}); // Halted - -// HaveDoubleLock() -// ================ -// Returns TRUE if support for the OS Double Lock is implemented. - -boolean HaveDoubleLock() - return !HasArchVersion(ARMv8p4) || boolean IMPLEMENTATION_DEFINED "OS Double Lock is implemented"; - -// DoubleLockStatus() -// ================== -// Returns the state of the OS Double Lock. -// FALSE if OSDLR_EL1.DLK == 0 or DBGPRCR_EL1.CORENPDRQ == 1 or the PE is in Debug state. -// TRUE if OSDLR_EL1.DLK == 1 and DBGPRCR_EL1.CORENPDRQ == 0 and the PE is in Non-debug state. - -boolean DoubleLockStatus() - if !HaveDoubleLock() then - return FALSE; - elsif ELUsingAArch32(EL1) then - return DBGOSDLR.DLK == '1' && DBGPRCR.CORENPDRQ == '0' && !Halted(); - else - return OSDLR_EL1.DLK == '1' && DBGPRCR_EL1.CORENPDRQ == '0' && !Halted(); - -// ExternalInvasiveDebugEnabled() -// ============================== -// The definition of this function is IMPLEMENTATION DEFINED. -// In the recommended interface, this function returns the state of the DBGEN signal. - -boolean ExternalInvasiveDebugEnabled() - return DBGEN == HIGH; - -// ExternalSecureInvasiveDebugEnabled() -// ==================================== -// The definition of this function is IMPLEMENTATION DEFINED. -// In the recommended interface, this function returns the state of the (DBGEN AND SPIDEN) signal. -// CoreSight allows asserting SPIDEN without also asserting DBGEN, but this is not recommended. - -boolean ExternalSecureInvasiveDebugEnabled() - if !HaveEL(EL3) && !IsSecure() then return FALSE; - return ExternalInvasiveDebugEnabled() && SPIDEN == HIGH; - -// HaltingAllowed() -// ================ -// Returns TRUE if halting is currently allowed, FALSE if halting is prohibited. - -boolean HaltingAllowed() - if Halted() || DoubleLockStatus() then - return FALSE; - elsif IsSecure() then - return ExternalSecureInvasiveDebugEnabled(); - else - return ExternalInvasiveDebugEnabled(); - -// HaltOnBreakpointOrWatchpoint() -// ============================== -// Returns TRUE if the Breakpoint and Watchpoint debug events should be considered for Debug -// state entry, FALSE if they should be considered for a debug exception. - -boolean HaltOnBreakpointOrWatchpoint() - return HaltingAllowed() && EDSCR.HDE == '1' && OSLSR_EL1.OSLK == '0'; - -// Have16bitVMID() -// =============== -// Returns TRUE if EL2 and support for a 16-bit VMID are implemented. - -boolean Have16bitVMID() - return HaveEL(EL2) && boolean IMPLEMENTATION_DEFINED; - -// AArch32.BreakpointValueMatch() -// ============================== -// The first result is whether an Address Match or Context breakpoint is programmed on the -// instruction at "address". The second result is whether an Address Mismatch breakpoint is -// programmed on the instruction, that is, whether the instruction should be stepped. - -(boolean,boolean) AArch32.BreakpointValueMatch(integer n, bits(32) vaddress, boolean linked_to) - - // "n" is the identity of the breakpoint unit to match against. - // "vaddress" is the current instruction address, ignored if linked_to is TRUE and for Context - // matching breakpoints. - // "linked_to" is TRUE if this is a call from StateMatch for linking. - - // If a non-existent breakpoint then it is CONSTRAINED UNPREDICTABLE whether this gives - // no match or the breakpoint is mapped to another UNKNOWN implemented breakpoint. - if n > UInt(DBGDIDR.BRPs) then - (c, n) = ConstrainUnpredictableInteger(0, UInt(DBGDIDR.BRPs), Unpredictable_BPNOTIMPL); - assert c IN {Constraint_DISABLED, Constraint_UNKNOWN}; - if c == Constraint_DISABLED then return (FALSE,FALSE); - - // If this breakpoint is not enabled, it cannot generate a match. (This could also happen on a - // call from StateMatch for linking). - if DBGBCR[n].E == '0' then return (FALSE,FALSE); - - context_aware = (n >= UInt(DBGDIDR.BRPs) - UInt(DBGDIDR.CTX_CMPs)); - - // If BT is set to a reserved type1, behaves either as disabled or as a not-reserved type1. - dbgtype = DBGBCR[n].BT; - - if ((dbgtype IN {'011x','11xx'} && !HaveVirtHostExt()) || // Context matching - (dbgtype == '010x' && HaltOnBreakpointOrWatchpoint()) || // Address mismatch - (dbgtype != '0x0x' && !context_aware) || // Context matching - (dbgtype == '1xxx' && !HaveEL(EL2))) then // EL2 extension - (c, dbgtype) = ConstrainUnpredictableBits(Unpredictable_RESBPTYPE); - assert c IN {Constraint_DISABLED, Constraint_UNKNOWN}; - if c == Constraint_DISABLED then return (FALSE,FALSE); - // Otherwise the value returned by ConstrainUnpredictableBits must be a not-reserved value - - // Determine what to compare against. - match_addr = (dbgtype == '0x0x'); - mismatch = (dbgtype == '010x'); - match_vmid = (dbgtype == '10xx'); - match_cid1 = (dbgtype == 'xx1x'); - match_cid2 = (dbgtype == '11xx'); - linked = (dbgtype == 'xxx1'); - - // If this is a call from StateMatch, return FALSE if the breakpoint is not programmed for a - // VMID and/or context ID match, of if not context-aware. The above assertions mean that the - // code can just test for match_addr == TRUE to confirm all these things. - if linked_to && (!linked || match_addr) then return (FALSE,FALSE); - - // If called from BreakpointMatch return FALSE for Linked context ID and/or VMID matches. - if !linked_to && linked && !match_addr then return (FALSE,FALSE); - - // Do the comparison. - if match_addr then - byte = UInt(vaddress[1:0]); - assert byte IN {0,2}; // "vaddress" is halfword aligned - byte_select_match = (DBGBCR[n].BAS[byte] == '1'); - BVR_match = vaddress[31:2] == DBGBVR[n][31:2] && byte_select_match; - elsif match_cid1 then - BVR_match = (PSTATE.EL != EL2 && CONTEXTIDR == DBGBVR[n][31:0]); - if match_vmid then - if ELUsingAArch32(EL2) then - vmid = ZeroExtend(VTTBR.VMID, 16); - bvr_vmid = ZeroExtend(DBGBXVR[n][7:0], 16); - elsif !Have16bitVMID() || VTCR_EL2.VS == '0' then - vmid = ZeroExtend(VTTBR_EL2.VMID[7:0], 16); - bvr_vmid = ZeroExtend(DBGBXVR[n][7:0], 16); - else - vmid = VTTBR_EL2.VMID; - bvr_vmid = DBGBXVR[n][15:0]; - BXVR_match = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - vmid == bvr_vmid); - elsif match_cid2 then - BXVR_match = (!IsSecure() && HaveVirtHostExt() && - !ELUsingAArch32(EL2) && - DBGBXVR[n][31:0] == CONTEXTIDR_EL2); - - bvr_match_valid = (match_addr || match_cid1); - bxvr_match_valid = (match_vmid || match_cid2); - - match = (!bxvr_match_valid || BXVR_match) && (!bvr_match_valid || BVR_match); - - return (match && !mismatch, !match && mismatch); - -// CheckValidStateMatch() -// ====================== -// Checks for an invalid state match that will generate Constrained Unpredictable behaviour, otherwise -// returns Constraint_NONE. - -(Constraint, bits(2), bit, bits(2)) CheckValidStateMatch(bits(2) SSC, bit HMC, bits(2) PxC, boolean isbreakpnt) - boolean reserved = FALSE; - - // Match 'Usr/Sys/Svc' only valid for AArch32 breakpoints - if (!isbreakpnt || !HaveAArch32EL(EL1)) && HMC:PxC == '000' && SSC != '11' then - reserved = TRUE; - - // Both EL3 and EL2 are not implemented - if !HaveEL(EL3) && !HaveEL(EL2) && (HMC != '0' || SSC != '00') then - reserved = TRUE; - - // EL3 is not implemented - if !HaveEL(EL3) && SSC IN {'01','10'} && HMC:SSC:PxC != '10100' then - reserved = TRUE; - - // EL3 using AArch64 only - if (!HaveEL(EL3) || HighestELUsingAArch32()) && HMC:SSC:PxC == '11000' then - reserved = TRUE; - - // EL2 is not implemented - if !HaveEL(EL2) && HMC:SSC:PxC == '11100' then - reserved = TRUE; - - // Secure EL2 is not implemented - if !HaveSecureEL2Ext() && (HMC:SSC:PxC) IN {'01100','10100','x11x1'} then - reserved = TRUE; - - // Values that are not allocated in any architecture version - if (HMC:SSC:PxC) IN {'01110','100x0','10110','11x10'} then - reserved = TRUE; - - if reserved then - // If parameters are set to a reserved type1, behaves as either disabled or a defined type1 - (c, [HMC,SSC,PxC]) = ConstrainUnpredictableBits(Unpredictable_RESBPWPCTRL); - assert c IN {Constraint_DISABLED, Constraint_UNKNOWN}; - if c == Constraint_DISABLED then - return (c, bits(2) UNKNOWN, bit UNKNOWN, bits(2) UNKNOWN); - // Otherwise the value returned by ConstrainUnpredictableBits must be a not-reserved value - - return (Constraint_NONE, SSC, HMC, PxC); - -// AArch32.StateMatch() -// ==================== -// Determine whether a breakpoint or watchpoint is enabled in the current mode and state. - -boolean AArch32.StateMatch(bits(2) SSC, bit HMC, bits(2) PxC, boolean linked, bits(4) LBN, - boolean isbreakpnt, boolean ispriv) - // "SSC", "HMC", "PxC" are the control fields from the DBGBCR[n] or DBGWCR[n] register. - // "linked" is TRUE if this is a linked breakpoint/watchpoint type1. - // "LBN" is the linked breakpoint number from the DBGBCR[n] or DBGWCR[n] register. - // "isbreakpnt" is TRUE for breakpoints, FALSE for watchpoints. - // "ispriv" is valid for watchpoints, and selects between privileged and unprivileged accesses. - - // If parameters are set to a reserved type1, behaves as either disabled or a defined type1 - (c, SSC, HMC, PxC) = CheckValidStateMatch(SSC, HMC, PxC, isbreakpnt); - if c == Constraint_DISABLED then return FALSE; - // Otherwise the HMC,SSC,PxC values are either valid or the values returned by - // CheckValidStateMatch are valid. - - PL2_match = HaveEL(EL2) && ((HMC == '1' && (SSC:PxC != '1000')) || SSC == '11'); - PL1_match = PxC[0] == '1'; - PL0_match = PxC[1] == '1'; - SSU_match = isbreakpnt && HMC == '0' && PxC == '00' && SSC != '11'; - - if !ispriv && !isbreakpnt then - priv_match = PL0_match; - elsif SSU_match then - priv_match = PSTATE.M IN {M32_User,M32_Svc,M32_System}; - else - case PSTATE.EL of - when EL3 priv_match = PL1_match; // EL3 and EL1 are both PL1 - when EL2 priv_match = PL2_match; - when EL1 priv_match = PL1_match; - when EL0 priv_match = PL0_match; - - case SSC of - when '00' security_state_match = TRUE; // Both - when '01' security_state_match = !IsSecure(); // Non-secure only - when '10' security_state_match = IsSecure(); // Secure only - when '11' security_state_match = (HMC == '1' || IsSecure()); // HMC=1 -> Both, 0 -> Secure only - - if linked then - // "LBN" must be an enabled context-aware breakpoint unit. If it is not context-aware then - // it is CONSTRAINED UNPREDICTABLE whether this gives no match, or LBN is mapped to some - // UNKNOWN breakpoint that is context-aware. - lbn = UInt(LBN); - first_ctx_cmp = (UInt(DBGDIDR.BRPs) - UInt(DBGDIDR.CTX_CMPs)); - last_ctx_cmp = UInt(DBGDIDR.BRPs); - if (lbn < first_ctx_cmp || lbn > last_ctx_cmp) then - (c, lbn) = ConstrainUnpredictableInteger(first_ctx_cmp, last_ctx_cmp, Unpredictable_BPNOTCTXCMP); - assert c IN {Constraint_DISABLED, Constraint_NONE, Constraint_UNKNOWN}; - case c of - when Constraint_DISABLED return FALSE; // Disabled - when Constraint_NONE linked = FALSE; // No linking - // Otherwise ConstrainUnpredictableInteger returned a context-aware breakpoint - - if linked then - vaddress = bits(32) UNKNOWN; - linked_to = TRUE; - (linked_match,-) = AArch32.BreakpointValueMatch(lbn, vaddress, linked_to); - - return priv_match && security_state_match && (!linked || linked_match); - -// AArch32.BreakpointMatch() -// ========================= -// Breakpoint matching in an AArch32 translation regime. - -(boolean,boolean) AArch32.BreakpointMatch(integer n, bits(32) vaddress, integer size) - assert ELUsingAArch32(S1TranslationRegime()); - assert n <= UInt(DBGDIDR.BRPs); - - enabled = DBGBCR[n].E == '1'; - ispriv = PSTATE.EL != EL0; - linked = DBGBCR[n].BT == '0x01'; - isbreakpnt = TRUE; - linked_to = FALSE; - - state_match = AArch32.StateMatch(DBGBCR[n].SSC, DBGBCR[n].HMC, DBGBCR[n].PMC, - linked, DBGBCR[n].LBN, isbreakpnt, ispriv); - (value_match, value_mismatch) = AArch32.BreakpointValueMatch(n, vaddress, linked_to); - - if size == 4 then // Check second halfword - // If the breakpoint address and BAS of an Address breakpoint match the address of the - // second halfword of an instruction, but not the address of the first halfword, it is - // CONSTRAINED UNPREDICTABLE whether or not this breakpoint generates a Breakpoint debug - // event. - (match_i, mismatch_i) = AArch32.BreakpointValueMatch(n, vaddress + 2, linked_to); - if !value_match && match_i then - value_match = ConstrainUnpredictableBool(Unpredictable_BPMATCHHALF); - if value_mismatch && !mismatch_i then - value_mismatch = ConstrainUnpredictableBool(Unpredictable_BPMISMATCHHALF); - if vaddress[1] == '1' && DBGBCR[n].BAS == '1111' then - // The above notwithstanding, if DBGBCR[n].BAS == '1111', then it is CONSTRAINED - // UNPREDICTABLE whether or not a Breakpoint debug event is generated for an instruction - // at the address DBGBVR[n]+2. - if value_match then value_match = ConstrainUnpredictableBool(Unpredictable_BPMATCHHALF); - if !value_mismatch then value_mismatch = ConstrainUnpredictableBool(Unpredictable_BPMISMATCHHALF); - - match = value_match && state_match && enabled; - mismatch = value_mismatch && state_match && enabled; - - return (match, mismatch); - -// AArch64.GenerateDebugExceptionsFrom() -// ===================================== - -boolean AArch64.GenerateDebugExceptionsFrom(bits(2) from, boolean secure, bit mask) - - if OSLSR_EL1.OSLK == '1' || DoubleLockStatus() || Halted() then - return FALSE; - - route_to_el2 = HaveEL(EL2) && (!secure || IsSecureEL2Enabled()) && (HCR_EL2.TGE == '1' || MDCR_EL2.TDE == '1'); - target = (if route_to_el2 then EL2 else EL1); - enabled = !HaveEL(EL3) || !secure || MDCR_EL3.SDD == '0'; - - if from == target then - enabled = enabled && MDSCR_EL1.KDE == '1' && mask == '0'; - else - enabled = enabled && UInt(target) > UInt(from); - - return enabled; - -// AArch32.GenerateDebugExceptionsFrom() -// ===================================== - -boolean AArch32.GenerateDebugExceptionsFrom(bits(2) from, boolean secure) - - if from == EL0 && !ELStateUsingAArch32(EL1, secure) then - mask = bit UNKNOWN; // PSTATE.D mask, unused for EL0 case - return AArch64.GenerateDebugExceptionsFrom(from, secure, mask); - - if DBGOSLSR.OSLK == '1' || DoubleLockStatus() || Halted() then - return FALSE; - - if HaveEL(EL3) && secure then - spd = if ELUsingAArch32(EL3) then SDCR.SPD else MDCR_EL3.SPD32; - if spd[1] == '1' then - enabled = spd[0] == '1'; - else - // SPD == 0b01 is reserved, but behaves the same as 0b00. - enabled = AArch32.SelfHostedSecurePrivilegedInvasiveDebugEnabled(); - if from == EL0 then enabled = enabled || SDER.SUIDEN == '1'; - else - enabled = from != EL2; - - return enabled; - -// AArch32.GenerateDebugExceptions() -// ================================= - -boolean AArch32.GenerateDebugExceptions() - return AArch32.GenerateDebugExceptionsFrom(PSTATE.EL, IsSecure()); - -enumeration CrossTriggerOut {CrossTriggerOut_DebugRequest, CrossTriggerOut_RestartRequest, - CrossTriggerOut_IRQ, CrossTriggerOut_RSVD3, - CrossTriggerOut_TraceExtIn0, CrossTriggerOut_TraceExtIn1, - CrossTriggerOut_TraceExtIn2, CrossTriggerOut_TraceExtIn3}; - -enumeration CrossTriggerIn {CrossTriggerIn_CrossHalt, CrossTriggerIn_PMUOverflow, - CrossTriggerIn_RSVD2, CrossTriggerIn_RSVD3, - CrossTriggerIn_TraceExtOut0, CrossTriggerIn_TraceExtOut1, - CrossTriggerIn_TraceExtOut2, CrossTriggerIn_TraceExtOut3}; - -enumeration InterruptID {InterruptID_PMUIRQ, InterruptID_COMMIRQ, InterruptID_CTIIRQ, - InterruptID_COMMRX, InterruptID_COMMTX}; - -// AArch64.CheckForPMUOverflow() -// ============================= -// Signal Performance Monitors overflow IRQ and CTI overflow events - -boolean AArch64.CheckForPMUOverflow() - - pmuirq = PMCR_EL0.E == '1' && PMINTENSET_EL1[31] == '1' && PMOVSSET_EL0[31] == '1'; - for n = 0 to UInt(PMCR_EL0.N) - 1 - if HaveEL(EL2) then - E = (if n < UInt(MDCR_EL2.HPMN) then PMCR_EL0.E else MDCR_EL2.HPME); - else - E = PMCR_EL0.E; - if E == '1' && PMINTENSET_EL1[n] == '1' && PMOVSSET_EL0[n] == '1' then pmuirq = TRUE; - - SetInterruptRequestLevel(InterruptID_PMUIRQ, if pmuirq then HIGH else LOW); - - CTI_SetEventLevel(CrossTriggerIn_PMUOverflow, if pmuirq then HIGH else LOW); - - // The request remains set until the condition is cleared. (For example, an interrupt handler - // or cross-triggered event handler clears the overflow status flag by writing to PMOVSCLR_EL0.) - - return pmuirq; - -// AArch32.CheckForPMUOverflow() -// ============================= -// Signal Performance Monitors overflow IRQ and CTI overflow events - -boolean AArch32.CheckForPMUOverflow() - - if !ELUsingAArch32(EL1) then return AArch64.CheckForPMUOverflow(); - pmuirq = PMCR.E == '1' && PMINTENSET[31] == '1' && PMOVSSET[31] == '1'; - for n = 0 to UInt(PMCR.N) - 1 - if HaveEL(EL2) then - hpmn = if !ELUsingAArch32(EL2) then MDCR_EL2.HPMN else HDCR.HPMN; - hpme = if !ELUsingAArch32(EL2) then MDCR_EL2.HPME else HDCR.HPME; - E = (if n < UInt(hpmn) then PMCR.E else hpme); - else - E = PMCR.E; - if E == '1' && PMINTENSET[n] == '1' && PMOVSSET[n] == '1' then pmuirq = TRUE; - - SetInterruptRequestLevel(InterruptID_PMUIRQ, if pmuirq then HIGH else LOW); - - CTI_SetEventLevel(CrossTriggerIn_PMUOverflow, if pmuirq then HIGH else LOW); - - // The request remains set until the condition is cleared. (For example, an interrupt handler - // or cross-triggered event handler clears the overflow status flag by writing to PMOVSCLR_EL0.) - - return pmuirq; - -// HaveNoninvasiveDebugAuth() -// ========================== -// Returns TRUE if the Non-invasive debug controls are implemented. - -boolean HaveNoninvasiveDebugAuth() - return !HasArchVersion(ARMv8p4); - -// ExternalNoninvasiveDebugEnabled() -// ================================= -// This function returns TRUE if the ARMv8.4-Debug is implemented, otherwise this -// function is IMPLEMENTATION DEFINED. -// In the recommended interface, ExternalNoninvasiveDebugEnabled returns the state of the (DBGEN -// OR NIDEN) signal. - -boolean ExternalNoninvasiveDebugEnabled() - return !HaveNoninvasiveDebugAuth() || ExternalInvasiveDebugEnabled() || NIDEN == HIGH; - -// ExternalSecureNoninvasiveDebugEnabled() -// ======================================= -// This function returns the value of ExternalSecureInvasiveDebugEnabled() when ARMv8.4-Debug -// is implemented. Otherwise, the definition of this function is IMPLEMENTATION DEFINED. -// In the recommended interface, this function returns the state of the (DBGEN OR NIDEN) AND -// (SPIDEN OR SPNIDEN) signal. - -boolean ExternalSecureNoninvasiveDebugEnabled() - if !HaveEL(EL3) && !IsSecure() then return FALSE; - if HaveNoninvasiveDebugAuth() then - return ExternalNoninvasiveDebugEnabled() && (SPIDEN == HIGH || SPNIDEN == HIGH); - else - return ExternalSecureInvasiveDebugEnabled(); - -// HaveHPMDExt() -// ============= - -boolean HaveHPMDExt() - return HasArchVersion(ARMv8p1); - -// HaveNoSecurePMUDisableOverride() -// ================================ - -boolean HaveNoSecurePMUDisableOverride() - return HasArchVersion(ARMv8p2); - -// AArch64.CountEvents() -// ===================== -// Return TRUE if counter "n" should count its event. For the cycle counter, n == 31. - -boolean AArch64.CountEvents(integer n) - assert n == 31 || n < UInt(PMCR_EL0.N); - - // Event counting is disabled in Debug state - debug = Halted(); - - // In Non-secure state, some counters are reserved for EL2 - if HaveEL(EL2) then - E = if n < UInt(MDCR_EL2.HPMN) || n == 31 then PMCR_EL0.E else MDCR_EL2.HPME; - else - E = PMCR_EL0.E; - enabled = E == '1' && PMCNTENSET_EL0[n] == '1'; - - // Event counting in Secure state is prohibited unless any one of: - // * EL3 is not implemented - // * EL3 is using AArch64 and MDCR_EL3.SPME == 1 - prohibited = HaveEL(EL3) && IsSecure() && MDCR_EL3.SPME == '0'; - - // Event counting at EL2 is prohibited if all of: - // * The HPMD Extension is implemented - // * Executing at EL2 - // * PMNx is not reserved for EL2 - // * MDCR_EL2.HPMD == 1 - if !prohibited && HaveEL(EL2) && HaveHPMDExt() && PSTATE.EL == EL2 && (n < UInt(MDCR_EL2.HPMN) || n == 31) then - prohibited = (MDCR_EL2.HPMD == '1'); - - // The IMPLEMENTATION DEFINED authentication interface might override software controls - if prohibited && !HaveNoSecurePMUDisableOverride() then - prohibited = !ExternalSecureNoninvasiveDebugEnabled(); - // For the cycle counter, PMCR_EL0.DP enables counting when otherwise prohibited - if prohibited && n == 31 then prohibited = (PMCR_EL0.DP == '1'); - - // Event counting can be filtered by the {P, U, NSK, NSU, NSH, M, SH} bits - filter = if n == 31 then PMCCFILTR else PMEVTYPER[n]; - - P = filter[31]; - U = filter[30]; - NSK = if HaveEL(EL3) then filter[29] else '0'; - NSU = if HaveEL(EL3) then filter[28] else '0'; - NSH = if HaveEL(EL2) then filter[27] else '0'; - M = if HaveEL(EL3) then filter[26] else '0'; - SH = if HaveSecureEL2Ext() then filter[24] else '0'; - - case PSTATE.EL of - when EL0 filtered = if IsSecure() then U == '1' else U != NSU; - when EL1 filtered = if IsSecure() then P == '1' else P != NSK; - when EL2 filtered = (if IsSecure() then NSH == SH else NSH == '0'); - when EL3 filtered = (M != P); - - return !debug && enabled && !prohibited && !filtered; - -// AArch32.CountEvents() -// ===================== -// Return TRUE if counter "n" should count its event. For the cycle counter, n == 31. - -boolean AArch32.CountEvents(integer n) - assert n == 31 || n < UInt(PMCR.N); - - if !ELUsingAArch32(EL1) then return AArch64.CountEvents(n); - // Event counting is disabled in Debug state - debug = Halted(); - - // In Non-secure state, some counters are reserved for EL2 - if HaveEL(EL2) then - hpmn = if !ELUsingAArch32(EL2) then MDCR_EL2.HPMN else HDCR.HPMN; - hpme = if !ELUsingAArch32(EL2) then MDCR_EL2.HPME else HDCR.HPME; - if HaveHPMDExt() then - hpmd = if !ELUsingAArch32(EL2) then MDCR_EL2.HPMD else HDCR.HPMD; - E = if n < UInt(hpmn) || n == 31 then PMCR.E else hpme; - else - E = PMCR.E; - enabled = E == '1' && PMCNTENSET[n] == '1'; - - // Event counting in Secure state is prohibited unless any one of: - // * EL3 is not implemented - // * EL3 is using AArch64 and MDCR_EL3.SPME == 1 - // * EL3 is using AArch32 and SDCR.SPME == 1 - // * Executing at EL0, and SDER.SUNIDEN == 1. - spme = (if ELUsingAArch32(EL3) then SDCR.SPME else MDCR_EL3.SPME); - prohibited = HaveEL(EL3) && IsSecure() && spme == '0' && (PSTATE.EL != EL0 || SDER.SUNIDEN == '0'); - - // Event counting at EL2 is prohibited if all of: - // * The HPMD Extension is implemented - // * Executing at EL2 - // * PMNx is not reserved for EL2 - // * HDCR.HPMD == 1 - if !prohibited && HaveEL(EL2) && HaveHPMDExt() && PSTATE.EL == EL2 && (n < UInt(hpmn) || n == 31) then - prohibited = (hpmd == '1'); - - // The IMPLEMENTATION DEFINED authentication interface might override software controls - if prohibited && !HaveNoSecurePMUDisableOverride() then - prohibited = !ExternalSecureNoninvasiveDebugEnabled(); - // For the cycle counter, PMCR.DP enables counting when otherwise prohibited - if prohibited && n == 31 then prohibited = (PMCR.DP == '1'); - - // Event counting can be filtered by the {P, U, NSK, NSU, NSH} bits - filter = if n == 31 then PMCCFILTR else PMEVTYPER[n]; - - P = filter[31]; - U = filter[30]; - NSK = if HaveEL(EL3) then filter[29] else '0'; - NSU = if HaveEL(EL3) then filter[28] else '0'; - NSH = if HaveEL(EL2) then filter[27] else '0'; - - case PSTATE.EL of - when EL0 filtered = if IsSecure() then U == '1' else U != NSU; - when EL1 filtered = if IsSecure() then P == '1' else P != NSK; - when EL2 filtered = (NSH == '0'); - when EL3 filtered = (P == '1'); - - return !debug && enabled && !prohibited && !filtered; - -enumeration Exception {Exception_Uncategorized, // Uncategorized or unknown reason - Exception_WFxTrap, // Trapped WFI or WFE instruction - Exception_CP15RTTrap, // Trapped AArch32 MCR or MRC access to CP15 - Exception_CP15RRTTrap, // Trapped AArch32 MCRR or MRRC access to CP15 - Exception_CP14RTTrap, // Trapped AArch32 MCR or MRC access to CP14 - Exception_CP14DTTrap, // Trapped AArch32 LDC or STC access to CP14 - Exception_AdvSIMDFPAccessTrap, // HCPTR-trapped access to SIMD or FP - Exception_FPIDTrap, // Trapped access to SIMD or FP ID register - // Trapped BXJ instruction not supported in Armv8 - Exception_PACTrap, // Trapped invalid PAC use - Exception_CP14RRTTrap, // Trapped MRRC access to CP14 from AArch32 - Exception_IllegalState, // Illegal Execution state - Exception_SupervisorCall, // Supervisor Call - Exception_HypervisorCall, // Hypervisor Call - Exception_MonitorCall, // Monitor Call or Trapped SMC instruction - Exception_SystemRegisterTrap, // Trapped MRS or MSR system register access - Exception_ERetTrap, // Trapped invalid ERET use - Exception_InstructionAbort, // Instruction Abort or Prefetch Abort - Exception_PCAlignment, // PC alignment fault - Exception_DataAbort, // Data Abort - Exception_NV2DataAbort, // Data abort at EL1 reported as being from EL2 - Exception_PACFail, // PAC Authentication failure - Exception_SPAlignment, // SP alignment fault - Exception_FPTrappedException, // IEEE trapped FP exception - Exception_SError, // SError interrupt - Exception_Breakpoint, // (Hardware) Breakpoint - Exception_SoftwareStep, // Software Step - Exception_Watchpoint, // Watchpoint - Exception_NV2Watchpoint, // Watchpoint at EL1 reported as being from EL2 - Exception_SoftwareBreakpoint, // Software Breakpoint Instruction - Exception_VectorCatch, // AArch32 Vector Catch - Exception_IRQ, // IRQ interrupt - Exception_SVEAccessTrap, // HCPTR trapped access to SVE - Exception_BranchTarget, // Branch Target Identification - Exception_FIQ}; // FIQ interrupt - -integer ThisInstrLength(); - -// AArch32.ExceptionClass() -// ======================== -// Returns the Exception Class and Instruction Length fields to be reported in HSR - -(integer,bit) AArch32.ExceptionClass(Exception exceptype) - - il = if ThisInstrLength() == 32 then '1' else '0'; - - case exceptype of - when Exception_Uncategorized ec = 0x00; il = '1'; - when Exception_WFxTrap ec = 0x01; - when Exception_CP15RTTrap ec = 0x03; - when Exception_CP15RRTTrap ec = 0x04; - when Exception_CP14RTTrap ec = 0x05; - when Exception_CP14DTTrap ec = 0x06; - when Exception_AdvSIMDFPAccessTrap ec = 0x07; - when Exception_FPIDTrap ec = 0x08; - when Exception_PACTrap ec = 0x09; - when Exception_CP14RRTTrap ec = 0x0C; - when Exception_BranchTarget ec = 0x0D; - when Exception_IllegalState ec = 0x0E; il = '1'; - when Exception_SupervisorCall ec = 0x11; - when Exception_HypervisorCall ec = 0x12; - when Exception_MonitorCall ec = 0x13; - when Exception_ERetTrap ec = 0x1A; - when Exception_PACFail ec = 0x1C; - when Exception_InstructionAbort ec = 0x20; il = '1'; - when Exception_PCAlignment ec = 0x22; il = '1'; - when Exception_DataAbort ec = 0x24; - when Exception_NV2DataAbort ec = 0x25; - when Exception_FPTrappedException ec = 0x28; - otherwise Unreachable(); - - if ec IN {0x20,0x24} && PSTATE.EL == EL2 then - ec = ec + 1; - - return (ec,il); - -type ExceptionRecord is (Exception exceptype, // Exception class - bits(25) syndrome, // Syndrome record - bits(64) vaddress, // Virtual fault address - boolean ipavalid, // Physical fault address for second stage faults is valid - bits(1) NS, // Physical fault address for second stage faults is Non-secure or secure - bits(52) ipaddress) // Physical fault address for second stage faults - -// AArch32.ReportHypEntry() -// ======================== -// Report syndrome information to Hyp mode registers. - -AArch32.ReportHypEntry(ExceptionRecord exception) - - Exception exceptype = exception.exceptype; - - (ec,il) = AArch32.ExceptionClass(exceptype); - iss = exception.syndrome; - - // IL is not valid for Data Abort exceptions without valid instruction syndrome information - if ec IN {0x24,0x25} && iss[24] == '0' then - il = '1'; - - HSR = ec[5:0]:il:iss; - - if exceptype IN {Exception_InstructionAbort, Exception_PCAlignment} then - HIFAR = exception.vaddress[31:0]; - HDFAR = bits(32) UNKNOWN; - elsif exceptype == Exception_DataAbort then - HIFAR = bits(32) UNKNOWN; - HDFAR = exception.vaddress[31:0]; - - if exception.ipavalid then - HPFAR[31:4] = exception.ipaddress[39:12]; - else - HPFAR[31:4] = bits(28) UNKNOWN; - - return; - -// ELFromM32() -// =========== - -(boolean,bits(2)) ELFromM32(bits(5) mode) - // Convert an AArch32 mode encoding to an Exception level. - // Returns (valid,EL): - // 'valid' is TRUE if 'mode[4:0]' encodes a mode that is both valid for this implementation - // and the current value of SCR.NS/SCR_EL3.NS. - // 'EL' is the Exception level decoded from 'mode'. - bits(2) el; - boolean valid = !BadMode(mode); // Check for modes that are not valid for this implementation - case mode of - when M32_Monitor - el = EL3; - when M32_Hyp - el = EL2; - valid = valid && (!HaveEL(EL3) || SCR_GEN[].NS == '1'); - when M32_FIQ, M32_IRQ, M32_Svc, M32_Abort, M32_Undef, M32_System - // If EL3 is implemented and using AArch32, then these modes are EL3 modes in Secure - // state, and EL1 modes in Non-secure state. If EL3 is not implemented or is using - // AArch64, then these modes are EL1 modes. - el = (if HaveEL(EL3) && HighestELUsingAArch32() && SCR.NS == '0' then EL3 else EL1); - when M32_User - el = EL0; - otherwise - valid = FALSE; // Passed an illegal mode value - if !valid then el = bits(2) UNKNOWN; - return (valid, el); - -// AArch32.WriteMode() -// =================== -// Function for dealing with writes to PSTATE.M from AArch32 state only. -// This ensures that PSTATE.EL and PSTATE.SP are always valid. - -AArch32.WriteMode(bits(5) mode) - (valid,el) = ELFromM32(mode); - assert valid; - PSTATE.M = mode; - PSTATE.EL = el; - PSTATE.nRW = '1'; - PSTATE.SP = (if mode IN {M32_User,M32_System} then '0' else '1'); - return; - -// Terminate processing of the current instruction. -EndOfInstruction(); - -// HaveSSBSExt() -// ============= -// Returns TRUE if support for SSBS is implemented, and FALSE otherwise. - -boolean HaveSSBSExt() - return HasArchVersion(ARMv8p5) || boolean IMPLEMENTATION_DEFINED "Has SSBS extension"; - -// SPSR[] - non-assignment form -// ============================ - -bits(32) SPSR[] - bits(32) result; - if UsingAArch32() then - case PSTATE.M of - when M32_FIQ result = SPSR_fiq; - when M32_IRQ result = SPSR_irq; - when M32_Svc result = SPSR_svc; - when M32_Monitor result = SPSR_mon; - when M32_Abort result = SPSR_abt; - when M32_Hyp result = SPSR_hyp; - when M32_Undef result = SPSR_und; - otherwise Unreachable(); - else - case PSTATE.EL of - when EL1 result = SPSR_EL1; - when EL2 result = SPSR_EL2; - when EL3 result = SPSR_EL3; - otherwise Unreachable(); - return result; - -// SPSR[] - assignment form -// ======================== - -SPSR[] = bits(32) value - if UsingAArch32() then - case PSTATE.M of - when M32_FIQ SPSR_fiq = value; - when M32_IRQ SPSR_irq = value; - when M32_Svc SPSR_svc = value; - when M32_Monitor SPSR_mon = value; - when M32_Abort SPSR_abt = value; - when M32_Hyp SPSR_hyp = value; - when M32_Undef SPSR_und = value; - otherwise Unreachable(); - else - case PSTATE.EL of - when EL1 SPSR_EL1 = value; - when EL2 SPSR_EL2 = value; - when EL3 SPSR_EL3 = value; - otherwise Unreachable(); - return; - -SynchronizeContext(); - -// UpdateEDSCRFields() -// =================== -// Update EDSCR PE state fields - -UpdateEDSCRFields() - - if !Halted() then - EDSCR.EL = '00'; - EDSCR.NS = bit UNKNOWN; - EDSCR.RW = '1111'; - else - EDSCR.EL = PSTATE.EL; - EDSCR.NS = if IsSecure() then '0' else '1'; - - bits(4) RW; - RW[1] = if ELUsingAArch32(EL1) then '0' else '1'; - if PSTATE.EL != EL0 then - RW[0] = RW[1]; - else - RW[0] = if UsingAArch32() then '0' else '1'; - if !HaveEL(EL2) || (HaveEL(EL3) && SCR_GEN[].NS == '0' && !IsSecureEL2Enabled()) then - RW[2] = RW[1]; - else - RW[2] = if ELUsingAArch32(EL2) then '0' else '1'; - if !HaveEL(EL3) then - RW[3] = RW[2]; - else - RW[3] = if ELUsingAArch32(EL3) then '0' else '1'; - - // The least-significant bits of EDSCR.RW are UNKNOWN if any higher EL is using AArch32. - if RW[3] == '0' then RW[2:0] = bits(3) UNKNOWN; - elsif RW[2] == '0' then RW[1:0] = bits(2) UNKNOWN; - elsif RW[1] == '0' then RW[0] = bit UNKNOWN; - EDSCR.RW = RW; - return; - -// AArch32.EnterHypModeInDebugState() -// ================================== -// Take an exception in Debug state to Hyp mode. - -AArch32.EnterHypModeInDebugState(ExceptionRecord exception) - SynchronizeContext(); - assert HaveEL(EL2) && !IsSecure() && ELUsingAArch32(EL2); - - AArch32.ReportHypEntry(exception); - AArch32.WriteMode(M32_Hyp); - SPSR[] = bits(32) UNKNOWN; - ELR_hyp = bits(32) UNKNOWN; - // In Debug state, the PE always execute T32 instructions when in AArch32 state, and - // PSTATE.{SS,A,I,F} are not observable so behave as UNKNOWN. - PSTATE.T = '1'; // PSTATE.J is RES0 - PSTATE.[SS,A,I,F] = bits(4) UNKNOWN; - DLR = bits(32) UNKNOWN; - DSPSR = bits(32) UNKNOWN; - PSTATE.E = HSCTLR.EE; - PSTATE.IL = '0'; - PSTATE.IT = '00000000'; - if HaveSSBSExt() then PSTATE.SSBS = bit UNKNOWN; - EDSCR.ERR = '1'; - UpdateEDSCRFields(); - - EndOfInstruction(); - -// HavePANExt() -// ============ - -boolean HavePANExt() - return HasArchVersion(ARMv8p1); - -// AArch32.EnterModeInDebugState() -// =============================== -// Take an exception in Debug state to a mode other than Monitor and Hyp mode. - -AArch32.EnterModeInDebugState(bits(5) target_mode) - SynchronizeContext(); - assert ELUsingAArch32(EL1) && PSTATE.EL != EL2; - - if PSTATE.M == M32_Monitor then SCR.NS = '0'; - AArch32.WriteMode(target_mode); - SPSR[] = bits(32) UNKNOWN; - R[14] = bits(32) UNKNOWN; - // In Debug state, the PE always execute T32 instructions when in AArch32 state, and - // PSTATE.{SS,A,I,F} are not observable so behave as UNKNOWN. - PSTATE.T = '1'; // PSTATE.J is RES0 - PSTATE.[SS,A,I,F] = bits(4) UNKNOWN; - DLR = bits(32) UNKNOWN; - DSPSR = bits(32) UNKNOWN; - PSTATE.E = SCTLR.EE; - PSTATE.IL = '0'; - PSTATE.IT = '00000000'; - if HavePANExt() && SCTLR.SPAN == '0' then PSTATE.PAN = '1'; - if HaveSSBSExt() then PSTATE.SSBS = bit UNKNOWN; - EDSCR.ERR = '1'; - UpdateEDSCRFields(); // Update EDSCR processor state flags. - - EndOfInstruction(); - -// AArch32.EnterMonitorModeInDebugState() -// ====================================== -// Take an exception in Debug state to Monitor mode. - -AArch32.EnterMonitorModeInDebugState() - SynchronizeContext(); - assert HaveEL(EL3) && ELUsingAArch32(EL3); - from_secure = IsSecure(); - if PSTATE.M == M32_Monitor then SCR.NS = '0'; - AArch32.WriteMode(M32_Monitor); - SPSR[] = bits(32) UNKNOWN; - R[14] = bits(32) UNKNOWN; - // In Debug state, the PE always execute T32 instructions when in AArch32 state, and - // PSTATE.{SS,A,I,F} are not observable so behave as UNKNOWN. - PSTATE.T = '1'; // PSTATE.J is RES0 - PSTATE.[SS,A,I,F] = bits(4) UNKNOWN; - PSTATE.E = SCTLR.EE; - PSTATE.IL = '0'; - PSTATE.IT = '00000000'; - if HavePANExt() then - if !from_secure then - PSTATE.PAN = '0'; - elsif SCTLR.SPAN == '0' then - PSTATE.PAN = '1'; - if HaveSSBSExt() then PSTATE.SSBS = bit UNKNOWN; - DLR = bits(32) UNKNOWN; - DSPSR = bits(32) UNKNOWN; - EDSCR.ERR = '1'; - UpdateEDSCRFields(); // Update EDSCR processor state flags. - - EndOfInstruction(); - -// AArch32.WatchpointByteMatch() -// ============================= - -boolean AArch32.WatchpointByteMatch(integer n, bits(32) vaddress) - - bottom = if DBGWVR[n][2] == '1' then 2 else 3; // Word or doubleword - byte_select_match = (DBGWCR[n].BAS[UInt(vaddress[bottom-1:0])] != '0'); - mask = UInt(DBGWCR[n].MASK); - - // If DBGWCR[n].MASK is non-zero value and DBGWCR[n].BAS is not set to '11111111', or - // DBGWCR[n].BAS specifies a non-contiguous set of bytes behavior is CONSTRAINED - // UNPREDICTABLE. - if mask > 0 && !IsOnes(DBGWCR[n].BAS) then - byte_select_match = ConstrainUnpredictableBool(Unpredictable_WPMASKANDBAS); - else - LSB = (DBGWCR[n].BAS AND NOT(DBGWCR[n].BAS - 1)); MSB = (DBGWCR[n].BAS + LSB); - if !IsZero(MSB AND (MSB - 1)) then // Not contiguous - byte_select_match = ConstrainUnpredictableBool(Unpredictable_WPBASCONTIGUOUS); - bottom = 3; // For the whole doubleword - - // If the address mask is set to a reserved value, the behavior is CONSTRAINED UNPREDICTABLE. - if mask > 0 && mask <= 2 then - (c, mask) = ConstrainUnpredictableInteger(3, 31, Unpredictable_RESWPMASK); - assert c IN {Constraint_DISABLED, Constraint_NONE, Constraint_UNKNOWN}; - case c of - when Constraint_DISABLED return FALSE; // Disabled - when Constraint_NONE mask = 0; // No masking - // Otherwise the value returned by ConstrainUnpredictableInteger is a not-reserved value - - if mask > bottom then - WVR_match = (vaddress[31:mask] == DBGWVR[n][31:mask]); - // If masked bits of DBGWVR_EL1[n] are not zero, the behavior is CONSTRAINED UNPREDICTABLE. - if WVR_match && !IsZero(DBGWVR[n][mask-1:bottom]) then - WVR_match = ConstrainUnpredictableBool(Unpredictable_WPMASKEDBITS); - else - WVR_match = vaddress[31:bottom] == DBGWVR[n][31:bottom]; - - return WVR_match && byte_select_match; - -// AArch32.WatchpointMatch() -// ========================= -// Watchpoint matching in an AArch32 translation regime. - -boolean AArch32.WatchpointMatch(integer n, bits(32) vaddress, integer size, boolean ispriv, - boolean iswrite) - assert ELUsingAArch32(S1TranslationRegime()); - assert n <= UInt(DBGDIDR.WRPs); - - // "ispriv" is FALSE for LDRT/STRT instructions executed at EL1 and all - // load/stores at EL0, TRUE for all other load/stores. "iswrite" is TRUE for stores, FALSE for - // loads. - enabled = DBGWCR[n].E == '1'; - linked = DBGWCR[n].WT == '1'; - isbreakpnt = FALSE; - - state_match = AArch32.StateMatch(DBGWCR[n].SSC, DBGWCR[n].HMC, DBGWCR[n].PAC, - linked, DBGWCR[n].LBN, isbreakpnt, ispriv); - - ls_match = (DBGWCR[n].LSC[(if iswrite then 1 else 0)] == '1'); - - value_match = FALSE; - for byte = 0 to size - 1 - value_match = value_match || AArch32.WatchpointByteMatch(n, vaddress + byte); - - return value_match && state_match && ls_match && enabled; - -enumeration AccType {AccType_NORMAL, AccType_VEC, // Normal loads and stores - AccType_STREAM, AccType_VECSTREAM, // Streaming loads and stores - AccType_ATOMIC, AccType_ATOMICRW, // Atomic loads and stores - AccType_ORDERED, AccType_ORDEREDRW, // Load-Acquire and Store-Release - AccType_ORDEREDATOMIC, // Load-Acquire and Store-Release with atomic access - AccType_ORDEREDATOMICRW, - AccType_LIMITEDORDERED, // Load-LOAcquire and Store-LORelease - AccType_UNPRIV, // Load and store unprivileged - AccType_IFETCH, // Instruction fetch - AccType_PTW, // Page table walk - AccType_NONFAULT, // Non-faulting loads - AccType_CNOTFIRST, // Contiguous FF load, not first element - AccType_NV2REGISTER, // MRS/MSR instruction used at EL1 and which is converted - // to a memory access that uses the EL2 translation regime - // Other operations - AccType_DC, // Data cache maintenance - AccType_DC_UNPRIV, // Data cache maintenance instruction used at EL0 - AccType_IC, // Instruction cache maintenance - AccType_DCZVA, // DC ZVA instructions - AccType_AT}; // Address translation - -enumeration Fault {Fault_None, - Fault_AccessFlag, - Fault_Alignment, - Fault_Background, - Fault_Domain, - Fault_Permission, - Fault_Translation, - Fault_AddressSize, - Fault_SyncExternal, - Fault_SyncExternalOnWalk, - Fault_SyncParity, - Fault_SyncParityOnWalk, - Fault_AsyncParity, - Fault_AsyncExternal, - Fault_Debug, - Fault_TLBConflict, - Fault_BranchTarget, - Fault_HWUpdateAccessFlag, - Fault_Lockdown, - Fault_Exclusive, - Fault_ICacheMaint}; - -// EncodeLDFSC() -// ============= -// Function that gives the Long-descriptor FSC code for types of Fault - -bits(6) EncodeLDFSC(Fault statuscode, integer level) - - bits(6) result; - case statuscode of - when Fault_AddressSize result = '0000':level[1:0]; assert level IN {0,1,2,3}; - when Fault_AccessFlag result = '0010':level[1:0]; assert level IN {1,2,3}; - when Fault_Permission result = '0011':level[1:0]; assert level IN {1,2,3}; - when Fault_Translation result = '0001':level[1:0]; assert level IN {0,1,2,3}; - when Fault_SyncExternal result = '010000'; - when Fault_SyncExternalOnWalk result = '0101':level[1:0]; assert level IN {0,1,2,3}; - when Fault_SyncParity result = '011000'; - when Fault_SyncParityOnWalk result = '0111':level[1:0]; assert level IN {0,1,2,3}; - when Fault_AsyncParity result = '011001'; - when Fault_AsyncExternal result = '010001'; - when Fault_Alignment result = '100001'; - when Fault_Debug result = '100010'; - when Fault_TLBConflict result = '110000'; - when Fault_HWUpdateAccessFlag result = '110001'; - when Fault_Lockdown result = '110100'; // IMPLEMENTATION DEFINED - when Fault_Exclusive result = '110101'; // IMPLEMENTATION DEFINED - otherwise Unreachable(); - - return result; - -type FullAddress is ( - bits(52) address, - bit NS // '0' = Secure, '1' = Non-secure -) - -type FaultRecord is (Fault statuscode, // Fault Status - AccType acctype, // Type of access that faulted - FullAddress ipaddress, // Intermediate physical address - boolean s2fs1walk, // Is on a Stage 1 page table walk - boolean write, // TRUE for a write, FALSE for a read - integer level, // For translation, access flag and permission faults - bit extflag, // IMPLEMENTATION DEFINED syndrome for external aborts - boolean secondstage, // Is a Stage 2 abort - bits(4) domain, // Domain number, AArch32 only - bits(2) errortype, // [Armv8.2 RAS] AArch32 AET or AArch64 SET - bits(4) debugmoe) // Debug method of entry, from AArch32 only - -type PARTIDtype = bits(16); -type PMGtype = bits(8); - -type MPAMinfo is ( - bit mpam_ns, - PARTIDtype partid, - PMGtype pmg -) - -// HaveRASExt() -// ============ - -boolean HaveRASExt() - return (HasArchVersion(ARMv8p2) || - boolean IMPLEMENTATION_DEFINED "Has RAS extension"); - -// IsAsyncAbort() -// ============== -// Returns TRUE if the abort currently being processed is an asynchronous abort, and FALSE -// otherwise. - -boolean IsAsyncAbort(Fault statuscode) - assert statuscode != Fault_None; - - return (statuscode IN {Fault_AsyncExternal, Fault_AsyncParity}); - -// IsAsyncAbort() -// ============== - -boolean IsAsyncAbort(FaultRecord fault) - return IsAsyncAbort(fault.statuscode); - -// IsExternalAbort() -// ================= -// Returns TRUE if the abort currently being processed is an external abort and FALSE otherwise. - -boolean IsExternalAbort(Fault statuscode) - assert statuscode != Fault_None; - - return (statuscode IN {Fault_SyncExternal, Fault_SyncParity, Fault_SyncExternalOnWalk, Fault_SyncParityOnWalk, - Fault_AsyncExternal, Fault_AsyncParity }); - -// IsExternalAbort() -// ================= - -boolean IsExternalAbort(FaultRecord fault) - return IsExternalAbort(fault.statuscode); - -// IsSecondStage() -// =============== - -boolean IsSecondStage(FaultRecord fault) - assert fault.statuscode != Fault_None; - - return fault.secondstage; - -bits(11) LSInstructionSyndrome(); - -// AArch32.FaultSyndrome() -// ======================= -// Creates an exception syndrome value for Abort and Watchpoint exceptions taken to -// AArch32 Hyp mode. - -bits(25) AArch32.FaultSyndrome(boolean d_side, FaultRecord fault) - assert fault.statuscode != Fault_None; - - bits(25) iss = Zeros(); - if HaveRASExt() && IsAsyncAbort(fault) then iss[11:10] = fault.errortype; // AET - if d_side then - if IsSecondStage(fault) && !fault.s2fs1walk then iss[24:14] = LSInstructionSyndrome(); - if fault.acctype IN {AccType_DC, AccType_DC_UNPRIV, AccType_IC, AccType_AT} then - iss[8] = '1'; iss[6] = '1'; - else - iss[6] = if fault.write then '1' else '0'; - if IsExternalAbort(fault) then iss[9] = fault.extflag; - iss[7] = if fault.s2fs1walk then '1' else '0'; - iss[5:0] = EncodeLDFSC(fault.statuscode, fault.level); - - return iss; - -// ExceptionSyndrome() -// =================== -// Return a blank exception syndrome record for an exception of the given type1. - -ExceptionRecord ExceptionSyndrome(Exception exceptype) - - ExceptionRecord r; - - r.exceptype = exceptype; - - // Initialize all other fields - r.syndrome = Zeros(); - r.vaddress = Zeros(); - r.ipavalid = FALSE; - r.NS = '0'; - r.ipaddress = Zeros(); - - return r; - -// IPAValid() -// ========== -// Return TRUE if the IPA is reported for the abort - -boolean IPAValid(FaultRecord fault) - assert fault.statuscode != Fault_None; - - if fault.s2fs1walk then - return fault.statuscode IN {Fault_AccessFlag, Fault_Permission, Fault_Translation, - Fault_AddressSize}; - elsif fault.secondstage then - return fault.statuscode IN {Fault_AccessFlag, Fault_Translation, Fault_AddressSize}; - else - return FALSE; - -// AArch32.AbortSyndrome() -// ======================= -// Creates an exception syndrome record for Abort exceptions taken to Hyp mode -// from an AArch32 translation regime. - -ExceptionRecord AArch32.AbortSyndrome(Exception exceptype, FaultRecord fault, bits(32) vaddress) - exception = ExceptionSyndrome(exceptype); - - d_side = exceptype == Exception_DataAbort; - - exception.syndrome = AArch32.FaultSyndrome(d_side, fault); - exception.vaddress = ZeroExtend(vaddress); - if IPAValid(fault) then - exception.ipavalid = TRUE; - exception.NS = fault.ipaddress.NS; - exception.ipaddress = ZeroExtend(fault.ipaddress.address); - else - exception.ipavalid = FALSE; - - return exception; - -// HavePACExt() -// ============ -// Returns TRUE if support for the PAC extension is implemented, FALSE otherwise. - -boolean HavePACExt() - return HasArchVersion(ARMv8p3); - -// AddrTop() -// ========= -// Return the MSB number of a virtual address in the stage 1 translation regime for "el". -// If EL1 is using AArch64 then addresses from EL0 using AArch32 are zero-extended to 64 bits. - -integer AddrTop(bits(64) address, boolean IsInstr, bits(2) el) - assert HaveEL(el); - regime = S1TranslationRegime(el); - if ELUsingAArch32(regime) then - // AArch32 translation regime. - return 31; - else - // AArch64 translation regime. - case regime of - when EL1 - tbi = (if address[55] == '1' then TCR_EL1.TBI1 else TCR_EL1.TBI0); - if HavePACExt() then - tbid = if address[55] == '1' then TCR_EL1.TBID1 else TCR_EL1.TBID0; - when EL2 - if HaveVirtHostExt() && ELIsInHost(el) then - tbi = (if address[55] == '1' then TCR_EL2.TBI1 else TCR_EL2.TBI0); - if HavePACExt() then - tbid = if address[55] == '1' then TCR_EL2.TBID1 else TCR_EL2.TBID0; - else - tbi = TCR_EL2.TBI; - if HavePACExt() then tbid = TCR_EL2.TBID; - when EL3 - tbi = TCR_EL3.TBI; - if HavePACExt() then tbid = TCR_EL3.TBID; - - return (if tbi == '1' && (!HavePACExt() || tbid == '0' || !IsInstr ) then 55 else 63); - -// IsInHost() -// ========== - -boolean IsInHost() - return ELIsInHost(PSTATE.EL); - -// AArch64.BranchAddr() -// ==================== -// Return the virtual address with tag bits removed for storing to the program counter. - -bits(64) AArch64.BranchAddr(bits(64) vaddress) - assert !UsingAArch32(); - msbit = AddrTop(vaddress, TRUE, PSTATE.EL); - if msbit == 63 then - return vaddress; - elsif (PSTATE.EL IN {EL0, EL1} || IsInHost()) && vaddress[msbit] == '1' then - return SignExtend(vaddress[msbit:0]); - else - return ZeroExtend(vaddress[msbit:0]); - -enumeration BranchType { - BranchType_DIRCALL, // Direct Branch with link - BranchType_INDCALL, // Indirect Branch with link - BranchType_ERET, // Exception return (indirect) - BranchType_DBGEXIT, // Exit from Debug state - BranchType_RET, // Indirect branch with function return hint - BranchType_DIR, // Direct branch - BranchType_INDIR, // Indirect branch - BranchType_EXCEPTION, // Exception entry - BranchType_RESET, // Reset - BranchType_UNKNOWN}; // Other - -// Report the hint passed to BranchTo() and BranchToAddr(), for consideration when processing -// the next instruction. -Hint_Branch(BranchType hint); - -bits(64) _PC; - -// BranchTo() -// ========== - -// Set program counter to a new address, with a branch type1 -// In AArch64 state the address might include a tag in the top eight bits. - -BranchTo(bits(N) target, BranchType branch_type) - Hint_Branch(branch_type); - if N == 32 then - assert UsingAArch32(); - _PC = ZeroExtend(target); - else - assert N == 64 && !UsingAArch32(); - _PC = AArch64.BranchAddr(target[63:0]); - return; - -// HaveBTIExt() -// ============ -// Returns TRUE if support for Branch Target Indentification is implemented. - -boolean HaveBTIExt() - return HasArchVersion(ARMv8p5); - -// HaveDITExt() -// ============ - -boolean HaveDITExt() - return HasArchVersion(ARMv8p4); - -// HaveMTEExt() -// ============ -// Returns TRUE if MTE implemented, and FALSE otherwise. - -boolean HaveMTEExt() - if !HasArchVersion(ARMv8p5) then - return FALSE; - return boolean IMPLEMENTATION_DEFINED "Has MTE extension"; - -// HaveUAOExt() -// ============ - -boolean HaveUAOExt() - return HasArchVersion(ARMv8p2); - -// GetPSRFromPSTATE() -// ================== -// Return a PSR value which represents the current PSTATE - -bits(32) GetPSRFromPSTATE() - bits(32) spsr = Zeros(); - spsr[31:28] = PSTATE.[N,Z,C,V]; - if HavePANExt() then spsr[22] = PSTATE.PAN; - spsr[20] = PSTATE.IL; - if PSTATE.nRW == '1' then // AArch32 state - spsr[27] = PSTATE.Q; - spsr[26:25] = PSTATE.IT[1:0]; - if HaveSSBSExt() then spsr[23] = PSTATE.SSBS; - if HaveDITExt() then spsr[21] = PSTATE.DIT; - spsr[19:16] = PSTATE.GE; - spsr[15:10] = PSTATE.IT[7:2]; - spsr[9] = PSTATE.E; - spsr[8:6] = PSTATE.[A,I,F]; // No PSTATE.D in AArch32 state - spsr[5] = PSTATE.T; - assert PSTATE.M[4] == PSTATE.nRW; // bit [4] is the discriminator - spsr[4:0] = PSTATE.M; - else // AArch64 state - if HaveMTEExt() then spsr[25] = PSTATE.TCO; - if HaveDITExt() then spsr[24] = PSTATE.DIT; - if HaveUAOExt() then spsr[23] = PSTATE.UAO; - spsr[21] = PSTATE.SS; - if HaveSSBSExt() then spsr[12] = PSTATE.SSBS; - if HaveBTIExt() then spsr[11:10] = PSTATE.BTYPE; - spsr[9:6] = PSTATE.[D,A,I,F]; - spsr[4] = PSTATE.nRW; - spsr[3:2] = PSTATE.EL; - spsr[0] = PSTATE.SP; - return spsr; - -// AArch32.EnterHypMode() -// ====================== -// Take an exception to Hyp mode. - -AArch32.EnterHypMode(ExceptionRecord exception, bits(32) preferred_exception_return, - integer vect_offset) - SynchronizeContext(); - assert HaveEL(EL2) && !IsSecure() && ELUsingAArch32(EL2); - - spsr = GetPSRFromPSTATE(); - if !(exception.exceptype IN {Exception_IRQ, Exception_FIQ}) then - AArch32.ReportHypEntry(exception); - AArch32.WriteMode(M32_Hyp); - SPSR[] = spsr; - ELR_hyp = preferred_exception_return; - PSTATE.T = HSCTLR.TE; // PSTATE.J is RES0 - PSTATE.SS = '0'; - if !HaveEL(EL3) || SCR_GEN[].EA == '0' then PSTATE.A = '1'; - if !HaveEL(EL3) || SCR_GEN[].IRQ == '0' then PSTATE.I = '1'; - if !HaveEL(EL3) || SCR_GEN[].FIQ == '0' then PSTATE.F = '1'; - PSTATE.E = HSCTLR.EE; - PSTATE.IL = '0'; - PSTATE.IT = '00000000'; - if HaveSSBSExt() then PSTATE.SSBS = HSCTLR.DSSBS; - BranchTo(HVBAR[31:5]:vect_offset[4:0], BranchType_EXCEPTION); - - EndOfInstruction(); - -// AArch32.EnterMode() -// =================== -// Take an exception to a mode other than Monitor and Hyp mode. - -AArch32.EnterMode(bits(5) target_mode, bits(32) preferred_exception_return, integer lr_offset, - integer vect_offset) - SynchronizeContext(); - assert ELUsingAArch32(EL1) && PSTATE.EL != EL2; - - spsr = GetPSRFromPSTATE(); - if PSTATE.M == M32_Monitor then SCR.NS = '0'; - AArch32.WriteMode(target_mode); - SPSR[] = spsr; - R[14] = preferred_exception_return + lr_offset; - PSTATE.T = SCTLR.TE; // PSTATE.J is RES0 - PSTATE.SS = '0'; - if target_mode == M32_FIQ then - PSTATE.[A,I,F] = '111'; - elsif target_mode IN {M32_Abort, M32_IRQ} then - PSTATE.[A,I] = '11'; - else - PSTATE.I = '1'; - PSTATE.E = SCTLR.EE; - PSTATE.IL = '0'; - PSTATE.IT = '00000000'; - if HavePANExt() && SCTLR.SPAN == '0' then PSTATE.PAN = '1'; - if HaveSSBSExt() then PSTATE.SSBS = SCTLR.DSSBS; - BranchTo(ExcVectorBase()[31:5]:vect_offset[4:0], BranchType_EXCEPTION); - - EndOfInstruction(); - -// AArch32.EnterMonitorMode() -// ========================== -// Take an exception to Monitor mode. - -AArch32.EnterMonitorMode(bits(32) preferred_exception_return, integer lr_offset, - integer vect_offset) - SynchronizeContext(); - assert HaveEL(EL3) && ELUsingAArch32(EL3); - from_secure = IsSecure(); - spsr = GetPSRFromPSTATE(); - if PSTATE.M == M32_Monitor then SCR.NS = '0'; - AArch32.WriteMode(M32_Monitor); - SPSR[] = spsr; - R[14] = preferred_exception_return + lr_offset; - PSTATE.T = SCTLR.TE; // PSTATE.J is RES0 - PSTATE.SS = '0'; - PSTATE.[A,I,F] = '111'; - PSTATE.E = SCTLR.EE; - PSTATE.IL = '0'; - PSTATE.IT = '00000000'; - if HavePANExt() then - if !from_secure then - PSTATE.PAN = '0'; - elsif SCTLR.SPAN == '0' then - PSTATE.PAN = '1'; - if HaveSSBSExt() then PSTATE.SSBS = SCTLR.DSSBS; - BranchTo(MVBAR[31:5]:vect_offset[4:0], BranchType_EXCEPTION); - - EndOfInstruction(); - -// AArch32.FaultStatusLD() -// ======================= -// Creates an exception fault status value for Abort and Watchpoint exceptions taken -// to Abort mode using AArch32 and Long-descriptor format. - -bits(32) AArch32.FaultStatusLD(boolean d_side, FaultRecord fault) - assert fault.statuscode != Fault_None; - - bits(32) fsr = Zeros(); - if HaveRASExt() && IsAsyncAbort(fault) then fsr[15:14] = fault.errortype; - if d_side then - if fault.acctype IN {AccType_DC, AccType_IC, AccType_AT} then - fsr[13] = '1'; fsr[11] = '1'; - else - fsr[11] = if fault.write then '1' else '0'; - if IsExternalAbort(fault) then fsr[12] = fault.extflag; - fsr[9] = '1'; - fsr[5:0] = EncodeLDFSC(fault.statuscode, fault.level); - - return fsr; - -// EncodeSDFSC() -// ============= -// Function that gives the Short-descriptor FSR code for different types of Fault - -bits(5) EncodeSDFSC(Fault statuscode, integer level) - - bits(5) result; - case statuscode of - when Fault_AccessFlag - assert level IN {1,2}; - result = if level == 1 then '00011' else '00110'; - when Fault_Alignment - result = '00001'; - when Fault_Permission - assert level IN {1,2}; - result = if level == 1 then '01101' else '01111'; - when Fault_Domain - assert level IN {1,2}; - result = if level == 1 then '01001' else '01011'; - when Fault_Translation - assert level IN {1,2}; - result = if level == 1 then '00101' else '00111'; - when Fault_SyncExternal - result = '01000'; - when Fault_SyncExternalOnWalk - assert level IN {1,2}; - result = if level == 1 then '01100' else '01110'; - when Fault_SyncParity - result = '11001'; - when Fault_SyncParityOnWalk - assert level IN {1,2}; - result = if level == 1 then '11100' else '11110'; - when Fault_AsyncParity - result = '11000'; - when Fault_AsyncExternal - result = '10110'; - when Fault_Debug - result = '00010'; - when Fault_TLBConflict - result = '10000'; - when Fault_Lockdown - result = '10100'; // IMPLEMENTATION DEFINED - when Fault_Exclusive - result = '10101'; // IMPLEMENTATION DEFINED - when Fault_ICacheMaint - result = '00100'; - otherwise - Unreachable(); - - return result; - -// AArch32.FaultStatusSD() -// ======================= -// Creates an exception fault status value for Abort and Watchpoint exceptions taken -// to Abort mode using AArch32 and Short-descriptor format. - -bits(32) AArch32.FaultStatusSD(boolean d_side, FaultRecord fault) - assert fault.statuscode != Fault_None; - - bits(32) fsr = Zeros(); - if HaveRASExt() && IsAsyncAbort(fault) then fsr[15:14] = fault.errortype; - if d_side then - if fault.acctype IN {AccType_DC, AccType_IC, AccType_AT} then - fsr[13] = '1'; fsr[11] = '1'; - else - fsr[11] = if fault.write then '1' else '0'; - if IsExternalAbort(fault) then fsr[12] = fault.extflag; - fsr[9] = '0'; - fsr[10,3:0] = EncodeSDFSC(fault.statuscode, fault.level); - if d_side then - fsr[7:4] = fault.domain; // Domain field (data fault only) - - return fsr; - -// IsSErrorInterrupt() -// =================== -// Returns TRUE if the abort currently being processed is an SError interrupt, and FALSE -// otherwise. - -boolean IsSErrorInterrupt(Fault statuscode) - assert statuscode != Fault_None; - - return (statuscode IN {Fault_AsyncExternal, Fault_AsyncParity}); - -// IsSErrorInterrupt() -// =================== - -boolean IsSErrorInterrupt(FaultRecord fault) - return IsSErrorInterrupt(fault.statuscode); - -// AArch32.ReportDataAbort() -// ========================= -// Report syndrome information for aborts taken to modes other than Hyp mode. - -AArch32.ReportDataAbort(boolean route_to_monitor, FaultRecord fault, bits(32) vaddress) - - // The encoding used in the IFSR or DFSR can be Long-descriptor format or Short-descriptor - // format. Normally, the current translation table format determines the format. For an abort - // from Non-secure state to Monitor mode, the IFSR or DFSR uses the Long-descriptor format if - // any of the following applies: - // * The Secure TTBCR.EAE is set to 1. - // * The abort is synchronous and either: - // - It is taken from Hyp mode. - // - It is taken from EL1 or EL0, and the Non-secure TTBCR.EAE is set to 1. - long_format = FALSE; - if route_to_monitor && !IsSecure() then - long_format = TTBCR_S.EAE == '1'; - if !IsSErrorInterrupt(fault) && !long_format then - long_format = PSTATE.EL == EL2 || TTBCR.EAE == '1'; - else - long_format = TTBCR.EAE == '1'; - d_side = TRUE; - if long_format then - syndrome = AArch32.FaultStatusLD(d_side, fault); - else - syndrome = AArch32.FaultStatusSD(d_side, fault); - - if fault.acctype == AccType_IC then - if (!long_format && - boolean IMPLEMENTATION_DEFINED "Report I-cache maintenance fault in IFSR") then - i_syndrome = syndrome; - syndrome[10,3:0] = EncodeSDFSC(Fault_ICacheMaint, 1); - else - i_syndrome = bits(32) UNKNOWN; - if route_to_monitor then - IFSR_S = i_syndrome; - else - IFSR = i_syndrome; - - if route_to_monitor then - DFSR_S = syndrome; - DFAR_S = vaddress; - else - DFSR = syndrome; - DFAR = vaddress; - - return; - -// IsDebugException() -// ================== - -boolean IsDebugException(FaultRecord fault) - assert fault.statuscode != Fault_None; - return fault.statuscode == Fault_Debug; - -// ThisInstrAddr() -// =============== -// Return address of the current instruction. - -bits(N) ThisInstrAddr() - assert N == 64 || (N == 32 && UsingAArch32()); - return _PC[N-1:0]; - -// AArch32.TakeDataAbortException() -// ================================ - -AArch32.TakeDataAbortException(bits(32) vaddress, FaultRecord fault) - route_to_monitor = HaveEL(EL3) && SCR.EA == '1' && IsExternalAbort(fault); - route_to_hyp = (HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0, EL1} && - (HCR.TGE == '1' || IsSecondStage(fault) || - (HaveRASExt() && HCR2.TEA == '1' && IsExternalAbort(fault)) || - (IsDebugException(fault) && HDCR.TDE == '1'))); - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x10; - lr_offset = 8; - - if IsDebugException(fault) then DBGDSCRext.MOE = fault.debugmoe; - if route_to_monitor then - AArch32.ReportDataAbort(route_to_monitor, fault, vaddress); - AArch32.EnterMonitorMode(preferred_exception_return, lr_offset, vect_offset); - elsif PSTATE.EL == EL2 || route_to_hyp then - exception = AArch32.AbortSyndrome(Exception_DataAbort, fault, vaddress); - if PSTATE.EL == EL2 then - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - else - AArch32.EnterHypMode(exception, preferred_exception_return, 0x14); - else - AArch32.ReportDataAbort(route_to_monitor, fault, vaddress); - AArch32.EnterMode(M32_Abort, preferred_exception_return, lr_offset, vect_offset); - -// AArch32.ReportPrefetchAbort() -// ============================= -// Report syndrome information for aborts taken to modes other than Hyp mode. - -AArch32.ReportPrefetchAbort(boolean route_to_monitor, FaultRecord fault, bits(32) vaddress) - // The encoding used in the IFSR can be Long-descriptor format or Short-descriptor format. - // Normally, the current translation table format determines the format. For an abort from - // Non-secure state to Monitor mode, the IFSR uses the Long-descriptor format if any of the - // following applies: - // * The Secure TTBCR.EAE is set to 1. - // * It is taken from Hyp mode. - // * It is taken from EL1 or EL0, and the Non-secure TTBCR.EAE is set to 1. - long_format = FALSE; - if route_to_monitor && !IsSecure() then - long_format = TTBCR_S.EAE == '1' || PSTATE.EL == EL2 || TTBCR.EAE == '1'; - else - long_format = TTBCR.EAE == '1'; - - d_side = FALSE; - if long_format then - fsr = AArch32.FaultStatusLD(d_side, fault); - else - fsr = AArch32.FaultStatusSD(d_side, fault); - - if route_to_monitor then - IFSR_S = fsr; - IFAR_S = vaddress; - else - IFSR = fsr; - IFAR = vaddress; - - return; - -// AArch32.TakePrefetchAbortException() -// ==================================== - -AArch32.TakePrefetchAbortException(bits(32) vaddress, FaultRecord fault) - route_to_monitor = HaveEL(EL3) && SCR.EA == '1' && IsExternalAbort(fault); - route_to_hyp = (HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0, EL1} && - (HCR.TGE == '1' || IsSecondStage(fault) || - (HaveRASExt() && HCR2.TEA == '1' && IsExternalAbort(fault)) || - (IsDebugException(fault) && HDCR.TDE == '1'))); - - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0C; - lr_offset = 4; - - if IsDebugException(fault) then DBGDSCRext.MOE = fault.debugmoe; - if route_to_monitor then - AArch32.ReportPrefetchAbort(route_to_monitor, fault, vaddress); - AArch32.EnterMonitorMode(preferred_exception_return, lr_offset, vect_offset); - elsif PSTATE.EL == EL2 || route_to_hyp then - if fault.statuscode == Fault_Alignment then // PC Alignment fault - exception = ExceptionSyndrome(Exception_PCAlignment); - exception.vaddress = ThisInstrAddr(); - else - exception = AArch32.AbortSyndrome(Exception_InstructionAbort, fault, vaddress); - if PSTATE.EL == EL2 then - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - else - AArch32.EnterHypMode(exception, preferred_exception_return, 0x14); - else - AArch32.ReportPrefetchAbort(route_to_monitor, fault, vaddress); - AArch32.EnterMode(M32_Abort, preferred_exception_return, lr_offset, vect_offset); - -// HaveNVExt() -// =========== -// Returns TRUE if Nested Virtualization is implemented. - -boolean HaveNVExt() - return HasArchVersion(ARMv8p3) && boolean IMPLEMENTATION_DEFINED "Has Nested Virtualization"; - -// HaveNV2Ext() -// ============ -// Returns TRUE if Enhanced Nested Virtualization is implemented. - -boolean HaveNV2Ext() - return (HasArchVersion(ARMv8p4) && HaveNVExt() - && boolean IMPLEMENTATION_DEFINED "Has support for Enhanced Nested Virtualization"); - -// IsExternalSyncAbort() -// ===================== -// Returns TRUE if the abort currently being processed is an external synchronous abort and FALSE otherwise. - -boolean IsExternalSyncAbort(Fault statuscode) - assert statuscode != Fault_None; - - return (statuscode IN {Fault_SyncExternal, Fault_SyncParity, Fault_SyncExternalOnWalk, Fault_SyncParityOnWalk}); - -// IsExternalSyncAbort() -// ===================== - -boolean IsExternalSyncAbort(FaultRecord fault) - return IsExternalSyncAbort(fault.statuscode); - -// AArch64.FaultSyndrome() -// ======================= -// Creates an exception syndrome value for Abort and Watchpoint exceptions taken to -// an Exception Level using AArch64. - -bits(25) AArch64.FaultSyndrome(boolean d_side, FaultRecord fault) - assert fault.statuscode != Fault_None; - - bits(25) iss = Zeros(); - if HaveRASExt() && IsExternalSyncAbort(fault) then iss[12:11] = fault.errortype; // SET - if d_side then - if IsSecondStage(fault) && !fault.s2fs1walk then iss[24:14] = LSInstructionSyndrome(); - if HaveNV2Ext() && fault.acctype == AccType_NV2REGISTER then - iss[13] = '1'; // Value of '1' indicates fault is generated by use of VNCR_EL2 - if fault.acctype IN {AccType_DC, AccType_DC_UNPRIV, AccType_IC, AccType_AT} then - iss[8] = '1'; iss[6] = '1'; - else - iss[6] = if fault.write then '1' else '0'; - if IsExternalAbort(fault) then iss[9] = fault.extflag; - iss[7] = if fault.s2fs1walk then '1' else '0'; - iss[5:0] = EncodeLDFSC(fault.statuscode, fault.level); - - return iss; - -// AArch64.AbortSyndrome() -// ======================= -// Creates an exception syndrome record for Abort and Watchpoint exceptions -// from an AArch64 translation regime. - -ExceptionRecord AArch64.AbortSyndrome(Exception exceptype, FaultRecord fault, bits(64) vaddress) - exception = ExceptionSyndrome(exceptype); - - d_side = exceptype IN {Exception_DataAbort, Exception_NV2DataAbort, Exception_Watchpoint, Exception_NV2Watchpoint}; - - exception.syndrome = AArch64.FaultSyndrome(d_side, fault); - exception.vaddress = ZeroExtend(vaddress); - if IPAValid(fault) then - exception.ipavalid = TRUE; - exception.NS = fault.ipaddress.NS; - exception.ipaddress = fault.ipaddress.address; - else - exception.ipavalid = FALSE; - - return exception; - -// AArch64.MaybeZeroRegisterUppers() -// ================================= -// On taking an exception to AArch64 from AArch32, it is CONSTRAINED UNPREDICTABLE whether the top -// 32 bits of registers visible at any lower Exception level using AArch32 are set to zero. - -AArch64.MaybeZeroRegisterUppers() - assert UsingAArch32(); // Always called from AArch32 state before entering AArch64 state - - if PSTATE.EL == EL0 && !ELUsingAArch32(EL1) then - first = 0; last = 14; include_R15 = FALSE; - elsif PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !ELUsingAArch32(EL2) then - first = 0; last = 30; include_R15 = FALSE; - else - first = 0; last = 30; include_R15 = TRUE; - - for n = first to last - if (n != 15 || include_R15) && ConstrainUnpredictableBool(Unpredictable_ZEROUPPER) then - _R[n][63:32] = Zeros(); - - return; - -// AArch64.ExceptionClass() -// ======================== -// Returns the Exception Class and Instruction Length fields to be reported in ESR - -(integer,bit) AArch64.ExceptionClass(Exception exceptype, bits(2) target_el) - - il = if ThisInstrLength() == 32 then '1' else '0'; - from_32 = UsingAArch32(); - assert from_32 || il == '1'; // AArch64 instructions always 32-bit - - case exceptype of - when Exception_Uncategorized ec = 0x00; il = '1'; - when Exception_WFxTrap ec = 0x01; - when Exception_CP15RTTrap ec = 0x03; assert from_32; - when Exception_CP15RRTTrap ec = 0x04; assert from_32; - when Exception_CP14RTTrap ec = 0x05; assert from_32; - when Exception_CP14DTTrap ec = 0x06; assert from_32; - when Exception_AdvSIMDFPAccessTrap ec = 0x07; - when Exception_FPIDTrap ec = 0x08; - when Exception_PACTrap ec = 0x09; - when Exception_CP14RRTTrap ec = 0x0C; assert from_32; - when Exception_BranchTarget ec = 0x0D; - when Exception_IllegalState ec = 0x0E; il = '1'; - when Exception_SupervisorCall ec = 0x11; - when Exception_HypervisorCall ec = 0x12; - when Exception_MonitorCall ec = 0x13; - when Exception_SystemRegisterTrap ec = 0x18; assert !from_32; - when Exception_SVEAccessTrap ec = 0x19; assert !from_32; - when Exception_ERetTrap ec = 0x1A; - when Exception_PACFail ec = 0x1C; - when Exception_InstructionAbort ec = 0x20; il = '1'; - when Exception_PCAlignment ec = 0x22; il = '1'; - when Exception_DataAbort ec = 0x24; - when Exception_NV2DataAbort ec = 0x25; - when Exception_SPAlignment ec = 0x26; il = '1'; assert !from_32; - when Exception_FPTrappedException ec = 0x28; - when Exception_SError ec = 0x2F; il = '1'; - when Exception_Breakpoint ec = 0x30; il = '1'; - when Exception_SoftwareStep ec = 0x32; il = '1'; - when Exception_Watchpoint ec = 0x34; il = '1'; - when Exception_NV2Watchpoint ec = 0x35; il = '1'; - when Exception_SoftwareBreakpoint ec = 0x38; - when Exception_VectorCatch ec = 0x3A; il = '1'; assert from_32; - otherwise Unreachable(); - - if ec IN {0x20,0x24,0x30,0x32,0x34} && target_el == PSTATE.EL then - ec = ec + 1; - - if ec IN {0x11,0x12,0x13,0x28,0x38} && !from_32 then - ec = ec + 4; - - return (ec,il); - -type ESRType; - -// ESR[] - non-assignment form -// =========================== - -ESRType ESR[bits(2) regime] - bits(32) r; - case regime of - when EL1 r = ESR_EL1; - when EL2 r = ESR_EL2; - when EL3 r = ESR_EL3; - otherwise Unreachable(); - return r; - -// ESR[] - non-assignment form -// =========================== - -ESRType ESR[] - return ESR[S1TranslationRegime()]; - -// ESR[] - assignment form -// ======================= - -ESR[bits(2) regime] = ESRType value - bits(32) r = value; - case regime of - when EL1 ESR_EL1 = r; - when EL2 ESR_EL2 = r; - when EL3 ESR_EL3 = r; - otherwise Unreachable(); - return; - -// ESR[] - assignment form -// ======================= - -ESR[] = ESRType value - ESR[S1TranslationRegime()] = value; - -// FAR[] - non-assignment form -// =========================== - -bits(64) FAR[bits(2) regime] - bits(64) r; - case regime of - when EL1 r = FAR_EL1; - when EL2 r = FAR_EL2; - when EL3 r = FAR_EL3; - otherwise Unreachable(); - return r; - -// FAR[] - non-assignment form -// =========================== - -bits(64) FAR[] - return FAR[S1TranslationRegime()]; - -// FAR[] - assignment form -// ======================= - -FAR[bits(2) regime] = bits(64) value - bits(64) r = value; - case regime of - when EL1 FAR_EL1 = r; - when EL2 FAR_EL2 = r; - when EL3 FAR_EL3 = r; - otherwise Unreachable(); - return; - -// FAR[] - assignment form -// ======================= - -FAR[] = bits(64) value - FAR[S1TranslationRegime()] = value; - return; - -// AArch64.ReportException() -// ========================= -// Report syndrome information for exception taken to AArch64 state. - -AArch64.ReportException(ExceptionRecord exception, bits(2) target_el) - - Exception exceptype = exception.exceptype; - - (ec,il) = AArch64.ExceptionClass(exceptype, target_el); - iss = exception.syndrome; - - // IL is not valid for Data Abort exceptions without valid instruction syndrome information - if ec IN {0x24,0x25} && iss[24] == '0' then - il = '1'; - - ESR[target_el] = ec[5:0]:il:iss; - - if exceptype IN {Exception_InstructionAbort, Exception_PCAlignment, Exception_DataAbort, - Exception_NV2DataAbort, Exception_NV2Watchpoint, - Exception_Watchpoint} then - FAR[target_el] = exception.vaddress; - else - FAR[target_el] = bits(64) UNKNOWN; - - if target_el == EL2 then - if exception.ipavalid then - HPFAR_EL2[43:4] = exception.ipaddress[51:12]; - if IsSecureEL2Enabled() && IsSecure() then - HPFAR_EL2.NS = exception.NS; - else - HPFAR_EL2.NS = '0'; - else - HPFAR_EL2[43:4] = bits(40) UNKNOWN; - - return; - -// ELR[] - non-assignment form -// =========================== - -bits(64) ELR[bits(2) el] - bits(64) r; - case el of - when EL1 r = ELR_EL1; - when EL2 r = ELR_EL2; - when EL3 r = ELR_EL3; - otherwise Unreachable(); - return r; - -// ELR[] - non-assignment form -// =========================== - -bits(64) ELR[] - assert PSTATE.EL != EL0; - return ELR[PSTATE.EL]; - -// ELR[] - assignment form -// ======================= - -ELR[bits(2) el] = bits(64) value - bits(64) r = value; - case el of - when EL1 ELR_EL1 = r; - when EL2 ELR_EL2 = r; - when EL3 ELR_EL3 = r; - otherwise Unreachable(); - return; - -// ELR[] - assignment form -// ======================= - -ELR[] = bits(64) value - assert PSTATE.EL != EL0; - ELR[PSTATE.EL] = value; - return; - -// HaveIESB() -// ========== - -boolean HaveIESB() - return (HaveRASExt() && - boolean IMPLEMENTATION_DEFINED "Has Implicit Error Synchronization Barrier"); - -// HaveDoubleFaultExt() -// ==================== - -boolean HaveDoubleFaultExt() - return (HasArchVersion(ARMv8p4) && HaveEL(EL3) && !ELUsingAArch32(EL3) && HaveIESB()); - -// If SCTLR_ELx.IESB is 1 when an exception is generated to ELx, any pending Unrecoverable -// SError interrupt must be taken before executing any instructions in the exception handler. -// However, this can be before the branch to the exception handler is made. -boolean InsertIESBBeforeException(bits(2) el); - -// AArch64.IsFPEnabled() -// ===================== -// Returns TRUE if access to the SIMD&FP instructions or System registers are -// enabled at the target exception level in AArch64 state and FALSE otherwise. - -boolean AArch64.IsFPEnabled(bits(2) el) - // Check if access disabled in CPACR_EL1 - if el IN {EL0, EL1} && !IsInHost() then - // Check FP&SIMD at EL0/EL1 - case CPACR_EL1.FPEN of - when 'x0' disabled = TRUE; - when '01' disabled = el == EL0; - when '11' disabled = FALSE; - if disabled then return FALSE; - - // Check if access disabled in CPTR_EL2 - if el IN {EL0, EL1, EL2} && EL2Enabled() then - if HaveVirtHostExt() && HCR_EL2.E2H == '1' then - case CPTR_EL2.FPEN of - when 'x0' disabled = TRUE; - when '01' disabled = el == EL0 && HCR_EL2.TGE == '1'; - when '11' disabled = FALSE; - if disabled then return FALSE; - else - if CPTR_EL2.TFP == '1' then return FALSE; - - // Check if access disabled in CPTR_EL3 - if HaveEL(EL3) then - if CPTR_EL3.TFP == '1' then return FALSE; - - return TRUE; - -// AArch32.IsFPEnabled() -// ===================== -// Returns TRUE if access to the SIMD&FP instructions or System registers are -// enabled at the target exception level in AArch32 state and FALSE otherwise. - -boolean AArch32.IsFPEnabled(bits(2) el) - if el == EL0 && !ELUsingAArch32(EL1) then - return AArch64.IsFPEnabled(el); - - if HaveEL(EL3) && ELUsingAArch32(EL3) && !IsSecure() then - // Check if access disabled in NSACR - if NSACR.cp10 == '0' then return FALSE; - - if el IN {EL0, EL1} then - // Check if access disabled in CPACR - case CPACR.cp10 of - when '00' disabled = TRUE; - when '01' disabled = el == EL0; - when '10' disabled = ConstrainUnpredictableBool(Unpredictable_RESCPACR); - when '11' disabled = FALSE; - if disabled then return FALSE; - - if el IN {EL0, EL1, EL2} then - if EL2Enabled() then - if !ELUsingAArch32(EL2) then - if CPTR_EL2.TFP == '1' then return FALSE; - else - if HCPTR.TCP10 == '1' then return FALSE; - - if HaveEL(EL3) && !ELUsingAArch32(EL3) then - // Check if access disabled in CPTR_EL3 - if CPTR_EL3.TFP == '1' then return FALSE; - - return TRUE; - -// IsFPEnabled() -// ============= -// Returns TRUE if accesses to the Advanced SIMD and floating-point -// registers are enabled at the target exception level in the current -// execution state and FALSE otherwise. - -boolean IsFPEnabled(bits(2) el) - if ELUsingAArch32(el) then - return AArch32.IsFPEnabled(el); - else - return AArch64.IsFPEnabled(el); - -// IsSVEEnabled() -// ============== -// Returns TRUE if access to SVE instructions and System registers is -// enabled at the target exception level and FALSE otherwise. - -boolean IsSVEEnabled(bits(2) el) - if ELUsingAArch32(el) then - return FALSE; - - // Check if access disabled in CPACR_EL1 - if el IN {EL0, EL1} && !IsInHost() then - // Check SVE at EL0/EL1 - case CPACR_EL1.ZEN of - when 'x0' disabled = TRUE; - when '01' disabled = el == EL0; - when '11' disabled = FALSE; - if disabled then return FALSE; - - // Check if access disabled in CPTR_EL2 - if el IN {EL0, EL1, EL2} && EL2Enabled() then - if HaveVirtHostExt() && HCR_EL2.E2H == '1' then - case CPTR_EL2.ZEN of - when 'x0' disabled = TRUE; - when '01' disabled = el == EL0 && HCR_EL2.TGE == '1'; - when '11' disabled = FALSE; - if disabled then return FALSE; - else - if CPTR_EL2.TZ == '1' then return FALSE; - - // Check if access disabled in CPTR_EL3 - if HaveEL(EL3) then - if CPTR_EL3.EZ == '0' then return FALSE; - - return TRUE; - -// ImplementedSVEVectorLength() -// ============================ -// Reduce SVE vector length to a supported value (e.g. power of two) - -integer ImplementedSVEVectorLength(integer nbits) - return integer IMPLEMENTATION_DEFINED; - -// Min() -// ===== - -integer Min(integer a, integer b) - return if a <= b then a else b; - -// Min() -// ===== - -real Min(real a, real b) - return if a <= b then a else b; - -// VL - non-assignment form -// ======================== - -integer VL - integer vl; - - if PSTATE.EL == EL1 || (PSTATE.EL == EL0 && !IsInHost()) then - vl = UInt(ZCR_EL1.LEN); - - if PSTATE.EL == EL2 || (PSTATE.EL == EL0 && IsInHost()) then - vl = UInt(ZCR_EL2.LEN); - elsif PSTATE.EL IN {EL0, EL1} && EL2Enabled() then - vl = Min(vl, UInt(ZCR_EL2.LEN)); - - if PSTATE.EL == EL3 then - vl = UInt(ZCR_EL3.LEN); - elsif HaveEL(EL3) then - vl = Min(vl, UInt(ZCR_EL3.LEN)); - - vl = (vl + 1) * 128; - vl = ImplementedSVEVectorLength(vl); - - return vl; - -constant integer MAX_PL = 256; - -constant integer MAX_VL = 128; - -array bits(MAX_VL) _Z[0..31]; -array bits(MAX_PL) _P[0..15]; -bits(MAX_PL) _FFR; - -// MaybeZeroSVEUppers() -// ==================== - -MaybeZeroSVEUppers(bits(2) target_el) - boolean lower_enabled; - - if UInt(target_el) <= UInt(PSTATE.EL) || !IsSVEEnabled(target_el) then - return; - - if target_el == EL3 then - if EL2Enabled() then - lower_enabled = IsFPEnabled(EL2); - else - lower_enabled = IsFPEnabled(EL1); - else - lower_enabled = IsFPEnabled(target_el - 1); - - if lower_enabled then - integer vl = if IsSVEEnabled(PSTATE.EL) then VL else 128; - integer pl = vl DIV 8; - for n = 0 to 31 - if ConstrainUnpredictableBool(Unpredictable_SVEZEROUPPER) then - _Z[n] = ZeroExtend(_Z[n][vl-1:0]); - for n = 0 to 15 - if ConstrainUnpredictableBool(Unpredictable_SVEZEROUPPER) then - _P[n] = ZeroExtend(_P[n][pl-1:0]); - if ConstrainUnpredictableBool(Unpredictable_SVEZEROUPPER) then - _FFR = ZeroExtend(_FFR[pl-1:0]); - -type SCTLRType; - -// SCTLR[] - non-assignment form -// ============================= - -SCTLRType SCTLR[bits(2) regime] - bits(64) r; - case regime of - when EL1 r = SCTLR_EL1; - when EL2 r = SCTLR_EL2; - when EL3 r = SCTLR_EL3; - otherwise Unreachable(); - return r; - -// SCTLR[] - non-assignment form -// ============================= - -SCTLRType SCTLR[] - return SCTLR[S1TranslationRegime()]; - -// Implements the error synchronization event. -SynchronizeErrors(); - -// Take any pending unmasked physical SError interrupt -TakeUnmaskedPhysicalSErrorInterrupts(boolean iesb_req); - -// AArch64.TakeException() -// ======================= -// Take an exception to an Exception Level using AArch64. - -AArch64.TakeException(bits(2) target_el, ExceptionRecord exception, - bits(64) preferred_exception_return, integer vect_offset) - assert HaveEL(target_el) && !ELUsingAArch32(target_el) && UInt(target_el) >= UInt(PSTATE.EL); - - sync_errors = HaveIESB() && SCTLR[target_el].IESB == '1'; - if HaveDoubleFaultExt() then - sync_errors = sync_errors || (SCR_EL3.EA == '1' && SCR_EL3.NMEA == '1' && PSTATE.EL == EL3); - if sync_errors && InsertIESBBeforeException(target_el) then - SynchronizeErrors(); - iesb_req = FALSE; - sync_errors = FALSE; - TakeUnmaskedPhysicalSErrorInterrupts(iesb_req); - - SynchronizeContext(); - - // If coming from AArch32 state, the top parts of the X[] registers might be set to zero - from_32 = UsingAArch32(); - if from_32 then AArch64.MaybeZeroRegisterUppers(); - MaybeZeroSVEUppers(target_el); - - if UInt(target_el) > UInt(PSTATE.EL) then - boolean lower_32; - if target_el == EL3 then - if EL2Enabled() then - lower_32 = ELUsingAArch32(EL2); - else - lower_32 = ELUsingAArch32(EL1); - elsif IsInHost() && PSTATE.EL == EL0 && target_el == EL2 then - lower_32 = ELUsingAArch32(EL0); - else - lower_32 = ELUsingAArch32(target_el - 1); - vect_offset = vect_offset + (if lower_32 then 0x600 else 0x400); - - elsif PSTATE.SP == '1' then - vect_offset = vect_offset + 0x200; - - spsr = GetPSRFromPSTATE(); - - if PSTATE.EL == EL1 && target_el == EL1 && EL2Enabled() then - if HaveNV2Ext() && (HCR_EL2.[NV,NV1,NV2] == '100' || HCR_EL2.[NV,NV1,NV2] == '111') then - spsr[3:2] = '10'; - else - if HaveNVExt() && HCR_EL2.[NV,NV1] == '10' then - spsr[3:2] = '10'; - - if HaveBTIExt() then - // SPSR[].BTYPE is only guaranteed valid for these exception types - if exception.exceptype IN {Exception_SError, Exception_IRQ, Exception_FIQ, - Exception_SoftwareStep, Exception_PCAlignment, - Exception_InstructionAbort, Exception_Breakpoint, - Exception_VectorCatch, Exception_SoftwareBreakpoint, - Exception_IllegalState, Exception_BranchTarget} then - zero_btype = FALSE; - else - zero_btype = ConstrainUnpredictableBool(Unpredictable_ZEROBTYPE); - if zero_btype then spsr[11:10] = '00'; - - if HaveNV2Ext() && exception.exceptype == Exception_NV2DataAbort && target_el == EL3 then - // external aborts are configured to be taken to EL3 - exception.exceptype = Exception_DataAbort; - if !(exception.exceptype IN {Exception_IRQ, Exception_FIQ}) then - AArch64.ReportException(exception, target_el); - - PSTATE.EL = target_el; - PSTATE.nRW = '0'; - PSTATE.SP = '1'; - - SPSR[] = spsr; - ELR[] = preferred_exception_return; - - PSTATE.SS = '0'; - PSTATE.[D,A,I,F] = '1111'; - PSTATE.IL = '0'; - if from_32 then // Coming from AArch32 - PSTATE.IT = '00000000'; - PSTATE.T = '0'; // PSTATE.J is RES0 - if (HavePANExt() && (PSTATE.EL == EL1 || (PSTATE.EL == EL2 && ELIsInHost(EL0))) && - SCTLR[].SPAN == '0') then - PSTATE.PAN = '1'; - if HaveUAOExt() then PSTATE.UAO = '0'; - if HaveBTIExt() then PSTATE.BTYPE = '00'; - if HaveSSBSExt() then PSTATE.SSBS = SCTLR[].DSSBS; - if HaveMTEExt() then PSTATE.TCO = '1'; - - BranchTo(VBAR[][63:11]:vect_offset[10:0], BranchType_EXCEPTION); - - if sync_errors then - SynchronizeErrors(); - iesb_req = TRUE; - TakeUnmaskedPhysicalSErrorInterrupts(iesb_req); - - EndOfInstruction(); - -// AArch64.BreakpointException() -// ============================= - -AArch64.BreakpointException(FaultRecord fault) - assert PSTATE.EL != EL3; - - route_to_el2 = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR_EL2.TGE == '1' || MDCR_EL2.TDE == '1')); - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - vaddress = bits(64) UNKNOWN; - exception = AArch64.AbortSyndrome(Exception_Breakpoint, fault, vaddress); - - if PSTATE.EL == EL2 || route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch64.DataAbort() -// =================== - -AArch64.DataAbort(bits(64) vaddress, FaultRecord fault) - route_to_el3 = HaveEL(EL3) && SCR_EL3.EA == '1' && IsExternalAbort(fault); - route_to_el2 = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && (HCR_EL2.TGE == '1' || - (HaveRASExt() && HCR_EL2.TEA == '1' && IsExternalAbort(fault)) || - (HaveNV2Ext() && fault.acctype == AccType_NV2REGISTER) || - IsSecondStage(fault))); - - bits(64) preferred_exception_return = ThisInstrAddr(); - if (HaveDoubleFaultExt() && (PSTATE.EL == EL3 || route_to_el3) && - IsExternalAbort(fault) && SCR_EL3.EASE == '1') then - vect_offset = 0x180; - else - vect_offset = 0x0; - if HaveNV2Ext() && fault.acctype == AccType_NV2REGISTER then - exception = AArch64.AbortSyndrome(Exception_NV2DataAbort, fault, vaddress); - else - exception = AArch64.AbortSyndrome(Exception_DataAbort, fault, vaddress); - if PSTATE.EL == EL3 || route_to_el3 then - AArch64.TakeException(EL3, exception, preferred_exception_return, vect_offset); - elsif PSTATE.EL == EL2 || route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch64.InstructionAbort() -// ========================== - -AArch64.InstructionAbort(bits(64) vaddress, FaultRecord fault) - // External aborts on instruction fetch must be taken synchronously - if HaveDoubleFaultExt() then assert fault.statuscode != Fault_AsyncExternal; - route_to_el3 = HaveEL(EL3) && SCR_EL3.EA == '1' && IsExternalAbort(fault); - route_to_el2 = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR_EL2.TGE == '1' || IsSecondStage(fault) || - (HaveRASExt() && HCR_EL2.TEA == '1' && IsExternalAbort(fault)))); - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = AArch64.AbortSyndrome(Exception_InstructionAbort, fault, vaddress); - - if PSTATE.EL == EL3 || route_to_el3 then - AArch64.TakeException(EL3, exception, preferred_exception_return, vect_offset); - elsif PSTATE.EL == EL2 || route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch64.VectorCatchException() -// ============================== -// Vector Catch taken from EL0 or EL1 to EL2. This can only be called when debug exceptions are -// being routed to EL2, as Vector Catch is a legacy debug event. - -AArch64.VectorCatchException(FaultRecord fault) - assert PSTATE.EL != EL2; - assert EL2Enabled() && (HCR_EL2.TGE == '1' || MDCR_EL2.TDE == '1'); - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - vaddress = bits(64) UNKNOWN; - exception = AArch64.AbortSyndrome(Exception_VectorCatch, fault, vaddress); - - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - -// AArch64.WatchpointException() -// ============================= - -AArch64.WatchpointException(bits(64) vaddress, FaultRecord fault) - assert PSTATE.EL != EL3; - - route_to_el2 = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR_EL2.TGE == '1' || MDCR_EL2.TDE == '1')); - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - if HaveNV2Ext() && fault.acctype == AccType_NV2REGISTER then - exception = AArch64.AbortSyndrome(Exception_NV2Watchpoint, fault, vaddress); - else - exception = AArch64.AbortSyndrome(Exception_Watchpoint, fault, vaddress); - - if PSTATE.EL == EL2 || route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -constant bits(4) DebugException_Breakpoint = '0001'; -constant bits(4) DebugException_BKPT = '0011'; -constant bits(4) DebugException_VectorCatch = '0101'; -constant bits(4) DebugException_Watchpoint = '1010'; - -// AArch64.Abort() -// =============== -// Abort and Debug exception handling in an AArch64 translation regime. - -AArch64.Abort(bits(64) vaddress, FaultRecord fault) - - if IsDebugException(fault) then - if fault.acctype == AccType_IFETCH then - if UsingAArch32() && fault.debugmoe == DebugException_VectorCatch then - AArch64.VectorCatchException(fault); - else - AArch64.BreakpointException(fault); - else - AArch64.WatchpointException(vaddress, fault); - elsif fault.acctype == AccType_IFETCH then - AArch64.InstructionAbort(vaddress, fault); - else - AArch64.DataAbort(vaddress, fault); - -// AArch32.Abort() -// =============== -// Abort and Debug exception handling in an AArch32 translation regime. - -AArch32.Abort(bits(32) vaddress, FaultRecord fault) - - // Check if routed to AArch64 state - route_to_aarch64 = PSTATE.EL == EL0 && !ELUsingAArch32(EL1); - - if !route_to_aarch64 && EL2Enabled() && !ELUsingAArch32(EL2) then - route_to_aarch64 = (HCR_EL2.TGE == '1' || IsSecondStage(fault) || - (HaveRASExt() && HCR2.TEA == '1' && IsExternalAbort(fault)) || - (IsDebugException(fault) && MDCR_EL2.TDE == '1')); - - if !route_to_aarch64 && HaveEL(EL3) && !ELUsingAArch32(EL3) then - route_to_aarch64 = SCR_EL3.EA == '1' && IsExternalAbort(fault); - - if route_to_aarch64 then - AArch64.Abort(ZeroExtend(vaddress), fault); - elsif fault.acctype == AccType_IFETCH then - AArch32.TakePrefetchAbortException(vaddress, fault); - else - AArch32.TakeDataAbortException(vaddress, fault); - -// AArch32.DomainValid() -// ===================== -// Returns TRUE if the Domain is valid for a Short-descriptor translation scheme. - -boolean AArch32.DomainValid(Fault statuscode, integer level) - assert statuscode != Fault_None; - - case statuscode of - when Fault_Domain - return TRUE; - when Fault_Translation, Fault_AccessFlag, Fault_SyncExternalOnWalk, Fault_SyncParityOnWalk - return level == 2; - otherwise - return FALSE; - -// AArch32.CreateFaultRecord() -// =========================== - -FaultRecord AArch32.CreateFaultRecord(Fault statuscode, bits(40) ipaddress, bits(4) domain, - integer level, AccType acctype, boolean write, bit extflag, - bits(4) debugmoe, bits(2) errortype, boolean secondstage, boolean s2fs1walk) - - FaultRecord fault; - fault.statuscode = statuscode; - if (statuscode != Fault_None && PSTATE.EL != EL2 && TTBCR.EAE == '0' && !secondstage && !s2fs1walk && - AArch32.DomainValid(statuscode, level)) then - fault.domain = domain; - else - fault.domain = bits(4) UNKNOWN; - fault.debugmoe = debugmoe; - fault.errortype = errortype; - fault.ipaddress.NS = bit UNKNOWN; - fault.ipaddress.address = ZeroExtend(ipaddress); - fault.level = level; - fault.acctype = acctype; - fault.write = write; - fault.extflag = extflag; - fault.secondstage = secondstage; - fault.s2fs1walk = s2fs1walk; - - return fault; - -// AArch32.AlignmentFault() -// ======================== - -FaultRecord AArch32.AlignmentFault(AccType acctype, boolean iswrite, boolean secondstage) - - ipaddress = bits(40) UNKNOWN; - domain = bits(4) UNKNOWN; - level = integer UNKNOWN; - extflag = bit UNKNOWN; - debugmoe = bits(4) UNKNOWN; - errortype = bits(2) UNKNOWN; - s2fs1walk = boolean UNKNOWN; - - return AArch32.CreateFaultRecord(Fault_Alignment, ipaddress, domain, level, acctype, iswrite, - extflag, debugmoe, errortype, secondstage, s2fs1walk); - -// AArch32.GeneralExceptionsToAArch64() -// ==================================== -// Returns TRUE if exceptions normally routed to EL1 are being handled at an Exception -// level using AArch64, because either EL1 is using AArch64 or TGE is in force and EL2 -// is using AArch64. - -boolean AArch32.GeneralExceptionsToAArch64() - return ((PSTATE.EL == EL0 && !ELUsingAArch32(EL1)) || - (EL2Enabled() && !ELUsingAArch32(EL2) && HCR_EL2.TGE == '1')); - -// AArch64.PCAlignmentFault() -// ========================== -// Called on unaligned program counter in AArch64 state. - -AArch64.PCAlignmentFault() - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_PCAlignment); - exception.vaddress = ThisInstrAddr(); - - if UInt(PSTATE.EL) > UInt(EL1) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif EL2Enabled() && HCR_EL2.TGE == '1' then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.CheckPCAlignment() -// ========================== - -AArch32.CheckPCAlignment() - - bits(32) pc = ThisInstrAddr(); - if (CurrentInstrSet() == InstrSet_A32 && pc[1] == '1') || pc[0] == '1' then - if AArch32.GeneralExceptionsToAArch64() then AArch64.PCAlignmentFault(); - - // Generate an Alignment fault Prefetch Abort exception - vaddress = pc; - acctype = AccType_IFETCH; - iswrite = FALSE; - secondstage = FALSE; - AArch32.Abort(vaddress, AArch32.AlignmentFault(acctype, iswrite, secondstage)); - -// BranchTargetException -// ===================== -// Raise branch target exception. - -AArch64.BranchTargetException(bits(52) vaddress) - - route_to_el2 = PSTATE.EL == EL0 && EL2Enabled() && HCR_EL2.TGE == '1'; - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_BranchTarget); - exception.syndrome[1:0] = PSTATE.BTYPE; - exception.syndrome[24:2] = Zeros(); // RES0 - - if UInt(PSTATE.EL) > UInt(EL1) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch64.TakePhysicalFIQException() -// ================================== - -AArch64.TakePhysicalFIQException() - - route_to_el3 = HaveEL(EL3) && SCR_EL3.FIQ == '1'; - route_to_el2 = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR_EL2.TGE == '1' || HCR_EL2.FMO == '1')); - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x100; - exception = ExceptionSyndrome(Exception_FIQ); - - if route_to_el3 then - AArch64.TakeException(EL3, exception, preferred_exception_return, vect_offset); - elsif PSTATE.EL == EL2 || route_to_el2 then - assert PSTATE.EL != EL3; - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - assert PSTATE.EL IN {EL0, EL1}; - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.TakePhysicalFIQException() -// ================================== - -AArch32.TakePhysicalFIQException() - - // Check if routed to AArch64 state - route_to_aarch64 = PSTATE.EL == EL0 && !ELUsingAArch32(EL1); - if !route_to_aarch64 && EL2Enabled() && !ELUsingAArch32(EL2) then - route_to_aarch64 = HCR_EL2.TGE == '1' || (HCR_EL2.FMO == '1' && !IsInHost()); - - if !route_to_aarch64 && HaveEL(EL3) && !ELUsingAArch32(EL3) then - route_to_aarch64 = SCR_EL3.FIQ == '1'; - - if route_to_aarch64 then AArch64.TakePhysicalFIQException(); - route_to_monitor = HaveEL(EL3) && SCR.FIQ == '1'; - route_to_hyp = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR.TGE == '1' || HCR.FMO == '1')); - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x1C; - lr_offset = 4; - if route_to_monitor then - AArch32.EnterMonitorMode(preferred_exception_return, lr_offset, vect_offset); - elsif PSTATE.EL == EL2 || route_to_hyp then - exception = ExceptionSyndrome(Exception_FIQ); - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - else - AArch32.EnterMode(M32_FIQ, preferred_exception_return, lr_offset, vect_offset); - -// AArch64.TakePhysicalIRQException() -// ================================== -// Take an enabled physical IRQ exception. - -AArch64.TakePhysicalIRQException() - - route_to_el3 = HaveEL(EL3) && SCR_EL3.IRQ == '1'; - route_to_el2 = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR_EL2.TGE == '1' || HCR_EL2.IMO == '1')); - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x80; - - exception = ExceptionSyndrome(Exception_IRQ); - - if route_to_el3 then - AArch64.TakeException(EL3, exception, preferred_exception_return, vect_offset); - elsif PSTATE.EL == EL2 || route_to_el2 then - assert PSTATE.EL != EL3; - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - assert PSTATE.EL IN {EL0, EL1}; - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.TakePhysicalIRQException() -// ================================== -// Take an enabled physical IRQ exception. - -AArch32.TakePhysicalIRQException() - - // Check if routed to AArch64 state - route_to_aarch64 = PSTATE.EL == EL0 && !ELUsingAArch32(EL1); - if !route_to_aarch64 && EL2Enabled() && !ELUsingAArch32(EL2) then - route_to_aarch64 = HCR_EL2.TGE == '1' || (HCR_EL2.IMO == '1' && !IsInHost()); - if !route_to_aarch64 && HaveEL(EL3) && !ELUsingAArch32(EL3) then - route_to_aarch64 = SCR_EL3.IRQ == '1'; - - if route_to_aarch64 then AArch64.TakePhysicalIRQException(); - - route_to_monitor = HaveEL(EL3) && SCR.IRQ == '1'; - route_to_hyp = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR.TGE == '1' || HCR.IMO == '1')); - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x18; - lr_offset = 4; - if route_to_monitor then - AArch32.EnterMonitorMode(preferred_exception_return, lr_offset, vect_offset); - elsif PSTATE.EL == EL2 || route_to_hyp then - exception = ExceptionSyndrome(Exception_IRQ); - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - else - AArch32.EnterMode(M32_IRQ, preferred_exception_return, lr_offset, vect_offset); - -// AArch32.AsynchExternalAbort() -// ============================= -// Wrapper function for asynchronous external aborts - -FaultRecord AArch32.AsynchExternalAbort(boolean parity, bits(2) errortype, bit extflag) - - faulttype = if parity then Fault_AsyncParity else Fault_AsyncExternal; - ipaddress = bits(40) UNKNOWN; - domain = bits(4) UNKNOWN; - level = integer UNKNOWN; - acctype = AccType_NORMAL; - iswrite = boolean UNKNOWN; - debugmoe = bits(4) UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - - return AArch32.CreateFaultRecord(faulttype, ipaddress, domain, level, acctype, iswrite, extflag, - debugmoe, errortype, secondstage, s2fs1walk); - -// Clear a pending physical SError interrupt -ClearPendingPhysicalSError(); - -// AArch64.TakePhysicalSErrorException() -// ===================================== - -AArch64.TakePhysicalSErrorException(boolean impdef_syndrome, bits(24) syndrome) - - route_to_el3 = HaveEL(EL3) && SCR_EL3.EA == '1'; - route_to_el2 = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR_EL2.TGE == '1' || (!IsInHost() && HCR_EL2.AMO == '1'))); - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x180; - - exception = ExceptionSyndrome(Exception_SError); - exception.syndrome[24] = if impdef_syndrome then '1' else '0'; - exception.syndrome[23:0] = syndrome; - - ClearPendingPhysicalSError(); - - if PSTATE.EL == EL3 || route_to_el3 then - AArch64.TakeException(EL3, exception, preferred_exception_return, vect_offset); - elsif PSTATE.EL == EL2 || route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.TakePhysicalSErrorException() -// ===================================== - -AArch32.TakePhysicalSErrorException(boolean parity, bit extflag, bits(2) errortype, - boolean impdef_syndrome, bits(24) full_syndrome) - - ClearPendingPhysicalSError(); - // Check if routed to AArch64 state - route_to_aarch64 = PSTATE.EL == EL0 && !ELUsingAArch32(EL1); - - if !route_to_aarch64 && EL2Enabled() && !ELUsingAArch32(EL2) then - route_to_aarch64 = (HCR_EL2.TGE == '1' || (!IsInHost() && HCR_EL2.AMO == '1')); - if !route_to_aarch64 && HaveEL(EL3) && !ELUsingAArch32(EL3) then - route_to_aarch64 = SCR_EL3.EA == '1'; - - if route_to_aarch64 then - AArch64.TakePhysicalSErrorException(impdef_syndrome, full_syndrome); - - route_to_monitor = HaveEL(EL3) && SCR.EA == '1'; - route_to_hyp = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR.TGE == '1' || HCR.AMO == '1')); - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x10; - lr_offset = 8; - - fault = AArch32.AsynchExternalAbort(parity, errortype, extflag); - vaddress = bits(32) UNKNOWN; - if route_to_monitor then - AArch32.ReportDataAbort(route_to_monitor, fault, vaddress); - AArch32.EnterMonitorMode(preferred_exception_return, lr_offset, vect_offset); - elsif PSTATE.EL == EL2 || route_to_hyp then - exception = AArch32.AbortSyndrome(Exception_DataAbort, fault, vaddress); - if PSTATE.EL == EL2 then - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - else - AArch32.EnterHypMode(exception, preferred_exception_return, 0x14); - else - AArch32.ReportDataAbort(route_to_monitor, fault, vaddress); - AArch32.EnterMode(M32_Abort, preferred_exception_return, lr_offset, vect_offset); - -// AArch64.TakeVirtualFIQException() -// ================================= - -AArch64.TakeVirtualFIQException() - assert PSTATE.EL IN {EL0, EL1} && EL2Enabled(); - assert HCR_EL2.TGE == '0' && HCR_EL2.FMO == '1'; // Virtual IRQ enabled if TGE==0 and FMO==1 - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x100; - - exception = ExceptionSyndrome(Exception_FIQ); - - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.TakeVirtualFIQException() -// ================================= - -AArch32.TakeVirtualFIQException() - assert PSTATE.EL IN {EL0, EL1} && EL2Enabled(); - if ELUsingAArch32(EL2) then // Virtual IRQ enabled if TGE==0 and FMO==1 - assert HCR.TGE == '0' && HCR.FMO == '1'; - else - assert HCR_EL2.TGE == '0' && HCR_EL2.FMO == '1'; - // Check if routed to AArch64 state - if PSTATE.EL == EL0 && !ELUsingAArch32(EL1) then AArch64.TakeVirtualFIQException(); - - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x1C; - lr_offset = 4; - - AArch32.EnterMode(M32_FIQ, preferred_exception_return, lr_offset, vect_offset); - -// AArch64.TakeVirtualIRQException() -// ================================= - -AArch64.TakeVirtualIRQException() - assert PSTATE.EL IN {EL0, EL1} && EL2Enabled(); - assert HCR_EL2.TGE == '0' && HCR_EL2.IMO == '1'; // Virtual IRQ enabled if TGE==0 and IMO==1 - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x80; - - exception = ExceptionSyndrome(Exception_IRQ); - - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.TakeVirtualIRQException() -// ================================= - -AArch32.TakeVirtualIRQException() - assert PSTATE.EL IN {EL0, EL1} && EL2Enabled(); - - if ELUsingAArch32(EL2) then // Virtual IRQs enabled if TGE==0 and IMO==1 - assert HCR.TGE == '0' && HCR.IMO == '1'; - else - assert HCR_EL2.TGE == '0' && HCR_EL2.IMO == '1'; - - // Check if routed to AArch64 state - if PSTATE.EL == EL0 && !ELUsingAArch32(EL1) then AArch64.TakeVirtualIRQException(); - - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x18; - lr_offset = 4; - - AArch32.EnterMode(M32_IRQ, preferred_exception_return, lr_offset, vect_offset); - -// Clear a pending virtual SError interrupt -ClearPendingVirtualSError(); - -// AArch64.TakeVirtualSErrorException() -// ==================================== - -AArch64.TakeVirtualSErrorException(boolean impdef_syndrome, bits(24) syndrome) - - assert PSTATE.EL IN {EL0, EL1} && EL2Enabled(); - assert HCR_EL2.TGE == '0' && HCR_EL2.AMO == '1'; // Virtual SError enabled if TGE==0 and AMO==1 - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x180; - - exception = ExceptionSyndrome(Exception_SError); - if HaveRASExt() then - exception.syndrome[24] = VSESR_EL2.IDS; - exception.syndrome[23:0] = VSESR_EL2.ISS; - else - exception.syndrome[24] = if impdef_syndrome then '1' else '0'; - if impdef_syndrome then exception.syndrome[23:0] = syndrome; - - ClearPendingVirtualSError(); - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.TakeVirtualSErrorException() -// ==================================== - -AArch32.TakeVirtualSErrorException(bit extflag, bits(2) errortype, boolean impdef_syndrome, bits(24) full_syndrome) - - assert PSTATE.EL IN {EL0, EL1} && EL2Enabled(); - if ELUsingAArch32(EL2) then // Virtual SError enabled if TGE==0 and AMO==1 - assert HCR.TGE == '0' && HCR.AMO == '1'; - else - assert HCR_EL2.TGE == '0' && HCR_EL2.AMO == '1'; - // Check if routed to AArch64 state - if PSTATE.EL == EL0 && !ELUsingAArch32(EL1) then AArch64.TakeVirtualSErrorException(impdef_syndrome, full_syndrome); - - route_to_monitor = FALSE; - - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x10; - lr_offset = 8; - - vaddress = bits(32) UNKNOWN; - parity = FALSE; - if HaveRASExt() then - if ELUsingAArch32(EL2) then - fault = AArch32.AsynchExternalAbort(FALSE, VDFSR.AET, VDFSR.ExT); - else - fault = AArch32.AsynchExternalAbort(FALSE, VSESR_EL2.AET, VSESR_EL2.ExT); - else - fault = AArch32.AsynchExternalAbort(parity, errortype, extflag); - - ClearPendingVirtualSError(); - AArch32.ReportDataAbort(route_to_monitor, fault, vaddress); - AArch32.EnterMode(M32_Abort, preferred_exception_return, lr_offset, vect_offset); - -// AArch32.DebugFault() -// ==================== - -FaultRecord AArch32.DebugFault(AccType acctype, boolean iswrite, bits(4) debugmoe) - - ipaddress = bits(40) UNKNOWN; - domain = bits(4) UNKNOWN; - errortype = bits(2) UNKNOWN; - level = integer UNKNOWN; - extflag = bit UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - - return AArch32.CreateFaultRecord(Fault_Debug, ipaddress, domain, level, acctype, iswrite, - extflag, debugmoe, errortype, secondstage, s2fs1walk); - -// AArch64.SoftwareBreakpoint() -// ============================ - -AArch64.SoftwareBreakpoint(bits(16) immediate) - - route_to_el2 = (PSTATE.EL IN {EL0, EL1} && - EL2Enabled() && (HCR_EL2.TGE == '1' || MDCR_EL2.TDE == '1')); - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_SoftwareBreakpoint); - exception.syndrome[15:0] = immediate; - - if UInt(PSTATE.EL) > UInt(EL1) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.SoftwareBreakpoint() -// ============================ - -AArch32.SoftwareBreakpoint(bits(16) immediate) - - if (EL2Enabled() && !ELUsingAArch32(EL2) && - (HCR_EL2.TGE == '1' || MDCR_EL2.TDE == '1')) || !ELUsingAArch32(EL1) then - AArch64.SoftwareBreakpoint(immediate); - vaddress = bits(32) UNKNOWN; - acctype = AccType_IFETCH; // Take as a Prefetch Abort - iswrite = FALSE; - entry = DebugException_BKPT; - - fault = AArch32.DebugFault(acctype, iswrite, entry); - AArch32.Abort(vaddress, fault); - -bits(4) AArch32.CurrentCond(); - -// ConditionHolds() -// ================ -// Return TRUE iff COND currently holds - -boolean ConditionHolds(bits(4) cond) - // Evaluate base condition. - case cond[3:1] of - when '000' result = (PSTATE.Z == '1'); // EQ or NE - when '001' result = (PSTATE.C == '1'); // CS or CC - when '010' result = (PSTATE.N == '1'); // MI or PL - when '011' result = (PSTATE.V == '1'); // VS or VC - when '100' result = (PSTATE.C == '1' && PSTATE.Z == '0'); // HI or LS - when '101' result = (PSTATE.N == PSTATE.V); // GE or LT - when '110' result = (PSTATE.N == PSTATE.V && PSTATE.Z == '0'); // GT or LE - when '111' result = TRUE; // AL - - // Condition flag values in the set '111x' indicate always true - // Otherwise, invert condition if necessary. - if cond[0] == '1' && cond != '1111' then - result = !result; - - return result; - -// ConditionSyndrome() -// =================== -// Return CV and COND fields of instruction syndrome - -bits(5) ConditionSyndrome() - - bits(5) syndrome; - - if UsingAArch32() then - cond = AArch32.CurrentCond(); - if PSTATE.T == '0' then // A32 - syndrome[4] = '1'; - // A conditional A32 instruction that is known to pass its condition code check - // can be presented either with COND set to 0xE, the value for unconditional, or - // the COND value held in the instruction. - if ConditionHolds(cond) && ConstrainUnpredictableBool(Unpredictable_ESRCONDPASS) then - syndrome[3:0] = '1110'; - else - syndrome[3:0] = cond; - else // T32 - // When a T32 instruction is trapped, it is IMPLEMENTATION DEFINED whether: - // * CV set to 0 and COND is set to an UNKNOWN value - // * CV set to 1 and COND is set to the condition code for the condition that - // applied to the instruction. - if boolean IMPLEMENTATION_DEFINED "Condition valid for trapped T32" then - syndrome[4] = '1'; - syndrome[3:0] = cond; - else - syndrome[4] = '0'; - syndrome[3:0] = bits(4) UNKNOWN; - else - syndrome[4] = '1'; - syndrome[3:0] = '1110'; - - return syndrome; - -// AArch32.SystemAccessTrapSyndrome() -// ================================== -// Returns the syndrome information for traps on AArch32 MCR, MCRR, MRC, MRRC, and VMRS, VMSR instructions, -// other than traps that are due to HCPTR or CPACR. - -ExceptionRecord AArch32.SystemAccessTrapSyndrome(bits(32) instr, integer ec) - ExceptionRecord exception; - - case ec of - when 0x0 exception = ExceptionSyndrome(Exception_Uncategorized); - when 0x3 exception = ExceptionSyndrome(Exception_CP15RTTrap); - when 0x4 exception = ExceptionSyndrome(Exception_CP15RRTTrap); - when 0x5 exception = ExceptionSyndrome(Exception_CP14RTTrap); - when 0x6 exception = ExceptionSyndrome(Exception_CP14DTTrap); - when 0x7 exception = ExceptionSyndrome(Exception_AdvSIMDFPAccessTrap); - when 0x8 exception = ExceptionSyndrome(Exception_FPIDTrap); - when 0xC exception = ExceptionSyndrome(Exception_CP14RRTTrap); - otherwise Unreachable(); - - bits(20) iss = Zeros(); - - if exception.exceptype IN {Exception_FPIDTrap, Exception_CP14RTTrap, Exception_CP15RTTrap} then - // Trapped MRC/MCR, VMRS on FPSID - iss[13:10] = instr[19:16]; // CRn, Reg in case of VMRS - iss[8:5] = instr[15:12]; // Rt - iss[9] = '0'; // RES0 - - if exception.exceptype != Exception_FPIDTrap then // When trap is not for VMRS - iss[19:17] = instr[7:5]; // opc2 - iss[16:14] = instr[23:21]; // opc1 - iss[4:1] = instr[3:0]; //CRm - else //VMRS Access - iss[19:17] = '000'; //opc2 - Hardcoded for VMRS - iss[16:14] = '111'; //opc1 - Hardcoded for VMRS - iss[4:1] = '0000'; //CRm - Hardcoded for VMRS - elsif exception.exceptype IN {Exception_CP14RRTTrap, Exception_AdvSIMDFPAccessTrap, Exception_CP15RRTTrap} then - // Trapped MRRC/MCRR, VMRS/VMSR - iss[19:16] = instr[7:4]; // opc1 - iss[13:10] = instr[19:16]; // Rt2 - iss[8:5] = instr[15:12]; // Rt - iss[4:1] = instr[3:0]; // CRm - elsif exception.exceptype == Exception_CP14DTTrap then - // Trapped LDC/STC - iss[19:12] = instr[7:0]; // imm8 - iss[4] = instr[23]; // U - iss[2:1] = instr[24,21]; // P,W - if instr[19:16] == '1111' then // Rn==15, LDC(Literal addressing)/STC - iss[8:5] = bits(4) UNKNOWN; - iss[3] = '1'; - elsif exception.exceptype == Exception_Uncategorized then - // Trapped for unknown reason - iss[8:5] = instr[19:16]; // Rn - iss[3] = '0'; - - iss[0] = instr[20]; // Direction - - exception.syndrome[24:20] = ConditionSyndrome(); - exception.syndrome[19:0] = iss; - - return exception; - -bits(32) ThisInstr(); - -// AArch32.TakeHypTrapException() -// ============================== -// Exceptions routed to Hyp mode as a Hyp Trap exception. - -AArch32.TakeHypTrapException(integer ec) - exception = AArch32.SystemAccessTrapSyndrome(ThisInstr(), ec); - AArch32.TakeHypTrapException(exception); - -// AArch32.TakeHypTrapException() -// ============================== -// Exceptions routed to Hyp mode as a Hyp Trap exception. - -AArch32.TakeHypTrapException(ExceptionRecord exception) - assert HaveEL(EL2) && !IsSecure() && ELUsingAArch32(EL2); - - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x14; - - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - -// AArch32.TakeUndefInstrException() -// ================================= - -AArch32.TakeUndefInstrException() - exception = ExceptionSyndrome(Exception_Uncategorized); - AArch32.TakeUndefInstrException(exception); - -// AArch32.TakeUndefInstrException() -// ================================= - -AArch32.TakeUndefInstrException(ExceptionRecord exception) - - route_to_hyp = PSTATE.EL == EL0 && EL2Enabled() && HCR.TGE == '1'; - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x04; - lr_offset = if CurrentInstrSet() == InstrSet_A32 then 4 else 2; - - if PSTATE.EL == EL2 then - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - elsif route_to_hyp then - AArch32.EnterHypMode(exception, preferred_exception_return, 0x14); - else - AArch32.EnterMode(M32_Undef, preferred_exception_return, lr_offset, vect_offset); - -// AArch32.SystemAccessTrap() -// ========================== -// Trapped system register access. - -AArch32.SystemAccessTrap(bits(5) mode, integer ec) - (valid, target_el) = ELFromM32(mode); - assert valid && HaveEL(target_el) && target_el != EL0 && UInt(target_el) >= UInt(PSTATE.EL); - - if target_el == EL2 then - exception = AArch32.SystemAccessTrapSyndrome(ThisInstr(), ec); - AArch32.TakeHypTrapException(exception); - else - AArch32.TakeUndefInstrException(); - -// AArch64.AArch32SystemAccessTrapSyndrome() -// ========================================= -// Returns the syndrome information for traps on AArch32 MCR, MCRR, MRC, MRRC, and VMRS, VMSR instructions, -// other than traps that are due to HCPTR or CPACR. - -ExceptionRecord AArch64.AArch32SystemAccessTrapSyndrome(bits(32) instr, integer ec) - ExceptionRecord exception; - - case ec of - when 0x0 exception = ExceptionSyndrome(Exception_Uncategorized); - when 0x3 exception = ExceptionSyndrome(Exception_CP15RTTrap); - when 0x4 exception = ExceptionSyndrome(Exception_CP15RRTTrap); - when 0x5 exception = ExceptionSyndrome(Exception_CP14RTTrap); - when 0x6 exception = ExceptionSyndrome(Exception_CP14DTTrap); - when 0x7 exception = ExceptionSyndrome(Exception_AdvSIMDFPAccessTrap); - when 0x8 exception = ExceptionSyndrome(Exception_FPIDTrap); - when 0xC exception = ExceptionSyndrome(Exception_CP14RRTTrap); - otherwise Unreachable(); - - bits(20) iss = Zeros(); - - if exception.exceptype IN {Exception_FPIDTrap, Exception_CP14RTTrap, Exception_CP15RTTrap} then - // Trapped MRC/MCR, VMRS on FPSID - if exception.exceptype != Exception_FPIDTrap then // When trap is not for VMRS - iss[19:17] = instr[7:5]; // opc2 - iss[16:14] = instr[23:21]; // opc1 - iss[13:10] = instr[19:16]; // CRn - iss[4:1] = instr[3:0]; // CRm - else - iss[19:17] = '000'; - iss[16:14] = '111'; - iss[13:10] = instr[19:16]; // reg - iss[4:1] = '0000'; - - if instr[20] == '1' && instr[15:12] == '1111' then // MRC, Rt==15 - iss[9:5] = '11111'; - elsif instr[20] == '0' && instr[15:12] == '1111' then // MCR, Rt==15 - iss[9:5] = bits(5) UNKNOWN; - else - iss[9:5] = LookUpRIndex(UInt(instr[15:12]), PSTATE.M)[4:0]; - elsif exception.exceptype IN {Exception_CP14RRTTrap, Exception_AdvSIMDFPAccessTrap, Exception_CP15RRTTrap} then - // Trapped MRRC/MCRR, VMRS/VMSR - iss[19:16] = instr[7:4]; // opc1 - if instr[19:16] == '1111' then // Rt2==15 - iss[14:10] = bits(5) UNKNOWN; - else - iss[14:10] = LookUpRIndex(UInt(instr[19:16]), PSTATE.M)[4:0]; - - if instr[15:12] == '1111' then // Rt==15 - iss[9:5] = bits(5) UNKNOWN; - else - iss[9:5] = LookUpRIndex(UInt(instr[15:12]), PSTATE.M)[4:0]; - iss[4:1] = instr[3:0]; // CRm - elsif exception.exceptype == Exception_CP14DTTrap then - // Trapped LDC/STC - iss[19:12] = instr[7:0]; // imm8 - iss[4] = instr[23]; // U - iss[2:1] = instr[24,21]; // P,W - if instr[19:16] == '1111' then // Rn==15, LDC(Literal addressing)/STC - iss[9:5] = bits(5) UNKNOWN; - iss[3] = '1'; - elsif exception.exceptype == Exception_Uncategorized then - // Trapped for unknown reason - iss[9:5] = LookUpRIndex(UInt(instr[19:16]), PSTATE.M)[4:0]; // Rn - iss[3] = '0'; - - iss[0] = instr[20]; // Direction - - exception.syndrome[24:20] = ConditionSyndrome(); - exception.syndrome[19:0] = iss; - - return exception; - -// AArch64.AArch32SystemAccessTrap() -// ================================= -// Trapped AARCH32 system register access. - -AArch64.AArch32SystemAccessTrap(bits(2) target_el, integer ec) - assert HaveEL(target_el) && target_el != EL0 && UInt(target_el) >= UInt(PSTATE.EL); - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = AArch64.AArch32SystemAccessTrapSyndrome(ThisInstr(), ec); - AArch64.TakeException(target_el, exception, preferred_exception_return, vect_offset); - -// AArch32.CheckAdvSIMDOrFPRegisterTraps() -// ======================================= -// Check if an instruction that accesses an Advanced SIMD and -// floating-point System register is trapped by an appropriate HCR.TIDx -// ID group trap control. - -AArch32.CheckAdvSIMDOrFPRegisterTraps(bits(4) reg) - - if PSTATE.EL == EL1 && EL2Enabled() then - tid0 = if ELUsingAArch32(EL2) then HCR.TID0 else HCR_EL2.TID0; - tid3 = if ELUsingAArch32(EL2) then HCR.TID3 else HCR_EL2.TID3; - - if (tid0 == '1' && reg == '0000') // FPSID - || (tid3 == '1' && reg IN {'0101', '0110', '0111'}) then // MVFRx - if ELUsingAArch32(EL2) then - AArch32.SystemAccessTrap(M32_Hyp, 0x8); // Exception_AdvSIMDFPAccessTrap - else - AArch64.AArch32SystemAccessTrap(EL2, 0x8); // Exception_AdvSIMDFPAccessTrap - -// Resets System registers and memory-mapped control registers that have architecturally-defined -// reset values to those values. -AArch32.ResetControlRegisters(boolean cold_reset); - -// AArch32.ResetGeneralRegisters() -// =============================== - -AArch32.ResetGeneralRegisters() - - for i = 0 to 7 - R[i] = bits(32) UNKNOWN; - for i = 8 to 12 - Rmode[i, M32_User] = bits(32) UNKNOWN; - Rmode[i, M32_FIQ] = bits(32) UNKNOWN; - if HaveEL(EL2) then Rmode[13, M32_Hyp] = bits(32) UNKNOWN; // No R14_hyp - for i = 13 to 14 - Rmode[i, M32_User] = bits(32) UNKNOWN; - Rmode[i, M32_FIQ] = bits(32) UNKNOWN; - Rmode[i, M32_IRQ] = bits(32) UNKNOWN; - Rmode[i, M32_Svc] = bits(32) UNKNOWN; - Rmode[i, M32_Abort] = bits(32) UNKNOWN; - Rmode[i, M32_Undef] = bits(32) UNKNOWN; - if HaveEL(EL3) then Rmode[i, M32_Monitor] = bits(32) UNKNOWN; - - return; - -// Q[] - non-assignment form -// ========================= - -bits(128) Q[integer n] - assert n >= 0 && n <= 15; - return V[n]; - -// Q[] - assignment form -// ===================== - -Q[integer n] = bits(128) value - assert n >= 0 && n <= 15; - V[n] = value; - return; - -// AArch32.ResetSIMDFPRegisters() -// ============================== - -AArch32.ResetSIMDFPRegisters() - - for i = 0 to 15 - Q[i] = bits(128) UNKNOWN; - - return; - -// AArch32.ResetSpecialRegisters() -// =============================== - -AArch32.ResetSpecialRegisters() - - // AArch32 special registers - SPSR_fiq = bits(32) UNKNOWN; - SPSR_irq = bits(32) UNKNOWN; - SPSR_svc = bits(32) UNKNOWN; - SPSR_abt = bits(32) UNKNOWN; - SPSR_und = bits(32) UNKNOWN; - if HaveEL(EL2) then - SPSR_hyp = bits(32) UNKNOWN; - ELR_hyp = bits(32) UNKNOWN; - if HaveEL(EL3) then - SPSR_mon = bits(32) UNKNOWN; - - // External debug special registers - DLR = bits(32) UNKNOWN; - DSPSR = bits(32) UNKNOWN; - - return; - -// Reset the External Debug registers in the Core power domain. -ResetExternalDebugRegisters(boolean cold_reset); - -// AArch32.TakeReset() -// =================== -// Reset into AArch32 state - -AArch32.TakeReset(boolean cold_reset) - assert HighestELUsingAArch32(); - - // Enter the highest implemented Exception level in AArch32 state - if HaveEL(EL3) then - AArch32.WriteMode(M32_Svc); - SCR.NS = '0'; // Secure state - elsif HaveEL(EL2) then - AArch32.WriteMode(M32_Hyp); - else - AArch32.WriteMode(M32_Svc); - - // Reset the CP14 and CP15 registers and other system components - AArch32.ResetControlRegisters(cold_reset); - FPEXC.EN = '0'; - - // Reset all other PSTATE fields, including instruction set and endianness according to the - // SCTLR values produced by the above call to ResetControlRegisters() - PSTATE.[A,I,F] = '111'; // All asynchronous exceptions masked - PSTATE.IT = '00000000'; // IT block state reset - PSTATE.T = SCTLR.TE; // Instruction set: TE=0: A32, TE=1: T32. PSTATE.J is RES0. - PSTATE.E = SCTLR.EE; // Endianness: EE=0: little-endian, EE=1: big-endian - PSTATE.IL = '0'; // Clear Illegal Execution state bit - - // All registers, bits and fields not reset by the above pseudocode or by the BranchTo() call - // below are UNKNOWN bitstrings after reset. In particular, the return information registers - // R14 or ELR_hyp and SPSR have UNKNOWN values, so that it - // is impossible to return from a reset in an architecturally defined way. - AArch32.ResetGeneralRegisters(); - AArch32.ResetSIMDFPRegisters(); - AArch32.ResetSpecialRegisters(); - ResetExternalDebugRegisters(cold_reset); - - bits(32) rv; // IMPLEMENTATION DEFINED reset vector - - if HaveEL(EL3) then - if MVBAR[0] == '1' then // Reset vector in MVBAR - rv = MVBAR[31:1]:'0'; - else - rv = bits(32) IMPLEMENTATION_DEFINED "reset vector address"; - else - rv = RVBAR[31:1]:'0'; - - // The reset vector must be correctly aligned - assert rv[0] == '0' && (PSTATE.T == '1' || rv[1] == '0'); - - BranchTo(rv, BranchType_RESET); - -// AArch64.FPTrappedException() -// ============================ - -AArch64.FPTrappedException(boolean is_ase, integer element, bits(8) accumulated_exceptions) - exception = ExceptionSyndrome(Exception_FPTrappedException); - if is_ase then - if boolean IMPLEMENTATION_DEFINED "vector instructions set TFV to 1" then - exception.syndrome[23] = '1'; // TFV - else - exception.syndrome[23] = '0'; // TFV - else - exception.syndrome[23] = '1'; // TFV - exception.syndrome[10:8] = bits(3) UNKNOWN; // VECITR - if exception.syndrome[23] == '1' then - exception.syndrome[7,4:0] = accumulated_exceptions[7,4:0]; // IDF,IXF,UFF,OFF,DZF,IOF - else - exception.syndrome[7,4:0] = bits(6) UNKNOWN; - - route_to_el2 = EL2Enabled() && HCR_EL2.TGE == '1'; - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - if UInt(PSTATE.EL) > UInt(EL1) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.FPTrappedException() -// ============================ - -AArch32.FPTrappedException(bits(8) accumulated_exceptions) - if AArch32.GeneralExceptionsToAArch64() then - is_ase = FALSE; - element = 0; - AArch64.FPTrappedException(is_ase, element, accumulated_exceptions); - FPEXC.DEX = '1'; - FPEXC.TFV = '1'; - FPEXC[7,4:0] = accumulated_exceptions[7,4:0]; // IDF,IXF,UFF,OFF,DZF,IOF - FPEXC[10:8] = '111'; // VECITR is RES1 - - AArch32.TakeUndefInstrException(); - -// LSL_C() -// ======= - -(bits(N), bit) LSL_C(bits(N) x, integer shift) - assert shift > 0; - extended_x = x : Zeros(shift); - result = extended_x[N-1:0]; - carry_out = extended_x[N]; - return (result, carry_out); - -// LSL() -// ===== - -bits(N) LSL(bits(N) x, integer shift) - assert shift >= 0; - if shift == 0 then - result = x; - else - (result, -) = LSL_C(x, shift); - return result; - -// AArch32.ITAdvance() -// =================== - -AArch32.ITAdvance() - if PSTATE.IT[2:0] == '000' then - PSTATE.IT = '00000000'; - else - PSTATE.IT[4:0] = LSL(PSTATE.IT[4:0], 1); - return; - -// Return address of the sequentially next instruction. -bits(N) NextInstrAddr(); - -// SSAdvance() -// =========== -// Advance the Software Step state machine. - -SSAdvance() - - // A simpler implementation of this function just clears PSTATE.SS to zero regardless of the - // current Software Step state machine. However, this check is made to illustrate that the - // processor only needs to consider advancing the state machine from the active-not-pending - // state. - target = DebugTarget(); - step_enabled = !ELUsingAArch32(target) && MDSCR_EL1.SS == '1'; - active_not_pending = step_enabled && PSTATE.SS == '1'; - - if active_not_pending then PSTATE.SS = '0'; - - return; - -// AArch32.TakeHVCException() -// ========================== - -AArch32.TakeHVCException(bits(16) immediate) - assert HaveEL(EL2) && ELUsingAArch32(EL2); - - AArch32.ITAdvance(); - SSAdvance(); - bits(32) preferred_exception_return = NextInstrAddr(); - vect_offset = 0x08; - - exception = ExceptionSyndrome(Exception_HypervisorCall); - exception.syndrome[15:0] = immediate; - - if PSTATE.EL == EL2 then - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - else - AArch32.EnterHypMode(exception, preferred_exception_return, 0x14); - -// AArch64.CallHypervisor() -// ======================== -// Performs a HVC call - -AArch64.CallHypervisor(bits(16) immediate) - assert HaveEL(EL2); - - if UsingAArch32() then AArch32.ITAdvance(); - SSAdvance(); - bits(64) preferred_exception_return = NextInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_HypervisorCall); - exception.syndrome[15:0] = immediate; - - if PSTATE.EL == EL3 then - AArch64.TakeException(EL3, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - -// AArch32.CallHypervisor() -// ======================== -// Performs a HVC call - -AArch32.CallHypervisor(bits(16) immediate) - assert HaveEL(EL2); - - if !ELUsingAArch32(EL2) then - AArch64.CallHypervisor(immediate); - else - AArch32.TakeHVCException(immediate); - -// AArch32.TakeSVCException() -// ========================== - -AArch32.TakeSVCException(bits(16) immediate) - - AArch32.ITAdvance(); - SSAdvance(); - route_to_hyp = PSTATE.EL == EL0 && EL2Enabled() && HCR.TGE == '1'; - - bits(32) preferred_exception_return = NextInstrAddr(); - vect_offset = 0x08; - lr_offset = 0; - - if PSTATE.EL == EL2 || route_to_hyp then - exception = ExceptionSyndrome(Exception_SupervisorCall); - exception.syndrome[15:0] = immediate; - if PSTATE.EL == EL2 then - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - else - AArch32.EnterHypMode(exception, preferred_exception_return, 0x14); - else - AArch32.EnterMode(M32_Svc, preferred_exception_return, lr_offset, vect_offset); - -// AArch64.CallSupervisor() -// ======================== -// Calls the Supervisor - -AArch64.CallSupervisor(bits(16) immediate) - - if UsingAArch32() then AArch32.ITAdvance(); - SSAdvance(); - route_to_el2 = PSTATE.EL == EL0 && EL2Enabled() && HCR_EL2.TGE == '1'; - - bits(64) preferred_exception_return = NextInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_SupervisorCall); - exception.syndrome[15:0] = immediate; - - if UInt(PSTATE.EL) > UInt(EL1) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.CallSupervisor() -// ======================== -// Calls the Supervisor - -AArch32.CallSupervisor(bits(16) immediate) - - if AArch32.CurrentCond() != '1110' then - immediate = bits(16) UNKNOWN; - if AArch32.GeneralExceptionsToAArch64() then - AArch64.CallSupervisor(immediate); - else - AArch32.TakeSVCException(immediate); - -// AArch32.TakeSMCException() -// ========================== - -AArch32.TakeSMCException() - assert HaveEL(EL3) && ELUsingAArch32(EL3); - AArch32.ITAdvance(); - SSAdvance(); - bits(32) preferred_exception_return = NextInstrAddr(); - vect_offset = 0x08; - lr_offset = 0; - - AArch32.EnterMonitorMode(preferred_exception_return, lr_offset, vect_offset); - -// AArch64.AdvSIMDFPAccessTrap() -// ============================= -// Trapped access to Advanced SIMD or FP registers due to CPACR[]. - -AArch64.AdvSIMDFPAccessTrap(bits(2) target_el) - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - route_to_el2 = (target_el == EL1 && EL2Enabled() && HCR_EL2.TGE == '1'); - - if route_to_el2 then - exception = ExceptionSyndrome(Exception_Uncategorized); - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - exception = ExceptionSyndrome(Exception_AdvSIMDFPAccessTrap); - exception.syndrome[24:20] = ConditionSyndrome(); - AArch64.TakeException(target_el, exception, preferred_exception_return, vect_offset); - - return; - -// AArch64.CheckFPAdvSIMDTrap() -// ============================ -// Check against CPTR_EL2 and CPTR_EL3. - -AArch64.CheckFPAdvSIMDTrap() - if PSTATE.EL IN {EL0, EL1, EL2} && EL2Enabled() then - // Check if access disabled in CPTR_EL2 - if HaveVirtHostExt() && HCR_EL2.E2H == '1' then - case CPTR_EL2.FPEN of - when 'x0' disabled = TRUE; - when '01' disabled = PSTATE.EL == EL0 && HCR_EL2.TGE == '1'; - when '11' disabled = FALSE; - if disabled then AArch64.AdvSIMDFPAccessTrap(EL2); - else - if CPTR_EL2.TFP == '1' then AArch64.AdvSIMDFPAccessTrap(EL2); - - if HaveEL(EL3) then - // Check if access disabled in CPTR_EL3 - if CPTR_EL3.TFP == '1' then AArch64.AdvSIMDFPAccessTrap(EL3); - - return; - -// AArch32.CheckFPAdvSIMDTrap() -// ============================ -// Check against CPTR_EL2 and CPTR_EL3. - -AArch32.CheckFPAdvSIMDTrap(boolean advsimd) - if EL2Enabled() && !ELUsingAArch32(EL2) then - AArch64.CheckFPAdvSIMDTrap(); - else - if HaveEL(EL2) && !IsSecure() then - hcptr_tase = HCPTR.TASE; - hcptr_cp10 = HCPTR.TCP10; - - if HaveEL(EL3) && ELUsingAArch32(EL3) && !IsSecure() then - // Check if access disabled in NSACR - if NSACR.NSASEDIS == '1' then hcptr_tase = '1'; - if NSACR.cp10 == '0' then hcptr_cp10 = '1'; - - // Check if access disabled in HCPTR - if (advsimd && hcptr_tase == '1') || hcptr_cp10 == '1' then - exception = ExceptionSyndrome(Exception_AdvSIMDFPAccessTrap); - exception.syndrome[24:20] = ConditionSyndrome(); - - if advsimd then - exception.syndrome[5] = '1'; - else - exception.syndrome[5] = '0'; - exception.syndrome[3:0] = '1010'; // coproc field, always 0xA - - if PSTATE.EL == EL2 then - AArch32.TakeUndefInstrException(exception); - else - AArch32.TakeHypTrapException(exception); - - if HaveEL(EL3) && !ELUsingAArch32(EL3) then - // Check if access disabled in CPTR_EL3 - if CPTR_EL3.TFP == '1' then AArch64.AdvSIMDFPAccessTrap(EL3); - return; - -// AArch64.CheckFPAdvSIMDEnabled() -// =============================== -// Check against CPACR[] - -AArch64.CheckFPAdvSIMDEnabled() - if PSTATE.EL IN {EL0, EL1} && !IsInHost() then - // Check if access disabled in CPACR_EL1 - case CPACR_EL1.FPEN of - when 'x0' disabled = TRUE; - when '01' disabled = PSTATE.EL == EL0; - when '11' disabled = FALSE; - if disabled then AArch64.AdvSIMDFPAccessTrap(EL1); - - AArch64.CheckFPAdvSIMDTrap(); // Also check against CPTR_EL2 and CPTR_EL3 - -// AArch32.CheckAdvSIMDOrFPEnabled() -// ================================= -// Check against CPACR, FPEXC, HCPTR, NSACR, and CPTR_EL3. - -AArch32.CheckAdvSIMDOrFPEnabled(boolean fpexc_check, boolean advsimd) - if PSTATE.EL == EL0 && (!HaveEL(EL2) || (!ELUsingAArch32(EL2) && HCR_EL2.TGE == '0')) && !ELUsingAArch32(EL1) then - // The PE behaves as if FPEXC.EN is 1 - AArch64.CheckFPAdvSIMDEnabled(); - elsif PSTATE.EL == EL0 && HaveEL(EL2) && !ELUsingAArch32(EL2) && HCR_EL2.TGE == '1' && !ELUsingAArch32(EL1) then - if fpexc_check && HCR_EL2.RW == '0' then - fpexc_en = bits(1) IMPLEMENTATION_DEFINED "FPEXC.EN value when TGE==1 and RW==0"; - if fpexc_en == '0' then UNDEFINED; - AArch64.CheckFPAdvSIMDEnabled(); - else - cpacr_asedis = CPACR.ASEDIS; - cpacr_cp10 = CPACR.cp10; - - if HaveEL(EL3) && ELUsingAArch32(EL3) && !IsSecure() then - // Check if access disabled in NSACR - if NSACR.NSASEDIS == '1' then cpacr_asedis = '1'; - if NSACR.cp10 == '0' then cpacr_cp10 = '00'; - - if PSTATE.EL != EL2 then - // Check if Advanced SIMD disabled in CPACR - if advsimd && cpacr_asedis == '1' then UNDEFINED; - - // Check if access disabled in CPACR - case cpacr_cp10 of - when '00' disabled = TRUE; - when '01' disabled = PSTATE.EL == EL0; - when '10' disabled = ConstrainUnpredictableBool(Unpredictable_RESCPACR); - when '11' disabled = FALSE; - if disabled then UNDEFINED; - - // If required, check FPEXC enabled bit. - if fpexc_check && FPEXC.EN == '0' then UNDEFINED; - - AArch32.CheckFPAdvSIMDTrap(advsimd); // Also check against HCPTR and CPTR_EL3 - -// AArch64.CheckForSMCUndefOrTrap() -// ================================ -// Check for UNDEFINED or trap on SMC instruction - -AArch64.CheckForSMCUndefOrTrap(bits(16) imm) - route_to_el2 = PSTATE.EL == EL1 && EL2Enabled() && HCR_EL2.TSC == '1'; - if PSTATE.EL == EL0 then UNDEFINED; - if !HaveEL(EL3) then - if PSTATE.EL == EL1 && EL2Enabled() then - if HaveNVExt() && HCR_EL2.NV == '1' && HCR_EL2.TSC == '1' then - route_to_el2 = TRUE; - else - UNDEFINED; - else - UNDEFINED; - else - route_to_el2 = PSTATE.EL == EL1 && EL2Enabled() && HCR_EL2.TSC == '1'; - if route_to_el2 then - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - exception = ExceptionSyndrome(Exception_MonitorCall); - exception.syndrome[15:0] = imm; - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - -// AArch32.CheckForSMCUndefOrTrap() -// ================================ -// Check for UNDEFINED or trap on SMC instruction - -AArch32.CheckForSMCUndefOrTrap() - if !HaveEL(EL3) || PSTATE.EL == EL0 then - UNDEFINED; - - if EL2Enabled() && !ELUsingAArch32(EL2) then - AArch64.CheckForSMCUndefOrTrap(Zeros(16)); - else - route_to_hyp = HaveEL(EL2) && !IsSecure() && PSTATE.EL == EL1 && HCR.TSC == '1'; - if route_to_hyp then - exception = ExceptionSyndrome(Exception_MonitorCall); - AArch32.TakeHypTrapException(exception); - -// HaveFGTExt() -// ============ -// Returns TRUE if Fine Grained Trap is implemented, and FALSE otherwise. - -boolean HaveFGTExt() - return HasArchVersion(ARMv8p6) && !ELUsingAArch32(EL2); - -// AArch32.CheckForSVCTrap() -// ========================= -// Check for trap on SVC instruction - -AArch32.CheckForSVCTrap(bits(16) immediate) - if HaveFGTExt() then - route_to_el2 = FALSE; - if PSTATE.EL == EL0 then - route_to_el2 = !ELUsingAArch32(EL1) && EL2Enabled() && HFGITR_EL2.SVC_EL0 == '1' && (HCR_EL2.[E2H, TGE] != '11' && (!HaveEL(EL3) || SCR_EL3.FGTEn == '1')) ; - - if route_to_el2 then - exception = ExceptionSyndrome(Exception_SupervisorCall); - exception.syndrome[15:0] = immediate; - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - -// AArch32.TakeMonitorTrapException() -// ================================== -// Exceptions routed to Monitor mode as a Monitor Trap exception. - -AArch32.TakeMonitorTrapException() - assert HaveEL(EL3) && ELUsingAArch32(EL3); - - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x04; - lr_offset = if CurrentInstrSet() == InstrSet_A32 then 4 else 2; - - AArch32.EnterMonitorMode(preferred_exception_return, lr_offset, vect_offset); - -// AArch64.WFxTrap() -// ================= - -AArch64.WFxTrap(bits(2) target_el, boolean is_wfe) - assert UInt(target_el) > UInt(PSTATE.EL); - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_WFxTrap); - exception.syndrome[24:20] = ConditionSyndrome(); - exception.syndrome[0] = if is_wfe then '1' else '0'; - - if target_el == EL1 && EL2Enabled() && HCR_EL2.TGE == '1' then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(target_el, exception, preferred_exception_return, vect_offset); - -// AArch64.CheckForWFxTrap() -// ========================= -// Check for trap on WFE or WFI instruction - -AArch64.CheckForWFxTrap(bits(2) target_el, boolean is_wfe) - assert HaveEL(target_el); - - case target_el of - when EL1 trap = (if is_wfe then SCTLR[].nTWE else SCTLR[].nTWI) == '0'; - when EL2 trap = (if is_wfe then HCR_EL2.TWE else HCR_EL2.TWI) == '1'; - when EL3 trap = (if is_wfe then SCR_EL3.TWE else SCR_EL3.TWI) == '1'; - if trap then - AArch64.WFxTrap(target_el, is_wfe); - -// AArch32.CheckForWFxTrap() -// ========================= -// Check for trap on WFE or WFI instruction - -AArch32.CheckForWFxTrap(bits(2) target_el, boolean is_wfe) - assert HaveEL(target_el); - - // Check for routing to AArch64 - if !ELUsingAArch32(target_el) then - AArch64.CheckForWFxTrap(target_el, is_wfe); - return; - case target_el of - when EL1 trap = (if is_wfe then SCTLR.nTWE else SCTLR.nTWI) == '0'; - when EL2 trap = (if is_wfe then HCR.TWE else HCR.TWI) == '1'; - when EL3 trap = (if is_wfe then SCR.TWE else SCR.TWI) == '1'; - if trap then - if target_el == EL1 && EL2Enabled() && !ELUsingAArch32(EL2) && HCR_EL2.TGE == '1' then - AArch64.WFxTrap(target_el, is_wfe); - if target_el == EL3 then - AArch32.TakeMonitorTrapException(); - elsif target_el == EL2 then - exception = ExceptionSyndrome(Exception_WFxTrap); - exception.syndrome[24:20] = ConditionSyndrome(); - exception.syndrome[0] = if is_wfe then '1' else '0'; - AArch32.TakeHypTrapException(exception); - else - AArch32.TakeUndefInstrException(); - -// AArch32.NoFault() -// ================= - -FaultRecord AArch32.NoFault() - - ipaddress = bits(40) UNKNOWN; - domain = bits(4) UNKNOWN; - level = integer UNKNOWN; - acctype = AccType_NORMAL; - iswrite = boolean UNKNOWN; - extflag = bit UNKNOWN; - debugmoe = bits(4) UNKNOWN; - errortype = bits(2) UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - - return AArch32.CreateFaultRecord(Fault_None, ipaddress, domain, level, acctype, iswrite, - extflag, debugmoe, errortype, secondstage, s2fs1walk); - -constant bits(6) DebugHalt_Breakpoint = '000111'; -constant bits(6) DebugHalt_EDBGRQ = '010011'; -constant bits(6) DebugHalt_Step_Normal = '011011'; -constant bits(6) DebugHalt_Step_Exclusive = '011111'; -constant bits(6) DebugHalt_OSUnlockCatch = '100011'; -constant bits(6) DebugHalt_ResetCatch = '100111'; -constant bits(6) DebugHalt_Watchpoint = '101011'; -constant bits(6) DebugHalt_HaltInstruction = '101111'; -constant bits(6) DebugHalt_SoftwareAccess = '110011'; -constant bits(6) DebugHalt_ExceptionCatch = '110111'; -constant bits(6) DebugHalt_Step_NoSyndrome = '111011'; - -// Signal a discrete event on a Cross Trigger input event trigger. -CTI_SignalEvent(CrossTriggerIn id); - -StopInstructionPrefetchAndEnableITR(); - -// Halt() -// ====== - -Halt(bits(6) reason) - - CTI_SignalEvent(CrossTriggerIn_CrossHalt); // Trigger other cores to halt - - bits(64) preferred_restart_address = ThisInstrAddr(); - spsr = GetPSRFromPSTATE(); - - if UsingAArch32() then - // If entering from AArch32 state, spsr[21] is the DIT bit which has to be moved for DSPSR - spsr[24] = spsr[21]; - spsr[21] = PSTATE.SS; // Always save the SS bit - - if (HaveBTIExt() && - !(reason IN {DebugHalt_Step_Normal, DebugHalt_Step_Exclusive, DebugHalt_Step_NoSyndrome, - DebugHalt_Breakpoint, DebugHalt_HaltInstruction}) && - ConstrainUnpredictableBool(Unpredictable_ZEROBTYPE)) then - DSPSR[11:10] = '00'; - - if UsingAArch32() then - DLR = preferred_restart_address[31:0]; - DSPSR = spsr; - else - DLR_EL0 = preferred_restart_address; - DSPSR_EL0 = spsr; - - EDSCR.ITE = '1'; - EDSCR.ITO = '0'; - if IsSecure() then - EDSCR.SDD = '0'; // If entered in Secure state, allow debug - elsif HaveEL(EL3) then - EDSCR.SDD = if ExternalSecureInvasiveDebugEnabled() then '0' else '1'; - else - assert EDSCR.SDD == '1'; // Otherwise EDSCR.SDD is RES1 - EDSCR.MA = '0'; - - // PSTATE.{SS,D,A,I,F} are not observable and ignored in Debug state, so behave as if - // UNKNOWN. PSTATE.{N,Z,C,V,Q,GE} are also not observable, but since these are not changed on - // exception entry, this function also leaves them unchanged. PSTATE.{E,M,nRW,EL,SP} are - // unchanged. PSTATE.IL is set to 0. - if UsingAArch32() then - PSTATE.[SS,A,I,F] = bits(4) UNKNOWN; - // In AArch32, all instructions are T32 and unconditional. - PSTATE.IT = '00000000'; - PSTATE.T = '1'; // PSTATE.J is RES0 - else - PSTATE.[SS,D,A,I,F] = bits(5) UNKNOWN; - PSTATE.IL = '0'; - - StopInstructionPrefetchAndEnableITR(); - EDSCR.STATUS = reason; // Signal entered Debug state - UpdateEDSCRFields(); // Update EDSCR PE state flags. - - return; - -// AArch32.CheckBreakpoint() -// ========================= -// Called before executing the instruction of length "size" bytes at "vaddress" in an AArch32 -// translation regime, when either debug exceptions are enabled, or halting debug is enabled -// and halting is allowed. - -FaultRecord AArch32.CheckBreakpoint(bits(32) vaddress, integer size) - assert ELUsingAArch32(S1TranslationRegime()); - assert size IN {2,4}; - - match = FALSE; - mismatch = FALSE; - - for i = 0 to UInt(DBGDIDR.BRPs) - (match_i, mismatch_i) = AArch32.BreakpointMatch(i, vaddress, size); - match = match || match_i; - mismatch = mismatch || mismatch_i; - - if match && HaltOnBreakpointOrWatchpoint() then - reason = DebugHalt_Breakpoint; - Halt(reason); - elsif (match || mismatch) then - acctype = AccType_IFETCH; - iswrite = FALSE; - debugmoe = DebugException_Breakpoint; - return AArch32.DebugFault(acctype, iswrite, debugmoe); - else - return AArch32.NoFault(); - -// AArch32.CheckVectorCatch() -// ========================== -// Called before executing the instruction of length "size" bytes at "vaddress" in an AArch32 -// translation regime, when debug exceptions are enabled. - -FaultRecord AArch32.CheckVectorCatch(bits(32) vaddress, integer size) - assert ELUsingAArch32(S1TranslationRegime()); - - match = AArch32.VCRMatch(vaddress); - if size == 4 && !match && AArch32.VCRMatch(vaddress + 2) then - match = ConstrainUnpredictableBool(Unpredictable_VCMATCHHALF); - - if match then - acctype = AccType_IFETCH; - iswrite = FALSE; - debugmoe = DebugException_VectorCatch; - return AArch32.DebugFault(acctype, iswrite, debugmoe); - else - return AArch32.NoFault(); - -// AArch32.AccessUsesEL() -// ====================== -// Returns the Exception Level of the regime that will manage the translation for a given access type1. - -bits(2) AArch32.AccessUsesEL(AccType acctype) - if acctype == AccType_UNPRIV then - return EL0; - else - return PSTATE.EL; - -// AArch32.AccessIsPrivileged() -// ============================ - -boolean AArch32.AccessIsPrivileged(AccType acctype) - - el = AArch32.AccessUsesEL(acctype); - - if el == EL0 then - ispriv = FALSE; - elsif el != EL1 then - ispriv = TRUE; - else - ispriv = (acctype != AccType_UNPRIV); - - return ispriv; - -// AArch32.CheckWatchpoint() -// ========================= -// Called before accessing the memory location of "size" bytes at "address", -// when either debug exceptions are enabled for the access, or halting debug -// is enabled and halting is allowed. - -FaultRecord AArch32.CheckWatchpoint(bits(32) vaddress, AccType acctype, - boolean iswrite, integer size) - assert ELUsingAArch32(S1TranslationRegime()); - - match = FALSE; - ispriv = AArch32.AccessIsPrivileged(acctype); - - for i = 0 to UInt(DBGDIDR.WRPs) - match = match || AArch32.WatchpointMatch(i, vaddress, size, ispriv, iswrite); - - if match && HaltOnBreakpointOrWatchpoint() then - reason = DebugHalt_Watchpoint; - Halt(reason); - elsif match then - debugmoe = DebugException_Watchpoint; - return AArch32.DebugFault(acctype, iswrite, debugmoe); - else - return AArch32.NoFault(); - -// AArch32.CheckDebug() -// ==================== -// Called on each access to check for a debug exception or entry to Debug state. - -FaultRecord AArch32.CheckDebug(bits(32) vaddress, AccType acctype, boolean iswrite, integer size) - - FaultRecord fault = AArch32.NoFault(); - - d_side = (acctype != AccType_IFETCH); - generate_exception = AArch32.GenerateDebugExceptions() && DBGDSCRext.MDBGen == '1'; - halt = HaltOnBreakpointOrWatchpoint(); - // Relative priority of Vector Catch and Breakpoint exceptions not defined in the architecture - vector_catch_first = ConstrainUnpredictableBool(Unpredictable_BPVECTORCATCHPRI); - - if !d_side && vector_catch_first && generate_exception then - fault = AArch32.CheckVectorCatch(vaddress, size); - - if fault.statuscode == Fault_None && (generate_exception || halt) then - if d_side then - fault = AArch32.CheckWatchpoint(vaddress, acctype, iswrite, size); - else - fault = AArch32.CheckBreakpoint(vaddress, size); - - if fault.statuscode == Fault_None && !d_side && !vector_catch_first && generate_exception then - return AArch32.CheckVectorCatch(vaddress, size); - - return fault; - -// AArch32.DomainFault() -// ===================== - -FaultRecord AArch32.DomainFault(bits(4) domain, integer level, AccType acctype, boolean iswrite) - - ipaddress = bits(40) UNKNOWN; - extflag = bit UNKNOWN; - debugmoe = bits(4) UNKNOWN; - errortype = bits(2) UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - - return AArch32.CreateFaultRecord(Fault_Domain, ipaddress, domain, level, acctype, iswrite, - extflag, debugmoe, errortype, secondstage, s2fs1walk); - -// AArch32.CheckDomain() -// ===================== - -(boolean, FaultRecord) AArch32.CheckDomain(bits(4) domain, bits(32) vaddress, integer level, - AccType acctype, boolean iswrite) - - index = 2 * UInt(domain); - attrfield = DACR[index+1:index]; - - if attrfield == '10' then // Reserved, maps to an allocated value - // Reserved value maps to an allocated value - (-, attrfield) = ConstrainUnpredictableBits(Unpredictable_RESDACR); - - if attrfield == '00' then - fault = AArch32.DomainFault(domain, level, acctype, iswrite); - else - fault = AArch32.NoFault(); - - permissioncheck = (attrfield == '01'); - - return (permissioncheck, fault); - -// HavePrivATExt() -// =============== - -boolean HavePrivATExt() - return HasArchVersion(ARMv8p2); - -// AArch32.ExecutingATS1xPInstr() -// ============================== -// Return TRUE if current instruction is AT S1CPR/WP - -boolean AArch32.ExecutingATS1xPInstr() - if !HavePrivATExt() then return FALSE; - - instr = ThisInstr(); - if instr[24+:4] == '1110' && instr[8+:4] == '1110' then - op1 = instr[21+:3]; - CRn = instr[16+:4]; - CRm = instr[0+:4]; - op2 = instr[5+:3]; - return (op1 == '000' && CRn == '0111' && CRm == '1001' && op2 IN {'000','001'}); - else - return FALSE; - -// AArch32.PermissionFault() -// ========================= - -FaultRecord AArch32.PermissionFault(bits(40) ipaddress, bits(4) domain, integer level, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - extflag = bit UNKNOWN; - debugmoe = bits(4) UNKNOWN; - errortype = bits(2) UNKNOWN; - return AArch32.CreateFaultRecord(Fault_Permission, ipaddress, domain, level, acctype, iswrite, - extflag, debugmoe, errortype, secondstage, s2fs1walk); - -type Permissions is ( - bits(3) ap, // Access permission bits - bit xn, // Execute-never bit - bit xxn, // [Armv8.2] Extended execute-never bit for stage 2 - bit pxn // Privileged execute-never bit -) - -// AArch32.CheckPermission() -// ========================= -// Function used for permission checking from AArch32 stage 1 translations - -FaultRecord AArch32.CheckPermission(Permissions perms, bits(32) vaddress, integer level, - bits(4) domain, bit NS, AccType acctype, boolean iswrite) - assert ELUsingAArch32(S1TranslationRegime()); - - if PSTATE.EL != EL2 then - wxn = SCTLR.WXN == '1'; - if TTBCR.EAE == '1' || SCTLR.AFE == '1' || perms.ap[0] == '1' then - priv_r = TRUE; - priv_w = perms.ap[2] == '0'; - user_r = perms.ap[1] == '1'; - user_w = perms.ap[2:1] == '01'; - else - priv_r = perms.ap[2:1] != '00'; - priv_w = perms.ap[2:1] == '01'; - user_r = perms.ap[1] == '1'; - user_w = FALSE; - uwxn = SCTLR.UWXN == '1'; - - ispriv = AArch32.AccessIsPrivileged(acctype); - - pan = if HavePANExt() then PSTATE.PAN else '0'; - is_ldst = !(acctype IN {AccType_DC, AccType_DC_UNPRIV, AccType_AT, AccType_IFETCH}); - is_ats1xp = (acctype == AccType_AT && AArch32.ExecutingATS1xPInstr()); - if pan == '1' && user_r && ispriv && (is_ldst || is_ats1xp) then - priv_r = FALSE; - priv_w = FALSE; - - user_xn = !user_r || perms.xn == '1' || (user_w && wxn); - priv_xn = (!priv_r || perms.xn == '1' || perms.pxn == '1' || - (priv_w && wxn) || (user_w && uwxn)); - - if ispriv then - (r, w, xn) = (priv_r, priv_w, priv_xn); - else - (r, w, xn) = (user_r, user_w, user_xn); - else - // Access from EL2 - wxn = HSCTLR.WXN == '1'; - r = TRUE; - w = perms.ap[2] == '0'; - xn = perms.xn == '1' || (w && wxn); - - // Restriction on Secure instruction fetch - if HaveEL(EL3) && IsSecure() && NS == '1' then - secure_instr_fetch = if ELUsingAArch32(EL3) then SCR.SIF else SCR_EL3.SIF; - if secure_instr_fetch == '1' then xn = TRUE; - - if acctype == AccType_IFETCH then - fail = xn; - failedread = TRUE; - elsif acctype IN { AccType_ATOMICRW, AccType_ORDEREDRW, AccType_ORDEREDATOMICRW } then - fail = !r || !w; - failedread = !r; - elsif acctype == AccType_DC then - // DC maintenance instructions operating by VA, cannot fault from stage 1 translation. - fail = FALSE; - elsif iswrite then - fail = !w; - failedread = FALSE; - else - fail = !r; - failedread = TRUE; - - if fail then - secondstage = FALSE; - s2fs1walk = FALSE; - ipaddress = bits(40) UNKNOWN; - return AArch32.PermissionFault(ipaddress, domain, level, acctype, - !failedread, secondstage, s2fs1walk); - else - return AArch32.NoFault(); - -// AArch32.ExecutingLSMInstr() -// =========================== -// Returns TRUE if processor is executing a Load/Store Multiple instruction - -boolean AArch32.ExecutingLSMInstr() - instr = ThisInstr(); - instr_set = CurrentInstrSet(); - assert instr_set IN {InstrSet_A32, InstrSet_T32}; - - if instr_set == InstrSet_A32 then - return (instr[28+:4] != '1111' && instr[25+:3] == '100'); - else // InstrSet_T32 - if ThisInstrLength() == 16 then - return (instr[12+:4] == '1100'); - else - return (instr[25+:7] == '1110100' && instr[22] == '0'); - -enumeration DeviceType {DeviceType_GRE, DeviceType_nGRE, DeviceType_nGnRE, DeviceType_nGnRnE}; - -type MemAttrHints is ( - bits(2) attrs, // See MemAttr_*, Cacheability attributes - bits(2) hints, // See MemHint_*, Allocation hints - boolean transient -) - -enumeration MemType {MemType_Normal, MemType_Device}; - -type MemoryAttributes is ( - MemType memtype, - - DeviceType device, // For Device memory types - MemAttrHints inner, // Inner hints and attributes - MemAttrHints outer, // Outer hints and attributes - boolean tagged, // Tagged access - boolean shareable, - boolean outershareable -) - -type AddressDescriptor is ( - FaultRecord fault, // fault.statuscode indicates whether the address is valid - MemoryAttributes memattrs, - FullAddress paddress, - bits(64) vaddress -) - -constant bits(2) MemAttr_NC = '00'; // Non-cacheable -constant bits(2) MemAttr_WT = '10'; // Write-through -constant bits(2) MemAttr_WB = '11'; // Write-back - -// MemAttrDefaults() -// ================= -// Supply default values for memory attributes, including overriding the shareability attributes -// for Device and Non-cacheable memory types. - -MemoryAttributes MemAttrDefaults(MemoryAttributes memattrs) - - if memattrs.memtype == MemType_Device then - memattrs.inner = MemAttrHints UNKNOWN; - memattrs.outer = MemAttrHints UNKNOWN; - memattrs.shareable = TRUE; - memattrs.outershareable = TRUE; - else - memattrs.device = DeviceType UNKNOWN; - if memattrs.inner.attrs == MemAttr_NC && memattrs.outer.attrs == MemAttr_NC then - memattrs.shareable = TRUE; - memattrs.outershareable = TRUE; - - return memattrs; - -constant bits(2) MemHint_No = '00'; // No Read-Allocate, No Write-Allocate -constant bits(2) MemHint_WA = '01'; // No Read-Allocate, Write-Allocate -constant bits(2) MemHint_RA = '10'; // Read-Allocate, No Write-Allocate -constant bits(2) MemHint_RWA = '11'; // Read-Allocate, Write-Allocate - -// AArch32.InstructionDevice() -// =========================== -// Instruction fetches from memory marked as Device but not execute-never might generate a -// Permission Fault but are otherwise treated as if from Normal Non-cacheable memory. - -AddressDescriptor AArch32.InstructionDevice(AddressDescriptor addrdesc, bits(32) vaddress, - bits(40) ipaddress, integer level, bits(4) domain, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - c = ConstrainUnpredictable(Unpredictable_INSTRDEVICE); - assert c IN {Constraint_NONE, Constraint_FAULT}; - - if c == Constraint_FAULT then - addrdesc.fault = AArch32.PermissionFault(ipaddress, domain, level, acctype, iswrite, - secondstage, s2fs1walk); - else - addrdesc.memattrs.memtype = MemType_Normal; - addrdesc.memattrs.inner.attrs = MemAttr_NC; - addrdesc.memattrs.inner.hints = MemHint_No; - addrdesc.memattrs.outer = addrdesc.memattrs.inner; - addrdesc.memattrs.tagged = FALSE; - addrdesc.memattrs = MemAttrDefaults(addrdesc.memattrs); - - return addrdesc; - -// HasS2Translation() -// ================== -// Returns TRUE if stage 2 translation is present for the current translation regime - -boolean HasS2Translation() - return (EL2Enabled() && !IsInHost() && PSTATE.EL IN {EL0,EL1}); - -type DescriptorUpdate is ( - boolean AF, // AF needs to be set - boolean AP, // AP[2] / S2AP[2] will be modified - AddressDescriptor descaddr // Descriptor to be updated -) - -type TLBRecord is ( - Permissions perms, - bit nG, // '0' = Global, '1' = not Global - bits(4) domain, // AArch32 only - bit GP, // Guarded Page - boolean contiguous, // Contiguous bit from page table - integer level, // AArch32 Short-descriptor format: Indicates Section/Page - integer blocksize, // Describes size of memory translated in KBytes - DescriptorUpdate descupdate, // [Armv8.1] Context for h/w update of table descriptor - bit CnP, // [Armv8.2] TLB entry can be shared between different PEs - AddressDescriptor addrdesc -) - -// AArch32.TranslateAddressS1Off() -// =============================== -// Called for stage 1 translations when translation is disabled to supply a default translation. -// Note that there are additional constraints on instruction prefetching that are not described in -// this pseudocode. - -TLBRecord AArch32.TranslateAddressS1Off(bits(32) vaddress, AccType acctype, boolean iswrite) - assert ELUsingAArch32(S1TranslationRegime()); - - TLBRecord result; - result.descupdate.AF = FALSE; - result.descupdate.AP = FALSE; - - default_cacheable = (HasS2Translation() && ((if ELUsingAArch32(EL2) then HCR.DC else HCR_EL2.DC) == '1')); - - if default_cacheable then - // Use default cacheable settings - result.addrdesc.memattrs.memtype = MemType_Normal; - result.addrdesc.memattrs.inner.attrs = MemAttr_WB; // Write-back - result.addrdesc.memattrs.inner.hints = MemHint_RWA; - result.addrdesc.memattrs.shareable = FALSE; - result.addrdesc.memattrs.outershareable = FALSE; - result.addrdesc.memattrs.tagged = HCR_EL2.DCT == '1'; - elsif acctype != AccType_IFETCH then - // Treat data as Device - result.addrdesc.memattrs.memtype = MemType_Device; - result.addrdesc.memattrs.device = DeviceType_nGnRnE; - result.addrdesc.memattrs.inner = MemAttrHints UNKNOWN; - result.addrdesc.memattrs.tagged = FALSE; - else - // Instruction cacheability controlled by SCTLR/HSCTLR.I - if PSTATE.EL == EL2 then - cacheable = HSCTLR.I == '1'; - else - cacheable = SCTLR.I == '1'; - result.addrdesc.memattrs.memtype = MemType_Normal; - if cacheable then - result.addrdesc.memattrs.inner.attrs = MemAttr_WT; - result.addrdesc.memattrs.inner.hints = MemHint_RA; - else - result.addrdesc.memattrs.inner.attrs = MemAttr_NC; - result.addrdesc.memattrs.inner.hints = MemHint_No; - result.addrdesc.memattrs.shareable = TRUE; - result.addrdesc.memattrs.outershareable = TRUE; - result.addrdesc.memattrs.tagged = FALSE; - - result.addrdesc.memattrs.outer = result.addrdesc.memattrs.inner; - - result.addrdesc.memattrs = MemAttrDefaults(result.addrdesc.memattrs); - - result.perms.ap = bits(3) UNKNOWN; - result.perms.xn = '0'; - result.perms.pxn = '0'; - - result.nG = bit UNKNOWN; - result.contiguous = boolean UNKNOWN; - result.domain = bits(4) UNKNOWN; - result.level = integer UNKNOWN; - result.blocksize = integer UNKNOWN; - result.addrdesc.paddress.address = ZeroExtend(vaddress); - result.addrdesc.paddress.NS = if IsSecure() then '0' else '1'; - result.addrdesc.fault = AArch32.NoFault(); - return result; - -// AArch32.AccessFlagFault() -// ========================= - -FaultRecord AArch32.AccessFlagFault(bits(40) ipaddress, bits(4) domain, integer level, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - extflag = bit UNKNOWN; - debugmoe = bits(4) UNKNOWN; - errortype = bits(2) UNKNOWN; - return AArch32.CreateFaultRecord(Fault_AccessFlag, ipaddress, domain, level, acctype, iswrite, - extflag, debugmoe, errortype, secondstage, s2fs1walk); - -// AArch32.AddressSizeFault() -// ========================== - -FaultRecord AArch32.AddressSizeFault(bits(40) ipaddress, bits(4) domain, integer level, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - extflag = bit UNKNOWN; - debugmoe = bits(4) UNKNOWN; - errortype = bits(2) UNKNOWN; - return AArch32.CreateFaultRecord(Fault_AddressSize, ipaddress, domain, level, acctype, iswrite, - extflag, debugmoe, errortype, secondstage, s2fs1walk); - -// AArch32.HaveHPDExt() -// ==================== - -boolean AArch32.HaveHPDExt() - return HasArchVersion(ARMv8p2); - -// S1CacheDisabled() -// ================= - -boolean S1CacheDisabled(AccType acctype) - if ELUsingAArch32(S1TranslationRegime()) then - if PSTATE.EL == EL2 then - enable = if acctype == AccType_IFETCH then HSCTLR.I else HSCTLR.C; - else - enable = if acctype == AccType_IFETCH then SCTLR.I else SCTLR.C; - else - enable = if acctype == AccType_IFETCH then SCTLR[].I else SCTLR[].C; - return enable == '0'; - -// LongConvertAttrsHints() -// ======================= -// Convert the long attribute fields for Normal memory as used in the MAIR fields -// to orthogonal attributes and hints - -MemAttrHints LongConvertAttrsHints(bits(4) attrfield, AccType acctype) - assert !IsZero(attrfield); - MemAttrHints result; - if S1CacheDisabled(acctype) then // Force Non-cacheable - result.attrs = MemAttr_NC; - result.hints = MemHint_No; - else - if attrfield[3:2] == '00' then // Write-through transient - result.attrs = MemAttr_WT; - result.hints = attrfield[1:0]; - result.transient = TRUE; - elsif attrfield[3:0] == '0100' then // Non-cacheable (no allocate) - result.attrs = MemAttr_NC; - result.hints = MemHint_No; - result.transient = FALSE; - elsif attrfield[3:2] == '01' then // Write-back transient - result.attrs = MemAttr_WB; - result.hints = attrfield[1:0]; - result.transient = TRUE; - else // Write-through/Write-back non-transient - result.attrs = attrfield[3:2]; - result.hints = attrfield[1:0]; - result.transient = FALSE; - - return result; - -// AArch32.S1AttrDecode() -// ====================== -// Converts the Stage 1 attribute fields, using the MAIR, to orthogonal -// attributes and hints. - -MemoryAttributes AArch32.S1AttrDecode(bits(2) SH, bits(3) attr, AccType acctype) - - MemoryAttributes memattrs; - - if PSTATE.EL == EL2 then - mair = HMAIR1:HMAIR0; - else - mair = MAIR1:MAIR0; - index = 8 * UInt(attr); - attrfield = mair[index+7:index]; - - memattrs.tagged = FALSE; - if ((attrfield[7:4] != '0000' && attrfield[7:4] != '1111' && attrfield[3:0] == '0000') || - (attrfield[7:4] == '0000' && attrfield[3:0] != 'xx00')) then - // Reserved, maps to an allocated value - (-, attrfield) = ConstrainUnpredictableBits(Unpredictable_RESMAIR); - if !HaveMTEExt() && attrfield[7:4] == '1111' && attrfield[3:0] == '0000' then - // Reserved, maps to an allocated value - (-, attrfield) = ConstrainUnpredictableBits(Unpredictable_RESMAIR); - - if attrfield[7:4] == '0000' then // Device - memattrs.memtype = MemType_Device; - case attrfield[3:0] of - when '0000' memattrs.device = DeviceType_nGnRnE; - when '0100' memattrs.device = DeviceType_nGnRE; - when '1000' memattrs.device = DeviceType_nGRE; - when '1100' memattrs.device = DeviceType_GRE; - otherwise Unreachable(); // Reserved, handled above - - elsif attrfield[3:0] != '0000' then // Normal - memattrs.memtype = MemType_Normal; - memattrs.outer = LongConvertAttrsHints(attrfield[7:4], acctype); - memattrs.inner = LongConvertAttrsHints(attrfield[3:0], acctype); - memattrs.shareable = SH[1] == '1'; - memattrs.outershareable = SH == '10'; - elsif HaveMTEExt() && attrfield == '11110000' then // Normal, Tagged if WB-RWA - memattrs.memtype = MemType_Normal; - memattrs.outer = LongConvertAttrsHints('1111', acctype); // WB_RWA - memattrs.inner = LongConvertAttrsHints('1111', acctype); // WB_RWA - memattrs.shareable = SH[1] == '1'; - memattrs.outershareable = SH == '10'; - memattrs.tagged = (memattrs.inner.attrs == MemAttr_WB && - memattrs.inner.hints == MemHint_RWA && - memattrs.outer.attrs == MemAttr_WB && - memattrs.outer.hints == MemHint_RWA); - else - Unreachable(); // Reserved, handled above - - return MemAttrDefaults(memattrs); - -// HaveExtendedExecuteNeverExt() -// ============================= - -boolean HaveExtendedExecuteNeverExt() - return HasArchVersion(ARMv8p2); - -// AArch32.CheckS2Permission() -// =========================== -// Function used for permission checking from AArch32 stage 2 translations - -FaultRecord AArch32.CheckS2Permission(Permissions perms, bits(32) vaddress, bits(40) ipaddress, - integer level, AccType acctype, boolean iswrite, - boolean s2fs1walk) - - assert HaveEL(EL2) && !IsSecure() && ELUsingAArch32(EL2) && HasS2Translation(); - - r = perms.ap[1] == '1'; - w = perms.ap[2] == '1'; - if HaveExtendedExecuteNeverExt() then - case perms.xn:perms.xxn of - when '00' xn = !r; - when '01' xn = !r || PSTATE.EL == EL1; - when '10' xn = TRUE; - when '11' xn = !r || PSTATE.EL == EL0; - else - xn = !r || perms.xn == '1'; - // Stage 1 walk is checked as a read, regardless of the original type1 - if acctype == AccType_IFETCH && !s2fs1walk then - fail = xn; - failedread = TRUE; - elsif (acctype IN { AccType_ATOMICRW, AccType_ORDEREDRW, AccType_ORDEREDATOMICRW }) && !s2fs1walk then - fail = !r || !w; - failedread = !r; - elsif acctype == AccType_DC && !s2fs1walk then - // DC maintenance instructions operating by VA, do not generate Permission faults - // from stage 2 translation, other than from stage 1 translation table walk. - fail = FALSE; - elsif iswrite && !s2fs1walk then - fail = !w; - failedread = FALSE; - else - fail = !r; - failedread = !iswrite; - - if fail then - domain = bits(4) UNKNOWN; - secondstage = TRUE; - return AArch32.PermissionFault(ipaddress, domain, level, acctype, - !failedread, secondstage, s2fs1walk); - else - return AArch32.NoFault(); - -// HaveStage2MemAttrControl() -// ========================== -// Returns TRUE if support for Stage2 control of memory types and cacheability attributes is implemented. - -boolean HaveStage2MemAttrControl() - return HasArchVersion(ARMv8p4); - -// CombineS1S2AttrHints() -// ====================== -// Combines cacheability attributes and allocation hints from stage 1 and stage 2 - -MemAttrHints CombineS1S2AttrHints(MemAttrHints s1desc, MemAttrHints s2desc) - - MemAttrHints result; - - apply_force_writeback = HaveStage2MemAttrControl() && HCR_EL2.FWB == '1'; - if apply_force_writeback then - if s2desc.attrs == '11' then - result.attrs = s1desc.attrs; - elsif s2desc.attrs == '10' then - result.attrs = MemAttr_WB; // force Write-back - else - result.attrs = MemAttr_NC; - else - if s2desc.attrs == '01' || s1desc.attrs == '01' then - result.attrs = bits(2) UNKNOWN; // Reserved - elsif s2desc.attrs == MemAttr_NC || s1desc.attrs == MemAttr_NC then - result.attrs = MemAttr_NC; // Non-cacheable - elsif s2desc.attrs == MemAttr_WT || s1desc.attrs == MemAttr_WT then - result.attrs = MemAttr_WT; // Write-through - else - result.attrs = MemAttr_WB; // Write-back - - if result.attrs == MemAttr_NC then - result.hints = MemHint_No; - elsif apply_force_writeback then - if s1desc.attrs != MemAttr_NC then - result.hints = s1desc.hints; - else - result.hints = MemHint_RWA; - else - result.hints = s1desc.hints; - result.transient = s1desc.transient; - - return result; - -// CombineS1S2Device() -// =================== -// Combines device types from stage 1 and stage 2 - -DeviceType CombineS1S2Device(DeviceType s1device, DeviceType s2device) - - if s2device == DeviceType_nGnRnE || s1device == DeviceType_nGnRnE then - result = DeviceType_nGnRnE; - elsif s2device == DeviceType_nGnRE || s1device == DeviceType_nGnRE then - result = DeviceType_nGnRE; - elsif s2device == DeviceType_nGRE || s1device == DeviceType_nGRE then - result = DeviceType_nGRE; - else - result = DeviceType_GRE; - - return result; - -// IsFault() -// ========= -// Return TRUE if a fault is associated with an address descriptor - -boolean IsFault(AddressDescriptor addrdesc) - return addrdesc.fault.statuscode != Fault_None; - -// AArch32.CombineS1S2Desc() -// ========================= -// Combines the address descriptors from stage 1 and stage 2 - -AddressDescriptor AArch32.CombineS1S2Desc(AddressDescriptor s1desc, AddressDescriptor s2desc) - - AddressDescriptor result; - - result.paddress = s2desc.paddress; - - apply_force_writeback = HaveStage2MemAttrControl() && HCR_EL2.FWB == '1'; - if IsFault(s1desc) || IsFault(s2desc) then - result = if IsFault(s1desc) then s1desc else s2desc; - else - result.fault = AArch32.NoFault(); - if s2desc.memattrs.memtype == MemType_Device || ( - (apply_force_writeback && s1desc.memattrs.memtype == MemType_Device && s2desc.memattrs.inner.attrs != '10') || - (!apply_force_writeback && s1desc.memattrs.memtype == MemType_Device) ) then - result.memattrs.memtype = MemType_Device; - if s1desc.memattrs.memtype == MemType_Normal then - result.memattrs.device = s2desc.memattrs.device; - elsif s2desc.memattrs.memtype == MemType_Normal then - result.memattrs.device = s1desc.memattrs.device; - else // Both Device - result.memattrs.device = CombineS1S2Device(s1desc.memattrs.device, - s2desc.memattrs.device); - result.memattrs.tagged = FALSE; - // S1 can be either Normal or Device, S2 is Normal. - else - result.memattrs.memtype = MemType_Normal; - result.memattrs.device = DeviceType UNKNOWN; - result.memattrs.inner = CombineS1S2AttrHints(s1desc.memattrs.inner, s2desc.memattrs.inner); - result.memattrs.outer = CombineS1S2AttrHints(s1desc.memattrs.outer, s2desc.memattrs.outer); - result.memattrs.shareable = (s1desc.memattrs.shareable || s2desc.memattrs.shareable); - result.memattrs.outershareable = (s1desc.memattrs.outershareable || - s2desc.memattrs.outershareable); - result.memattrs.tagged = (s1desc.memattrs.tagged && - result.memattrs.inner.attrs == MemAttr_WB && - result.memattrs.inner.hints == MemHint_RWA && - result.memattrs.outer.attrs == MemAttr_WB && - result.memattrs.outer.hints == MemHint_RWA); - - result.memattrs = MemAttrDefaults(result.memattrs); - - return result; - -// AArch64.CreateFaultRecord() -// =========================== - -FaultRecord AArch64.CreateFaultRecord(Fault statuscode, bits(52) ipaddress, boolean NS, - integer level, AccType acctype, boolean write, bit extflag, - bits(2) errortype, boolean secondstage, boolean s2fs1walk) - - FaultRecord fault; - fault.statuscode = statuscode; - fault.domain = bits(4) UNKNOWN; // Not used from AArch64 - fault.debugmoe = bits(4) UNKNOWN; // Not used from AArch64 - fault.errortype = errortype; - fault.ipaddress.NS = if NS then '1' else '0'; - fault.ipaddress.address = ipaddress; - fault.level = level; - fault.acctype = acctype; - fault.write = write; - fault.extflag = extflag; - fault.secondstage = secondstage; - fault.s2fs1walk = s2fs1walk; - - return fault; - -// AArch64.AlignmentFault() -// ======================== - -FaultRecord AArch64.AlignmentFault(AccType acctype, boolean iswrite, boolean secondstage) - - ipaddress = bits(52) UNKNOWN; - level = integer UNKNOWN; - extflag = bit UNKNOWN; - errortype = bits(2) UNKNOWN; - s2fs1walk = boolean UNKNOWN; - - return AArch64.CreateFaultRecord(Fault_Alignment, ipaddress, boolean UNKNOWN, level, acctype, iswrite, - extflag, errortype, secondstage, s2fs1walk); - -// AArch64.AccessUsesEL() -// ====================== -// Returns the Exception Level of the regime that will manage the translation for a given access type1. - -bits(2) AArch64.AccessUsesEL(AccType acctype) - if acctype == AccType_UNPRIV then - return EL0; - elsif acctype == AccType_NV2REGISTER then - return EL2; - else - return PSTATE.EL; - -// AArch64.SecondStageWalk() -// ========================= -// Perform a stage 2 translation on a stage 1 translation page table walk access. - -AddressDescriptor AArch64.SecondStageWalk(AddressDescriptor S1, bits(64) vaddress, AccType acctype, - boolean iswrite, integer size, boolean hwupdatewalk) - - assert HasS2Translation(); - - s2fs1walk = TRUE; - wasaligned = TRUE; - return AArch64.SecondStageTranslate(S1, vaddress, acctype, iswrite, wasaligned, s2fs1walk, - size, hwupdatewalk); - -// BigEndianReverse() -// ================== - -bits(width) BigEndianReverse (bits(width) value) - assert width IN {8, 16, 32, 64, 128}; - integer half = width DIV 2; - if width == 8 then return value; - return BigEndianReverse(value[half-1:0]) : BigEndianReverse(value[width-1:half]); - -type AccessDescriptor is ( - AccType acctype, - MPAMinfo mpam, - boolean page_table_walk, - boolean secondstage, - boolean s2fs1walk, - integer level -) - -// CreateAccessDescriptor() -// ======================== - -AccessDescriptor CreateAccessDescriptor(AccType acctype) - AccessDescriptor accdesc; - accdesc.acctype = acctype; - accdesc.mpam = GenMPAMcurEL(acctype IN {AccType_IFETCH, AccType_IC}); - accdesc.page_table_walk = FALSE; - return accdesc; - -// These two _Mem[] accessors are the hardware operations which perform single-copy atomic, -// aligned, little-endian memory accesses of size bytes from/to the underlying physical -// memory array of bytes. -// -// The functions address the array using desc.paddress which supplies: -// * A 52-bit physical address -// * A single NS bit to select between Secure and Non-secure parts of the array. -// -// The accdesc descriptor describes the access type1: normal, exclusive, ordered, streaming, -// etc and other parameters required to access the physical memory or for setting syndrome -// register in the event of an external abort. -bits(8*size) _Mem[AddressDescriptor desc, integer size, AccessDescriptor accdesc]; - -_Mem[AddressDescriptor desc, integer size, AccessDescriptor accdesc] = bits(8*size) value; - -// AArch64.CheckAndUpdateDescriptor() -// ================================== -// Check and update translation table descriptor if hardware update is configured - -FaultRecord AArch64.CheckAndUpdateDescriptor(DescriptorUpdate result, FaultRecord fault, - boolean secondstage, bits(64) vaddress, AccType acctype, - boolean iswrite, boolean s2fs1walk, boolean hwupdatewalk) - - boolean hw_update_AF = FALSE; - boolean hw_update_AP = FALSE; - - // Check if access flag can be updated - // Address translation instructions are permitted to update AF but not required - if result.AF then - if fault.statuscode == Fault_None || ConstrainUnpredictable(Unpredictable_AFUPDATE) == Constraint_TRUE then - hw_update_AF = TRUE; - - if result.AP && fault.statuscode == Fault_None then - write_perm_req = (iswrite || acctype IN {AccType_ATOMICRW,AccType_ORDEREDRW, AccType_ORDEREDATOMICRW }) && !s2fs1walk; - hw_update_AP = (write_perm_req && !(acctype IN {AccType_AT, AccType_DC, AccType_DC_UNPRIV})) || hwupdatewalk; - - if hw_update_AF || hw_update_AP then - if secondstage || !HasS2Translation() then - descaddr2 = result.descaddr; - else - hwupdatewalk = TRUE; - descaddr2 = AArch64.SecondStageWalk(result.descaddr, vaddress, acctype, iswrite, 8, hwupdatewalk); - if IsFault(descaddr2) then - return descaddr2.fault; - - accdesc = CreateAccessDescriptor(AccType_ATOMICRW); - desc = _Mem[descaddr2, 8, accdesc]; - el = AArch64.AccessUsesEL(acctype); - case el of - when EL3 - reversedescriptors = SCTLR_EL3.EE == '1'; - when EL2 - reversedescriptors = SCTLR_EL2.EE == '1'; - otherwise - reversedescriptors = SCTLR_EL1.EE == '1'; - if reversedescriptors then - desc = BigEndianReverse(desc); - - if hw_update_AF then - desc[10] = '1'; - if hw_update_AP then - desc[7] = (if secondstage then '1' else '0'); - - _Mem[descaddr2,8,accdesc] = if reversedescriptors then BigEndianReverse(desc) else desc; - - return fault; - -// AArch64.NoFault() -// ================= - -FaultRecord AArch64.NoFault() - - ipaddress = bits(52) UNKNOWN; - level = integer UNKNOWN; - acctype = AccType_NORMAL; - iswrite = boolean UNKNOWN; - extflag = bit UNKNOWN; - errortype = bits(2) UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - - return AArch64.CreateFaultRecord(Fault_None, ipaddress, boolean UNKNOWN, level, acctype, iswrite, - extflag, errortype, secondstage, s2fs1walk); - -// AArch64.PermissionFault() -// ========================= - -FaultRecord AArch64.PermissionFault(bits(52) ipaddress,boolean NS, integer level, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - extflag = bit UNKNOWN; - errortype = bits(2) UNKNOWN; - return AArch64.CreateFaultRecord(Fault_Permission, ipaddress, NS, level, acctype, iswrite, - extflag, errortype, secondstage, s2fs1walk); - -// AArch64.CheckS2Permission() -// =========================== -// Function used for permission checking from AArch64 stage 2 translations - -FaultRecord AArch64.CheckS2Permission(Permissions perms, bits(64) vaddress, bits(52) ipaddress, - integer level, AccType acctype, boolean iswrite, boolean NS, - boolean s2fs1walk, boolean hwupdatewalk) - - assert (IsSecureEL2Enabled() || (HaveEL(EL2) && !IsSecure() && !ELUsingAArch32(EL2))) && HasS2Translation(); - - r = perms.ap[1] == '1'; - w = perms.ap[2] == '1'; - if HaveExtendedExecuteNeverExt() then - case perms.xn:perms.xxn of - when '00' xn = FALSE; - when '01' xn = PSTATE.EL == EL1; - when '10' xn = TRUE; - when '11' xn = PSTATE.EL == EL0; - else - xn = perms.xn == '1'; - // Stage 1 walk is checked as a read, regardless of the original type1 - if acctype == AccType_IFETCH && !s2fs1walk then - fail = xn; - failedread = TRUE; - elsif (acctype IN { AccType_ATOMICRW, AccType_ORDEREDRW, AccType_ORDEREDATOMICRW }) && !s2fs1walk then - fail = !r || !w; - failedread = !r; - elsif iswrite && !s2fs1walk then - fail = !w; - failedread = FALSE; - elsif acctype == AccType_DC && PSTATE.EL != EL0 && !s2fs1walk then - // DC maintenance instructions operating by VA, with the exception of DC IVAC, do - // not generate Permission faults from stage 2 translation, other than when - // performing a stage 1 translation table walk. - fail = FALSE; - elsif hwupdatewalk then - fail = !w; - failedread = !iswrite; - else - fail = !r; - failedread = !iswrite; - - if fail then - domain = bits(4) UNKNOWN; - secondstage = TRUE; - return AArch64.PermissionFault(ipaddress,NS, level, acctype, - !failedread, secondstage, s2fs1walk); - else - return AArch64.NoFault(); - -// AArch64.CombineS1S2Desc() -// ========================= -// Combines the address descriptors from stage 1 and stage 2 - -AddressDescriptor AArch64.CombineS1S2Desc(AddressDescriptor s1desc, AddressDescriptor s2desc) - - AddressDescriptor result; - - result.paddress = s2desc.paddress; - - apply_force_writeback = HaveStage2MemAttrControl() && HCR_EL2.FWB == '1'; - if IsFault(s1desc) || IsFault(s2desc) then - result = if IsFault(s1desc) then s1desc else s2desc; - else - result.fault = AArch64.NoFault(); - if s2desc.memattrs.memtype == MemType_Device || ( - (apply_force_writeback && s1desc.memattrs.memtype == MemType_Device && s2desc.memattrs.inner.attrs != '10') || - (!apply_force_writeback && s1desc.memattrs.memtype == MemType_Device) ) then - result.memattrs.memtype = MemType_Device; - if s1desc.memattrs.memtype == MemType_Normal then - result.memattrs.device = s2desc.memattrs.device; - elsif s2desc.memattrs.memtype == MemType_Normal then - result.memattrs.device = s1desc.memattrs.device; - else // Both Device - result.memattrs.device = CombineS1S2Device(s1desc.memattrs.device, - s2desc.memattrs.device); - result.memattrs.tagged = FALSE; - // S1 can be either Normal or Device, S2 is Normal. - else - result.memattrs.memtype = MemType_Normal; - result.memattrs.device = DeviceType UNKNOWN; - result.memattrs.inner = CombineS1S2AttrHints(s1desc.memattrs.inner, s2desc.memattrs.inner); - result.memattrs.outer = CombineS1S2AttrHints(s1desc.memattrs.outer, s2desc.memattrs.outer); - result.memattrs.shareable = (s1desc.memattrs.shareable || s2desc.memattrs.shareable); - result.memattrs.outershareable = (s1desc.memattrs.outershareable || - s2desc.memattrs.outershareable); - result.memattrs.tagged = (s1desc.memattrs.tagged && - result.memattrs.inner.attrs == MemAttr_WB && - result.memattrs.inner.hints == MemHint_RWA && - result.memattrs.outer.attrs == MemAttr_WB && - result.memattrs.outer.hints == MemHint_RWA); - - result.memattrs = MemAttrDefaults(result.memattrs); - - return result; - -// AArch64.InstructionDevice() -// =========================== -// Instruction fetches from memory marked as Device but not execute-never might generate a -// Permission Fault but are otherwise treated as if from Normal Non-cacheable memory. - -AddressDescriptor AArch64.InstructionDevice(AddressDescriptor addrdesc, bits(64) vaddress, - bits(52) ipaddress, integer level, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - c = ConstrainUnpredictable(Unpredictable_INSTRDEVICE); - assert c IN {Constraint_NONE, Constraint_FAULT}; - - if c == Constraint_FAULT then - addrdesc.fault = AArch64.PermissionFault(ipaddress, boolean UNKNOWN, level, acctype, iswrite, - secondstage, s2fs1walk); - else - addrdesc.memattrs.memtype = MemType_Normal; - addrdesc.memattrs.inner.attrs = MemAttr_NC; - addrdesc.memattrs.inner.hints = MemHint_No; - addrdesc.memattrs.outer = addrdesc.memattrs.inner; - addrdesc.memattrs.tagged = FALSE; - addrdesc.memattrs = MemAttrDefaults(addrdesc.memattrs); - - return addrdesc; - -// AArch64.AccessFlagFault() -// ========================= - -FaultRecord AArch64.AccessFlagFault(bits(52) ipaddress,boolean NS, integer level, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - extflag = bit UNKNOWN; - errortype = bits(2) UNKNOWN; - return AArch64.CreateFaultRecord(Fault_AccessFlag, ipaddress, NS, level, acctype, iswrite, - extflag, errortype, secondstage, s2fs1walk); - -// AArch64.AddressSizeFault() -// ========================== - -FaultRecord AArch64.AddressSizeFault(bits(52) ipaddress,boolean NS, integer level, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - extflag = bit UNKNOWN; - errortype = bits(2) UNKNOWN; - return AArch64.CreateFaultRecord(Fault_AddressSize, ipaddress, NS, level, acctype, iswrite, - extflag, errortype, secondstage, s2fs1walk); - -// AArch64.HaveHPDExt() -// ==================== - -boolean AArch64.HaveHPDExt() - return HasArchVersion(ARMv8p1); - -type MAIRType; - -// MAIR[] - non-assignment form -// ============================ - -MAIRType MAIR[bits(2) regime] - bits(64) r; - case regime of - when EL1 r = MAIR_EL1; - when EL2 r = MAIR_EL2; - when EL3 r = MAIR_EL3; - otherwise Unreachable(); - return r; - -// MAIR[] - non-assignment form -// ============================ - -MAIRType MAIR[] - return MAIR[S1TranslationRegime()]; - -// AArch64.S1AttrDecode() -// ====================== -// Converts the Stage 1 attribute fields, using the MAIR, to orthogonal -// attributes and hints. - -MemoryAttributes AArch64.S1AttrDecode(bits(2) SH, bits(3) attr, AccType acctype) - - MemoryAttributes memattrs; - - mair = MAIR[]; - index = 8 * UInt(attr); - attrfield = mair[index+7:index]; - - memattrs.tagged = FALSE; - if ((attrfield[7:4] != '0000' && attrfield[7:4] != '1111' && attrfield[3:0] == '0000') || - (attrfield[7:4] == '0000' && attrfield[3:0] != 'xx00')) then - // Reserved, maps to an allocated value - (-, attrfield) = ConstrainUnpredictableBits(Unpredictable_RESMAIR); - if !HaveMTEExt() && attrfield[7:4] == '1111' && attrfield[3:0] == '0000' then - // Reserved, maps to an allocated value - (-, attrfield) = ConstrainUnpredictableBits(Unpredictable_RESMAIR); - - if attrfield[7:4] == '0000' then // Device - memattrs.memtype = MemType_Device; - case attrfield[3:0] of - when '0000' memattrs.device = DeviceType_nGnRnE; - when '0100' memattrs.device = DeviceType_nGnRE; - when '1000' memattrs.device = DeviceType_nGRE; - when '1100' memattrs.device = DeviceType_GRE; - otherwise Unreachable(); // Reserved, handled above - - elsif attrfield[3:0] != '0000' then // Normal - memattrs.memtype = MemType_Normal; - memattrs.outer = LongConvertAttrsHints(attrfield[7:4], acctype); - memattrs.inner = LongConvertAttrsHints(attrfield[3:0], acctype); - memattrs.shareable = SH[1] == '1'; - memattrs.outershareable = SH == '10'; - elsif HaveMTEExt() && attrfield == '11110000' then // Normal, Tagged if WB-RWA - memattrs.memtype = MemType_Normal; - memattrs.outer = LongConvertAttrsHints('1111', acctype); // WB_RWA - memattrs.inner = LongConvertAttrsHints('1111', acctype); // WB_RWA - memattrs.shareable = SH[1] == '1'; - memattrs.outershareable = SH == '10'; - memattrs.tagged = (memattrs.inner.attrs == MemAttr_WB && - memattrs.inner.hints == MemHint_RWA && - memattrs.outer.attrs == MemAttr_WB && - memattrs.outer.hints == MemHint_RWA); - else - Unreachable(); // Reserved, handled above - - return MemAttrDefaults(memattrs); - -// AArch64.TranslationFault() -// ========================== - -FaultRecord AArch64.TranslationFault(bits(52) ipaddress, boolean NS, integer level, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - extflag = bit UNKNOWN; - errortype = bits(2) UNKNOWN; - return AArch64.CreateFaultRecord(Fault_Translation, ipaddress, NS, level, acctype, iswrite, - extflag, errortype, secondstage, s2fs1walk); - -// CreateAccessDescriptorPTW() -// =========================== - -AccessDescriptor CreateAccessDescriptorPTW(AccType acctype, boolean secondstage, - boolean s2fs1walk, integer level) - AccessDescriptor accdesc; - accdesc.acctype = acctype; - accdesc.mpam = GenMPAMcurEL(acctype IN {AccType_IFETCH, AccType_IC}); - accdesc.page_table_walk = TRUE; - accdesc.s2fs1walk = s2fs1walk; - accdesc.secondstage = secondstage; - accdesc.level = level; - return accdesc; - -// Have52BitPAExt() -// ================ -// Returns TRUE if Large Physical Address extension -// support is implemented and FALSE otherwise. - -boolean Have52BitPAExt() - return HasArchVersion(ARMv8p2) && boolean IMPLEMENTATION_DEFINED "Has large 52-bit PA/IPA support"; - -// Have52BitVAExt() -// ================ -// Returns TRUE if Large Virtual Address extension -// support is implemented and FALSE otherwise. - -boolean Have52BitVAExt() - return HasArchVersion(ARMv8p2) && boolean IMPLEMENTATION_DEFINED "Has large 52-bit VA support"; - -// HaveQRDMLAHExt() -// ================ - -boolean HaveQRDMLAHExt() - return HasArchVersion(ARMv8p1); - -boolean HaveAccessFlagUpdateExt() - return HasArchVersion(ARMv8p1); - -boolean HaveDirtyBitModifierExt() - return HasArchVersion(ARMv8p1); - -// HaveBlockBBM() -// ============== -// Returns TRUE if support for changing block size without requring break-before-make is implemented. - -boolean HaveBlockBBM() - return HasArchVersion(ARMv8p4); - -// HaveCommonNotPrivateTransExt() -// ============================== - -boolean HaveCommonNotPrivateTransExt() - return HasArchVersion(ARMv8p2); - -// HaveE0PDExt() -// ============= -// Returns TRUE if support for constant fault times for unprivileged accesses -// to the memory map is implemented. - -boolean HaveE0PDExt() - return HasArchVersion(ARMv8p5); - -// HaveSmallPageTblExt() -// ===================== -// Returns TRUE if Small Page Table Support is implemented. - -boolean HaveSmallPageTblExt() - return HasArchVersion(ARMv8p4) && boolean IMPLEMENTATION_DEFINED "Has Small Page Table extension"; - -// If the implementation supports changing the block size without a break-before-make -// approach, then for implementations that have level 1 or 2 support, the nT bit in -// the block descriptor is valid. -boolean IsBlockDescriptorNTBitValid(); - -// PAMax() -// ======= -// Returns the IMPLEMENTATION DEFINED upper limit on the physical address -// size for this processor, as log2(). - -integer PAMax() - return integer IMPLEMENTATION_DEFINED "Maximum Physical Address Size"; - -// S2CacheDisabled() -// ================= - -boolean S2CacheDisabled(AccType acctype) - if ELUsingAArch32(EL2) then - disable = if acctype == AccType_IFETCH then HCR2.ID else HCR2.CD; - else - disable = if acctype == AccType_IFETCH then HCR_EL2.ID else HCR_EL2.CD; - return disable == '1'; - -// S2ConvertAttrsHints() -// ===================== -// Converts the attribute fields for Normal memory as used in stage 2 -// descriptors to orthogonal attributes and hints - -MemAttrHints S2ConvertAttrsHints(bits(2) attr, AccType acctype) - assert !IsZero(attr); - - MemAttrHints result; - - if HCR_EL2.FWB=='0' && S2CacheDisabled(acctype) then // Force Non-cacheable - result.attrs = MemAttr_NC; - result.hints = MemHint_No; - else - case attr of - when '01' // Non-cacheable (no allocate) - result.attrs = MemAttr_NC; - result.hints = MemHint_No; - when '10' // Write-through - result.attrs = MemAttr_WT; - result.hints = MemHint_RWA; - when '11' // Write-back - result.attrs = MemAttr_WB; - result.hints = MemHint_RWA; - - result.transient = FALSE; - - return result; - -// S2AttrDecode() -// ============== -// Converts the Stage 2 attribute fields into orthogonal attributes and hints - -MemoryAttributes S2AttrDecode(bits(2) SH, bits(4) attr, AccType acctype) - - MemoryAttributes memattrs; - - apply_force_writeback = HaveStage2MemAttrControl() && HCR_EL2.FWB == '1'; - - // Device memory - if (apply_force_writeback && attr[2] == '0') || attr[3:2] == '00' then - memattrs.memtype = MemType_Device; - case attr[1:0] of - when '00' memattrs.device = DeviceType_nGnRnE; - when '01' memattrs.device = DeviceType_nGnRE; - when '10' memattrs.device = DeviceType_nGRE; - when '11' memattrs.device = DeviceType_GRE; - - // Normal memory - elsif apply_force_writeback then - if attr[2] == '1' then - memattrs.memtype = MemType_Normal; - memattrs.inner.attrs = attr[1:0]; - memattrs.outer.attrs = attr[1:0]; - elsif attr[1:0] != '00' then - memattrs.memtype = MemType_Normal; - memattrs.outer = S2ConvertAttrsHints(attr[3:2], acctype); - memattrs.inner = S2ConvertAttrsHints(attr[1:0], acctype); - memattrs.shareable = SH[1] == '1'; - memattrs.outershareable = SH == '10'; - else - memattrs = MemoryAttributes UNKNOWN; // Reserved - - return MemAttrDefaults(memattrs); - -// ShortConvertAttrsHints() -// ======================== -// Converts the short attribute fields for Normal memory as used in the TTBR and -// TEX fields to orthogonal attributes and hints - -MemAttrHints ShortConvertAttrsHints(bits(2) RGN, AccType acctype, boolean secondstage) - - MemAttrHints result; - - if (!secondstage && S1CacheDisabled(acctype)) || (secondstage && S2CacheDisabled(acctype)) then - // Force Non-cacheable - result.attrs = MemAttr_NC; - result.hints = MemHint_No; - else - case RGN of - when '00' // Non-cacheable (no allocate) - result.attrs = MemAttr_NC; - result.hints = MemHint_No; - when '01' // Write-back, Read and Write allocate - result.attrs = MemAttr_WB; - result.hints = MemHint_RWA; - when '10' // Write-through, Read allocate - result.attrs = MemAttr_WT; - result.hints = MemHint_RA; - when '11' // Write-back, Read allocate - result.attrs = MemAttr_WB; - result.hints = MemHint_RA; - - result.transient = FALSE; - - return result; - -// WalkAttrDecode() -// ================ - -MemoryAttributes WalkAttrDecode(bits(2) SH, bits(2) ORGN, bits(2) IRGN, boolean secondstage) - - MemoryAttributes memattrs; - - AccType acctype = AccType_NORMAL; - - memattrs.memtype = MemType_Normal; - memattrs.inner = ShortConvertAttrsHints(IRGN, acctype, secondstage); - memattrs.outer = ShortConvertAttrsHints(ORGN, acctype, secondstage); - memattrs.shareable = SH[1] == '1'; - memattrs.outershareable = SH == '10'; - memattrs.tagged = FALSE; - - return MemAttrDefaults(memattrs); - -// AArch64.TranslationTableWalk() -// ============================== -// Returns a result of a translation table walk -// -// Implementations might cache information from memory in any number of non-coherent TLB -// caching structures, and so avoid memory accesses that have been expressed in this -// pseudocode. The use of such TLBs is not expressed in this pseudocode. - -TLBRecord AArch64.TranslationTableWalk(bits(52) ipaddress, boolean s1_nonsecure, bits(64) vaddress, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk, integer size) - if !secondstage then - assert !ELUsingAArch32(S1TranslationRegime()); - else - assert (IsSecureEL2Enabled() || (HaveEL(EL2) && !IsSecure() && !ELUsingAArch32(EL2))) && HasS2Translation(); - - TLBRecord result; - AddressDescriptor descaddr; - bits(64) baseregister; - bits(64) inputaddr; // Input Address is 'vaddress' for stage 1, 'ipaddress' for stage 2 - bit nswalk; // Stage 2 translation table walks are to Secure or to Non-secure PA space - - descaddr.memattrs.memtype = MemType_Normal; - result.descupdate.AF = FALSE; - result.descupdate.AP = FALSE; - - // Derived parameters for the page table walk: - // grainsize = Log2(Size of Table) - Size of Table is 4KB, 16KB or 64KB in AArch64 - // stride = Log2(Address per Level) - Bits of address consumed at each level - // firstblocklevel = First level where a block entry is allowed - // ps = Physical Address size as encoded in TCR_EL1.IPS or TCR_ELx/VTCR_EL2.PS - // inputsize = Log2(Size of Input Address) - Input Address size in bits - // level = Level to start walk from - // This means that the number of levels after start level = 3-level - - if !secondstage then - // First stage translation - inputaddr = ZeroExtend(vaddress); - el = AArch64.AccessUsesEL(acctype); - top = AddrTop(inputaddr, (acctype == AccType_IFETCH), el); - if el == EL3 then - largegrain = TCR_EL3.TG0 == '01'; - midgrain = TCR_EL3.TG0 == '10'; - inputsize = 64 - UInt(TCR_EL3.T0SZ); - inputsize_max = if Have52BitVAExt() && largegrain then 52 else 48; - inputsize_min = 64 - (if !HaveSmallPageTblExt() then 39 else if largegrain then 47 else 48); - if inputsize < inputsize_min then - c = ConstrainUnpredictable(Unpredictable_RESTnSZ); - assert c IN {Constraint_FORCE, Constraint_FAULT}; - if c == Constraint_FORCE then inputsize = inputsize_min; - ps = TCR_EL3.PS; - basefound = inputsize >= inputsize_min && inputsize <= inputsize_max && IsZero(inputaddr[top:inputsize]); - disabled = FALSE; - baseregister = TTBR0_EL3; - descaddr.memattrs = WalkAttrDecode(TCR_EL3.SH0, TCR_EL3.ORGN0, TCR_EL3.IRGN0, secondstage); - reversedescriptors = SCTLR_EL3.EE == '1'; - lookupsecure = TRUE; - singlepriv = TRUE; - update_AF = HaveAccessFlagUpdateExt() && TCR_EL3.HA == '1'; - update_AP = HaveDirtyBitModifierExt() && update_AF && TCR_EL3.HD == '1'; - hierattrsdisabled = AArch64.HaveHPDExt() && TCR_EL3.HPD == '1'; - elsif ELIsInHost(el) then - if inputaddr[top] == '0' then - largegrain = TCR_EL2.TG0 == '01'; - midgrain = TCR_EL2.TG0 == '10'; - inputsize = 64 - UInt(TCR_EL2.T0SZ); - inputsize_max = if Have52BitVAExt() && largegrain then 52 else 48; - inputsize_min = 64 - (if !HaveSmallPageTblExt() then 39 else if largegrain then 47 else 48); - if inputsize < inputsize_min then - c = ConstrainUnpredictable(Unpredictable_RESTnSZ); - assert c IN {Constraint_FORCE, Constraint_FAULT}; - if c == Constraint_FORCE then inputsize = inputsize_min; - basefound = inputsize >= inputsize_min && inputsize <= inputsize_max && IsZero(inputaddr[top:inputsize]); - disabled = TCR_EL2.EPD0 == '1' || (PSTATE.EL == EL0 && HaveE0PDExt() && TCR_EL2.E0PD0 == '1'); - baseregister = TTBR0_EL2; - descaddr.memattrs = WalkAttrDecode(TCR_EL2.SH0, TCR_EL2.ORGN0, TCR_EL2.IRGN0, secondstage); - hierattrsdisabled = AArch64.HaveHPDExt() && TCR_EL2.HPD0 == '1'; - else - inputsize = 64 - UInt(TCR_EL2.T1SZ); - largegrain = TCR_EL2.TG1 == '11'; // TG1 and TG0 encodings differ - midgrain = TCR_EL2.TG1 == '01'; - inputsize_max = if Have52BitVAExt() && largegrain then 52 else 48; - inputsize_min = 64 - (if !HaveSmallPageTblExt() then 39 else if largegrain then 47 else 48); - if inputsize < inputsize_min then - c = ConstrainUnpredictable(Unpredictable_RESTnSZ); - assert c IN {Constraint_FORCE, Constraint_FAULT}; - if c == Constraint_FORCE then inputsize = inputsize_min; - basefound = inputsize >= inputsize_min && inputsize <= inputsize_max && IsOnes(inputaddr[top:inputsize]); - disabled = TCR_EL2.EPD1 == '1' || (PSTATE.EL == EL0 && HaveE0PDExt() && TCR_EL2.E0PD1 == '1'); - baseregister = TTBR1_EL2; - descaddr.memattrs = WalkAttrDecode(TCR_EL2.SH1, TCR_EL2.ORGN1, TCR_EL2.IRGN1, secondstage); - hierattrsdisabled = AArch64.HaveHPDExt() && TCR_EL2.HPD1 == '1'; - ps = TCR_EL2.IPS; - reversedescriptors = SCTLR_EL2.EE == '1'; - lookupsecure = if IsSecureEL2Enabled() then IsSecure() else FALSE; - singlepriv = FALSE; - update_AF = HaveAccessFlagUpdateExt() && TCR_EL2.HA == '1'; - update_AP = HaveDirtyBitModifierExt() && update_AF && TCR_EL2.HD == '1'; - elsif el == EL2 then - inputsize = 64 - UInt(TCR_EL2.T0SZ); - largegrain = TCR_EL2.TG0 == '01'; - midgrain = TCR_EL2.TG0 == '10'; - inputsize_max = if Have52BitVAExt() && largegrain then 52 else 48; - inputsize_min = 64 - (if !HaveSmallPageTblExt() then 39 else if largegrain then 47 else 48); - if inputsize < inputsize_min then - c = ConstrainUnpredictable(Unpredictable_RESTnSZ); - assert c IN {Constraint_FORCE, Constraint_FAULT}; - if c == Constraint_FORCE then inputsize = inputsize_min; - ps = TCR_EL2.PS; - basefound = inputsize >= inputsize_min && inputsize <= inputsize_max && IsZero(inputaddr[top:inputsize]); - disabled = FALSE; - baseregister = TTBR0_EL2; - descaddr.memattrs = WalkAttrDecode(TCR_EL2.SH0, TCR_EL2.ORGN0, TCR_EL2.IRGN0, secondstage); - reversedescriptors = SCTLR_EL2.EE == '1'; - lookupsecure = if IsSecureEL2Enabled() then IsSecure() else FALSE; - singlepriv = TRUE; - update_AF = HaveAccessFlagUpdateExt() && TCR_EL2.HA == '1'; - update_AP = HaveDirtyBitModifierExt() && update_AF && TCR_EL2.HD == '1'; - hierattrsdisabled = AArch64.HaveHPDExt() && TCR_EL2.HPD == '1'; - else - if inputaddr[top] == '0' then - inputsize = 64 - UInt(TCR_EL1.T0SZ); - largegrain = TCR_EL1.TG0 == '01'; - midgrain = TCR_EL1.TG0 == '10'; - inputsize_max = if Have52BitVAExt() && largegrain then 52 else 48; - inputsize_min = 64 - (if !HaveSmallPageTblExt() then 39 else if largegrain then 47 else 48); - if inputsize < inputsize_min then - c = ConstrainUnpredictable(Unpredictable_RESTnSZ); - assert c IN {Constraint_FORCE, Constraint_FAULT}; - if c == Constraint_FORCE then inputsize = inputsize_min; - basefound = inputsize >= inputsize_min && inputsize <= inputsize_max && IsZero(inputaddr[top:inputsize]); - disabled = TCR_EL1.EPD0 == '1' || (PSTATE.EL == EL0 && HaveE0PDExt() && TCR_EL1.E0PD0 == '1'); - disabled = disabled || (el == EL0 && acctype == AccType_NONFAULT && TCR_EL1.NFD0 == '1'); - baseregister = TTBR0_EL1; - descaddr.memattrs = WalkAttrDecode(TCR_EL1.SH0, TCR_EL1.ORGN0, TCR_EL1.IRGN0, secondstage); - hierattrsdisabled = AArch64.HaveHPDExt() && TCR_EL1.HPD0 == '1'; - else - inputsize = 64 - UInt(TCR_EL1.T1SZ); - largegrain = TCR_EL1.TG1 == '11'; // TG1 and TG0 encodings differ - midgrain = TCR_EL1.TG1 == '01'; - inputsize_max = if Have52BitVAExt() && largegrain then 52 else 48; - inputsize_min = 64 - (if !HaveSmallPageTblExt() then 39 else if largegrain then 47 else 48); - if inputsize < inputsize_min then - c = ConstrainUnpredictable(Unpredictable_RESTnSZ); - assert c IN {Constraint_FORCE, Constraint_FAULT}; - if c == Constraint_FORCE then inputsize = inputsize_min; - basefound = inputsize >= inputsize_min && inputsize <= inputsize_max && IsOnes(inputaddr[top:inputsize]); - disabled = TCR_EL1.EPD1 == '1' || (PSTATE.EL == EL0 && HaveE0PDExt() && TCR_EL1.E0PD1 == '1'); - disabled = disabled || (el == EL0 && acctype == AccType_NONFAULT && TCR_EL1.NFD1 == '1'); - baseregister = TTBR1_EL1; - descaddr.memattrs = WalkAttrDecode(TCR_EL1.SH1, TCR_EL1.ORGN1, TCR_EL1.IRGN1, secondstage); - hierattrsdisabled = AArch64.HaveHPDExt() && TCR_EL1.HPD1 == '1'; - ps = TCR_EL1.IPS; - reversedescriptors = SCTLR_EL1.EE == '1'; - lookupsecure = IsSecure(); - singlepriv = FALSE; - update_AF = HaveAccessFlagUpdateExt() && TCR_EL1.HA == '1'; - update_AP = HaveDirtyBitModifierExt() && update_AF && TCR_EL1.HD == '1'; - if largegrain then - grainsize = 16; // Log2(64KB page size) - firstblocklevel = (if Have52BitPAExt() then 1 else 2); // Largest block is 4TB (2^42 bytes) for 52 bit PA - // and 512MB (2^29 bytes) otherwise - elsif midgrain then - grainsize = 14; // Log2(16KB page size) - firstblocklevel = 2; // Largest block is 32MB (2^25 bytes) - else // Small grain - grainsize = 12; // Log2(4KB page size) - firstblocklevel = 1; // Largest block is 1GB (2^30 bytes) - stride = grainsize - 3; // Log2(page size / 8 bytes) - // The starting level is the number of strides needed to consume the input address - level = 4 - (1 + ((inputsize - grainsize - 1) DIV stride)); - - else - // Second stage translation - inputaddr = ZeroExtend(ipaddress); - if IsSecureBelowEL3() then - // Second stage for Secure translation regime - if s1_nonsecure then // Non-secure IPA space - t0size = VTCR_EL2.T0SZ; - tg0 = VTCR_EL2.TG0; - nswalk = VTCR_EL2.NSW; - else // Secure IPA space - t0size = VSTCR_EL2.T0SZ; - tg0 = VSTCR_EL2.TG0; - nswalk = VSTCR_EL2.SW; - - // Stage 2 translation accesses the Non-secure PA space or the Secure PA space - if nswalk == '1' then - // When walk is Non-secure, access must be to the Non-secure PA space - nsaccess = '1'; - elsif !s1_nonsecure then - // When walk is Secure and in the Secure IPA space, - // access is specified by VSTCR_EL2.SA - nsaccess = VSTCR_EL2.SA; - elsif VSTCR_EL2.SW == '1' || VSTCR_EL2.SA == '1' then - // When walk is Secure and in the Non-secure IPA space, - // access is Non-secure when VSTCR_EL2.SA specifies the Non-secure PA space - nsaccess = '1'; - else - // When walk is Secure and in the Non-secure IPA space, - // if VSTCR_EL2.SA specifies the Secure PA space, access is specified by VTCR_EL2.NSA - nsaccess = VTCR_EL2.NSA; - else - // Second stage for Non-secure translation regime - t0size = VTCR_EL2.T0SZ; - tg0 = VTCR_EL2.TG0; - nswalk = '1'; - nsaccess = '1'; - - inputsize = 64 - UInt(t0size); - largegrain = tg0 == '01'; - midgrain = tg0 == '10'; - - inputsize_max = if Have52BitPAExt() && PAMax() == 52 && largegrain then 52 else 48; - inputsize_min = 64 - (if !HaveSmallPageTblExt() then 39 else if largegrain then 47 else 48); - if inputsize < inputsize_min then - c = ConstrainUnpredictable(Unpredictable_RESTnSZ); - assert c IN {Constraint_FORCE, Constraint_FAULT}; - if c == Constraint_FORCE then inputsize = inputsize_min; - ps = VTCR_EL2.PS; - basefound = inputsize >= inputsize_min && inputsize <= inputsize_max && IsZero(inputaddr[63:inputsize]); - disabled = FALSE; - descaddr.memattrs = WalkAttrDecode(VTCR_EL2.SH0, VTCR_EL2.ORGN0, VTCR_EL2.IRGN0, secondstage); - reversedescriptors = SCTLR_EL2.EE == '1'; - singlepriv = TRUE; - update_AF = HaveAccessFlagUpdateExt() && VTCR_EL2.HA == '1'; - update_AP = HaveDirtyBitModifierExt() && update_AF && VTCR_EL2.HD == '1'; - - if IsSecureEL2Enabled() then - lookupsecure = !s1_nonsecure; - else - lookupsecure = FALSE; - - if lookupsecure then - baseregister = VSTTBR_EL2; - startlevel = UInt(VSTCR_EL2.SL0); - else - baseregister = VTTBR_EL2; - startlevel = UInt(VTCR_EL2.SL0); - if largegrain then - grainsize = 16; // Log2(64KB page size) - level = 3 - startlevel; - firstblocklevel = (if Have52BitPAExt() then 1 else 2); // Largest block is 4TB (2^42 bytes) for 52 bit PA - // and 512MB (2^29 bytes) otherwise - elsif midgrain then - grainsize = 14; // Log2(16KB page size) - level = 3 - startlevel; - firstblocklevel = 2; // Largest block is 32MB (2^25 bytes) - else // Small grain - grainsize = 12; // Log2(4KB page size) - if HaveSmallPageTblExt() && startlevel == 3 then - level = startlevel; // Startlevel 3 (VTCR_EL2.SL0 or VSCTR_EL2.SL0 == 0b11) for 4KB granule - else - level = 2 - startlevel; - firstblocklevel = 1; // Largest block is 1GB (2^30 bytes) - stride = grainsize - 3; // Log2(page size / 8 bytes) - - // Limits on IPA controls based on implemented PA size. Level 0 is only - // supported by small grain translations - if largegrain then // 64KB pages - // Level 1 only supported if implemented PA size is greater than 2^42 bytes - if level == 0 || (level == 1 && PAMax() <= 42) then basefound = FALSE; - elsif midgrain then // 16KB pages - // Level 1 only supported if implemented PA size is greater than 2^40 bytes - if level == 0 || (level == 1 && PAMax() <= 40) then basefound = FALSE; - else // Small grain, 4KB pages - // Level 0 only supported if implemented PA size is greater than 2^42 bytes - if level < 0 || (level == 0 && PAMax() <= 42) then basefound = FALSE; - - // If the inputsize exceeds the PAMax value, the behavior is CONSTRAINED UNPREDICTABLE - inputsizecheck = inputsize; - if inputsize > PAMax() && (!ELUsingAArch32(EL1) || inputsize > 40) then - case ConstrainUnpredictable(Unpredictable_LARGEIPA) of - when Constraint_FORCE - // Restrict the inputsize to the PAMax value - inputsize = PAMax(); - inputsizecheck = PAMax(); - when Constraint_FORCENOSLCHECK - // As FORCE, except use the configured inputsize in the size checks below - inputsize = PAMax(); - when Constraint_FAULT - // Generate a translation fault - basefound = FALSE; - otherwise - Unreachable(); - - // Number of entries in the starting level table = - // (Size of Input Address)/((Address per level)^(Num levels remaining)*(Size of Table)) - startsizecheck = inputsizecheck - ((3 - level)*stride + grainsize); // Log2(Num of entries) - - // Check for starting level table with fewer than 2 entries or longer than 16 pages. - // Lower bound check is: startsizecheck < Log2(2 entries) - // Upper bound check is: startsizecheck > Log2(pagesize/8*16) - if startsizecheck < 1 || startsizecheck > stride + 4 then basefound = FALSE; - if !basefound || disabled then - level = 0; // AArch32 reports this as a level 1 fault - result.addrdesc.fault = AArch64.TranslationFault(ipaddress, s1_nonsecure, level, acctype, iswrite, - secondstage, s2fs1walk); - return result; - - case ps of - when '000' outputsize = 32; - when '001' outputsize = 36; - when '010' outputsize = 40; - when '011' outputsize = 42; - when '100' outputsize = 44; - when '101' outputsize = 48; - when '110' outputsize = (if Have52BitPAExt() && largegrain then 52 else 48); - otherwise outputsize = integer IMPLEMENTATION_DEFINED "Reserved Intermediate Physical Address size value"; - - if outputsize > PAMax() then outputsize = PAMax(); - - if outputsize < 48 && !IsZero(baseregister[47:outputsize]) then - level = 0; - result.addrdesc.fault = AArch64.AddressSizeFault(ipaddress,s1_nonsecure, level, acctype, iswrite, - secondstage, s2fs1walk); - return result; - - // Bottom bound of the Base address is: - // Log2(8 bytes per entry)+Log2(Number of entries in starting level table) - // Number of entries in starting level table = - // (Size of Input Address)/((Address per level)^(Num levels remaining)*(Size of Table)) - baselowerbound = 3 + inputsize - ((3-level)*stride + grainsize); // Log2(Num of entries*8) - bits(52) baseaddress; - if outputsize == 52 then - z = (if baselowerbound < 6 then 6 else baselowerbound); - baseaddress = baseregister[5:2]:baseregister[47:z]:Zeros(z); - else - baseaddress = ZeroExtend(baseregister[47:baselowerbound]:Zeros(baselowerbound)); - - ns_table = if lookupsecure then '0' else '1'; - ap_table = '00'; - xn_table = '0'; - pxn_table = '0'; - - addrselecttop = inputsize - 1; - - apply_nvnv1_effect = HaveNVExt() && EL2Enabled() && HCR_EL2.[NV,NV1] == '11' && S1TranslationRegime() == EL1 && !secondstage; - repeat - addrselectbottom = (3-level)*stride + grainsize; - - bits(52) index = ZeroExtend(inputaddr[addrselecttop:addrselectbottom]:'000'); - descaddr.paddress.address = baseaddress OR index; - descaddr.paddress.NS = if secondstage then nswalk else ns_table; - - // If there are two stages of translation, then the first stage table walk addresses - // are themselves subject to translation - if secondstage || !HasS2Translation() || (HaveNV2Ext() && acctype == AccType_NV2REGISTER) then - descaddr2 = descaddr; - else - hwupdatewalk = FALSE; - descaddr2 = AArch64.SecondStageWalk(descaddr, vaddress, acctype, iswrite, 8, hwupdatewalk); - // Check for a fault on the stage 2 walk - if IsFault(descaddr2) then - result.addrdesc.fault = descaddr2.fault; - return result; - - // Update virtual address for abort functions - descaddr2.vaddress = ZeroExtend(vaddress); - - accdesc = CreateAccessDescriptorPTW(acctype, secondstage, s2fs1walk, level); - desc = _Mem[descaddr2, 8, accdesc]; - - if reversedescriptors then desc = BigEndianReverse(desc); - - if desc[0] == '0' || (desc[1:0] == '01' && (level == 3 || - (HaveBlockBBM() && IsBlockDescriptorNTBitValid() && desc[16] == '1'))) then - // Fault (00), Reserved (10), Block (01) at level 3, or Block(01) with nT bit set. - result.addrdesc.fault = AArch64.TranslationFault(ipaddress, s1_nonsecure, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - // Valid Block, Page, or Table entry - if desc[1:0] == '01' || level == 3 then // Block (01) or Page (11) - blocktranslate = TRUE; - else // Table (11) - if (outputsize < 52 && largegrain && !IsZero(desc[15:12])) || (outputsize < 48 && !IsZero(desc[47:outputsize])) then - result.addrdesc.fault = AArch64.AddressSizeFault(ipaddress,s1_nonsecure, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - if outputsize == 52 then - baseaddress = desc[15:12]:desc[47:grainsize]:Zeros(grainsize); - else - baseaddress = ZeroExtend(desc[47:grainsize]:Zeros(grainsize)); - if !secondstage then - // Unpack the upper and lower table attributes - ns_table = ns_table OR desc[63]; - if !secondstage && !hierattrsdisabled then - ap_table[1] = ap_table[1] OR desc[62]; // read-only - - if apply_nvnv1_effect then - pxn_table = pxn_table OR desc[60]; - else - xn_table = xn_table OR desc[60]; - // pxn_table and ap_table[0] apply in EL1&0 or EL2&0 translation regimes - if !singlepriv then - if !apply_nvnv1_effect then - pxn_table = pxn_table OR desc[59]; - ap_table[0] = ap_table[0] OR desc[61]; // privileged - - level = level + 1; - addrselecttop = addrselectbottom - 1; - blocktranslate = FALSE; - until blocktranslate; - - // Check block size is supported at this level - if level < firstblocklevel then - result.addrdesc.fault = AArch64.TranslationFault(ipaddress, s1_nonsecure, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - // Check for misprogramming of the contiguous bit - if largegrain then - num_ch_entries = 5; - elsif midgrain then - if level == 3 then - num_ch_entries = 7; - else num_ch_entries = 5; - else num_ch_entries = 4; - - contiguousbitcheck = inputsize < (addrselectbottom + num_ch_entries); - - if contiguousbitcheck && desc[52] == '1' then - if boolean IMPLEMENTATION_DEFINED "Translation fault on misprogrammed contiguous bit" then - result.addrdesc.fault = AArch64.TranslationFault(ipaddress, s1_nonsecure, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - // Unpack the descriptor into address and upper and lower block attributes - if largegrain then - outputaddress = desc[15:12]:desc[47:addrselectbottom]:inputaddr[addrselectbottom-1:0]; - else - outputaddress = ZeroExtend(desc[47:addrselectbottom]:inputaddr[addrselectbottom-1:0]); - - // When 52-bit PA is supported, for 64 Kbyte translation granule, - // block size might be larger than the supported output address size - if outputsize < 52 && !IsZero(outputaddress[51:outputsize]) then - result.addrdesc.fault = AArch64.AddressSizeFault(ipaddress,s1_nonsecure, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - // Check Access Flag - if desc[10] == '0' then - if !update_AF then - result.addrdesc.fault = AArch64.AccessFlagFault(ipaddress,s1_nonsecure, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - else - result.descupdate.AF = TRUE; - - if update_AP && desc[51] == '1' then - // If hw update of access permission field is configured consider AP[2] as '0' / S2AP[2] as '1' - if !secondstage && desc[7] == '1' then - desc[7] = '0'; - result.descupdate.AP = TRUE; - elsif secondstage && desc[7] == '0' then - desc[7] = '1'; - result.descupdate.AP = TRUE; - - // Required descriptor if AF or AP[2]/S2AP[2] needs update - result.descupdate.descaddr = descaddr; - - if apply_nvnv1_effect then - pxn = desc[54]; // Bit[54] of the block/page descriptor holds PXN instead of UXN - xn = '0'; // XN is '0' - ap = desc[7]:'01'; // Bit[6] of the block/page descriptor is treated as '0' regardless of value programmed - else - xn = desc[54]; // Bit[54] of the block/page descriptor holds UXN - pxn = desc[53]; // Bit[53] of the block/page descriptor holds PXN - ap = desc[7:6]:'1'; // Bits[7:6] of the block/page descriptor hold AP[2:1] - contiguousbit = desc[52]; - nG = desc[11]; - sh = desc[9:8]; - memattr = desc[5:2]; // AttrIndx and NS bit in stage 1 - - result.domain = bits(4) UNKNOWN; // Domains not used - result.level = level; - result.blocksize = 2^((3-level)*stride + grainsize); - - // Stage 1 translation regimes also inherit attributes from the tables - if !secondstage then - result.perms.xn = xn OR xn_table; - result.perms.ap[2] = ap[2] OR ap_table[1]; // Force read-only - // PXN, nG and AP[1] apply in EL1&0 or EL2&0 stage 1 translation regimes - if !singlepriv then - result.perms.ap[1] = ap[1] AND NOT(ap_table[0]); // Force privileged only - result.perms.pxn = pxn OR pxn_table; - // Pages from Non-secure tables are marked non-global in Secure EL1&0 - if IsSecure() then - result.nG = nG OR ns_table; - else - result.nG = nG; - else - result.perms.ap[1] = '1'; - result.perms.pxn = '0'; - result.nG = '0'; - result.GP = desc[50]; // Stage 1 block or pages might be guarded - result.perms.ap[0] = '1'; - result.addrdesc.memattrs = AArch64.S1AttrDecode(sh, memattr[2:0], acctype); - result.addrdesc.paddress.NS = memattr[3] OR ns_table; - else - result.perms.ap[2:1] = ap[2:1]; - result.perms.ap[0] = '1'; - result.perms.xn = xn; - if HaveExtendedExecuteNeverExt() then result.perms.xxn = desc[53]; - result.perms.pxn = '0'; - result.nG = '0'; - if s2fs1walk then - result.addrdesc.memattrs = S2AttrDecode(sh, memattr, AccType_PTW); - else - result.addrdesc.memattrs = S2AttrDecode(sh, memattr, acctype); - result.addrdesc.paddress.NS = nsaccess; - - result.addrdesc.paddress.address = outputaddress; - result.addrdesc.fault = AArch64.NoFault(); - result.contiguous = contiguousbit == '1'; - if HaveCommonNotPrivateTransExt() then result.CnP = baseregister[0]; - - return result; - -// AArch64.SecondStageTranslate() -// ============================== -// Perform a stage 2 translation walk. The function used by Address Translation operations is -// similar except it uses the translation regime specified for the instruction. - -AddressDescriptor AArch64.SecondStageTranslate(AddressDescriptor S1, bits(64) vaddress, - AccType acctype, boolean iswrite, boolean wasaligned, - boolean s2fs1walk, integer size, boolean hwupdatewalk) - assert HasS2Translation(); - - s2_enabled = HCR_EL2.VM == '1' || HCR_EL2.DC == '1'; - secondstage = TRUE; - - if s2_enabled then // Second stage enabled - ipaddress = S1.paddress.address[51:0]; - NS = S1.paddress.NS == '1'; - S2 = AArch64.TranslationTableWalk(ipaddress, NS, vaddress, acctype, iswrite, secondstage, - s2fs1walk, size); - - // Check for unaligned data accesses to Device memory - if ((!wasaligned && acctype != AccType_IFETCH) || (acctype == AccType_DCZVA)) - && S2.addrdesc.memattrs.memtype == MemType_Device && !IsFault(S2.addrdesc) then - S2.addrdesc.fault = AArch64.AlignmentFault(acctype, iswrite, secondstage); - - // Check for permissions on Stage2 translations - if !IsFault(S2.addrdesc) then - S2.addrdesc.fault = AArch64.CheckS2Permission(S2.perms, vaddress, ipaddress, S2.level, - acctype, iswrite, NS,s2fs1walk, hwupdatewalk); - - // Check for instruction fetches from Device memory not marked as execute-never. As there - // has not been a Permission Fault then the memory is not marked execute-never. - if (!s2fs1walk && !IsFault(S2.addrdesc) && S2.addrdesc.memattrs.memtype == MemType_Device && - acctype == AccType_IFETCH) then - S2.addrdesc = AArch64.InstructionDevice(S2.addrdesc, vaddress, ipaddress, S2.level, - acctype, iswrite, - secondstage, s2fs1walk); - - if (s2fs1walk && !IsFault(S2.addrdesc) && - S2.addrdesc.memattrs.memtype == MemType_Device) then - // Check for protected table walk. - if HCR_EL2.PTW == '1' then - S2.addrdesc.fault = AArch64.PermissionFault(ipaddress, - NS, S2.level, - acctype, iswrite, secondstage, s2fs1walk); - else - // Translation table walk occurs as Normal Non-cacheable memory. - S2.addrdesc.memattrs.memtype = MemType_Normal; - S2.addrdesc.memattrs.inner.attrs = MemAttr_NC; - S2.addrdesc.memattrs.outer.attrs = MemAttr_NC; - S2.addrdesc.memattrs.shareable = TRUE; - S2.addrdesc.memattrs.outershareable = TRUE; - - // Check and update translation table descriptor if required - S2.addrdesc.fault = AArch64.CheckAndUpdateDescriptor(S2.descupdate, S2.addrdesc.fault, - secondstage, vaddress, acctype, - iswrite, s2fs1walk, hwupdatewalk); - result = AArch64.CombineS1S2Desc(S1, S2.addrdesc); - else - result = S1; - - return result; - -// AArch32.SecondStageTranslate() -// ============================== -// Perform a stage 2 translation walk. The function used by Address Translation operations is -// similar except it uses the translation regime specified for the instruction. - -AddressDescriptor AArch32.SecondStageTranslate(AddressDescriptor S1, bits(32) vaddress, - AccType acctype, boolean iswrite, boolean wasaligned, - boolean s2fs1walk, integer size) - assert HasS2Translation(); - assert IsZero(S1.paddress.address[47:40]); - hwupdatewalk = FALSE; - if !ELUsingAArch32(EL2) then - return AArch64.SecondStageTranslate(S1, ZeroExtend(vaddress, 64), acctype, iswrite, - wasaligned, s2fs1walk, size, hwupdatewalk); - - s2_enabled = HCR.VM == '1' || HCR.DC == '1'; - secondstage = TRUE; - - if s2_enabled then // Second stage enabled - ipaddress = S1.paddress.address[39:0]; - S2 = AArch32.TranslationTableWalkLD(ipaddress, vaddress, acctype, iswrite, secondstage, - s2fs1walk, size); - - // Check for unaligned data accesses to Device memory - if ((!wasaligned && acctype != AccType_IFETCH) || (acctype == AccType_DCZVA)) - && S2.addrdesc.memattrs.memtype == MemType_Device && !IsFault(S2.addrdesc) then - S2.addrdesc.fault = AArch32.AlignmentFault(acctype, iswrite, secondstage); - - // Check for permissions on Stage2 translations - if !IsFault(S2.addrdesc) then - S2.addrdesc.fault = AArch32.CheckS2Permission(S2.perms, vaddress, ipaddress, S2.level, - acctype, iswrite, s2fs1walk); - - // Check for instruction fetches from Device memory not marked as execute-never. As there - // has not been a Permission Fault then the memory is not marked execute-never. - if (!s2fs1walk && !IsFault(S2.addrdesc) && S2.addrdesc.memattrs.memtype == MemType_Device && - acctype == AccType_IFETCH) then - domain = bits(4) UNKNOWN; - S2.addrdesc = AArch32.InstructionDevice(S2.addrdesc, vaddress, ipaddress, S2.level, - domain, acctype, iswrite, - secondstage, s2fs1walk); - - if (s2fs1walk && !IsFault(S2.addrdesc) && - S2.addrdesc.memattrs.memtype == MemType_Device) then - // Check for protected table walk. - if HCR.PTW == '1' then - domain = bits(4) UNKNOWN; - S2.addrdesc.fault = AArch32.PermissionFault(ipaddress, - domain, S2.level, - acctype, iswrite, secondstage, s2fs1walk); - else - // Translation table walk occurs as Normal Non-cacheable memory. - S2.addrdesc.memattrs.memtype = MemType_Normal; - S2.addrdesc.memattrs.inner.attrs = MemAttr_NC; - S2.addrdesc.memattrs.outer.attrs = MemAttr_NC; - S2.addrdesc.memattrs.shareable = TRUE; - S2.addrdesc.memattrs.outershareable = TRUE; - - result = AArch32.CombineS1S2Desc(S1, S2.addrdesc); - else - result = S1; - - return result; - -// AArch32.SecondStageWalk() -// ========================= -// Perform a stage 2 translation on a stage 1 translation page table walk access. - -AddressDescriptor AArch32.SecondStageWalk(AddressDescriptor S1, bits(32) vaddress, AccType acctype, - boolean iswrite, integer size) - - assert HasS2Translation(); - - s2fs1walk = TRUE; - wasaligned = TRUE; - return AArch32.SecondStageTranslate(S1, vaddress, acctype, iswrite, wasaligned, s2fs1walk, - size); - -// AArch32.TranslationFault() -// ========================== - -FaultRecord AArch32.TranslationFault(bits(40) ipaddress, bits(4) domain, integer level, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk) - - extflag = bit UNKNOWN; - debugmoe = bits(4) UNKNOWN; - errortype = bits(2) UNKNOWN; - return AArch32.CreateFaultRecord(Fault_Translation, ipaddress, domain, level, acctype, iswrite, - extflag, debugmoe, errortype, secondstage, s2fs1walk); - -// AArch32.TranslationTableWalkLD() -// ================================ -// Returns a result of a translation table walk using the Long-descriptor format -// -// Implementations might cache information from memory in any number of non-coherent TLB -// caching structures, and so avoid memory accesses that have been expressed in this -// pseudocode. The use of such TLBs is not expressed in this pseudocode. - -TLBRecord AArch32.TranslationTableWalkLD(bits(40) ipaddress, bits(32) vaddress, - AccType acctype, boolean iswrite, boolean secondstage, - boolean s2fs1walk, integer size) - if !secondstage then - assert ELUsingAArch32(S1TranslationRegime()); - else - assert HaveEL(EL2) && !IsSecure() && ELUsingAArch32(EL2) && HasS2Translation(); - - TLBRecord result; - AddressDescriptor descaddr; - bits(64) baseregister; - bits(40) inputaddr; // Input Address is 'vaddress' for stage 1, 'ipaddress' for stage 2 - bit nswalk; // Stage 2 translation table walks are to Secure or to Non-secure PA space - - domain = bits(4) UNKNOWN; - - descaddr.memattrs.memtype = MemType_Normal; - result.descupdate.AF = FALSE; - result.descupdate.AP = FALSE; - - // Fixed parameters for the page table walk: - // grainsize = Log2(Size of Table) - Size of Table is 4KB in AArch32 - // stride = Log2(Address per Level) - Bits of address consumed at each level - constant integer grainsize = 12; // Log2(4KB page size) - constant integer stride = grainsize - 3; // Log2(page size / 8 bytes) - - // Derived parameters for the page table walk: - // inputsize = Log2(Size of Input Address) - Input Address size in bits - // level = Level to start walk from - // This means that the number of levels after start level = 3-level - - if !secondstage then - // First stage translation - inputaddr = ZeroExtend(vaddress); - el = AArch32.AccessUsesEL(acctype); - if el == EL2 then - inputsize = 32 - UInt(HTCR.T0SZ); - basefound = inputsize == 32 || IsZero(inputaddr[31:inputsize]); - disabled = FALSE; - baseregister = HTTBR; - descaddr.memattrs = WalkAttrDecode(HTCR.SH0, HTCR.ORGN0, HTCR.IRGN0, secondstage); - reversedescriptors = HSCTLR.EE == '1'; - lookupsecure = FALSE; - singlepriv = TRUE; - hierattrsdisabled = AArch32.HaveHPDExt() && HTCR.HPD == '1'; - else - basefound = FALSE; - disabled = FALSE; - t0size = UInt(TTBCR.T0SZ); - if t0size == 0 || IsZero(inputaddr[31:(32-t0size)]) then - inputsize = 32 - t0size; - basefound = TRUE; - baseregister = TTBR0; - descaddr.memattrs = WalkAttrDecode(TTBCR.SH0, TTBCR.ORGN0, TTBCR.IRGN0, secondstage); - hierattrsdisabled = AArch32.HaveHPDExt() && TTBCR.T2E == '1' && TTBCR2.HPD0 == '1'; - t1size = UInt(TTBCR.T1SZ); - if (t1size == 0 && !basefound) || (t1size > 0 && IsOnes(inputaddr[31:(32-t1size)])) then - inputsize = 32 - t1size; - basefound = TRUE; - baseregister = TTBR1; - descaddr.memattrs = WalkAttrDecode(TTBCR.SH1, TTBCR.ORGN1, TTBCR.IRGN1, secondstage); - hierattrsdisabled = AArch32.HaveHPDExt() && TTBCR.T2E == '1' && TTBCR2.HPD1 == '1'; - reversedescriptors = SCTLR.EE == '1'; - lookupsecure = IsSecure(); - singlepriv = FALSE; - // The starting level is the number of strides needed to consume the input address - level = 4 - (1 + ((inputsize - grainsize - 1) DIV stride)); - - else - // Second stage translation - inputaddr = ipaddress; - inputsize = 32 - SInt(VTCR.T0SZ); - // VTCR.S must match VTCR.T0SZ[3] - if VTCR.S != VTCR.T0SZ[3] then - (-, inputsize) = ConstrainUnpredictableInteger(32-7, 32+8, Unpredictable_RESVTCRS); - basefound = inputsize == 40 || IsZero(inputaddr[39:inputsize]); - disabled = FALSE; - descaddr.memattrs = WalkAttrDecode(VTCR.SH0, VTCR.ORGN0, VTCR.IRGN0, secondstage); - reversedescriptors = HSCTLR.EE == '1'; - singlepriv = TRUE; - - lookupsecure = FALSE; - baseregister = VTTBR; - startlevel = UInt(VTCR.SL0); - level = 2 - startlevel; - if level <= 0 then basefound = FALSE; - - // Number of entries in the starting level table = - // (Size of Input Address)/((Address per level)^(Num levels remaining)*(Size of Table)) - startsizecheck = inputsize - ((3 - level)*stride + grainsize); // Log2(Num of entries) - - // Check for starting level table with fewer than 2 entries or longer than 16 pages. - // Lower bound check is: startsizecheck < Log2(2 entries) - // That is, VTCR.SL0 == '00' and SInt(VTCR.T0SZ) > 1, Size of Input Address < 2^31 bytes - // Upper bound check is: startsizecheck > Log2(pagesize/8*16) - // That is, VTCR.SL0 == '01' and SInt(VTCR.T0SZ) [ -2, Size of Input Address ] 2^34 bytes - if startsizecheck < 1 || startsizecheck > stride + 4 then basefound = FALSE; - if !basefound || disabled then - level = 1; // AArch64 reports this as a level 0 fault - result.addrdesc.fault = AArch32.TranslationFault(ipaddress, domain, level, acctype, iswrite, - secondstage, s2fs1walk); - return result; - - if !IsZero(baseregister[47:40]) then - level = 0; - result.addrdesc.fault = AArch32.AddressSizeFault(ipaddress, domain, level, acctype, iswrite, - secondstage, s2fs1walk); - return result; - - // Bottom bound of the Base address is: - // Log2(8 bytes per entry)+Log2(Number of entries in starting level table) - // Number of entries in starting level table = - // (Size of Input Address)/((Address per level)^(Num levels remaining)*(Size of Table)) - baselowerbound = 3 + inputsize - ((3-level)*stride + grainsize); // Log2(Num of entries*8) - baseaddress = baseregister[39:baselowerbound]:Zeros(baselowerbound); - - ns_table = if lookupsecure then '0' else '1'; - ap_table = '00'; - xn_table = '0'; - pxn_table = '0'; - - addrselecttop = inputsize - 1; - - repeat - addrselectbottom = (3-level)*stride + grainsize; - - bits(40) index = ZeroExtend(inputaddr[addrselecttop:addrselectbottom]:'000'); - descaddr.paddress.address = ZeroExtend(baseaddress OR index); - descaddr.paddress.NS = ns_table; - - // If there are two stages of translation, then the first stage table walk addresses - // are themselves subject to translation - if secondstage || !HasS2Translation() || (HaveNV2Ext() && acctype == AccType_NV2REGISTER) then - descaddr2 = descaddr; - else - descaddr2 = AArch32.SecondStageWalk(descaddr, vaddress, acctype, iswrite, 8); - // Check for a fault on the stage 2 walk - if IsFault(descaddr2) then - result.addrdesc.fault = descaddr2.fault; - return result; - - // Update virtual address for abort functions - descaddr2.vaddress = ZeroExtend(vaddress); - - accdesc = CreateAccessDescriptorPTW(acctype, secondstage, s2fs1walk, level); - desc = _Mem[descaddr2, 8, accdesc]; - - if reversedescriptors then desc = BigEndianReverse(desc); - - if desc[0] == '0' || (desc[1:0] == '01' && level == 3) then - // Fault (00), Reserved (10), or Block (01) at level 3. - result.addrdesc.fault = AArch32.TranslationFault(ipaddress, domain, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - // Valid Block, Page, or Table entry - if desc[1:0] == '01' || level == 3 then // Block (01) or Page (11) - blocktranslate = TRUE; - else // Table (11) - if !IsZero(desc[47:40]) then - result.addrdesc.fault = AArch32.AddressSizeFault(ipaddress, domain, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - baseaddress = desc[39:grainsize]:Zeros(grainsize); - if !secondstage then - // Unpack the upper and lower table attributes - ns_table = ns_table OR desc[63]; - if !secondstage && !hierattrsdisabled then - ap_table[1] = ap_table[1] OR desc[62]; // read-only - - xn_table = xn_table OR desc[60]; - // pxn_table and ap_table[0] apply only in EL1&0 translation regimes - if !singlepriv then - pxn_table = pxn_table OR desc[59]; - ap_table[0] = ap_table[0] OR desc[61]; // privileged - - level = level + 1; - addrselecttop = addrselectbottom - 1; - blocktranslate = FALSE; - until blocktranslate; - - // Unpack the descriptor into address and upper and lower block attributes - outputaddress = desc[39:addrselectbottom]:inputaddr[addrselectbottom-1:0]; - - // Check the output address is inside the supported range - if !IsZero(desc[47:40]) then - result.addrdesc.fault = AArch32.AddressSizeFault(ipaddress, domain, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - // Check the access flag - if desc[10] == '0' then - result.addrdesc.fault = AArch32.AccessFlagFault(ipaddress, domain, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - xn = desc[54]; // Bit[54] of the block/page descriptor holds UXN - pxn = desc[53]; // Bit[53] of the block/page descriptor holds PXN - ap = desc[7:6]:'1'; // Bits[7:6] of the block/page descriptor hold AP[2:1] - contiguousbit = desc[52]; - nG = desc[11]; - sh = desc[9:8]; - memattr = desc[5:2]; // AttrIndx and NS bit in stage 1 - - result.domain = bits(4) UNKNOWN; // Domains not used - result.level = level; - result.blocksize = 2^((3-level)*stride + grainsize); - - // Stage 1 translation regimes also inherit attributes from the tables - if !secondstage then - result.perms.xn = xn OR xn_table; - result.perms.ap[2] = ap[2] OR ap_table[1]; // Force read-only - // PXN, nG and AP[1] apply only in EL1&0 stage 1 translation regimes - if !singlepriv then - result.perms.ap[1] = ap[1] AND NOT(ap_table[0]); // Force privileged only - result.perms.pxn = pxn OR pxn_table; - // Pages from Non-secure tables are marked non-global in Secure EL1&0 - if IsSecure() then - result.nG = nG OR ns_table; - else - result.nG = nG; - else - result.perms.ap[1] = '1'; - result.perms.pxn = '0'; - result.nG = '0'; - result.GP = desc[50]; // Stage 1 block or pages might be guarded - result.perms.ap[0] = '1'; - result.addrdesc.memattrs = AArch32.S1AttrDecode(sh, memattr[2:0], acctype); - result.addrdesc.paddress.NS = memattr[3] OR ns_table; - else - result.perms.ap[2:1] = ap[2:1]; - result.perms.ap[0] = '1'; - result.perms.xn = xn; - if HaveExtendedExecuteNeverExt() then result.perms.xxn = desc[53]; - result.perms.pxn = '0'; - result.nG = '0'; - if s2fs1walk then - result.addrdesc.memattrs = S2AttrDecode(sh, memattr, AccType_PTW); - else - result.addrdesc.memattrs = S2AttrDecode(sh, memattr, acctype); - result.addrdesc.paddress.NS = '1'; - - result.addrdesc.paddress.address = ZeroExtend(outputaddress); - result.addrdesc.fault = AArch32.NoFault(); - result.contiguous = contiguousbit == '1'; - if HaveCommonNotPrivateTransExt() then result.CnP = baseregister[0]; - - return result; - -// AArch32.DefaultTEXDecode() -// ========================== - -MemoryAttributes AArch32.DefaultTEXDecode(bits(3) TEX, bit C, bit B, bit S, AccType acctype) - - MemoryAttributes memattrs; - - // Reserved values map to allocated values - if (TEX == '001' && C:B == '01') || (TEX == '010' && C:B != '00') || TEX == '011' then - bits(5) texcb; - (-, texcb) = ConstrainUnpredictableBits(Unpredictable_RESTEXCB); - TEX = texcb[4:2]; C = texcb[1]; B = texcb[0]; - - case TEX:C:B of - when '00000' - // Device-nGnRnE - memattrs.memtype = MemType_Device; - memattrs.device = DeviceType_nGnRnE; - when '00001', '01000' - // Device-nGnRE - memattrs.memtype = MemType_Device; - memattrs.device = DeviceType_nGnRE; - when '00010', '00011', '00100' - // Write-back or Write-through Read allocate, or Non-cacheable - memattrs.memtype = MemType_Normal; - memattrs.inner = ShortConvertAttrsHints(C:B, acctype, FALSE); - memattrs.outer = ShortConvertAttrsHints(C:B, acctype, FALSE); - memattrs.shareable = (S == '1'); - when '00110' - memattrs = MemoryAttributes IMPLEMENTATION_DEFINED; - when '00111' - // Write-back Read and Write allocate - memattrs.memtype = MemType_Normal; - memattrs.inner = ShortConvertAttrsHints('01', acctype, FALSE); - memattrs.outer = ShortConvertAttrsHints('01', acctype, FALSE); - memattrs.shareable = (S == '1'); - when '1xxxx' - // Cacheable, TEX[1:0] = Outer attrs, {C,B} = Inner attrs - memattrs.memtype = MemType_Normal; - memattrs.inner = ShortConvertAttrsHints(C:B, acctype, FALSE); - memattrs.outer = ShortConvertAttrsHints(TEX[1:0], acctype, FALSE); - memattrs.shareable = (S == '1'); - otherwise - // Reserved, handled above - Unreachable(); - - // transient bits are not supported in this format - memattrs.inner.transient = FALSE; - memattrs.outer.transient = FALSE; - - // distinction between inner and outer shareable is not supported in this format - memattrs.outershareable = memattrs.shareable; - memattrs.tagged = FALSE; - - return MemAttrDefaults(memattrs); - -// AArch32.RemappedTEXDecode() -// =========================== - -MemoryAttributes AArch32.RemappedTEXDecode(bits(3) TEX, bit C, bit B, bit S, AccType acctype) - - MemoryAttributes memattrs; - - region = UInt(TEX[0]:C:B); // TEX[2:1] are ignored in this mapping scheme - if region == 6 then - memattrs = MemoryAttributes IMPLEMENTATION_DEFINED; - else - base = 2 * region; - attrfield = PRRR[base+1:base]; - - if attrfield == '11' then // Reserved, maps to allocated value - (-, attrfield) = ConstrainUnpredictableBits(Unpredictable_RESPRRR); - - case attrfield of - when '00' // Device-nGnRnE - memattrs.memtype = MemType_Device; - memattrs.device = DeviceType_nGnRnE; - when '01' // Device-nGnRE - memattrs.memtype = MemType_Device; - memattrs.device = DeviceType_nGnRE; - when '10' - memattrs.memtype = MemType_Normal; - memattrs.inner = ShortConvertAttrsHints(NMRR[base+1:base], acctype, FALSE); - memattrs.outer = ShortConvertAttrsHints(NMRR[base+17:base+16], acctype, FALSE); - s_bit = if S == '0' then PRRR.NS0 else PRRR.NS1; - memattrs.shareable = (s_bit == '1'); - memattrs.outershareable = (s_bit == '1' && PRRR[region+24] == '0'); - when '11' - Unreachable(); - - // transient bits are not supported in this format - memattrs.inner.transient = FALSE; - memattrs.outer.transient = FALSE; - memattrs.tagged = FALSE; - - return MemAttrDefaults(memattrs); - -boolean RemapRegsHaveResetValues(); - -// AArch32.TranslationTableWalkSD() -// ================================ -// Returns a result of a translation table walk using the Short-descriptor format -// -// Implementations might cache information from memory in any number of non-coherent TLB -// caching structures, and so avoid memory accesses that have been expressed in this -// pseudocode. The use of such TLBs is not expressed in this pseudocode. - -TLBRecord AArch32.TranslationTableWalkSD(bits(32) vaddress, AccType acctype, boolean iswrite, - integer size) - assert ELUsingAArch32(S1TranslationRegime()); - - // This is only called when address translation is enabled - TLBRecord result; - AddressDescriptor l1descaddr; - AddressDescriptor l2descaddr; - bits(40) outputaddress; - - result.descupdate.AF = FALSE; - result.descupdate.AP = FALSE; - - // Variables for Abort functions - ipaddress = bits(40) UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - NS = bit UNKNOWN; - - // Default setting of the domain - domain = bits(4) UNKNOWN; - - // Determine correct Translation Table Base Register to use. - bits(64) ttbr; - n = UInt(TTBCR.N); - if n == 0 || IsZero(vaddress[31:(32-n)]) then - ttbr = TTBR0; - disabled = (TTBCR.PD0 == '1'); - else - ttbr = TTBR1; - disabled = (TTBCR.PD1 == '1'); - n = 0; // TTBR1 translation always works like N=0 TTBR0 translation - - // Check this Translation Table Base Register is not disabled. - if disabled then - level = 1; - result.addrdesc.fault = AArch32.TranslationFault(ipaddress, domain, level, acctype, iswrite, - secondstage, s2fs1walk); - return result; - - // Obtain descriptor from initial lookup. - l1descaddr.paddress.address = ZeroExtend(ttbr[31:14-n]:vaddress[31-n:20]:'00'); - l1descaddr.paddress.NS = if IsSecure() then '0' else '1'; - IRGN = ttbr[0]:ttbr[6]; // TTBR.IRGN - RGN = ttbr[4:3]; // TTBR.RGN - SH = ttbr[1]:ttbr[5]; // TTBR.S:TTBR.NOS - l1descaddr.memattrs = WalkAttrDecode(SH, RGN, IRGN, secondstage); - - if !HaveEL(EL2) || (IsSecure() && !IsSecureEL2Enabled()) then - // if only 1 stage of translation - l1descaddr2 = l1descaddr; - else - l1descaddr2 = AArch32.SecondStageWalk(l1descaddr, vaddress, acctype, iswrite, 4); - // Check for a fault on the stage 2 walk - if IsFault(l1descaddr2) then - result.addrdesc.fault = l1descaddr2.fault; - return result; - - // Update virtual address for abort functions - l1descaddr2.vaddress = ZeroExtend(vaddress); - - accdesc = CreateAccessDescriptorPTW(acctype, secondstage, s2fs1walk, level); - l1desc = _Mem[l1descaddr2, 4,accdesc]; - - if SCTLR.EE == '1' then l1desc = BigEndianReverse(l1desc); - - // Process descriptor from initial lookup. - case l1desc[1:0] of - when '00' // Fault, Reserved - level = 1; - result.addrdesc.fault = AArch32.TranslationFault(ipaddress, domain, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - when '01' // Large page or Small page - domain = l1desc[8:5]; - level = 2; - pxn = l1desc[2]; - NS = l1desc[3]; - - // Obtain descriptor from level 2 lookup. - l2descaddr.paddress.address = ZeroExtend(l1desc[31:10]:vaddress[19:12]:'00'); - l2descaddr.paddress.NS = if IsSecure() then '0' else '1'; - l2descaddr.memattrs = l1descaddr.memattrs; - - if !HaveEL(EL2) || (IsSecure() && !IsSecureEL2Enabled()) then - // if only 1 stage of translation - l2descaddr2 = l2descaddr; - else - l2descaddr2 = AArch32.SecondStageWalk(l2descaddr, vaddress, acctype, iswrite, 4); - // Check for a fault on the stage 2 walk - if IsFault(l2descaddr2) then - result.addrdesc.fault = l2descaddr2.fault; - return result; - - // Update virtual address for abort functions - l2descaddr2.vaddress = ZeroExtend(vaddress); - - accdesc = CreateAccessDescriptorPTW(acctype, secondstage, s2fs1walk, level); - l2desc = _Mem[l2descaddr2, 4, accdesc]; - - if SCTLR.EE == '1' then l2desc = BigEndianReverse(l2desc); - - // Process descriptor from level 2 lookup. - if l2desc[1:0] == '00' then - result.addrdesc.fault = AArch32.TranslationFault(ipaddress, domain, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - nG = l2desc[11]; - S = l2desc[10]; - ap = l2desc[9,5:4]; - - if SCTLR.AFE == '1' && l2desc[4] == '0' then - // Armv8 VMSAv8-32 does not support hardware management of the Access flag. - result.addrdesc.fault = AArch32.AccessFlagFault(ipaddress, domain, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - if l2desc[1] == '0' then // Large page - xn = l2desc[15]; - tex = l2desc[14:12]; - c = l2desc[3]; - b = l2desc[2]; - blocksize = 64; - outputaddress = ZeroExtend(l2desc[31:16]:vaddress[15:0]); - else // Small page - tex = l2desc[8:6]; - c = l2desc[3]; - b = l2desc[2]; - xn = l2desc[0]; - blocksize = 4; - outputaddress = ZeroExtend(l2desc[31:12]:vaddress[11:0]); - - when '1x' // Section or Supersection - NS = l1desc[19]; - nG = l1desc[17]; - S = l1desc[16]; - ap = l1desc[15,11:10]; - tex = l1desc[14:12]; - xn = l1desc[4]; - c = l1desc[3]; - b = l1desc[2]; - pxn = l1desc[0]; - level = 1; - - if SCTLR.AFE == '1' && l1desc[10] == '0' then - // Armv8 VMSAv8-32 does not support hardware management of the Access flag. - result.addrdesc.fault = AArch32.AccessFlagFault(ipaddress, domain, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - if l1desc[18] == '0' then // Section - domain = l1desc[8:5]; - blocksize = 1024; - outputaddress = ZeroExtend(l1desc[31:20]:vaddress[19:0]); - else // Supersection - domain = '0000'; - blocksize = 16384; - outputaddress = l1desc[8:5]:l1desc[23:20]:l1desc[31:24]:vaddress[23:0]; - - // Decode the TEX, C, B and S bits to produce the TLBRecord's memory attributes - if SCTLR.TRE == '0' then - if RemapRegsHaveResetValues() then - result.addrdesc.memattrs = AArch32.DefaultTEXDecode(tex, c, b, S, acctype); - else - result.addrdesc.memattrs = MemoryAttributes IMPLEMENTATION_DEFINED; - else - result.addrdesc.memattrs = AArch32.RemappedTEXDecode(tex, c, b, S, acctype); - - // Set the rest of the TLBRecord, try to add it to the TLB, and return it. - result.perms.ap = ap; - result.perms.xn = xn; - result.perms.pxn = pxn; - result.nG = nG; - result.domain = domain; - result.level = level; - result.blocksize = blocksize; - result.addrdesc.paddress.address = ZeroExtend(outputaddress); - result.addrdesc.paddress.NS = if IsSecure() then NS else '1'; - result.addrdesc.fault = AArch32.NoFault(); - - return result; - -// HaveTrapLoadStoreMultipleDeviceExt() -// ==================================== - -boolean HaveTrapLoadStoreMultipleDeviceExt() - return HasArchVersion(ARMv8p2); - -// AArch32.FirstStageTranslate() -// ============================= -// Perform a stage 1 translation walk. The function used by Address Translation operations is -// similar except it uses the translation regime specified for the instruction. - -AddressDescriptor AArch32.FirstStageTranslate(bits(32) vaddress, AccType acctype, boolean iswrite, - boolean wasaligned, integer size) - - if PSTATE.EL == EL2 then - s1_enabled = HSCTLR.M == '1'; - elsif EL2Enabled() then - tge = (if ELUsingAArch32(EL2) then HCR.TGE else HCR_EL2.TGE); - dc = (if ELUsingAArch32(EL2) then HCR.DC else HCR_EL2.DC); - s1_enabled = tge == '0' && dc == '0' && SCTLR.M == '1'; - else - s1_enabled = SCTLR.M == '1'; - - ipaddress = bits(40) UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - - if s1_enabled then // First stage enabled - use_long_descriptor_format = PSTATE.EL == EL2 || TTBCR.EAE == '1'; - if use_long_descriptor_format then - S1 = AArch32.TranslationTableWalkLD(ipaddress, vaddress, acctype, iswrite, secondstage, - s2fs1walk, size); - permissioncheck = TRUE; domaincheck = FALSE; - else - S1 = AArch32.TranslationTableWalkSD(vaddress, acctype, iswrite, size); - permissioncheck = TRUE; domaincheck = TRUE; - else - S1 = AArch32.TranslateAddressS1Off(vaddress, acctype, iswrite); - permissioncheck = FALSE; domaincheck = FALSE; - - if !IsFault(S1.addrdesc) && UsingAArch32() && HaveTrapLoadStoreMultipleDeviceExt() && AArch32.ExecutingLSMInstr() then - if S1.addrdesc.memattrs.memtype == MemType_Device && S1.addrdesc.memattrs.device != DeviceType_GRE then - nTLSMD = if S1TranslationRegime() == EL2 then HSCTLR.nTLSMD else SCTLR.nTLSMD; - if nTLSMD == '0' then - S1.addrdesc.fault = AArch32.AlignmentFault(acctype, iswrite, secondstage); - - // Check for unaligned data accesses to Device memory - if ((!wasaligned && acctype != AccType_IFETCH) || (acctype == AccType_DCZVA)) - && !IsFault(S1.addrdesc) && S1.addrdesc.memattrs.memtype == MemType_Device then - S1.addrdesc.fault = AArch32.AlignmentFault(acctype, iswrite, secondstage); - if !IsFault(S1.addrdesc) && domaincheck then - (permissioncheck, abort) = AArch32.CheckDomain(S1.domain, vaddress, S1.level, acctype, - iswrite); - S1.addrdesc.fault = abort; - - if !IsFault(S1.addrdesc) && permissioncheck then - S1.addrdesc.fault = AArch32.CheckPermission(S1.perms, vaddress, S1.level, - S1.domain, S1.addrdesc.paddress.NS, - acctype, iswrite); - - // Check for instruction fetches from Device memory not marked as execute-never. If there has - // not been a Permission Fault then the memory is not marked execute-never. - if (!IsFault(S1.addrdesc) && S1.addrdesc.memattrs.memtype == MemType_Device && - acctype == AccType_IFETCH) then - S1.addrdesc = AArch32.InstructionDevice(S1.addrdesc, vaddress, ipaddress, S1.level, - S1.domain, acctype, iswrite, - secondstage, s2fs1walk); - - return S1.addrdesc; - -// AArch32.FullTranslate() -// ======================= -// Perform both stage 1 and stage 2 translation walks for the current translation regime. The -// function used by Address Translation operations is similar except it uses the translation -// regime specified for the instruction. - -AddressDescriptor AArch32.FullTranslate(bits(32) vaddress, AccType acctype, boolean iswrite, - boolean wasaligned, integer size) - - // First Stage Translation - S1 = AArch32.FirstStageTranslate(vaddress, acctype, iswrite, wasaligned, size); - if !IsFault(S1) && !(HaveNV2Ext() && acctype == AccType_NV2REGISTER) && HasS2Translation() then - s2fs1walk = FALSE; - result = AArch32.SecondStageTranslate(S1, vaddress, acctype, iswrite, wasaligned, s2fs1walk, - size); - else - result = S1; - - return result; - -// AArch64.BreakpointValueMatch() -// ============================== - -boolean AArch64.BreakpointValueMatch(integer n, bits(64) vaddress, boolean linked_to) - - // "n" is the identity of the breakpoint unit to match against. - // "vaddress" is the current instruction address, ignored if linked_to is TRUE and for Context - // matching breakpoints. - // "linked_to" is TRUE if this is a call from StateMatch for linking. - - // If a non-existent breakpoint then it is CONSTRAINED UNPREDICTABLE whether this gives - // no match or the breakpoint is mapped to another UNKNOWN implemented breakpoint. - if n > UInt(ID_AA64DFR0_EL1.BRPs) then - (c, n) = ConstrainUnpredictableInteger(0, UInt(ID_AA64DFR0_EL1.BRPs), Unpredictable_BPNOTIMPL); - assert c IN {Constraint_DISABLED, Constraint_UNKNOWN}; - if c == Constraint_DISABLED then return FALSE; - - // If this breakpoint is not enabled, it cannot generate a match. (This could also happen on a - // call from StateMatch for linking). - if DBGBCR_EL1[n].E == '0' then return FALSE; - - context_aware = (n >= UInt(ID_AA64DFR0_EL1.BRPs) - UInt(ID_AA64DFR0_EL1.CTX_CMPs)); - - // If BT is set to a reserved type1, behaves either as disabled or as a not-reserved type1. - dbgtype = DBGBCR_EL1[n].BT; - - if ((dbgtype IN {'011x','11xx'} && !HaveVirtHostExt()) || // Context matching - dbgtype == '010x' || // Reserved - (dbgtype != '0x0x' && !context_aware) || // Context matching - (dbgtype == '1xxx' && !HaveEL(EL2))) then // EL2 extension - (c, dbgtype) = ConstrainUnpredictableBits(Unpredictable_RESBPTYPE); - assert c IN {Constraint_DISABLED, Constraint_UNKNOWN}; - if c == Constraint_DISABLED then return FALSE; - // Otherwise the value returned by ConstrainUnpredictableBits must be a not-reserved value - - // Determine what to compare against. - match_addr = (dbgtype == '0x0x'); - match_vmid = (dbgtype == '10xx'); - match_cid = (dbgtype == '001x'); - match_cid1 = (dbgtype IN { '101x', 'x11x'}); - match_cid2 = (dbgtype == '11xx'); - linked = (dbgtype == 'xxx1'); - - // If this is a call from StateMatch, return FALSE if the breakpoint is not programmed for a - // VMID and/or context ID match, of if not context-aware. The above assertions mean that the - // code can just test for match_addr == TRUE to confirm all these things. - if linked_to && (!linked || match_addr) then return FALSE; - - // If called from BreakpointMatch return FALSE for Linked context ID and/or VMID matches. - if !linked_to && linked && !match_addr then return FALSE; - - // Do the comparison. - if match_addr then - byte = UInt(vaddress[1:0]); - if HaveAnyAArch32() then - // T32 instructions can be executed at EL0 in an AArch64 translation regime. - assert byte IN {0,2}; // "vaddress" is halfword aligned - byte_select_match = (DBGBCR_EL1[n].BAS[byte] == '1'); - else - assert byte == 0; // "vaddress" is word aligned - byte_select_match = TRUE; // DBGBCR_EL1[n].BAS[byte] is RES1 - top = AddrTop(vaddress, TRUE, PSTATE.EL); - BVR_match = vaddress[top:2] == DBGBVR_EL1[n][top:2] && byte_select_match; - elsif match_cid then - if IsInHost() then - BVR_match = (CONTEXTIDR_EL2 == DBGBVR_EL1[n][31:0]); - else - BVR_match = (PSTATE.EL IN {EL0, EL1} && CONTEXTIDR_EL1 == DBGBVR_EL1[n][31:0]); - elsif match_cid1 then - BVR_match = (PSTATE.EL IN {EL0, EL1} && !IsInHost() && CONTEXTIDR_EL1 == DBGBVR_EL1[n][31:0]); - if match_vmid then - if !Have16bitVMID() || VTCR_EL2.VS == '0' then - vmid = ZeroExtend(VTTBR_EL2.VMID[7:0], 16); - bvr_vmid = ZeroExtend(DBGBVR_EL1[n][39:32], 16); - else - vmid = VTTBR_EL2.VMID; - bvr_vmid = DBGBVR_EL1[n][47:32]; - BXVR_match = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - !IsInHost() && - vmid == bvr_vmid); - elsif match_cid2 then - BXVR_match = (!IsSecure() && HaveVirtHostExt() && - DBGBVR_EL1[n][63:32] == CONTEXTIDR_EL2); - - bvr_match_valid = (match_addr || match_cid || match_cid1); - bxvr_match_valid = (match_vmid || match_cid2); - - match = (!bxvr_match_valid || BXVR_match) && (!bvr_match_valid || BVR_match); - - return match; - -// AArch64.StateMatch() -// ==================== -// Determine whether a breakpoint or watchpoint is enabled in the current mode and state. - -boolean AArch64.StateMatch(bits(2) SSC, bit HMC, bits(2) PxC, boolean linked, bits(4) LBN, - boolean isbreakpnt, AccType acctype, boolean ispriv) - // "SSC", "HMC", "PxC" are the control fields from the DBGBCR[n] or DBGWCR[n] register. - // "linked" is TRUE if this is a linked breakpoint/watchpoint type1. - // "LBN" is the linked breakpoint number from the DBGBCR[n] or DBGWCR[n] register. - // "isbreakpnt" is TRUE for breakpoints, FALSE for watchpoints. - // "ispriv" is valid for watchpoints, and selects between privileged and unprivileged accesses. - - // If parameters are set to a reserved type1, behaves as either disabled or a defined type1 - (c, SSC, HMC, PxC) = CheckValidStateMatch(SSC, HMC, PxC, isbreakpnt); - if c == Constraint_DISABLED then return FALSE; - // Otherwise the HMC,SSC,PxC values are either valid or the values returned by - // CheckValidStateMatch are valid. - - EL3_match = HaveEL(EL3) && HMC == '1' && SSC[0] == '0'; - EL2_match = HaveEL(EL2) && ((HMC == '1' && (SSC:PxC != '1000')) || SSC == '11'); - EL1_match = PxC[0] == '1'; - EL0_match = PxC[1] == '1'; - - if HaveNV2Ext() && acctype == AccType_NV2REGISTER && !isbreakpnt then - priv_match = EL2_match; - elsif !ispriv && !isbreakpnt then - priv_match = EL0_match; - else - case PSTATE.EL of - when EL3 priv_match = EL3_match; - when EL2 priv_match = EL2_match; - when EL1 priv_match = EL1_match; - when EL0 priv_match = EL0_match; - - case SSC of - when '00' security_state_match = TRUE; // Both - when '01' security_state_match = !IsSecure(); // Non-secure only - when '10' security_state_match = IsSecure(); // Secure only - when '11' security_state_match = (HMC == '1' || IsSecure()); // HMC=1 -> Both, 0 -> Secure only - - if linked then - // "LBN" must be an enabled context-aware breakpoint unit. If it is not context-aware then - // it is CONSTRAINED UNPREDICTABLE whether this gives no match, or LBN is mapped to some - // UNKNOWN breakpoint that is context-aware. - lbn = UInt(LBN); - first_ctx_cmp = (UInt(ID_AA64DFR0_EL1.BRPs) - UInt(ID_AA64DFR0_EL1.CTX_CMPs)); - last_ctx_cmp = UInt(ID_AA64DFR0_EL1.BRPs); - if (lbn < first_ctx_cmp || lbn > last_ctx_cmp) then - (c, lbn) = ConstrainUnpredictableInteger(first_ctx_cmp, last_ctx_cmp, Unpredictable_BPNOTCTXCMP); - assert c IN {Constraint_DISABLED, Constraint_NONE, Constraint_UNKNOWN}; - case c of - when Constraint_DISABLED return FALSE; // Disabled - when Constraint_NONE linked = FALSE; // No linking - // Otherwise ConstrainUnpredictableInteger returned a context-aware breakpoint - - if linked then - vaddress = bits(64) UNKNOWN; - linked_to = TRUE; - linked_match = AArch64.BreakpointValueMatch(lbn, vaddress, linked_to); - - return priv_match && security_state_match && (!linked || linked_match); - -// AArch64.BreakpointMatch() -// ========================= -// Breakpoint matching in an AArch64 translation regime. - -boolean AArch64.BreakpointMatch(integer n, bits(64) vaddress, AccType acctype, integer size) - assert !ELUsingAArch32(S1TranslationRegime()); - assert n <= UInt(ID_AA64DFR0_EL1.BRPs); - - enabled = DBGBCR_EL1[n].E == '1'; - ispriv = PSTATE.EL != EL0; - linked = DBGBCR_EL1[n].BT == '0x01'; - isbreakpnt = TRUE; - linked_to = FALSE; - - state_match = AArch64.StateMatch(DBGBCR_EL1[n].SSC, DBGBCR_EL1[n].HMC, DBGBCR_EL1[n].PMC, - linked, DBGBCR_EL1[n].LBN, isbreakpnt, acctype, ispriv); - value_match = AArch64.BreakpointValueMatch(n, vaddress, linked_to); - - if HaveAnyAArch32() && size == 4 then // Check second halfword - // If the breakpoint address and BAS of an Address breakpoint match the address of the - // second halfword of an instruction, but not the address of the first halfword, it is - // CONSTRAINED UNPREDICTABLE whether or not this breakpoint generates a Breakpoint debug - // event. - match_i = AArch64.BreakpointValueMatch(n, vaddress + 2, linked_to); - if !value_match && match_i then - value_match = ConstrainUnpredictableBool(Unpredictable_BPMATCHHALF); - if vaddress[1] == '1' && DBGBCR_EL1[n].BAS == '1111' then - // The above notwithstanding, if DBGBCR_EL1[n].BAS == '1111', then it is CONSTRAINED - // UNPREDICTABLE whether or not a Breakpoint debug event is generated for an instruction - // at the address DBGBVR_EL1[n]+2. - if value_match then value_match = ConstrainUnpredictableBool(Unpredictable_BPMATCHHALF); - - match = value_match && state_match && enabled; - - return match; - -// AArch64.DebugFault() -// ==================== - -FaultRecord AArch64.DebugFault(AccType acctype, boolean iswrite) - - ipaddress = bits(52) UNKNOWN; - errortype = bits(2) UNKNOWN; - level = integer UNKNOWN; - extflag = bit UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - - return AArch64.CreateFaultRecord(Fault_Debug, ipaddress, boolean UNKNOWN, level, acctype, iswrite, - extflag, errortype, secondstage, s2fs1walk); - -// AArch64.CheckBreakpoint() -// ========================= -// Called before executing the instruction of length "size" bytes at "vaddress" in an AArch64 -// translation regime, when either debug exceptions are enabled, or halting debug is enabled -// and halting is allowed. - -FaultRecord AArch64.CheckBreakpoint(bits(64) vaddress, AccType acctype, integer size) - assert !ELUsingAArch32(S1TranslationRegime()); - assert (UsingAArch32() && size IN {2,4}) || size == 4; - - match = FALSE; - - for i = 0 to UInt(ID_AA64DFR0_EL1.BRPs) - match_i = AArch64.BreakpointMatch(i, vaddress, acctype, size); - match = match || match_i; - - if match && HaltOnBreakpointOrWatchpoint() then - reason = DebugHalt_Breakpoint; - Halt(reason); - elsif match then - acctype = AccType_IFETCH; - iswrite = FALSE; - return AArch64.DebugFault(acctype, iswrite); - else - return AArch64.NoFault(); - -// AArch64.AccessIsPrivileged() -// ============================ - -boolean AArch64.AccessIsPrivileged(AccType acctype) - - el = AArch64.AccessUsesEL(acctype); - - if el == EL0 then - ispriv = FALSE; - elsif el == EL3 then - ispriv = TRUE; - elsif el == EL2 && (!IsInHost() || HCR_EL2.TGE == '0') then - ispriv = TRUE; - elsif HaveUAOExt() && PSTATE.UAO == '1' then - ispriv = TRUE; - else - ispriv = (acctype != AccType_UNPRIV); - - return ispriv; - -// AArch64.WatchpointByteMatch() -// ============================= - -boolean AArch64.WatchpointByteMatch(integer n, AccType acctype, bits(64) vaddress) - - el = if HaveNV2Ext() && acctype == AccType_NV2REGISTER then EL2 else PSTATE.EL; - top = AddrTop(vaddress, FALSE, el); - bottom = if DBGWVR_EL1[n][2] == '1' then 2 else 3; // Word or doubleword - byte_select_match = (DBGWCR_EL1[n].BAS[UInt(vaddress[bottom-1:0])] != '0'); - mask = UInt(DBGWCR_EL1[n].MASK); - - // If DBGWCR_EL1[n].MASK is non-zero value and DBGWCR_EL1[n].BAS is not set to '11111111', or - // DBGWCR_EL1[n].BAS specifies a non-contiguous set of bytes behavior is CONSTRAINED - // UNPREDICTABLE. - if mask > 0 && !IsOnes(DBGWCR_EL1[n].BAS) then - byte_select_match = ConstrainUnpredictableBool(Unpredictable_WPMASKANDBAS); - else - LSB = (DBGWCR_EL1[n].BAS AND NOT(DBGWCR_EL1[n].BAS - 1)); MSB = (DBGWCR_EL1[n].BAS + LSB); - if !IsZero(MSB AND (MSB - 1)) then // Not contiguous - byte_select_match = ConstrainUnpredictableBool(Unpredictable_WPBASCONTIGUOUS); - bottom = 3; // For the whole doubleword - - // If the address mask is set to a reserved value, the behavior is CONSTRAINED UNPREDICTABLE. - if mask > 0 && mask <= 2 then - (c, mask) = ConstrainUnpredictableInteger(3, 31, Unpredictable_RESWPMASK); - assert c IN {Constraint_DISABLED, Constraint_NONE, Constraint_UNKNOWN}; - case c of - when Constraint_DISABLED return FALSE; // Disabled - when Constraint_NONE mask = 0; // No masking - // Otherwise the value returned by ConstrainUnpredictableInteger is a not-reserved value - - if mask > bottom then - WVR_match = (vaddress[top:mask] == DBGWVR_EL1[n][top:mask]); - // If masked bits of DBGWVR_EL1[n] are not zero, the behavior is CONSTRAINED UNPREDICTABLE. - if WVR_match && !IsZero(DBGWVR_EL1[n][mask-1:bottom]) then - WVR_match = ConstrainUnpredictableBool(Unpredictable_WPMASKEDBITS); - else - WVR_match = vaddress[top:bottom] == DBGWVR_EL1[n][top:bottom]; - - return WVR_match && byte_select_match; - -// AArch64.WatchpointMatch() -// ========================= -// Watchpoint matching in an AArch64 translation regime. - -boolean AArch64.WatchpointMatch(integer n, bits(64) vaddress, integer size, boolean ispriv, - AccType acctype, boolean iswrite) - assert !ELUsingAArch32(S1TranslationRegime()); - assert n <= UInt(ID_AA64DFR0_EL1.WRPs); - - // "ispriv" is FALSE for LDTR/STTR instructions executed at EL1 and all - // load/stores at EL0, TRUE for all other load/stores. "iswrite" is TRUE for stores, FALSE for - // loads. - enabled = DBGWCR_EL1[n].E == '1'; - linked = DBGWCR_EL1[n].WT == '1'; - isbreakpnt = FALSE; - - state_match = AArch64.StateMatch(DBGWCR_EL1[n].SSC, DBGWCR_EL1[n].HMC, DBGWCR_EL1[n].PAC, - linked, DBGWCR_EL1[n].LBN, isbreakpnt, acctype, ispriv); - - ls_match = (DBGWCR_EL1[n].LSC[(if iswrite then 1 else 0)] == '1'); - - value_match = FALSE; - for byte = 0 to size - 1 - value_match = value_match || AArch64.WatchpointByteMatch(n, acctype, vaddress + byte); - - return value_match && state_match && ls_match && enabled; - -// AArch64.CheckWatchpoint() -// ========================= -// Called before accessing the memory location of "size" bytes at "address", -// when either debug exceptions are enabled for the access, or halting debug -// is enabled and halting is allowed. - -FaultRecord AArch64.CheckWatchpoint(bits(64) vaddress, AccType acctype, - boolean iswrite, integer size) - assert !ELUsingAArch32(S1TranslationRegime()); - - match = FALSE; - ispriv = AArch64.AccessIsPrivileged(acctype); - - for i = 0 to UInt(ID_AA64DFR0_EL1.WRPs) - match = match || AArch64.WatchpointMatch(i, vaddress, size, ispriv, acctype, iswrite); - - if match && HaltOnBreakpointOrWatchpoint() then - if acctype != AccType_NONFAULT && acctype != AccType_CNOTFIRST then - reason = DebugHalt_Watchpoint; - Halt(reason); - else - // Fault will be reported and cancelled - return AArch64.DebugFault(acctype, iswrite); - elsif match then - return AArch64.DebugFault(acctype, iswrite); - else - return AArch64.NoFault(); - -// AArch64.GenerateDebugExceptions() -// ================================= - -boolean AArch64.GenerateDebugExceptions() - return AArch64.GenerateDebugExceptionsFrom(PSTATE.EL, IsSecure(), PSTATE.D); - -// AArch64.CheckDebug() -// ==================== -// Called on each access to check for a debug exception or entry to Debug state. - -FaultRecord AArch64.CheckDebug(bits(64) vaddress, AccType acctype, boolean iswrite, integer size) - - FaultRecord fault = AArch64.NoFault(); - - d_side = (acctype != AccType_IFETCH); - if HaveNV2Ext() && acctype == AccType_NV2REGISTER then - mask = '0'; - generate_exception = AArch64.GenerateDebugExceptionsFrom(EL2, IsSecure(), mask) && MDSCR_EL1.MDE == '1'; - else - generate_exception = AArch64.GenerateDebugExceptions() && MDSCR_EL1.MDE == '1'; - halt = HaltOnBreakpointOrWatchpoint(); - - if generate_exception || halt then - if d_side then - fault = AArch64.CheckWatchpoint(vaddress, acctype, iswrite, size); - else - fault = AArch64.CheckBreakpoint(vaddress, acctype, size); - - return fault; - -// AArch64.ExecutingATS1xPInstr() -// ============================== -// Return TRUE if current instruction is AT S1E1R/WP - -boolean AArch64.ExecutingATS1xPInstr() - if !HavePrivATExt() then return FALSE; - - instr = ThisInstr(); - if instr[22+:10] == '1101010100' then - op1 = instr[16+:3]; - CRn = instr[12+:4]; - CRm = instr[8+:4]; - op2 = instr[5+:3]; - return op1 == '000' && CRn == '0111' && CRm == '1001' && op2 IN {'000','001'}; - else - return FALSE; - -// AArch64.CheckPermission() -// ========================= -// Function used for permission checking from AArch64 stage 1 translations - -FaultRecord AArch64.CheckPermission(Permissions perms, bits(64) vaddress, integer level, - bit NS, AccType acctype, boolean iswrite) - assert !ELUsingAArch32(S1TranslationRegime()); - - wxn = SCTLR[].WXN == '1'; - - if (PSTATE.EL == EL0 || - IsInHost() || - (PSTATE.EL == EL1 && !HaveNV2Ext()) || - (PSTATE.EL == EL1 && HaveNV2Ext() && (acctype != AccType_NV2REGISTER || !ELIsInHost(EL2)))) then - priv_r = TRUE; - priv_w = perms.ap[2] == '0'; - user_r = perms.ap[1] == '1'; - user_w = perms.ap[2:1] == '01'; - - ispriv = AArch64.AccessIsPrivileged(acctype); - - pan = if HavePANExt() then PSTATE.PAN else '0'; - if (EL2Enabled() && ((PSTATE.EL == EL1 && HaveNVExt() && HCR_EL2.[NV, NV1] == '11') || - (HaveNV2Ext() && acctype == AccType_NV2REGISTER && HCR_EL2.NV2 == '1'))) then - pan = '0'; - is_ldst = !(acctype IN {AccType_DC, AccType_DC_UNPRIV, AccType_AT, AccType_IFETCH}); - is_ats1xp = (acctype == AccType_AT && AArch64.ExecutingATS1xPInstr()); - if pan == '1' && user_r && ispriv && (is_ldst || is_ats1xp) then - priv_r = FALSE; - priv_w = FALSE; - - user_xn = perms.xn == '1' || (user_w && wxn); - priv_xn = perms.pxn == '1' || (priv_w && wxn) || user_w; - - if ispriv then - (r, w, xn) = (priv_r, priv_w, priv_xn); - else - (r, w, xn) = (user_r, user_w, user_xn); - else - // Access from EL2 or EL3 - r = TRUE; - w = perms.ap[2] == '0'; - xn = perms.xn == '1' || (w && wxn); - - // Restriction on Secure instruction fetch - if HaveEL(EL3) && IsSecure() && NS == '1' && SCR_EL3.SIF == '1' then - xn = TRUE; - - if acctype == AccType_IFETCH then - fail = xn; - failedread = TRUE; - elsif acctype IN { AccType_ATOMICRW, AccType_ORDEREDRW, AccType_ORDEREDATOMICRW } then - fail = !r || !w; - failedread = !r; - elsif iswrite then - fail = !w; - failedread = FALSE; - elsif acctype == AccType_DC && PSTATE.EL != EL0 then - // DC maintenance instructions operating by VA, cannot fault from stage 1 translation, - // other than DC IVAC, which requires write permission, and operations executed at EL0, - // which require read permission. - fail = FALSE; - else - fail = !r; - failedread = TRUE; - - if fail then - secondstage = FALSE; - s2fs1walk = FALSE; - ipaddress = bits(52) UNKNOWN; - return AArch64.PermissionFault(ipaddress,boolean UNKNOWN, level, acctype, - !failedread, secondstage, s2fs1walk); - else - return AArch64.NoFault(); - -// AArch64.TranslateAddressS1Off() -// =============================== -// Called for stage 1 translations when translation is disabled to supply a default translation. -// Note that there are additional constraints on instruction prefetching that are not described in -// this pseudocode. - -TLBRecord AArch64.TranslateAddressS1Off(bits(64) vaddress, AccType acctype, boolean iswrite) - assert !ELUsingAArch32(S1TranslationRegime()); - - TLBRecord result; - result.descupdate.AF = FALSE; - result.descupdate.AP = FALSE; - - Top = AddrTop(vaddress, (acctype == AccType_IFETCH), PSTATE.EL); - if !IsZero(vaddress[Top:PAMax()]) then - level = 0; - ipaddress = bits(52) UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - result.addrdesc.fault = AArch64.AddressSizeFault(ipaddress,boolean UNKNOWN, level, acctype, - iswrite, secondstage, s2fs1walk); - return result; - - default_cacheable = (HasS2Translation() && HCR_EL2.DC == '1'); - - if default_cacheable then - // Use default cacheable settings - result.addrdesc.memattrs.memtype = MemType_Normal; - result.addrdesc.memattrs.inner.attrs = MemAttr_WB; // Write-back - result.addrdesc.memattrs.inner.hints = MemHint_RWA; - result.addrdesc.memattrs.shareable = FALSE; - result.addrdesc.memattrs.outershareable = FALSE; - result.addrdesc.memattrs.tagged = HCR_EL2.DCT == '1'; - elsif acctype != AccType_IFETCH then - // Treat data as Device - result.addrdesc.memattrs.memtype = MemType_Device; - result.addrdesc.memattrs.device = DeviceType_nGnRnE; - result.addrdesc.memattrs.inner = MemAttrHints UNKNOWN; - result.addrdesc.memattrs.tagged = FALSE; - else - // Instruction cacheability controlled by SCTLR_ELx.I - cacheable = SCTLR[].I == '1'; - result.addrdesc.memattrs.memtype = MemType_Normal; - if cacheable then - result.addrdesc.memattrs.inner.attrs = MemAttr_WT; - result.addrdesc.memattrs.inner.hints = MemHint_RA; - else - result.addrdesc.memattrs.inner.attrs = MemAttr_NC; - result.addrdesc.memattrs.inner.hints = MemHint_No; - result.addrdesc.memattrs.shareable = TRUE; - result.addrdesc.memattrs.outershareable = TRUE; - result.addrdesc.memattrs.tagged = FALSE; - - result.addrdesc.memattrs.outer = result.addrdesc.memattrs.inner; - - result.addrdesc.memattrs = MemAttrDefaults(result.addrdesc.memattrs); - - result.perms.ap = bits(3) UNKNOWN; - result.perms.xn = '0'; - result.perms.pxn = '0'; - - result.nG = bit UNKNOWN; - result.contiguous = boolean UNKNOWN; - result.domain = bits(4) UNKNOWN; - result.level = integer UNKNOWN; - result.blocksize = integer UNKNOWN; - result.addrdesc.paddress.address = vaddress[51:0]; - result.addrdesc.paddress.NS = if IsSecure() then '0' else '1'; - result.addrdesc.fault = AArch64.NoFault(); - return result; - -boolean InGuardedPage; - -// AArch64.FirstStageTranslate() -// ============================= -// Perform a stage 1 translation walk. The function used by Address Translation operations is -// similar except it uses the translation regime specified for the instruction. - -AddressDescriptor AArch64.FirstStageTranslate(bits(64) vaddress, AccType acctype, boolean iswrite, - boolean wasaligned, integer size) - - if HaveNV2Ext() && acctype == AccType_NV2REGISTER then - s1_enabled = SCTLR_EL2.M == '1'; - elsif HasS2Translation() then - s1_enabled = HCR_EL2.TGE == '0' && HCR_EL2.DC == '0' && SCTLR_EL1.M == '1'; - else - s1_enabled = SCTLR[].M == '1'; - - ipaddress = bits(52) UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - - if s1_enabled then // First stage enabled - S1 = AArch64.TranslationTableWalk(ipaddress, TRUE, vaddress, acctype, iswrite, secondstage, - s2fs1walk, size); - permissioncheck = TRUE; - if acctype == AccType_IFETCH then - InGuardedPage = S1.GP == '1'; // Global state updated on instruction fetch that denotes - // if the fetched instruction is from a guarded page. - else - S1 = AArch64.TranslateAddressS1Off(vaddress, acctype, iswrite); - permissioncheck = FALSE; - - if !IsFault(S1.addrdesc) && UsingAArch32() && HaveTrapLoadStoreMultipleDeviceExt() && AArch32.ExecutingLSMInstr() then - if S1.addrdesc.memattrs.memtype == MemType_Device && S1.addrdesc.memattrs.device != DeviceType_GRE then - nTLSMD = if S1TranslationRegime() == EL2 then SCTLR_EL2.nTLSMD else SCTLR_EL1.nTLSMD; - if nTLSMD == '0' then - S1.addrdesc.fault = AArch64.AlignmentFault(acctype, iswrite, secondstage); - - // Check for unaligned data accesses to Device memory - if ((!wasaligned && acctype != AccType_IFETCH) || (acctype == AccType_DCZVA)) - && !IsFault(S1.addrdesc) && S1.addrdesc.memattrs.memtype == MemType_Device then - S1.addrdesc.fault = AArch64.AlignmentFault(acctype, iswrite, secondstage); - if !IsFault(S1.addrdesc) && permissioncheck then - S1.addrdesc.fault = AArch64.CheckPermission(S1.perms, vaddress, S1.level, - S1.addrdesc.paddress.NS, - acctype, iswrite); - - // Check for instruction fetches from Device memory not marked as execute-never. If there has - // not been a Permission Fault then the memory is not marked execute-never. - if (!IsFault(S1.addrdesc) && S1.addrdesc.memattrs.memtype == MemType_Device && - acctype == AccType_IFETCH) then - S1.addrdesc = AArch64.InstructionDevice(S1.addrdesc, vaddress, ipaddress, S1.level, - acctype, iswrite, - secondstage, s2fs1walk); - // Check and update translation table descriptor if required - hwupdatewalk = FALSE; - s2fs1walk = FALSE; - S1.addrdesc.fault = AArch64.CheckAndUpdateDescriptor(S1.descupdate, S1.addrdesc.fault, - secondstage, vaddress, acctype, - iswrite, s2fs1walk, hwupdatewalk); - - return S1.addrdesc; - -// AArch64.FullTranslate() -// ======================= -// Perform both stage 1 and stage 2 translation walks for the current translation regime. The -// function used by Address Translation operations is similar except it uses the translation -// regime specified for the instruction. - -AddressDescriptor AArch64.FullTranslate(bits(64) vaddress, AccType acctype, boolean iswrite, - boolean wasaligned, integer size) - - // First Stage Translation - S1 = AArch64.FirstStageTranslate(vaddress, acctype, iswrite, wasaligned, size); - if !IsFault(S1) && !(HaveNV2Ext() && acctype == AccType_NV2REGISTER) && HasS2Translation() then - s2fs1walk = FALSE; - hwupdatewalk = FALSE; - result = AArch64.SecondStageTranslate(S1, vaddress, acctype, iswrite, wasaligned, s2fs1walk, - size, hwupdatewalk); - else - result = S1; - - return result; - -// AArch64.TranslateAddress() -// ========================== -// Main entry point for translating an address - -AddressDescriptor AArch64.TranslateAddress(bits(64) vaddress, AccType acctype, boolean iswrite, - boolean wasaligned, integer size) - - result = AArch64.FullTranslate(vaddress, acctype, iswrite, wasaligned, size); - - if !(acctype IN {AccType_PTW, AccType_IC, AccType_AT}) && !IsFault(result) then - result.fault = AArch64.CheckDebug(vaddress, acctype, iswrite, size); - - // Update virtual address for abort functions - result.vaddress = ZeroExtend(vaddress); - - return result; - -// AArch32.TranslateAddress() -// ========================== -// Main entry point for translating an address - -AddressDescriptor AArch32.TranslateAddress(bits(32) vaddress, AccType acctype, boolean iswrite, - boolean wasaligned, integer size) - - if !ELUsingAArch32(S1TranslationRegime()) then - return AArch64.TranslateAddress(ZeroExtend(vaddress, 64), acctype, iswrite, wasaligned, - size); - result = AArch32.FullTranslate(vaddress, acctype, iswrite, wasaligned, size); - - if !(acctype IN {AccType_PTW, AccType_IC, AccType_AT}) && !IsFault(result) then - result.fault = AArch32.CheckDebug(vaddress, acctype, iswrite, size); - - // Update virtual address for abort functions - result.vaddress = ZeroExtend(vaddress); - - return result; - -// AArch64.AllocationTagAccessIsEnabled() -// ====================================== -// Check whether access to Allocation Tags is enabled. - -boolean AArch64.AllocationTagAccessIsEnabled() - if SCR_EL3.ATA == '0' && PSTATE.EL IN {EL0, EL1, EL2} then - return FALSE; - elsif HCR_EL2.ATA == '0' && PSTATE.EL IN {EL0, EL1} && EL2Enabled() && HCR_EL2.[E2H,TGE] != '11' then - return FALSE; - elsif SCTLR_EL3.ATA == '0' && PSTATE.EL == EL3 then - return FALSE; - elsif SCTLR_EL2.ATA == '0' && PSTATE.EL == EL2 then - return FALSE; - elsif SCTLR_EL1.ATA == '0' && PSTATE.EL == EL1 then - return FALSE; - elsif SCTLR_EL2.ATA0 == '0' && PSTATE.EL == EL0 && EL2Enabled() && HCR_EL2.[E2H,TGE] == '11' then - return FALSE; - elsif SCTLR_EL1.ATA0 == '0' && PSTATE.EL == EL0 && !(EL2Enabled() && HCR_EL2.[E2H,TGE] == '11') then - return FALSE; - else - return TRUE; - -// EffectiveTBI() -// ============== -// Returns the effective TBI in the AArch64 stage 1 translation regime for "el". - -bit EffectiveTBI(bits(64) address, boolean IsInstr, bits(2) el) - assert HaveEL(el); - regime = S1TranslationRegime(el); - assert(!ELUsingAArch32(regime)); - - case regime of - when EL1 - tbi = if address[55] == '1' then TCR_EL1.TBI1 else TCR_EL1.TBI0; - if HavePACExt() then - tbid = if address[55] == '1' then TCR_EL1.TBID1 else TCR_EL1.TBID0; - when EL2 - if HaveVirtHostExt() && ELIsInHost(el) then - tbi = if address[55] == '1' then TCR_EL2.TBI1 else TCR_EL2.TBI0; - if HavePACExt() then - tbid = if address[55] == '1' then TCR_EL2.TBID1 else TCR_EL2.TBID0; - else - tbi = TCR_EL2.TBI; - if HavePACExt() then tbid = TCR_EL2.TBID; - when EL3 - tbi = TCR_EL3.TBI; - if HavePACExt() then tbid = TCR_EL3.TBID; - - return (if tbi == '1' && (!HavePACExt() || tbid == '0' || !IsInstr) then '1' else '0'); - -// EffectiveTCMA() -// =============== -// Returns the effective TCMA of a virtual address in the stage 1 translation regime for "el". - -bit EffectiveTCMA(bits(64) address, bits(2) el) - assert HaveEL(el); - regime = S1TranslationRegime(el); - assert(!ELUsingAArch32(regime)); - - case regime of - when EL1 - tcma = if address[55] == '1' then TCR_EL1.TCMA1 else TCR_EL1.TCMA0; - when EL2 - if HaveVirtHostExt() && ELIsInHost(el) then - tcma = if address[55] == '1' then TCR_EL2.TCMA1 else TCR_EL2.TCMA0; - else - tcma = TCR_EL2.TCMA; - when EL3 - tcma = TCR_EL3.TCMA; - - return tcma; - -// Returns True if the current instruction uses tag-checked memory access, -// False otherwise. -boolean IsTagCheckedInstruction(); - -// AArch64.AccessIsTagChecked() -// ============================ -// TRUE if a given access is tag-checked, FALSE otherwise. - -boolean AArch64.AccessIsTagChecked(bits(64) vaddr, AccType acctype) - if PSTATE.M[4] == '1' then return FALSE; - - if EffectiveTBI(vaddr, FALSE, PSTATE.EL) == '0' then - return FALSE; - - if EffectiveTCMA(vaddr, PSTATE.EL) == '1' && (vaddr[59:55] == '00000' || vaddr[59:55] == '11111') then - return FALSE; - - if !AArch64.AllocationTagAccessIsEnabled() then - return FALSE; - - if acctype IN {AccType_IFETCH, AccType_PTW} then - return FALSE; - - if acctype == AccType_NV2REGISTER then - return FALSE; - - if PSTATE.TCO=='1' then - return FALSE; - - if !IsTagCheckedInstruction() then - return FALSE; - - return TRUE; - -// This _MemTag[] accessor is the hardware operation which perform a single-copy atomic, -// Allocation Tag granule aligned, memory access from the tag in PA space. -// -// The function address the array using desc.paddress which supplies: -// * A 52-bit physical address -// * A single NS bit to select between Secure and Non-secure parts of the array. -// -// The accdesc descriptor describes the access type1: normal, exclusive, ordered, streaming, -// etc and other parameters required to access the physical memory or for setting syndrome -// register in the event of an external abort. -bits(4) _MemTag[AddressDescriptor desc, AccessDescriptor accdesc]; - -// This _MemTag[] accessor is the hardware operation which perform a single-copy atomic, -// Allocation Tag granule aligned, memory access to the tag in PA space. -// -// The functions address the array using desc.paddress which supplies: -// * A 52-bit physical address -// * A single NS bit to select between Secure and Non-secure parts of the array. -// -// The accdesc descriptor describes the access type1: normal, exclusive, ordered, streaming, -// etc and other parameters required to access the physical memory or for setting syndrome -// register in the event of an external abort. -_MemTag[AddressDescriptor desc, AccessDescriptor accdesc] = bits(4) value; - -// Workaround for type error in published spec. -// (Note that this will not work if MTE is enabled.) -bits(4) _MemTag[AddressDescriptor desc]; -_MemTag[AddressDescriptor desc] = bits(4) value; - -// AArch64.CheckTag() -// ================== -// Performs a Tag Check operation for a memory access and returns -// whether the check passed - -boolean AArch64.CheckTag(AddressDescriptor memaddrdesc, bits(4) ptag, boolean write) - if memaddrdesc.memattrs.tagged then - return ptag == _MemTag[memaddrdesc]; - else - return TRUE; - -// AArch64.PhysicalTag() -// ===================== -// Generate a Physical Tag from a Logical Tag in an address - -bits(4) AArch64.PhysicalTag(bits(64) vaddr) - return vaddr[59:56]; - -// AArch64.EffectiveTCF() -// ====================== -// Returns the TCF field applied to Tag Check Fails in the given Exception Level. - -bits(2) AArch64.EffectiveTCF(bits(2) el) - bits(2) tcf; - - if el == EL3 then - tcf = SCTLR_EL3.TCF; - elsif el == EL2 then - tcf = SCTLR_EL2.TCF; - elsif el == EL1 then - tcf = SCTLR_EL1.TCF; - elsif el == EL0 && HCR_EL2.[E2H,TGE] == '11' then - tcf = SCTLR_EL2.TCF0; - elsif el == EL0 && HCR_EL2.[E2H,TGE] != '11' then - tcf = SCTLR_EL1.TCF0; - - if tcf == '11' then - (-,tcf) = ConstrainUnpredictableBits(Unpredictable_RESTCF); - - return tcf; - -// AArch64.ReportTagCheckFail() -// ============================ -// Records a tag fail exception into the appropriate TCFR_ELx. - -AArch64.ReportTagCheckFail(bits(2) el, bit ttbr) - if el == EL3 then - assert ttbr == '0'; - TFSR_EL3.TF0 = '1'; - elsif el == EL2 then - if ttbr == '0' then - TFSR_EL2.TF0 = '1'; - else - TFSR_EL2.TF1 = '1'; - elsif el == EL1 then - if ttbr == '0' then - TFSR_EL1.TF0 = '1'; - else - TFSR_EL1.TF1 = '1'; - elsif el == EL0 then - if ttbr == '0' then - TFSRE0_EL1.TF0 = '1'; - else - TFSRE0_EL1.TF1 = '1'; - -// AArch64.TagCheckFault() -// ======================= -// Raise a tag check fail exception. - -AArch64.TagCheckFault(bits(64) va, boolean write) - bits(2) target_el; - bits(64) preferred_exception_return = ThisInstrAddr(); - integer vect_offset = 0x0; - - if PSTATE.EL == EL0 then - target_el = if HCR_EL2.TGE == '0' then EL1 else EL2; - else - target_el = PSTATE.EL; - - exception = ExceptionSyndrome(Exception_DataAbort); - exception.syndrome[5:0] = '010001'; - if write then - exception.syndrome[6] = '1'; - exception.vaddress = bits(4) UNKNOWN : va[59:0]; - - AArch64.TakeException(target_el, exception, preferred_exception_return, vect_offset); - -// AArch64.TagCheckFail() -// ====================== -// Handle a tag check fail condition. - -AArch64.TagCheckFail(bits(64) vaddress, boolean iswrite) - bits(2) tcf = AArch64.EffectiveTCF(PSTATE.EL); - if tcf == '01' then - AArch64.TagCheckFault(vaddress, iswrite); - elsif tcf == '10' then - AArch64.ReportTagCheckFail(PSTATE.EL, vaddress[55]); - -// Align() -// ======= - -integer Align(integer x, integer y) - return y * (x DIV y); - -// Align() -// ======= - -bits(N) Align(bits(N) x, integer y) - return Align(UInt(x), y)[N-1:0]; - -// Clear the global Exclusives monitors for all PEs EXCEPT processorid if they -// record any part of the physical address region of size bytes starting at paddress. -// It is IMPLEMENTATION DEFINED whether the global Exclusives monitor for processorid -// is also cleared if it records any part of the address region. -ClearExclusiveByAddress(FullAddress paddress, integer processorid, integer size); - -// Return the ID of the currently executing PE. -integer ProcessorID(); - -// AArch32.MemSingle[] - non-assignment (read) form -// ================================================ -// Perform an atomic, little-endian read of 'size' bytes. - -bits(size*8) AArch32.MemSingle[bits(32) address, integer size, AccType acctype, boolean wasaligned] - assert size IN {1, 2, 4, 8, 16}; - assert address == Align(address, size); - - AddressDescriptor memaddrdesc; - bits(size*8) value; - iswrite = FALSE; - - memaddrdesc = AArch32.TranslateAddress(address, acctype, iswrite, wasaligned, size); - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - AArch32.Abort(address, memaddrdesc.fault); - - // Memory array access - accdesc = CreateAccessDescriptor(acctype); - if HaveMTEExt() then - if AArch64.AccessIsTagChecked(ZeroExtend(address, 64), acctype) then - bits(4) ptag = AArch64.PhysicalTag(ZeroExtend(address, 64)); - if !AArch64.CheckTag(memaddrdesc, ptag, iswrite) then - AArch64.TagCheckFail(ZeroExtend(address, 64), iswrite); - value = _Mem[memaddrdesc, size, accdesc]; - return value; - -// AArch32.MemSingle[] - assignment (write) form -// ============================================= -// Perform an atomic, little-endian write of 'size' bytes. - -AArch32.MemSingle[bits(32) address, integer size, AccType acctype, boolean wasaligned] = bits(size*8) value - assert size IN {1, 2, 4, 8, 16}; - assert address == Align(address, size); - - AddressDescriptor memaddrdesc; - iswrite = TRUE; - - memaddrdesc = AArch32.TranslateAddress(address, acctype, iswrite, wasaligned, size); - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - AArch32.Abort(address, memaddrdesc.fault); - - // Effect on exclusives - if memaddrdesc.memattrs.shareable then - ClearExclusiveByAddress(memaddrdesc.paddress, ProcessorID(), size); - - // Memory array access - accdesc = CreateAccessDescriptor(acctype); - if HaveMTEExt() then - if AArch64.AccessIsTagChecked(ZeroExtend(address, 64), acctype) then - bits(4) ptag = AArch64.PhysicalTag(ZeroExtend(address, 64)); - if !AArch64.CheckTag(memaddrdesc, ptag, iswrite) then - AArch64.TagCheckFail(ZeroExtend(address, 64), iswrite); - _Mem[memaddrdesc, size, accdesc] = value; - return; - -// AArch32.CheckITEnabled() -// ======================== -// Check whether the T32 IT instruction is disabled. - -AArch32.CheckITEnabled(bits(4) mask) - if PSTATE.EL == EL2 then - it_disabled = HSCTLR.ITD; - else - it_disabled = (if ELUsingAArch32(EL1) then SCTLR.ITD else SCTLR[].ITD); - if it_disabled == '1' then - if mask != '1000' then UNDEFINED; - - // Otherwise whether the IT block is allowed depends on hw1 of the next instruction. - next_instr = AArch32.MemSingle[NextInstrAddr(), 2, AccType_IFETCH, TRUE]; - - if next_instr IN {'11xxxxxxxxxxxxxx', '1011xxxxxxxxxxxx', '10100xxxxxxxxxxx', - '01001xxxxxxxxxxx', '010001xxx1111xxx', '010001xx1xxxx111'} then - // It is IMPLEMENTATION DEFINED whether the Undefined Instruction exception is - // taken on the IT instruction or the next instruction. This is not reflected in - // the pseudocode, which always takes the exception on the IT instruction. This - // also does not take into account cases where the next instruction is UNPREDICTABLE. - UNDEFINED; - - return; - -// AArch64.CheckIllegalState() -// =========================== -// Check PSTATE.IL bit and generate Illegal Execution state exception if set. - -AArch64.CheckIllegalState() - if PSTATE.IL == '1' then - route_to_el2 = PSTATE.EL == EL0 && EL2Enabled() && HCR_EL2.TGE == '1'; - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_IllegalState); - - if UInt(PSTATE.EL) > UInt(EL1) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.CheckIllegalState() -// =========================== -// Check PSTATE.IL bit and generate Illegal Execution state exception if set. - -AArch32.CheckIllegalState() - if AArch32.GeneralExceptionsToAArch64() then - AArch64.CheckIllegalState(); - elsif PSTATE.IL == '1' then - route_to_hyp = PSTATE.EL == EL0 && EL2Enabled() && HCR.TGE == '1'; - - bits(32) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x04; - - if PSTATE.EL == EL2 || route_to_hyp then - exception = ExceptionSyndrome(Exception_IllegalState); - if PSTATE.EL == EL2 then - AArch32.EnterHypMode(exception, preferred_exception_return, vect_offset); - else - AArch32.EnterHypMode(exception, preferred_exception_return, 0x14); - else - AArch32.TakeUndefInstrException(); - -// AArch32.CheckSETENDEnabled() -// ============================ -// Check whether the AArch32 SETEND instruction is disabled. - -AArch32.CheckSETENDEnabled() - if PSTATE.EL == EL2 then - setend_disabled = HSCTLR.SED; - else - setend_disabled = (if ELUsingAArch32(EL1) then SCTLR.SED else SCTLR[].SED); - if setend_disabled == '1' then - UNDEFINED; - - return; - -// AArch64.UndefinedFault() -// ======================== - -AArch64.UndefinedFault() - - route_to_el2 = PSTATE.EL == EL0 && EL2Enabled() && HCR_EL2.TGE == '1'; - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_Uncategorized); - - if UInt(PSTATE.EL) > UInt(EL1) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// AArch32.UndefinedFault() -// ======================== - -AArch32.UndefinedFault() - - if AArch32.GeneralExceptionsToAArch64() then AArch64.UndefinedFault(); - AArch32.TakeUndefInstrException(); - -enumeration SRType {SRType_LSL, SRType_LSR, SRType_ASR, SRType_ROR, SRType_RRX}; - -// ASR_C() -// ======= - -(bits(N), bit) ASR_C(bits(N) x, integer shift) - assert shift > 0; - extended_x = SignExtend(x, shift+N); - result = extended_x[shift+N-1:shift]; - carry_out = extended_x[shift-1]; - return (result, carry_out); - -// LSR_C() -// ======= - -(bits(N), bit) LSR_C(bits(N) x, integer shift) - assert shift > 0; - extended_x = ZeroExtend(x, shift+N); - result = extended_x[shift+N-1:shift]; - carry_out = extended_x[shift-1]; - return (result, carry_out); - -// LSR() -// ===== - -bits(N) LSR(bits(N) x, integer shift) - assert shift >= 0; - if shift == 0 then - result = x; - else - (result, -) = LSR_C(x, shift); - return result; - -// ROR_C() -// ======= - -(bits(N), bit) ROR_C(bits(N) x, integer shift) - assert shift != 0; - m = shift MOD N; - result = LSR(x,m) OR LSL(x,N-m); - carry_out = result[N-1]; - return (result, carry_out); - -// RRX_C() -// ======= - -(bits(N), bit) RRX_C(bits(N) x, bit carry_in) - result = carry_in : x[N-1:1]; - carry_out = x[0]; - return (result, carry_out); - -// Shift_C() -// ========= - -(bits(N), bit) Shift_C(bits(N) value, SRType srtype, integer amount, bit carry_in) - assert !(srtype == SRType_RRX && amount != 1); - - if amount == 0 then - (result, carry_out) = (value, carry_in); - else - case srtype of - when SRType_LSL - (result, carry_out) = LSL_C(value, amount); - when SRType_LSR - (result, carry_out) = LSR_C(value, amount); - when SRType_ASR - (result, carry_out) = ASR_C(value, amount); - when SRType_ROR - (result, carry_out) = ROR_C(value, amount); - when SRType_RRX - (result, carry_out) = RRX_C(value, carry_in); - - return (result, carry_out); - -// A32ExpandImm_C() -// ================ - -(bits(32), bit) A32ExpandImm_C(bits(12) imm12, bit carry_in) - - unrotated_value = ZeroExtend(imm12[7:0], 32); - (imm32, carry_out) = Shift_C(unrotated_value, SRType_ROR, 2*UInt(imm12[11:8]), carry_in); - - return (imm32, carry_out); - -// A32ExpandImm() -// ============== - -bits(32) A32ExpandImm(bits(12) imm12) - - // PSTATE.C argument to following function call does not affect the imm32 result. - (imm32, -) = A32ExpandImm_C(imm12, PSTATE.C); - - return imm32; - -// DecodeImmShift() -// ================ - -(SRType, integer) DecodeImmShift(bits(2) srtype, bits(5) imm5) - - case srtype of - when '00' - shift_t = SRType_LSL; shift_n = UInt(imm5); - when '01' - shift_t = SRType_LSR; shift_n = if imm5 == '00000' then 32 else UInt(imm5); - when '10' - shift_t = SRType_ASR; shift_n = if imm5 == '00000' then 32 else UInt(imm5); - when '11' - if imm5 == '00000' then - shift_t = SRType_RRX; shift_n = 1; - else - shift_t = SRType_ROR; shift_n = UInt(imm5); - - return (shift_t, shift_n); - -// DecodeRegShift() -// ================ - -SRType DecodeRegShift(bits(2) srtype) - case srtype of - when '00' shift_t = SRType_LSL; - when '01' shift_t = SRType_LSR; - when '10' shift_t = SRType_ASR; - when '11' shift_t = SRType_ROR; - return shift_t; - -// RRX() -// ===== - -bits(N) RRX(bits(N) x, bit carry_in) - (result, -) = RRX_C(x, carry_in); - return result; - -// Shift() -// ======= - -bits(N) Shift(bits(N) value, SRType srtype, integer amount, bit carry_in) - (result, -) = Shift_C(value, srtype, amount, carry_in); - return result; - -// T32ExpandImm_C() -// ================ - -(bits(32), bit) T32ExpandImm_C(bits(12) imm12, bit carry_in) - - if imm12[11:10] == '00' then - case imm12[9:8] of - when '00' - imm32 = ZeroExtend(imm12[7:0], 32); - when '01' - imm32 = '00000000' : imm12[7:0] : '00000000' : imm12[7:0]; - when '10' - imm32 = imm12[7:0] : '00000000' : imm12[7:0] : '00000000'; - when '11' - imm32 = imm12[7:0] : imm12[7:0] : imm12[7:0] : imm12[7:0]; - carry_out = carry_in; - else - unrotated_value = ZeroExtend('1':imm12[6:0], 32); - (imm32, carry_out) = ROR_C(unrotated_value, UInt(imm12[11:7])); - - return (imm32, carry_out); - -// T32ExpandImm() -// ============== - -bits(32) T32ExpandImm(bits(12) imm12) - - // PSTATE.C argument to following function call does not affect the imm32 result. - (imm32, -) = T32ExpandImm_C(imm12, PSTATE.C); - - return imm32; - -// AArch64.CheckCP15InstrCoarseTraps() -// =================================== -// Check for coarse-grained AArch32 CP15 traps in HSTR_EL2 and HCR_EL2. - -boolean AArch64.CheckCP15InstrCoarseTraps(integer CRn, integer nreg, integer CRm) - - // Check for coarse-grained Hyp traps - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then - // Check for MCR, MRC, MCRR and MRRC disabled by HSTR_EL2 - major = if nreg == 1 then CRn else CRm; - if !IsInHost() && !(major IN {4,14}) && HSTR_EL2[major] == '1' then - return TRUE; - - // Check for MRC and MCR disabled by HCR_EL2.TIDCP - if (HCR_EL2.TIDCP == '1' && nreg == 1 && - ((CRn == 9 && CRm IN {0,1,2, 5,6,7,8 }) || - (CRn == 10 && CRm IN {0,1, 4, 8 }) || - (CRn == 11 && CRm IN {0,1,2,3,4,5,6,7,8,15}))) then - return TRUE; - - return FALSE; - -// AArch32.CheckCP15InstrCoarseTraps() -// =================================== -// Check for coarse-grained CP15 traps in HSTR and HCR. - -boolean AArch32.CheckCP15InstrCoarseTraps(integer CRn, integer nreg, integer CRm) - - // Check for coarse-grained Hyp traps - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then - if PSTATE.EL == EL0 && !ELUsingAArch32(EL2) then - return AArch64.CheckCP15InstrCoarseTraps(CRn, nreg, CRm); - // Check for MCR, MRC, MCRR and MRRC disabled by HSTR - major = if nreg == 1 then CRn else CRm; - if !(major IN {4,14}) && HSTR[major] == '1' then - return TRUE; - - // Check for MRC and MCR disabled by HCR.TIDCP - if (HCR.TIDCP == '1' && nreg == 1 && - ((CRn == 9 && CRm IN {0,1,2, 5,6,7,8 }) || - (CRn == 10 && CRm IN {0,1, 4, 8 }) || - (CRn == 11 && CRm IN {0,1,2,3,4,5,6,7,8,15}))) then - return TRUE; - - return FALSE; - -// AArch32.CheckAlignment() -// ======================== - -boolean AArch32.CheckAlignment(bits(32) address, integer alignment, AccType acctype, - boolean iswrite) - - if PSTATE.EL == EL0 && !ELUsingAArch32(S1TranslationRegime()) then - A = SCTLR[].A; //use AArch64 register, when higher Exception level is using AArch64 - elsif PSTATE.EL == EL2 then - A = HSCTLR.A; - else - A = SCTLR.A; - aligned = (address == Align(address, alignment)); - atomic = acctype IN { AccType_ATOMIC, AccType_ATOMICRW, AccType_ORDEREDATOMIC, AccType_ORDEREDATOMICRW }; - ordered = acctype IN { AccType_ORDERED, AccType_ORDEREDRW, AccType_LIMITEDORDERED, AccType_ORDEREDATOMIC, AccType_ORDEREDATOMICRW }; - vector = acctype == AccType_VEC; - - // AccType_VEC is used for SIMD element alignment checks only - check = (atomic || ordered || vector || A == '1'); - - if check && !aligned then - secondstage = FALSE; - AArch32.Abort(address, AArch32.AlignmentFault(acctype, iswrite, secondstage)); - - return aligned; - -// An optional IMPLEMENTATION DEFINED test for an exclusive access to a virtual -// address region of size bytes starting at address. -// -// It is permitted (but not required) for this function to return FALSE and -// cause a store exclusive to fail if the virtual address region is not -// totally included within the region recorded by MarkExclusiveVA(). -// -// It is always safe to return TRUE which will check the physical address only. -boolean AArch32.IsExclusiveVA(bits(32) address, integer processorid, integer size); - -// Clear the local Exclusives monitor for the specified processorid. -ClearExclusiveLocal(integer processorid); - -// Return TRUE if the global Exclusives monitor for processorid includes all of -// the physical address region of size bytes starting at paddress. -boolean IsExclusiveGlobal(FullAddress paddress, integer processorid, integer size); - -// Return TRUE if the local Exclusives monitor for processorid includes all of -// the physical address region of size bytes starting at paddress. -boolean IsExclusiveLocal(FullAddress paddress, integer processorid, integer size); - -// AArch32.ExclusiveMonitorsPass() -// =============================== - -// Return TRUE if the Exclusives monitors for the current PE include all of the addresses -// associated with the virtual address region of size bytes starting at address. -// The immediately following memory write must be to the same addresses. - -boolean AArch32.ExclusiveMonitorsPass(bits(32) address, integer size) - - // It is IMPLEMENTATION DEFINED whether the detection of memory aborts happens - // before or after the check on the local Exclusives monitor. As a result a failure - // of the local monitor can occur on some implementations even if the memory - // access would give an memory abort. - - acctype = AccType_ATOMIC; - iswrite = TRUE; - - aligned = AArch32.CheckAlignment(address, size, acctype, iswrite); - - passed = AArch32.IsExclusiveVA(address, ProcessorID(), size); - if !passed then - return FALSE; - - memaddrdesc = AArch32.TranslateAddress(address, acctype, iswrite, aligned, size); - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - AArch32.Abort(address, memaddrdesc.fault); - - passed = IsExclusiveLocal(memaddrdesc.paddress, ProcessorID(), size); - ClearExclusiveLocal(ProcessorID()); - - if passed then - if memaddrdesc.memattrs.shareable then - passed = IsExclusiveGlobal(memaddrdesc.paddress, ProcessorID(), size); - - return passed; - -// Optionally record an exclusive access to the virtual address region of size bytes -// starting at address for processorid. -AArch32.MarkExclusiveVA(bits(32) address, integer processorid, integer size); - -// Record the physical address region of size bytes starting at paddress in -// the global Exclusives monitor for processorid. -MarkExclusiveGlobal(FullAddress paddress, integer processorid, integer size); - -// Record the physical address region of size bytes starting at paddress in -// the local Exclusives monitor for processorid. -MarkExclusiveLocal(FullAddress paddress, integer processorid, integer size); - -// AArch32.SetExclusiveMonitors() -// ============================== - -// Sets the Exclusives monitors for the current PE to record the addresses associated -// with the virtual address region of size bytes starting at address. - -AArch32.SetExclusiveMonitors(bits(32) address, integer size) - - acctype = AccType_ATOMIC; - iswrite = FALSE; - aligned = (address == Align(address, size)); - - memaddrdesc = AArch32.TranslateAddress(address, acctype, iswrite, aligned, size); - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - return; - - if memaddrdesc.memattrs.shareable then - MarkExclusiveGlobal(memaddrdesc.paddress, ProcessorID(), size); - - MarkExclusiveLocal(memaddrdesc.paddress, ProcessorID(), size); - - AArch32.MarkExclusiveVA(address, ProcessorID(), size); - -// D[] - non-assignment form -// ========================= - -bits(64) D[integer n] - assert n >= 0 && n <= 31; - base = (n MOD 2) * 64; - bits(128) vreg = V[n DIV 2]; - return vreg[base+63:base]; - -// D[] - assignment form -// ===================== - -D[integer n] = bits(64) value - assert n >= 0 && n <= 31; - base = (n MOD 2) * 64; - bits(128) vreg = V[n DIV 2]; - vreg[base+63:base] = value; - V[n DIV 2] = vreg; - return; - -array bits(64) _Dclone[0..31]; - -// CheckAdvSIMDEnabled() -// ===================== - -CheckAdvSIMDEnabled() - - fpexc_check = TRUE; - advsimd = TRUE; - - AArch32.CheckAdvSIMDOrFPEnabled(fpexc_check, advsimd); - // Return from CheckAdvSIMDOrFPEnabled() occurs only if Advanced SIMD access is permitted - - // Make temporary copy of D registers - // _Dclone[] is used as input data for instruction pseudocode - for i = 0 to 31 - _Dclone[i] = D[i]; - - return; - -// CheckAdvSIMDOrVFPEnabled() -// ========================== - -CheckAdvSIMDOrVFPEnabled(boolean include_fpexc_check, boolean advsimd) - AArch32.CheckAdvSIMDOrFPEnabled(include_fpexc_check, advsimd); - // Return from CheckAdvSIMDOrFPEnabled() occurs only if VFP access is permitted - return; - -// CheckCryptoEnabled32() -// ====================== - -CheckCryptoEnabled32() - CheckAdvSIMDEnabled(); - // Return from CheckAdvSIMDEnabled() occurs only if access is permitted - return; - -// CheckVFPEnabled() -// ================= - -CheckVFPEnabled(boolean include_fpexc_check) - advsimd = FALSE; - AArch32.CheckAdvSIMDOrFPEnabled(include_fpexc_check, advsimd); - // Return from CheckAdvSIMDOrFPEnabled() occurs only if VFP access is permitted - return; - -type FPCRType; - -// FPDefaultNaN() -// ============== - -bits(N) FPDefaultNaN() - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - sign = '0'; - bits(E) exp = Ones(E); - bits(F) frac = '1':Zeros(F-1); - return sign : exp : frac; - -enumeration FPExc {FPExc_InvalidOp, FPExc_DivideByZero, FPExc_Overflow, - FPExc_Underflow, FPExc_Inexact, FPExc_InputDenorm}; - -// FPInfinity() -// ============ - -bits(N) FPInfinity(bit sign) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - bits(E) exp = Ones(E); - bits(F) frac = Zeros(F); - return sign : exp : frac; - -// FPProcessException() -// ==================== -// -// The 'fpcr' argument supplies FPCR control bits. Status information is -// updated directly in the FPSR where appropriate. - -FPProcessException(FPExc exception, FPCRType fpcr) - // Determine the cumulative exception bit number - case exception of - when FPExc_InvalidOp cumul = 0; - when FPExc_DivideByZero cumul = 1; - when FPExc_Overflow cumul = 2; - when FPExc_Underflow cumul = 3; - when FPExc_Inexact cumul = 4; - when FPExc_InputDenorm cumul = 7; - enable = cumul + 8; - if fpcr[enable] == '1' then - // Trapping of the exception enabled. - // It is IMPLEMENTATION DEFINED whether the enable bit may be set at all, and - // if so then how exceptions may be accumulated before calling FPTrappedException() - IMPLEMENTATION_DEFINED "floating-point trap handling"; - elsif UsingAArch32() then - // Set the cumulative exception bit - FPSCR[cumul] = '1'; - else - // Set the cumulative exception bit - FPSR[cumul] = '1'; - return; - -enumeration FPType {FPType_Nonzero, FPType_Zero, FPType_Infinity, - FPType_QNaN, FPType_SNaN}; - -// FPProcessNaN() -// ============== - -bits(N) FPProcessNaN(FPType fptype, bits(N) op, FPCRType fpcr) - assert N IN {16,32,64}; - assert fptype IN {FPType_QNaN, FPType_SNaN}; - - case N of - when 16 topfrac = 9; - when 32 topfrac = 22; - when 64 topfrac = 51; - - result = op; - if fptype == FPType_SNaN then - result[topfrac] = '1'; - FPProcessException(FPExc_InvalidOp, fpcr); - if fpcr.DN == '1' then // DefaultNaN requested - result = FPDefaultNaN(); - return result; - -// FPProcessNaNs() -// =============== -// -// The boolean part of the return value says whether a NaN has been found and -// processed. The bits(N) part is only relevant if it has and supplies the -// result of the operation. -// -// The 'fpcr' argument supplies FPCR control bits. Status information is -// updated directly in the FPSR where appropriate. - -(boolean, bits(N)) FPProcessNaNs(FPType type1, FPType type2, - bits(N) op1, bits(N) op2, - FPCRType fpcr) - assert N IN {16,32,64}; - if type1 == FPType_SNaN then - done = TRUE; result = FPProcessNaN(type1, op1, fpcr); - elsif type2 == FPType_SNaN then - done = TRUE; result = FPProcessNaN(type2, op2, fpcr); - elsif type1 == FPType_QNaN then - done = TRUE; result = FPProcessNaN(type1, op1, fpcr); - elsif type2 == FPType_QNaN then - done = TRUE; result = FPProcessNaN(type2, op2, fpcr); - else - done = FALSE; result = Zeros(); // 'Don't care' result - return (done, result); - -// FPMaxNormal() -// ============= - -bits(N) FPMaxNormal(bit sign) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - exp = Ones(E-1):'0'; - frac = Ones(F); - return sign : exp : frac; - -enumeration FPRounding {FPRounding_TIEEVEN, FPRounding_POSINF, - FPRounding_NEGINF, FPRounding_ZERO, - FPRounding_TIEAWAY, FPRounding_ODD}; - -// FPDecodeRounding() -// ================== - -// Decode floating-point rounding mode and common AArch64 encoding. - -FPRounding FPDecodeRounding(bits(2) rmode) - case rmode of - when '00' return FPRounding_TIEEVEN; // N - when '01' return FPRounding_POSINF; // P - when '10' return FPRounding_NEGINF; // M - when '11' return FPRounding_ZERO; // Z - -// FPRoundingMode() -// ================ - -// Return the current floating-point rounding mode. - -FPRounding FPRoundingMode(FPCRType fpcr) - return FPDecodeRounding(fpcr.RMode); - -// FPZero() -// ======== - -bits(N) FPZero(bit sign) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - exp = Zeros(E); - frac = Zeros(F); - return sign : exp : frac; - -// Max() -// ===== - -integer Max(integer a, integer b) - return if a >= b then a else b; - -// Max() -// ===== - -real Max(real a, real b) - return if a >= b then a else b; - -// FPRound() -// ========= -// Used by data processing and int/fixed [-] FP conversion instructions. -// For half-precision data it ignores AHP, and observes FZ16. - -bits(N) FPRound(real op, FPCRType fpcr, FPRounding rounding) - fpcr.AHP = '0'; - boolean isbfloat = FALSE; - return FPRoundBase(op, fpcr, rounding, isbfloat); - -// Convert a real number OP into an N-bit floating-point value using the -// supplied rounding mode RMODE. - -bits(N) FPRoundBase(real op, FPCRType fpcr, FPRounding rounding, boolean isbfloat) - assert N IN {16,32,64}; - assert op != 0.0; - assert rounding != FPRounding_TIEAWAY; - bits(N) result; - - // Obtain format parameters - minimum exponent, numbers of exponent and fraction bits. - if N == 16 then - minimum_exp = -14; E = 5; F = 10; - elsif N == 32 && isbfloat then - minimum_exp = -126; E = 8; F = 7; - elsif N == 32 then - minimum_exp = -126; E = 8; F = 23; - else // N == 64 - minimum_exp = -1022; E = 11; F = 52; - - // Split value into sign, unrounded mantissa and exponent. - if op < 0.0 then - sign = '1'; mantissa = -op; - else - sign = '0'; mantissa = op; - exponent = 0; - while mantissa < 1.0 do - mantissa = mantissa * 2.0; exponent = exponent - 1; - while mantissa >= 2.0 do - mantissa = mantissa / 2.0; exponent = exponent + 1; - - // Deal with flush-to-zero. - if ((fpcr.FZ == '1' && N != 16) || (fpcr.FZ16 == '1' && N == 16)) && exponent < minimum_exp then - // Flush-to-zero never generates a trapped exception - if UsingAArch32() then - FPSCR.UFC = '1'; - else - FPSR.UFC = '1'; - return FPZero(sign); - - // Start creating the exponent value for the result. Start by biasing the actual exponent - // so that the minimum exponent becomes 1, lower values 0 (indicating possible underflow). - biased_exp = Max(exponent - minimum_exp + 1, 0); - if biased_exp == 0 then mantissa = mantissa / 2.0^(minimum_exp - exponent); - - // Get the unrounded mantissa as an integer, and the "units in last place" rounding error. - int_mant = RoundDown(mantissa * 2.0^F); // < 2.0^F if biased_exp == 0, >= 2.0^F if not - error = mantissa * 2.0^F - Real(int_mant); - - // Underflow occurs if exponent is too small before rounding, and result is inexact or - // the Underflow exception is trapped. - if biased_exp == 0 && (error != 0.0 || fpcr.UFE == '1') then - FPProcessException(FPExc_Underflow, fpcr); - - // Round result according to rounding mode. - case rounding of - when FPRounding_TIEEVEN - round_up = (error > 0.5 || (error == 0.5 && int_mant[0] == '1')); - overflow_to_inf = TRUE; - when FPRounding_POSINF - round_up = (error != 0.0 && sign == '0'); - overflow_to_inf = (sign == '0'); - when FPRounding_NEGINF - round_up = (error != 0.0 && sign == '1'); - overflow_to_inf = (sign == '1'); - when FPRounding_ZERO, FPRounding_ODD - round_up = FALSE; - overflow_to_inf = FALSE; - - if round_up then - int_mant = int_mant + 1; - if int_mant == 2^F then // Rounded up from denormalized to normalized - biased_exp = 1; - if int_mant == 2^(F+1) then // Rounded up to next exponent - biased_exp = biased_exp + 1; int_mant = int_mant DIV 2; - - // Handle rounding to odd aka Von Neumann rounding - if error != 0.0 && rounding == FPRounding_ODD then - int_mant[0] = '1'; - - // Deal with overflow and generate result. - if N != 16 || fpcr.AHP == '0' then // Single, double or IEEE half precision - if biased_exp >= 2^E - 1 then - result = if overflow_to_inf then FPInfinity(sign) else FPMaxNormal(sign); - FPProcessException(FPExc_Overflow, fpcr); - error = 1.0; // Ensure that an Inexact exception occurs - else - result = sign : biased_exp[E-1:0] : int_mant[F-1:0] : Zeros(N-(E+F+1)); - else // Alternative half precision - if biased_exp >= 2^E then - result = sign : Ones(N-1); - FPProcessException(FPExc_InvalidOp, fpcr); - error = 0.0; // Ensure that an Inexact exception does not occur - else - result = sign : biased_exp[E-1:0] : int_mant[F-1:0] : Zeros(N-(E+F+1)); - - // Deal with Inexact exception. - if error != 0.0 then - FPProcessException(FPExc_Inexact, fpcr); - - return result; - -// FPRound() -// ========= - -bits(N) FPRound(real op, FPCRType fpcr) - return FPRound(op, fpcr, FPRoundingMode(fpcr)); - -// FPUnpackBase() -// ============== -// -// Unpack a floating-point number into its type1, sign bit and the real number -// that it represents. The real number result has the correct sign for numbers -// and infinities, is very large in magnitude for infinities, and is 0.0 for -// NaNs. (These values are chosen to simplify the description of comparisons -// and conversions.) -// -// The 'fpcr' argument supplies FPCR control bits. Status information is -// updated directly in the FPSR where appropriate. - -(FPType, bit, real) FPUnpackBase(bits(N) fpval, FPCRType fpcr) - assert N IN {16,32,64}; - - if N == 16 then - sign = fpval[15]; - exp16 = fpval[14:10]; - frac16 = fpval[9:0]; - if IsZero(exp16) then - // Produce zero if value is zero or flush-to-zero is selected - if IsZero(frac16) || fpcr.FZ16 == '1' then - fptype = FPType_Zero; value = 0.0; - else - fptype = FPType_Nonzero; value = 2.0^-14 * (Real(UInt(frac16)) * 2.0^-10); - elsif IsOnes(exp16) && fpcr.AHP == '0' then // Infinity or NaN in IEEE format - if IsZero(frac16) then - fptype = FPType_Infinity; value = 2.0^1000000; - else - fptype = if frac16[9] == '1' then FPType_QNaN else FPType_SNaN; - value = 0.0; - else - fptype = FPType_Nonzero; - value = 2.0^(UInt(exp16)-15) * (1.0 + Real(UInt(frac16)) * 2.0^-10); - - elsif N == 32 then - - sign = fpval[31]; - exp32 = fpval[30:23]; - frac32 = fpval[22:0]; - if IsZero(exp32) then - // Produce zero if value is zero or flush-to-zero is selected. - if IsZero(frac32) || fpcr.FZ == '1' then - fptype = FPType_Zero; value = 0.0; - if !IsZero(frac32) then // Denormalized input flushed to zero - FPProcessException(FPExc_InputDenorm, fpcr); - else - fptype = FPType_Nonzero; value = 2.0^-126 * (Real(UInt(frac32)) * 2.0^-23); - elsif IsOnes(exp32) then - if IsZero(frac32) then - fptype = FPType_Infinity; value = 2.0^1000000; - else - fptype = if frac32[22] == '1' then FPType_QNaN else FPType_SNaN; - value = 0.0; - else - fptype = FPType_Nonzero; - value = 2.0^(UInt(exp32)-127) * (1.0 + Real(UInt(frac32)) * 2.0^-23); - - else // N == 64 - - sign = fpval[63]; - exp64 = fpval[62:52]; - frac64 = fpval[51:0]; - if IsZero(exp64) then - // Produce zero if value is zero or flush-to-zero is selected. - if IsZero(frac64) || fpcr.FZ == '1' then - fptype = FPType_Zero; value = 0.0; - if !IsZero(frac64) then // Denormalized input flushed to zero - FPProcessException(FPExc_InputDenorm, fpcr); - else - fptype = FPType_Nonzero; value = 2.0^-1022 * (Real(UInt(frac64)) * 2.0^-52); - elsif IsOnes(exp64) then - if IsZero(frac64) then - fptype = FPType_Infinity; value = 2.0^1000000; - else - fptype = if frac64[51] == '1' then FPType_QNaN else FPType_SNaN; - value = 0.0; - else - fptype = FPType_Nonzero; - value = 2.0^(UInt(exp64)-1023) * (1.0 + Real(UInt(frac64)) * 2.0^-52); - - if sign == '1' then value = -value; - return (fptype, sign, value); - -// FPUnpack() -// ========== -// -// Used by data processing and int/fixed [-] FP conversion instructions. -// For half-precision data it ignores AHP, and observes FZ16. - -(FPType, bit, real) FPUnpack(bits(N) fpval, FPCRType fpcr) - fpcr.AHP = '0'; - (fp_type, sign, value) = FPUnpackBase(fpval, fpcr); - return (fp_type, sign, value); - -// FPHalvedSub() -// ============= - -bits(N) FPHalvedSub(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - rounding = FPRoundingMode(fpcr); - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - inf1 = (type1 == FPType_Infinity); inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); zero2 = (type2 == FPType_Zero); - if inf1 && inf2 && sign1 == sign2 then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - elsif (inf1 && sign1 == '0') || (inf2 && sign2 == '1') then - result = FPInfinity('0'); - elsif (inf1 && sign1 == '1') || (inf2 && sign2 == '0') then - result = FPInfinity('1'); - elsif zero1 && zero2 && sign1 != sign2 then - result = FPZero(sign1); - else - result_value = (value1 - value2) / 2.0; - if result_value == 0.0 then // Sign of exact zero result depends on rounding mode - result_sign = if rounding == FPRounding_NEGINF then '1' else '0'; - result = FPZero(result_sign); - else - result = FPRound(result_value, fpcr); - return result; - -// FPMul() -// ======= - -bits(N) FPMul(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - inf1 = (type1 == FPType_Infinity); - inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); - zero2 = (type2 == FPType_Zero); - if (inf1 && zero2) || (zero1 && inf2) then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - elsif inf1 || inf2 then - result = FPInfinity(sign1 EOR sign2); - elsif zero1 || zero2 then - result = FPZero(sign1 EOR sign2); - else - result = FPRound(value1*value2, fpcr); - return result; - -// FPThree() -// ========= - -bits(N) FPThree(bit sign) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - exp = '1':Zeros(E-1); - frac = '1':Zeros(F-1); - return sign : exp : frac; - -// StandardFPSCRValue() -// ==================== - -FPCRType StandardFPSCRValue() - return '00000' : FPSCR.AHP : '110000' : FPSCR.FZ16 : '0000000000000000000'; - -// FPRSqrtStep() -// ============= - -bits(N) FPRSqrtStep(bits(N) op1, bits(N) op2) - assert N IN {16,32}; - FPCRType fpcr = StandardFPSCRValue(); - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - inf1 = (type1 == FPType_Infinity); inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); zero2 = (type2 == FPType_Zero); - bits(N) product; - if (inf1 && zero2) || (zero1 && inf2) then - product = FPZero('0'); - else - product = FPMul(op1, op2, fpcr); - bits(N) three = FPThree('0'); - result = FPHalvedSub(three, product, fpcr); - return result; - -// FPSub() -// ======= - -bits(N) FPSub(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - rounding = FPRoundingMode(fpcr); - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - inf1 = (type1 == FPType_Infinity); - inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); - zero2 = (type2 == FPType_Zero); - if inf1 && inf2 && sign1 == sign2 then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - elsif (inf1 && sign1 == '0') || (inf2 && sign2 == '1') then - result = FPInfinity('0'); - elsif (inf1 && sign1 == '1') || (inf2 && sign2 == '0') then - result = FPInfinity('1'); - elsif zero1 && zero2 && sign1 == NOT(sign2) then - result = FPZero(sign1); - else - result_value = value1 - value2; - if result_value == 0.0 then // Sign of exact zero result depends on rounding mode - result_sign = if rounding == FPRounding_NEGINF then '1' else '0'; - result = FPZero(result_sign); - else - result = FPRound(result_value, fpcr, rounding); - return result; - -// FPTwo() -// ======= - -bits(N) FPTwo(bit sign) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - exp = '1':Zeros(E-1); - frac = Zeros(F); - return sign : exp : frac; - -// FPRecipStep() -// ============= - -bits(N) FPRecipStep(bits(N) op1, bits(N) op2) - assert N IN {16,32}; - FPCRType fpcr = StandardFPSCRValue(); - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - inf1 = (type1 == FPType_Infinity); inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); zero2 = (type2 == FPType_Zero); - bits(N) product; - if (inf1 && zero2) || (zero1 && inf2) then - product = FPZero('0'); - else - product = FPMul(op1, op2, fpcr); - bits(N) two = FPTwo('0'); - result = FPSub(two, product, fpcr); - return result; - -Hint_PreloadData(bits(32) address); - -Hint_PreloadDataForWrite(bits(32) address); - -Hint_PreloadInstr(bits(32) address); - -// BigEndian() -// =========== - -boolean BigEndian() - boolean bigend; - if UsingAArch32() then - bigend = (PSTATE.E != '0'); - elsif PSTATE.EL == EL0 then - bigend = (SCTLR[].E0E != '0'); - else - bigend = (SCTLR[].EE != '0'); - return bigend; - -// Mem_with_type[] - non-assignment (read) form -// ============================================ -// Perform a read of 'size' bytes. The access byte order is reversed for a big-endian access. -// Instruction fetches would call AArch32.MemSingle directly. - -bits(size*8) Mem_with_type[bits(32) address, integer size, AccType acctype] - assert size IN {1, 2, 4, 8, 16}; - bits(size*8) value; - boolean iswrite = FALSE; - - aligned = AArch32.CheckAlignment(address, size, acctype, iswrite); - if !aligned then - assert size > 1; - value[7:0] = AArch32.MemSingle[address, 1, acctype, aligned]; - - // For subsequent bytes it is CONSTRAINED UNPREDICTABLE whether an unaligned Device memory - // access will generate an Alignment Fault, as to get this far means the first byte did - // not, so we must be changing to a new translation page. - c = ConstrainUnpredictable(Unpredictable_DEVPAGE2); - assert c IN {Constraint_FAULT, Constraint_NONE}; - if c == Constraint_NONE then aligned = TRUE; - - for i = 1 to size-1 - value[8*i+7:8*i] = AArch32.MemSingle[address+i, 1, acctype, aligned]; - else - value = AArch32.MemSingle[address, size, acctype, aligned]; - - if BigEndian() then - value = BigEndianReverse(value); - return value; - -// Mem_with_type[] - assignment (write) form -// ========================================= -// Perform a write of 'size' bytes. The byte order is reversed for a big-endian access. - -Mem_with_type[bits(32) address, integer size, AccType acctype] = bits(size*8) value - boolean iswrite = TRUE; - - if BigEndian() then - value = BigEndianReverse(value); - - aligned = AArch32.CheckAlignment(address, size, acctype, iswrite); - - if !aligned then - assert size > 1; - AArch32.MemSingle[address, 1, acctype, aligned] = value[7:0]; - - // For subsequent bytes it is CONSTRAINED UNPREDICTABLE whether an unaligned Device memory - // access will generate an Alignment Fault, as to get this far means the first byte did - // not, so we must be changing to a new translation page. - c = ConstrainUnpredictable(Unpredictable_DEVPAGE2); - assert c IN {Constraint_FAULT, Constraint_NONE}; - if c == Constraint_NONE then aligned = TRUE; - - for i = 1 to size-1 - AArch32.MemSingle[address+i, 1, acctype, aligned] = value[8*i+7:8*i]; - else - AArch32.MemSingle[address, size, acctype, aligned] = value; - return; - -// MemA[] - non-assignment form -// ============================ - -bits(8*size) MemA[bits(32) address, integer size] - acctype = AccType_ATOMIC; - return Mem_with_type[address, size, acctype]; - -// MemA[] - assignment form -// ======================== - -MemA[bits(32) address, integer size] = bits(8*size) value - acctype = AccType_ATOMIC; - Mem_with_type[address, size, acctype] = value; - return; - -// MemO[] - non-assignment form -// ============================ - -bits(8*size) MemO[bits(32) address, integer size] - acctype = AccType_ORDERED; - return Mem_with_type[address, size, acctype]; - -// MemO[] - assignment form -// ======================== - -MemO[bits(32) address, integer size] = bits(8*size) value - acctype = AccType_ORDERED; - Mem_with_type[address, size, acctype] = value; - return; - -// MemU[] - non-assignment form -// ============================ - -bits(8*size) MemU[bits(32) address, integer size] - acctype = AccType_NORMAL; - return Mem_with_type[address, size, acctype]; - -// MemU[] - assignment form -// ======================== - -MemU[bits(32) address, integer size] = bits(8*size) value - acctype = AccType_NORMAL; - Mem_with_type[address, size, acctype] = value; - return; - -// MemU_unpriv[] - non-assignment form -// =================================== - -bits(8*size) MemU_unpriv[bits(32) address, integer size] - acctype = AccType_UNPRIV; - return Mem_with_type[address, size, acctype]; - -// MemU_unpriv[] - assignment form -// =============================== - -MemU_unpriv[bits(32) address, integer size] = bits(8*size) value - acctype = AccType_UNPRIV; - Mem_with_type[address, size, acctype] = value; - return; - -type AArch32.SErrorSyndrome is ( - bits(2) AET, - bit ExT -) - -// Return the SError syndrome -AArch32.SErrorSyndrome AArch32.PhysicalSErrorSyndrome(); - -// HaveAnyAArch64() -// ================ -// Return TRUE if AArch64 state is supported at any Exception level - -boolean HaveAnyAArch64() - return !HighestELUsingAArch32(); - -// AArch32.ReportDeferredSError() -// ============================== -// Return deferred SError syndrome - -bits(32) AArch32.ReportDeferredSError(bits(2) AET, bit ExT) - bits(32) target; - target[31] = '1'; // A - syndrome = Zeros(16); - if PSTATE.EL == EL2 then - syndrome[11:10] = AET; // AET - syndrome[9] = ExT; // EA - syndrome[5:0] = '010001'; // DFSC - else - syndrome[15:14] = AET; // AET - syndrome[12] = ExT; // ExT - syndrome[9] = TTBCR.EAE; // LPAE - if TTBCR.EAE == '1' then // Long-descriptor format - syndrome[5:0] = '010001'; // STATUS - else // Short-descriptor format - syndrome[10,3:0] = '10110'; // FS - if HaveAnyAArch64() then - target[24:0] = ZeroExtend(syndrome);// Any RES0 fields must be set to zero - else - target[15:0] = syndrome; - return target; - -// Return the SError syndrome -bits(25) AArch64.PhysicalSErrorSyndrome(boolean implicit_esb); - -// AArch64.ReportDeferredSError() -// ============================== -// Generate deferred SError syndrome - -bits(64) AArch64.ReportDeferredSError(bits(25) syndrome) - bits(64) target; - target[31] = '1'; // A - target[24] = syndrome[24]; // IDS - target[23:0] = syndrome[23:0]; // ISS - return target; - -// ExternalDebugInterruptsDisabled() -// ================================= -// Determine whether EDSCR disables interrupts routed to 'target' - -boolean ExternalDebugInterruptsDisabled(bits(2) target) - case target of - when EL3 - int_dis = EDSCR.INTdis == '11' && ExternalSecureInvasiveDebugEnabled(); - when EL2 - int_dis = EDSCR.INTdis == '1x' && ExternalInvasiveDebugEnabled(); - when EL1 - if IsSecure() then - int_dis = EDSCR.INTdis == '1x' && ExternalSecureInvasiveDebugEnabled(); - else - int_dis = EDSCR.INTdis != '00' && ExternalInvasiveDebugEnabled(); - return int_dis; - -// Return TRUE if a physical SError interrupt is pending -boolean IsPhysicalSErrorPending(); - -// AArch64.ESBOperation() -// ====================== -// Perform the AArch64 ESB operation, either for ESB executed in AArch64 state, or for -// ESB in AArch32 state when SError interrupts are routed to an Exception level using -// AArch64 - -AArch64.ESBOperation() - - route_to_el3 = HaveEL(EL3) && SCR_EL3.EA == '1'; - route_to_el2 = (EL2Enabled() && - (HCR_EL2.TGE == '1' || HCR_EL2.AMO == '1')); - - target = if route_to_el3 then EL3 elsif route_to_el2 then EL2 else EL1; - - if target == EL1 then - mask_active = PSTATE.EL IN {EL0, EL1}; - elsif HaveVirtHostExt() && target == EL2 && HCR_EL2.[E2H,TGE] == '11' then - mask_active = PSTATE.EL IN {EL0, EL2}; - else - mask_active = PSTATE.EL == target; - - mask_set = (PSTATE.A == '1' && (!HaveDoubleFaultExt() || SCR_EL3.EA == '0' || - PSTATE.EL != EL3 || SCR_EL3.NMEA == '0')); - intdis = Halted() || ExternalDebugInterruptsDisabled(target); - masked = (UInt(target) < UInt(PSTATE.EL)) || intdis || (mask_active && mask_set); - - // Check for a masked Physical SError pending - if IsPhysicalSErrorPending() && masked then - // This function might be called for an interworking case, and INTdis is masking - // the SError interrupt. - if ELUsingAArch32(S1TranslationRegime()) then - syndrome32 = AArch32.PhysicalSErrorSyndrome(); - DISR = AArch32.ReportDeferredSError(syndrome32.AET, syndrome32.ExT); - else - implicit_esb = FALSE; - syndrome64 = AArch64.PhysicalSErrorSyndrome(implicit_esb); - DISR_EL1 = AArch64.ReportDeferredSError(syndrome64); - ClearPendingPhysicalSError(); // Set ISR_EL1.A to 0 - - return; - -// AArch32.ESBOperation() -// ====================== -// Perform the AArch32 ESB operation for ESB executed in AArch32 state - -AArch32.ESBOperation() - - // Check if routed to AArch64 state - route_to_aarch64 = PSTATE.EL == EL0 && !ELUsingAArch32(EL1); - if !route_to_aarch64 && EL2Enabled() && !ELUsingAArch32(EL2) then - route_to_aarch64 = HCR_EL2.TGE == '1' || HCR_EL2.AMO == '1'; - if !route_to_aarch64 && HaveEL(EL3) && !ELUsingAArch32(EL3) then - route_to_aarch64 = SCR_EL3.EA == '1'; - - if route_to_aarch64 then - AArch64.ESBOperation(); - return; - - route_to_monitor = HaveEL(EL3) && ELUsingAArch32(EL3) && SCR.EA == '1'; - route_to_hyp = PSTATE.EL IN {EL0, EL1} && EL2Enabled() && (HCR.TGE == '1' || HCR.AMO == '1'); - - if route_to_monitor then - target = M32_Monitor; - elsif route_to_hyp || PSTATE.M == M32_Hyp then - target = M32_Hyp; - else - target = M32_Abort; - - if IsSecure() then - mask_active = TRUE; - elsif target == M32_Monitor then - mask_active = SCR.AW == '1' && (!HaveEL(EL2) || (HCR.TGE == '0' && HCR.AMO == '0')); - else - mask_active = target == M32_Abort || PSTATE.M == M32_Hyp; - - mask_set = PSTATE.A == '1'; - (-, el) = ELFromM32(target); - intdis = Halted() || ExternalDebugInterruptsDisabled(el); - masked = intdis || (mask_active && mask_set); - - // Check for a masked Physical SError pending - if IsPhysicalSErrorPending() && masked then - syndrome32 = AArch32.PhysicalSErrorSyndrome(); - DISR = AArch32.ReportDeferredSError(syndrome32.AET, syndrome32.ExT); - ClearPendingPhysicalSError(); - - return; - -// AArch64.vESBOperation() -// ======================= -// Perform the AArch64 ESB operation for virtual SError interrupts, either for ESB -// executed in AArch64 state, or for ESB in AArch32 state with EL2 using AArch64 state - -AArch64.vESBOperation() - assert PSTATE.EL IN {EL0, EL1} && EL2Enabled(); - - // If physical SError interrupts are routed to EL2, and TGE is not set, then a virtual - // SError interrupt might be pending - vSEI_enabled = HCR_EL2.TGE == '0' && HCR_EL2.AMO == '1'; - vSEI_pending = vSEI_enabled && HCR_EL2.VSE == '1'; - vintdis = Halted() || ExternalDebugInterruptsDisabled(EL1); - vmasked = vintdis || PSTATE.A == '1'; - - // Check for a masked virtual SError pending - if vSEI_pending && vmasked then - // This function might be called for the interworking case, and INTdis is masking - // the virtual SError interrupt. - if ELUsingAArch32(EL1) then - VDISR = AArch32.ReportDeferredSError(VDFSR[15:14], VDFSR[12]); - else - VDISR_EL2 = AArch64.ReportDeferredSError(VSESR_EL2[24:0]); - HCR_EL2.VSE = '0'; // Clear pending virtual SError - - return; - -// AArch32.vESBOperation() -// ======================= -// Perform the ESB operation for virtual SError interrupts executed in AArch32 state - -AArch32.vESBOperation() - assert PSTATE.EL IN {EL0, EL1} && EL2Enabled(); - - // Check for EL2 using AArch64 state - if !ELUsingAArch32(EL2) then - AArch64.vESBOperation(); - return; - - // If physical SError interrupts are routed to Hyp mode, and TGE is not set, then a - // virtual SError interrupt might be pending - vSEI_enabled = HCR.TGE == '0' && HCR.AMO == '1'; - vSEI_pending = vSEI_enabled && HCR.VA == '1'; - vintdis = Halted() || ExternalDebugInterruptsDisabled(EL1); - vmasked = vintdis || PSTATE.A == '1'; - - // Check for a masked virtual SError pending - if vSEI_pending && vmasked then - VDISR = AArch32.ReportDeferredSError(VDFSR[15:14], VDFSR[12]); - HCR.VA = '0'; // Clear pending virtual SError - - return; - -AArch32.ResetSystemRegisters(boolean cold_reset); - -bits(1) EventRegister; - -// SendEventLocal() -// ================ -// Set the local Event Register of this PE. -// When a PE executes the SEVL instruction, it causes this function to be executed - -SendEventLocal() - EventRegister = '1'; - return; - -// ELFromSPSR() -// ============ - -// Convert an SPSR value encoding to an Exception level. -// Returns (valid,EL): -// 'valid' is TRUE if 'spsr[4:0]' encodes a valid mode for the current state. -// 'EL' is the Exception level decoded from 'spsr'. - -(boolean,bits(2)) ELFromSPSR(bits(32) spsr) - if spsr[4] == '0' then // AArch64 state - el = spsr[3:2]; - if HighestELUsingAArch32() then // No AArch64 support - valid = FALSE; - elsif !HaveEL(el) then // Exception level not implemented - valid = FALSE; - elsif spsr[1] == '1' then // M[1] must be 0 - valid = FALSE; - elsif el == EL0 && spsr[0] == '1' then // for EL0, M[0] must be 0 - valid = FALSE; - elsif el == EL2 && HaveEL(EL3) && !IsSecureEL2Enabled() && SCR_EL3.NS == '0' then - valid = FALSE; // Unless Secure EL2 is enabled, EL2 only valid in Non-secure state - else - valid = TRUE; - elsif HaveAnyAArch32() then // AArch32 state - (valid, el) = ELFromM32(spsr[4:0]); - else - valid = FALSE; - - if !valid then el = bits(2) UNKNOWN; - return (valid,el); - -// ELUsingAArch32K() -// ================= - -(boolean,boolean) ELUsingAArch32K(bits(2) el) - return ELStateUsingAArch32K(el, IsSecureBelowEL3()); - -// IllegalExceptionReturn() -// ======================== - -boolean IllegalExceptionReturn(bits(32) spsr) - - // Check for illegal return: - // * To an unimplemented Exception level. - // * To EL2 in Secure state, when SecureEL2 is not enabled. - // * To EL0 using AArch64 state, with SPSR.M[0]==1. - // * To AArch64 state with SPSR.M[1]==1. - // * To AArch32 state with an illegal value of SPSR.M. - (valid, target) = ELFromSPSR(spsr); - if !valid then return TRUE; - - // Check for return to higher Exception level - if UInt(target) > UInt(PSTATE.EL) then return TRUE; - - spsr_mode_is_aarch32 = (spsr[4] == '1'); - - // Check for illegal return: - // * To EL1, EL2 or EL3 with register width specified in the SPSR different from the - // Execution state used in the Exception level being returned to, as determined by - // the SCR_EL3.RW or HCR_EL2.RW bits, or as configured from reset. - // * To EL0 using AArch64 state when EL1 is using AArch32 state as determined by the - // SCR_EL3.RW or HCR_EL2.RW bits or as configured from reset. - // * To AArch64 state from AArch32 state (should be caught by above) - (known, target_el_is_aarch32) = ELUsingAArch32K(target); - assert known || (target == EL0 && !ELUsingAArch32(EL1)); - if known && spsr_mode_is_aarch32 != target_el_is_aarch32 then return TRUE; - - // Check for illegal return from AArch32 to AArch64 - if UsingAArch32() && !spsr_mode_is_aarch32 then return TRUE; - - // Check for illegal return to EL1 when HCR.TGE is set and when either of - // * SecureEL2 is enabled. - // * SecureEL2 is not enabled and EL1 is in Non-secure state. - if HaveEL(EL2) && target == EL1 && HCR_EL2.TGE == '1' then - if (!IsSecureBelowEL3() || IsSecureEL2Enabled()) then return TRUE; - return FALSE; - -// Restarting() -// ============ - -boolean Restarting() - return EDSCR.STATUS == '000001'; // Restarting - -// DebugExceptionReturnSS() -// ======================== -// Returns value to write to PSTATE.SS on an exception return or Debug state exit. - -bit DebugExceptionReturnSS(bits(32) spsr) - assert Halted() || Restarting() || PSTATE.EL != EL0; - - SS_bit = '0'; - - if MDSCR_EL1.SS == '1' then - if Restarting() then - enabled_at_source = FALSE; - elsif UsingAArch32() then - enabled_at_source = AArch32.GenerateDebugExceptions(); - else - enabled_at_source = AArch64.GenerateDebugExceptions(); - - if IllegalExceptionReturn(spsr) then - dest = PSTATE.EL; - else - (valid, dest) = ELFromSPSR(spsr); assert valid; - - secure = IsSecureBelowEL3() || dest == EL3; - if ELUsingAArch32(dest) then - enabled_at_dest = AArch32.GenerateDebugExceptionsFrom(dest, secure); - else - mask = spsr[9]; - enabled_at_dest = AArch64.GenerateDebugExceptionsFrom(dest, secure, mask); - ELd = DebugTargetFrom(secure); - if !ELUsingAArch32(ELd) && !enabled_at_source && enabled_at_dest then - SS_bit = spsr[21]; - return SS_bit; - -// RestoredITBits() -// ================ -// Get the value of PSTATE.IT to be restored on this exception return. - -bits(8) RestoredITBits(bits(32) spsr) - it = spsr[15:10,26:25]; - - // When PSTATE.IL is set, it is CONSTRAINED UNPREDICTABLE whether the IT bits are each set - // to zero or copied from the SPSR. - if PSTATE.IL == '1' then - if ConstrainUnpredictableBool(Unpredictable_ILZEROIT) then return '00000000'; - else return it; - - // The IT bits are forced to zero when they are set to a reserved value. - if !IsZero(it[7:4]) && IsZero(it[3:0]) then - return '00000000'; - - // The IT bits are forced to zero when returning to A32 state, or when returning to an EL - // with the ITD bit set to 1, and the IT bits are describing a multi-instruction block. - itd = if PSTATE.EL == EL2 then HSCTLR.ITD else SCTLR.ITD; - if (spsr[5] == '0' && !IsZero(it)) || (itd == '1' && !IsZero(it[2:0])) then - return '00000000'; - else - return it; - -boolean ShouldAdvanceIT; - -// SetPSTATEFromPSR() -// ================== -// Set PSTATE based on a PSR value - -SetPSTATEFromPSR(bits(32) spsr) - PSTATE.SS = DebugExceptionReturnSS(spsr); - if IllegalExceptionReturn(spsr) then - PSTATE.IL = '1'; - if HaveSSBSExt() then PSTATE.SSBS = bit UNKNOWN; - else - // State that is reinstated only on a legal exception return - PSTATE.IL = spsr[20]; - if spsr[4] == '1' then // AArch32 state - AArch32.WriteMode(spsr[4:0]); // Sets PSTATE.EL correctly - if HaveSSBSExt() then PSTATE.SSBS = spsr[23]; - else // AArch64 state - PSTATE.nRW = '0'; - PSTATE.EL = spsr[3:2]; - PSTATE.SP = spsr[0]; - if HaveSSBSExt() then PSTATE.SSBS = spsr[12]; - - // If PSTATE.IL is set and returning to AArch32 state, it is CONSTRAINED UNPREDICTABLE whether - // the T bit is set to zero or copied from SPSR. - if PSTATE.IL == '1' && PSTATE.nRW == '1' then - if ConstrainUnpredictableBool(Unpredictable_ILZEROT) then spsr[5] = '0'; - - // State that is reinstated regardless of illegal exception return - PSTATE.[N,Z,C,V] = spsr[31:28]; - if HavePANExt() then PSTATE.PAN = spsr[22]; - if PSTATE.nRW == '1' then // AArch32 state - PSTATE.Q = spsr[27]; - PSTATE.IT = RestoredITBits(spsr); - ShouldAdvanceIT = FALSE; - if HaveDITExt() then PSTATE.DIT = (if Restarting() then spsr[24] else spsr[21]); - PSTATE.GE = spsr[19:16]; - PSTATE.E = spsr[9]; - PSTATE.[A,I,F] = spsr[8:6]; // No PSTATE.D in AArch32 state - PSTATE.T = spsr[5]; // PSTATE.J is RES0 - else // AArch64 state - if HaveMTEExt() then PSTATE.TCO = spsr[25]; - if HaveDITExt() then PSTATE.DIT = spsr[24]; - if HaveUAOExt() then PSTATE.UAO = spsr[23]; - if HaveBTIExt() then PSTATE.BTYPE = spsr[11:10]; - PSTATE.[D,A,I,F] = spsr[9:6]; // No PSTATE.[Q,IT,GE,E,T] in AArch64 state - return; - -// AArch32.ExceptionReturn() -// ========================= - -AArch32.ExceptionReturn(bits(32) new_pc, bits(32) spsr) - - SynchronizeContext(); - - // Attempts to change to an illegal mode or state will invoke the Illegal Execution state - // mechanism - SetPSTATEFromPSR(spsr); - ClearExclusiveLocal(ProcessorID()); - SendEventLocal(); - - if PSTATE.IL == '1' then - // If the exception return is illegal, PC[1:0] are UNKNOWN - new_pc[1:0] = bits(2) UNKNOWN; - else - // LR[1:0] or LR[0] are treated as being 0, depending on the target instruction set state - if PSTATE.T == '1' then - new_pc[0] = '0'; // T32 - else - new_pc[1:0] = '00'; // A32 - - BranchTo(new_pc, BranchType_ERET); - -// ALUExceptionReturn() -// ==================== - -ALUExceptionReturn(bits(32) address) - if PSTATE.EL == EL2 then - UNDEFINED; - elsif PSTATE.M IN {M32_User,M32_System} then - UNPREDICTABLE; // UNDEFINED or NOP - else - AArch32.ExceptionReturn(address, SPSR[]); - -// SelectInstrSet() -// ================ - -SelectInstrSet(InstrSet iset) - assert CurrentInstrSet() IN {InstrSet_A32, InstrSet_T32}; - assert iset IN {InstrSet_A32, InstrSet_T32}; - - PSTATE.T = if iset == InstrSet_A32 then '0' else '1'; - - return; - -// BXWritePC() -// =========== - -BXWritePC(bits(32) address, BranchType branch_type) - if address[0] == '1' then - SelectInstrSet(InstrSet_T32); - address[0] = '0'; - else - SelectInstrSet(InstrSet_A32); - // For branches to an unaligned PC counter in A32 state, the processor takes the branch - // and does one of: - // * Forces the address to be aligned - // * Leaves the PC unaligned, meaning the target generates a PC Alignment fault. - if address[1] == '1' && ConstrainUnpredictableBool(Unpredictable_A32FORCEALIGNPC) then - address[1] = '0'; - BranchTo(address, branch_type); - -// BranchWritePC() -// =============== - -BranchWritePC(bits(32) address, BranchType branch_type) - if CurrentInstrSet() == InstrSet_A32 then - address[1:0] = '00'; - else - address[0] = '0'; - BranchTo(address, branch_type); - -// ALUWritePC() -// ============ - -ALUWritePC(bits(32) address) - if CurrentInstrSet() == InstrSet_A32 then - BXWritePC(address, BranchType_INDIR); - else - BranchWritePC(address, BranchType_INDIR); - -// Din[] - non-assignment form -// =========================== - -bits(64) Din[integer n] - assert n >= 0 && n <= 31; - return _Dclone[n]; - -// LR - assignment form -// ==================== - -LR = bits(32) value - R[14] = value; - return; - -// LR - non-assignment form -// ======================== - -bits(32) LR - return R[14]; - -// LoadWritePC() -// ============= - -LoadWritePC(bits(32) address) - BXWritePC(address, BranchType_INDIR); - -// PC - non-assignment form -// ======================== - -bits(32) PC - return R[15]; // This includes the offset from AArch32 state - -// PCStoreValue() -// ============== - -bits(32) PCStoreValue() - // This function returns the PC value. On architecture versions before Armv7, it - // is permitted to instead return PC+4, provided it does so consistently. It is - // used only to describe A32 instructions, so it returns the address of the current - // instruction plus 8 (normally) or 12 (when the alternative is permitted). - return PC; - -// Qin[] - non-assignment form -// =========================== - -bits(128) Qin[integer n] - assert n >= 0 && n <= 15; - return Din[2*n+1]:Din[2*n]; - -// S[] - non-assignment form -// ========================= - -bits(32) S[integer n] - assert n >= 0 && n <= 31; - base = (n MOD 4) * 32; - bits(128) vreg = V[n DIV 4]; - return vreg[base+31:base]; - -// S[] - assignment form -// ===================== - -S[integer n] = bits(32) value - assert n >= 0 && n <= 31; - base = (n MOD 4) * 32; - bits(128) vreg = V[n DIV 4]; - vreg[base+31:base] = value; - V[n DIV 4] = vreg; - return; - -// AArch32.ExecutingCP10or11Instr() -// ================================ - -boolean AArch32.ExecutingCP10or11Instr() - instr = ThisInstr(); - instr_set = CurrentInstrSet(); - assert instr_set IN {InstrSet_A32, InstrSet_T32}; - - if instr_set == InstrSet_A32 then - return ((instr[27:24] == '1110' || instr[27:25] == '110') && instr[11:8] == '101x'); - else // InstrSet_T32 - return (instr[31:28] == '111x' && (instr[27:24] == '1110' || instr[27:25] == '110') && instr[11:8] == '101x'); - -// Read from a 32-bit AArch32 System register and return the register's contents. -bits(32) AArch32.SysRegRead(integer cp_num, bits(32) instr); - -// Read from a 64-bit AArch32 System register and return the register's contents. -bits(64) AArch32.SysRegRead64(integer cp_num, bits(32) instr); - -// AArch32.SysRegReadCanWriteAPSR() -// ================================ -// Determines whether the AArch32 System register read instruction can write to APSR flags. - -boolean AArch32.SysRegReadCanWriteAPSR(integer cp_num, bits(32) instr) - assert UsingAArch32(); - assert (cp_num IN {14,15}); - assert cp_num == UInt(instr[11:8]); - - opc1 = UInt(instr[23:21]); - opc2 = UInt(instr[7:5]); - CRn = UInt(instr[19:16]); - CRm = UInt(instr[3:0]); - - if cp_num == 14 && opc1 == 0 && CRn == 0 && CRm == 1 && opc2 == 0 then // DBGDSCRint - return TRUE; - - return FALSE; - -// Write to a 32-bit AArch32 System register. -AArch32.SysRegWrite(integer cp_num, bits(32) instr, bits(32) val); - -// Write to a 64-bit AArch32 System register. -AArch32.SysRegWrite64(integer cp_num, bits(32) instr, bits(64) val); - -// AArch32.WriteModeByInstr() -// ========================== -// Function for dealing with writes to PSTATE.M from an AArch32 instruction, and ensuring that -// illegal state changes are correctly flagged in PSTATE.IL. - -AArch32.WriteModeByInstr(bits(5) mode) - (valid,el) = ELFromM32(mode); - - // 'valid' is set to FALSE if' mode' is invalid for this implementation or the current value - // of SCR.NS/SCR_EL3.NS. Additionally, it is illegal for an instruction to write 'mode' to - // PSTATE.EL if it would result in any of: - // * A change to a mode that would cause entry to a higher Exception level. - if UInt(el) > UInt(PSTATE.EL) then - valid = FALSE; - - // * A change to or from Hyp mode. - if (PSTATE.M == M32_Hyp || mode == M32_Hyp) && PSTATE.M != mode then - valid = FALSE; - - // * When EL2 is implemented, the value of HCR.TGE is '1', a change to a Non-secure EL1 mode. - if PSTATE.M == M32_Monitor && HaveEL(EL2) && el == EL1 && SCR.NS == '1' && HCR.TGE == '1' then - valid = FALSE; - - if !valid then - PSTATE.IL = '1'; - else - AArch32.WriteMode(mode); - -// BankedRegisterAccessValid() -// =========================== -// Checks for MRS (Banked register) or MSR (Banked register) accesses to registers -// other than the SPSRs that are invalid. This includes ELR_hyp accesses. - -BankedRegisterAccessValid(bits(5) SYSm, bits(5) mode) - - case SYSm of - when '000xx', '00100' // R8_usr to R12_usr - if mode != M32_FIQ then UNPREDICTABLE; - when '00101' // SP_usr - if mode == M32_System then UNPREDICTABLE; - when '00110' // LR_usr - if mode IN {M32_Hyp,M32_System} then UNPREDICTABLE; - when '010xx', '0110x', '01110' // R8_fiq to R12_fiq, SP_fiq, LR_fiq - if mode == M32_FIQ then UNPREDICTABLE; - when '1000x' // LR_irq, SP_irq - if mode == M32_IRQ then UNPREDICTABLE; - when '1001x' // LR_svc, SP_svc - if mode == M32_Svc then UNPREDICTABLE; - when '1010x' // LR_abt, SP_abt - if mode == M32_Abort then UNPREDICTABLE; - when '1011x' // LR_und, SP_und - if mode == M32_Undef then UNPREDICTABLE; - when '1110x' // LR_mon, SP_mon - if !HaveEL(EL3) || !IsSecure() || mode == M32_Monitor then UNPREDICTABLE; - when '11110' // ELR_hyp, only from Monitor or Hyp mode - if !HaveEL(EL2) || !(mode IN {M32_Monitor,M32_Hyp}) then UNPREDICTABLE; - when '11111' // SP_hyp, only from Monitor mode - if !HaveEL(EL2) || mode != M32_Monitor then UNPREDICTABLE; - otherwise - UNPREDICTABLE; - - return; - -// CPSRWriteByInstr() -// ================== -// Update PSTATE.[N,Z,C,V,Q,GE,E,A,I,F,M] from a CPSR value written by an MSR instruction. - -CPSRWriteByInstr(bits(32) value, bits(4) bytemask) - privileged = PSTATE.EL != EL0; // PSTATE.[A,I,F,M] are not writable at EL0 - - // Write PSTATE from 'value', ignoring bytes masked by 'bytemask' - if bytemask[3] == '1' then - PSTATE.[N,Z,C,V,Q] = value[31:27]; - // Bits [26:24] are ignored - - if bytemask[2] == '1' then - // Bit [23] is RES0 - if privileged then - PSTATE.PAN = value[22]; - if HaveDITExt() then - PSTATE.DIT = value[21]; - // Bit [20] is RES0 - PSTATE.GE = value[19:16]; - - if bytemask[1] == '1' then - // Bits [15:10] are RES0 - PSTATE.E = value[9]; // PSTATE.E is writable at EL0 - if privileged then - PSTATE.A = value[8]; - - if bytemask[0] == '1' then - if privileged then - PSTATE.[I,F] = value[7:6]; - // Bit [5] is RES0 - // AArch32.WriteModeByInstr() sets PSTATE.IL to 1 if this is an illegal mode change. - AArch32.WriteModeByInstr(value[4:0]); - return; - -// ConditionPassed() -// ================= - -boolean ConditionPassed() - return ConditionHolds(AArch32.CurrentCond()); - -// InITBlock() -// =========== - -boolean InITBlock() - if CurrentInstrSet() == InstrSet_T32 then - return PSTATE.IT[3:0] != '0000'; - else - return FALSE; - -// LastInITBlock() -// =============== - -boolean LastInITBlock() - return (PSTATE.IT[3:0] == '1000'); - -// SPSRWriteByInstr() -// ================== - -SPSRWriteByInstr(bits(32) value, bits(4) bytemask) - - new_spsr = SPSR[]; - - if bytemask[3] == '1' then - new_spsr[31:24] = value[31:24]; // N,Z,C,V,Q flags, IT[1:0],J bits - - if bytemask[2] == '1' then - new_spsr[23:16] = value[23:16]; // IL bit, GE[3:0] flags - - if bytemask[1] == '1' then - new_spsr[15:8] = value[15:8]; // IT[7:2] bits, E bit, A interrupt mask - - if bytemask[0] == '1' then - new_spsr[7:0] = value[7:0]; // I,F interrupt masks, T bit, Mode bits - - SPSR[] = new_spsr; // UNPREDICTABLE if User or System mode - - return; - -// SPSRaccessValid() -// ================= -// Checks for MRS (Banked register) or MSR (Banked register) accesses to the SPSRs -// that are UNPREDICTABLE - -SPSRaccessValid(bits(5) SYSm, bits(5) mode) - case SYSm of - when '01110' // SPSR_fiq - if mode == M32_FIQ then UNPREDICTABLE; - when '10000' // SPSR_irq - if mode == M32_IRQ then UNPREDICTABLE; - when '10010' // SPSR_svc - if mode == M32_Svc then UNPREDICTABLE; - when '10100' // SPSR_abt - if mode == M32_Abort then UNPREDICTABLE; - when '10110' // SPSR_und - if mode == M32_Undef then UNPREDICTABLE; - when '11100' // SPSR_mon - if !HaveEL(EL3) || mode == M32_Monitor || !IsSecure() then UNPREDICTABLE; - when '11110' // SPSR_hyp - if !HaveEL(EL2) || mode != M32_Monitor then UNPREDICTABLE; - otherwise - UNPREDICTABLE; - - return; - -// SignedSatQ() -// ============ - -(bits(N), boolean) SignedSatQ(integer i, integer N) - if i > 2^(N-1) - 1 then - result = 2^(N-1) - 1; saturated = TRUE; - elsif i < -(2^(N-1)) then - result = -(2^(N-1)); saturated = TRUE; - else - result = i; saturated = FALSE; - return (result[N-1:0], saturated); - -// SignedSat() -// =========== - -bits(N) SignedSat(integer i, integer N) - (result, -) = SignedSatQ(i, N); - return result; - -// UnsignedSatQ() -// ============== - -(bits(N), boolean) UnsignedSatQ(integer i, integer N) - if i > 2^N - 1 then - result = 2^N - 1; saturated = TRUE; - elsif i < 0 then - result = 0; saturated = TRUE; - else - result = i; saturated = FALSE; - return (result[N-1:0], saturated); - -// UnsignedSat() -// ============= - -bits(N) UnsignedSat(integer i, integer N) - (result, -) = UnsignedSatQ(i, N); - return result; - -// Sat() -// ===== - -bits(N) Sat(integer i, integer N, boolean unsigned) - result = if unsigned then UnsignedSat(i, N) else SignedSat(i, N); - return result; - -// BranchToAddr() -// ============== - -// Set program counter to a new address, with a branch type1 -// In AArch64 state the address does not include a tag in the top eight bits. - -BranchToAddr(bits(N) target, BranchType branch_type) - Hint_Branch(branch_type); - if N == 32 then - assert UsingAArch32(); - _PC = ZeroExtend(target); - else - assert N == 64 && !UsingAArch32(); - _PC = target[63:0]; - return; - -// AArch64.ExceptionReturn() -// ========================= - -AArch64.ExceptionReturn(bits(64) new_pc, bits(32) spsr) - - SynchronizeContext(); - - sync_errors = HaveIESB() && SCTLR[].IESB == '1'; - if HaveDoubleFaultExt() then - sync_errors = sync_errors || (SCR_EL3.EA == '1' && SCR_EL3.NMEA == '1' && PSTATE.EL == EL3); - if sync_errors then - SynchronizeErrors(); - iesb_req = TRUE; - TakeUnmaskedPhysicalSErrorInterrupts(iesb_req); - // Attempts to change to an illegal state will invoke the Illegal Execution state mechanism - SetPSTATEFromPSR(spsr); - ClearExclusiveLocal(ProcessorID()); - SendEventLocal(); - - if PSTATE.IL == '1' && spsr[4] == '1' && spsr[20] == '0' then - // If the exception return is illegal, PC[63:32,1:0] are UNKNOWN - new_pc[63:32] = bits(32) UNKNOWN; - new_pc[1:0] = bits(2) UNKNOWN; - elsif UsingAArch32() then // Return to AArch32 - // ELR_ELx[1:0] or ELR_ELx[0] are treated as being 0, depending on the target instruction set state - if PSTATE.T == '1' then - new_pc[0] = '0'; // T32 - else - new_pc[1:0] = '00'; // A32 - else // Return to AArch64 - // ELR_ELx[63:56] might include a tag - new_pc = AArch64.BranchAddr(new_pc); - - if UsingAArch32() then - // 32 most significant bits are ignored. - BranchTo(new_pc[31:0], BranchType_ERET); - else - BranchToAddr(new_pc, BranchType_ERET); - -enumeration CountOp {CountOp_CLZ, CountOp_CLS, CountOp_CNT}; - -// HaveStatisticalProfiling() -// ========================== - -boolean HaveStatisticalProfiling() - return HasArchVersion(ARMv8p2); - -enumeration SysRegAccess { SysRegAccess_OK, - SysRegAccess_UNDEFINED, - SysRegAccess_TrapToEL1, - SysRegAccess_TrapToEL2, - SysRegAccess_TrapToEL3 }; - -// CheckProfilingBufferAccess() -// ============================ - -SysRegAccess CheckProfilingBufferAccess() - if !HaveStatisticalProfiling() || PSTATE.EL == EL0 || UsingAArch32() then - return SysRegAccess_UNDEFINED; - - if PSTATE.EL == EL1 && EL2Enabled() && MDCR_EL2.E2PB[0] != '1' then - return SysRegAccess_TrapToEL2; - - if HaveEL(EL3) && PSTATE.EL != EL3 && MDCR_EL3.NSPB != SCR_EL3.NS:'1' then - return SysRegAccess_TrapToEL3; - - return SysRegAccess_OK; - -// CheckStatisticalProfilingAccess() -// ================================= - -SysRegAccess CheckStatisticalProfilingAccess() - if !HaveStatisticalProfiling() || PSTATE.EL == EL0 || UsingAArch32() then - return SysRegAccess_UNDEFINED; - - if PSTATE.EL == EL1 && EL2Enabled() && MDCR_EL2.TPMS == '1' then - return SysRegAccess_TrapToEL2; - - if HaveEL(EL3) && PSTATE.EL != EL3 && MDCR_EL3.NSPB != SCR_EL3.NS:'1' then - return SysRegAccess_TrapToEL3; - - return SysRegAccess_OK; - -// ProfilingBufferOwner() -// ====================== - -(boolean, bits(2)) ProfilingBufferOwner() - secure = if HaveEL(EL3) then (MDCR_EL3.NSPB[1] == '0') else IsSecure(); - el = if !secure && HaveEL(EL2) && MDCR_EL2.E2PB == '00' then EL2 else EL1; - return (secure, el); - -// ProfilingBufferEnabled() -// ======================== - -boolean ProfilingBufferEnabled() - if !HaveStatisticalProfiling() then return FALSE; - (secure, el) = ProfilingBufferOwner(); - non_secure_bit = if secure then '0' else '1'; - return (!ELUsingAArch32(el) && non_secure_bit == SCR_EL3.NS && - PMBLIMITR_EL1.E == '1' && PMBSR_EL1.S == '0'); - -// StatisticalProfilingEnabled() -// ============================= - -boolean StatisticalProfilingEnabled() - if !HaveStatisticalProfiling() || UsingAArch32() || !ProfilingBufferEnabled() then - return FALSE; - - in_host = EL2Enabled() && HCR_EL2.TGE == '1'; - (secure, el) = ProfilingBufferOwner(); - if UInt(el) < UInt(PSTATE.EL) || secure != IsSecure() || (in_host && el == EL1) then - return FALSE; - - case PSTATE.EL of - when EL3 Unreachable(); - when EL2 spe_bit = PMSCR_EL2.E2SPE; - when EL1 spe_bit = PMSCR_EL1.E1SPE; - when EL0 spe_bit = (if in_host then PMSCR_EL2.E0HSPE else PMSCR_EL1.E0SPE); - - return spe_bit == '1'; - -// CollectContextIDR1() -// ==================== - -boolean CollectContextIDR1() - if !StatisticalProfilingEnabled() then return FALSE; - if PSTATE.EL == EL2 then return FALSE; - if EL2Enabled() && HCR_EL2.TGE == '1' then return FALSE; - return PMSCR_EL1.CX == '1'; - -// CollectContextIDR2() -// ==================== - -boolean CollectContextIDR2() - if !StatisticalProfilingEnabled() then return FALSE; - if EL2Enabled() then return FALSE; - return PMSCR_EL2.CX == '1'; - -// CollectPhysicalAddress() -// ======================== - -boolean CollectPhysicalAddress() - if !StatisticalProfilingEnabled() then return FALSE; - (secure, el) = ProfilingBufferOwner(); - if !secure && HaveEL(EL2) then - return PMSCR_EL2.PA == '1' && (el == EL2 || PMSCR_EL1.PA == '1'); - else - return PMSCR_EL1.PA == '1'; - -// HaveSVE() -// ========= - -boolean HaveSVE() - return HasArchVersion(ARMv8p2) && boolean IMPLEMENTATION_DEFINED "Have SVE ISA"; - -enumeration OpType { - OpType_Load, // Any memory-read operation other than atomics, compare-and-swap, and swap - OpType_Store, // Any memory-write operation, including atomics without return - OpType_LoadAtomic, // Atomics with return, compare-and-swap and swap - OpType_Branch, // Software write to the PC - OpType_Other // Any other class of operation - }; - -// CollectRecord() -// =============== - -boolean CollectRecord(bits(64) events, integer total_latency, OpType optype) - assert StatisticalProfilingEnabled(); - - // Filtering by event - if PMSFCR_EL1.FE == '1' && !IsZero(PMSEVFR_EL1) then - bits(64) mask = 0xFFFF0000FF00F0AA[63:0]; // Bits [63:48,31:24,15:12,7,5,3,1] - if HaveStatisticalProfiling() then - mask[11] = '1'; // Alignment flag - if HaveSVE() then mask[18:17] = Ones(); // Predicate flags - e = events AND mask; - m = PMSEVFR_EL1 AND mask; - if !IsZero(NOT(e) AND m) then return FALSE; - - // Filtering by type1 - if PMSFCR_EL1.FT == '1' && !IsZero(PMSFCR_EL1.[B,LD,ST]) then - case optype of - when OpType_Branch - if PMSFCR_EL1.B == '0' then return FALSE; - when OpType_Load - if PMSFCR_EL1.LD == '0' then return FALSE; - when OpType_Store - if PMSFCR_EL1.ST == '0' then return FALSE; - when OpType_LoadAtomic - if PMSFCR_EL1.[LD,ST] == '00' then return FALSE; - otherwise - return FALSE; - - // Filtering by latency - if PMSFCR_EL1.FL == '1' && !IsZero(PMSLATFR_EL1.MINLAT) then - if total_latency < UInt(PMSLATFR_EL1.MINLAT) then - return FALSE; - - // Check for UNPREDICTABLE cases - if ((PMSFCR_EL1.FE == '1' && !IsZero(PMSEVFR_EL1)) || - (PMSFCR_EL1.FT == '1' && !IsZero(PMSFCR_EL1.[B,LD,ST])) || - (PMSFCR_EL1.FL == '1' && !IsZero(PMSLATFR_EL1.MINLAT))) then - return ConstrainUnpredictableBool(Unpredictable_BADPMSFCR); - - return TRUE; - -enumeration TimeStamp { - TimeStamp_None, // No timestamp - TimeStamp_CoreSight, // CoreSight time (IMPLEMENTATION DEFINED) - TimeStamp_Virtual, // Physical counter value minus CNTVOFF_EL2 - TimeStamp_Physical }; // Physical counter value with no offset - -// CollectTimeStamp() -// ================== - -TimeStamp CollectTimeStamp() - if !StatisticalProfilingEnabled() then return TimeStamp_None; - (secure, el) = ProfilingBufferOwner(); - if el == EL2 then - if PMSCR_EL2.TS == '0' then return TimeStamp_None; - else - if PMSCR_EL1.TS == '0' then return TimeStamp_None; - if EL2Enabled() then - pct = PMSCR_EL2.PCT == '01' && (el == EL2 || PMSCR_EL1.PCT == '01'); - else - pct = PMSCR_EL1.PCT == '01'; - return (if pct then TimeStamp_Physical else TimeStamp_Virtual); - -// Barrier to ensure that all existing profiling data has been formatted, and profiling buffer -// addresses have been translated such that writes to the profiling buffer have been initiated. -// A following DSB completes when writes to the profiling buffer have completed. -ProfilingSynchronizationBarrier(); - -// AArch64.TakeExceptionInDebugState() -// =================================== -// Take an exception in Debug state to an Exception Level using AArch64. - -AArch64.TakeExceptionInDebugState(bits(2) target_el, ExceptionRecord exception) - assert HaveEL(target_el) && !ELUsingAArch32(target_el) && UInt(target_el) >= UInt(PSTATE.EL); - - sync_errors = HaveIESB() && SCTLR[target_el].IESB == '1'; - if HaveDoubleFaultExt() then - sync_errors = sync_errors || (SCR_EL3.EA == '1' && SCR_EL3.NMEA == '1' && PSTATE.EL == EL3); - // SCTLR[].IESB might be ignored in Debug state. - if !ConstrainUnpredictableBool(Unpredictable_IESBinDebug) then - sync_errors = FALSE; - - SynchronizeContext(); - - // If coming from AArch32 state, the top parts of the X[] registers might be set to zero - from_32 = UsingAArch32(); - if from_32 then AArch64.MaybeZeroRegisterUppers(); - MaybeZeroSVEUppers(target_el); - - AArch64.ReportException(exception, target_el); - - PSTATE.EL = target_el; - PSTATE.nRW = '0'; - PSTATE.SP = '1'; - - SPSR[] = bits(32) UNKNOWN; - ELR[] = bits(64) UNKNOWN; - - // PSTATE.{SS,D,A,I,F} are not observable and ignored in Debug state, so behave as if UNKNOWN. - PSTATE.[SS,D,A,I,F] = bits(5) UNKNOWN; - PSTATE.IL = '0'; - if from_32 then // Coming from AArch32 - PSTATE.IT = '00000000'; - PSTATE.T = '0'; // PSTATE.J is RES0 - if (HavePANExt() && (PSTATE.EL == EL1 || (PSTATE.EL == EL2 && ELIsInHost(EL0))) && - SCTLR[].SPAN == '0') then - PSTATE.PAN = '1'; - if HaveUAOExt() then PSTATE.UAO = '0'; - if HaveBTIExt() then PSTATE.BTYPE = '00'; - if HaveSSBSExt() then PSTATE.SSBS = bit UNKNOWN; - if HaveMTEExt() then PSTATE.TCO = '1'; - - DLR_EL0 = bits(64) UNKNOWN; - DSPSR_EL0 = bits(32) UNKNOWN; - - EDSCR.ERR = '1'; - UpdateEDSCRFields(); // Update EDSCR processor state flags. - - if sync_errors then - SynchronizeErrors(); - - EndOfInstruction(); - -// AArch64.CheckPCAlignment() -// ========================== - -AArch64.CheckPCAlignment() - - bits(64) pc = ThisInstrAddr(); - if pc[1:0] != '00' then - AArch64.PCAlignmentFault(); - -// AArch64.SPAlignmentFault() -// ========================== -// Called on an unaligned stack pointer in AArch64 state. - -AArch64.SPAlignmentFault() - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_SPAlignment); - - if UInt(PSTATE.EL) > UInt(EL1) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif EL2Enabled() && HCR_EL2.TGE == '1' then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// BranchTargetException -// ===================== -// Raise branch target exception. - -AArch64.BranchTargetException(bits(52) vaddress) - - route_to_el2 = PSTATE.EL == EL0 && EL2Enabled() && HCR_EL2.TGE == '1'; - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_BranchTarget); - exception.syndrome[1:0] = PSTATE.BTYPE; - exception.syndrome[24:2] = Zeros(); // RES0 - - if UInt(PSTATE.EL) > UInt(EL1) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// Returns TRUE if the previously executed instruction was executed in the inactive state, that is, -// if it was not itself stepped. -// Might return TRUE or FALSE if the previously executed instruction was an ISB or ERET executed -// in the active-not-pending state, or if another exception was taken before the Software Step exception. -// Returns FALSE otherwise, indicating that the previously executed instruction was executed in the -// active-not-pending state, that is, the instruction was stepped. -boolean SoftwareStep_DidNotStep(); - -// Returns a value that describes the previously executed instruction. The result is valid only if -// SoftwareStep_DidNotStep() returns FALSE. -// Might return TRUE or FALSE if the instruction was an AArch32 LDREX that failed its condition code test. -// Otherwise returns TRUE if the instruction was a Load-Exclusive class instruction, and FALSE if the -// instruction was not a Load-Exclusive class instruction. -boolean SoftwareStep_SteppedEX(); - -// AArch64.SoftwareStepException() -// =============================== - -AArch64.SoftwareStepException() - assert PSTATE.EL != EL3; - - route_to_el2 = (PSTATE.EL IN {EL0, EL1} && EL2Enabled() && - (HCR_EL2.TGE == '1' || MDCR_EL2.TDE == '1')); - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_SoftwareStep); - if SoftwareStep_DidNotStep() then - exception.syndrome[24] = '0'; - else - exception.syndrome[24] = '1'; - exception.syndrome[6] = if SoftwareStep_SteppedEX() then '1' else '0'; - - if PSTATE.EL == EL2 || route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// Resets System registers and memory-mapped control registers that have architecturally-defined -// reset values to those values. -AArch64.ResetControlRegisters(boolean cold_reset); - -// X[] - assignment form -// ===================== -// Write to general-purpose register from either a 32-bit or a 64-bit value. - -X[integer n] = bits(width) value - assert n >= 0 && n <= 31; - assert width IN {32,64}; - if n != 31 then - _R[n] = ZeroExtend(value); - return; - -// X[] - non-assignment form -// ========================= -// Read from general-purpose register with implicit slice of 8, 16, 32 or 64 bits. - -bits(width) X[integer n] - assert n >= 0 && n <= 31; - assert width IN {8,16,32,64}; - if n != 31 then - return _R[n][width-1:0]; - else - return Zeros(width); - -// AArch64.ResetGeneralRegisters() -// =============================== - -AArch64.ResetGeneralRegisters() - - for i = 0 to 30 - X[i] = bits(64) UNKNOWN; - - return; - -// V[] - assignment form -// ===================== -// Write to SIMD&FP register with implicit extension from -// 8, 16, 32, 64 or 128 bits. - -V[integer n] = bits(width) value - assert n >= 0 && n <= 31; - assert width IN {8,16,32,64,128}; - integer vlen = if IsSVEEnabled(PSTATE.EL) then VL else 128; - if ConstrainUnpredictableBool(Unpredictable_SVEZEROUPPER) then - _Z[n] = ZeroExtend(value); - else - _Z[n][vlen-1:0] = ZeroExtend(value); - -// V[] - non-assignment form -// ========================= -// Read from SIMD&FP register with implicit slice of 8, 16 -// 32, 64 or 128 bits. - -bits(width) V[integer n] - assert n >= 0 && n <= 31; - assert width IN {8,16,32,64,128}; - return _Z[n][width-1:0]; - -// AArch64.ResetSIMDFPRegisters() -// ============================== - -AArch64.ResetSIMDFPRegisters() - - for i = 0 to 31 - V[i] = bits(128) UNKNOWN; - - return; - -// AArch64.ResetSpecialRegisters() -// =============================== - -AArch64.ResetSpecialRegisters() - - // AArch64 special registers - SP_EL0 = bits(64) UNKNOWN; - SP_EL1 = bits(64) UNKNOWN; - SPSR_EL1 = bits(32) UNKNOWN; - ELR_EL1 = bits(64) UNKNOWN; - if HaveEL(EL2) then - SP_EL2 = bits(64) UNKNOWN; - SPSR_EL2 = bits(32) UNKNOWN; - ELR_EL2 = bits(64) UNKNOWN; - if HaveEL(EL3) then - SP_EL3 = bits(64) UNKNOWN; - SPSR_EL3 = bits(32) UNKNOWN; - ELR_EL3 = bits(64) UNKNOWN; - - // AArch32 special registers that are not architecturally mapped to AArch64 registers - if HaveAArch32EL(EL1) then - SPSR_fiq = bits(32) UNKNOWN; - SPSR_irq = bits(32) UNKNOWN; - SPSR_abt = bits(32) UNKNOWN; - SPSR_und = bits(32) UNKNOWN; - - // External debug special registers - DLR_EL0 = bits(64) UNKNOWN; - DSPSR_EL0 = bits(32) UNKNOWN; - - return; - -// AArch64.TakeReset() -// =================== -// Reset into AArch64 state - -AArch64.TakeReset(boolean cold_reset) - assert !HighestELUsingAArch32(); - - // Enter the highest implemented Exception level in AArch64 state - PSTATE.nRW = '0'; - if HaveEL(EL3) then - PSTATE.EL = EL3; - elsif HaveEL(EL2) then - PSTATE.EL = EL2; - else - PSTATE.EL = EL1; - - // Reset the system registers and other system components - AArch64.ResetControlRegisters(cold_reset); - - // Reset all other PSTATE fields - PSTATE.SP = '1'; // Select stack pointer - PSTATE.[D,A,I,F] = '1111'; // All asynchronous exceptions masked - PSTATE.SS = '0'; // Clear software step bit - PSTATE.DIT = '0'; // PSTATE.DIT is reset to 0 when resetting into AArch64 - PSTATE.IL = '0'; // Clear Illegal Execution state bit - - // All registers, bits and fields not reset by the above pseudocode or by the BranchTo() call - // below are UNKNOWN bitstrings after reset. In particular, the return information registers - // ELR_ELx and SPSR_ELx have UNKNOWN values, so that it - // is impossible to return from a reset in an architecturally defined way. - AArch64.ResetGeneralRegisters(); - AArch64.ResetSIMDFPRegisters(); - AArch64.ResetSpecialRegisters(); - ResetExternalDebugRegisters(cold_reset); - - bits(64) rv; // IMPLEMENTATION DEFINED reset vector - - if HaveEL(EL3) then - rv = RVBAR_EL3; - elsif HaveEL(EL2) then - rv = RVBAR_EL2; - else - rv = RVBAR_EL1; - - // The reset vector must be correctly aligned - assert IsZero(rv[63:PAMax()]) && IsZero(rv[1:0]); - - BranchTo(rv, BranchType_RESET); - -// AArch64.CallSecureMonitor() -// =========================== - -AArch64.CallSecureMonitor(bits(16) immediate) - assert HaveEL(EL3) && !ELUsingAArch32(EL3); - if UsingAArch32() then AArch32.ITAdvance(); - SSAdvance(); - bits(64) preferred_exception_return = NextInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_MonitorCall); - exception.syndrome[15:0] = immediate; - - AArch64.TakeException(EL3, exception, preferred_exception_return, vect_offset); - -// AArch64.CheckForERetTrap() -// ========================== -// Check for trap on ERET, ERETAA, ERETAB instruction - -AArch64.CheckForERetTrap(boolean eret_with_pac, boolean pac_uses_key_a) - - route_to_el2 = FALSE; - // Non-secure EL1 execution of ERET, ERETAA, ERETAB when either HCR_EL2.NV or HFGITR_EL2.ERET is set, - // is trapped to EL2 - route_to_el2 = PSTATE.EL == EL1 && EL2Enabled() && ( (HaveNVExt() && HCR_EL2.NV == '1') || (HaveFGTExt() && HCR_EL2.[E2H, TGE] != '11' && (!HaveEL(EL3) || SCR_EL3.FGTEn == '1') && HFGITR_EL2.ERET == '1') ); - if route_to_el2 then - ExceptionRecord exception; - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - exception = ExceptionSyndrome(Exception_ERetTrap); - if !eret_with_pac then // ERET - exception.syndrome[1] = '0'; - exception.syndrome[0] = '0'; // RES0 - else - exception.syndrome[1] = '1'; - if pac_uses_key_a then // ERETAA - exception.syndrome[0] = '0'; - else // ERETAB - exception.syndrome[0] = '1'; - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - -// AArch64.CheckForSVCTrap() -// ========================= -// Check for trap on SVC instruction - -AArch64.CheckForSVCTrap(bits(16) immediate) - if HaveFGTExt() then - route_to_el2 = FALSE; - if PSTATE.EL == EL0 then - route_to_el2 = !ELUsingAArch32(EL0) && !ELUsingAArch32(EL1) && EL2Enabled() && HFGITR_EL2.SVC_EL0 == '1' && (HCR_EL2.[E2H, TGE] != '11' && (!HaveEL(EL3) || SCR_EL3.FGTEn == '1')); - - elsif PSTATE.EL == EL1 then - route_to_el2 = !ELUsingAArch32(EL1) && EL2Enabled() && HFGITR_EL2.SVC_EL1 == '1' && (HCR_EL2.[E2H, TGE] != '11' && (!HaveEL(EL3) || SCR_EL3.FGTEn == '1')); - - if route_to_el2 then - exception = ExceptionSyndrome(Exception_SupervisorCall); - exception.syndrome[15:0] = immediate; - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - -// AArch64.MonitorModeTrap() -// ========================= -// Trapped use of Monitor mode features in a Secure EL1 AArch32 mode - -AArch64.MonitorModeTrap() - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_Uncategorized); - - if IsSecureEL2Enabled() then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - AArch64.TakeException(EL3, exception, preferred_exception_return, vect_offset); - -// AArch64.SystemAccessTrapSyndrome() -// ================================== -// Returns the syndrome information for traps on AArch64 MSR/MRS instructions. - -ExceptionRecord AArch64.SystemAccessTrapSyndrome(bits(32) instr, integer ec) - ExceptionRecord exception; - case ec of - when 0x0 // Trapped access due to unknown reason. - exception = ExceptionSyndrome(Exception_Uncategorized); - when 0x7 // Trapped access to SVE, Advance SIMD&FP system register. - exception = ExceptionSyndrome(Exception_AdvSIMDFPAccessTrap); - exception.syndrome[24:20] = ConditionSyndrome(); - when 0x18 // Trapped access to system register or system instruction. - exception = ExceptionSyndrome(Exception_SystemRegisterTrap); - instr = ThisInstr(); - exception.syndrome[21:20] = instr[20:19]; // Op0 - exception.syndrome[19:17] = instr[7:5]; // Op2 - exception.syndrome[16:14] = instr[18:16]; // Op1 - exception.syndrome[13:10] = instr[15:12]; // CRn - exception.syndrome[9:5] = instr[4:0]; // Rt - exception.syndrome[4:1] = instr[11:8]; // CRm - exception.syndrome[0] = instr[21]; // Direction - when 0x19 // Trapped access to SVE System register - exception = ExceptionSyndrome(Exception_SVEAccessTrap); - otherwise - Unreachable(); - - return exception; - -// AArch64.SystemAccessTrap() -// ========================== -// Trapped access to AArch64 system register or system instruction. - -AArch64.SystemAccessTrap(bits(2) target_el, integer ec) - assert HaveEL(target_el) && target_el != EL0 && UInt(target_el) >= UInt(PSTATE.EL); - - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = AArch64.SystemAccessTrapSyndrome(ThisInstr(), ec); - AArch64.TakeException(target_el, exception, preferred_exception_return, vect_offset); - -// CheckFPAdvSIMDEnabled64() -// ========================= -// AArch64 instruction wrapper - -CheckFPAdvSIMDEnabled64() - AArch64.CheckFPAdvSIMDEnabled(); - -enumeration ExtendType {ExtendType_SXTB, ExtendType_SXTH, ExtendType_SXTW, ExtendType_SXTX, - ExtendType_UXTB, ExtendType_UXTH, ExtendType_UXTW, ExtendType_UXTX}; - -// DecodeRegExtend() -// ================= -// Decode a register extension option - -ExtendType DecodeRegExtend(bits(3) op) - case op of - when '000' return ExtendType_UXTB; - when '001' return ExtendType_UXTH; - when '010' return ExtendType_UXTW; - when '011' return ExtendType_UXTX; - when '100' return ExtendType_SXTB; - when '101' return ExtendType_SXTH; - when '110' return ExtendType_SXTW; - when '111' return ExtendType_SXTX; - -// Extend() -// ======== - -bits(N) Extend(bits(M) x, integer N, boolean unsigned) - return if unsigned then ZeroExtend(x, N) else SignExtend(x, N); - -// Extend() -// ======== - -bits(N) Extend(bits(M) x, boolean unsigned) - return Extend(x, N, unsigned); - -// ExtendReg() -// =========== -// Perform a register extension and shift - -bits(N) ExtendReg(integer reg, ExtendType exttype, integer shift) - assert shift >= 0 && shift <= 4; - bits(N) val = X[reg]; - boolean unsigned; - integer len; - - case exttype of - when ExtendType_SXTB unsigned = FALSE; len = 8; - when ExtendType_SXTH unsigned = FALSE; len = 16; - when ExtendType_SXTW unsigned = FALSE; len = 32; - when ExtendType_SXTX unsigned = FALSE; len = 64; - when ExtendType_UXTB unsigned = TRUE; len = 8; - when ExtendType_UXTH unsigned = TRUE; len = 16; - when ExtendType_UXTW unsigned = TRUE; len = 32; - when ExtendType_UXTX unsigned = TRUE; len = 64; - - // Note the extended width of the intermediate value and - // that sign extension occurs from bit [len+shift-1], not - // from bit [len-1]. This is equivalent to the instruction - // [SU]BFIZ Rtmp, Rreg, #shift, #len - // It may also be seen as a sign/zero extend followed by a shift: - // LSL(Extend(val[len-1:0], N, unsigned), shift); - - len = Min(len, N - shift); - return Extend(val[len-1:0] : Zeros(shift), N, unsigned); - -enumeration FPMaxMinOp {FPMaxMinOp_MAX, FPMaxMinOp_MIN, - FPMaxMinOp_MAXNUM, FPMaxMinOp_MINNUM}; - -enumeration FPUnaryOp {FPUnaryOp_ABS, FPUnaryOp_MOV, - FPUnaryOp_NEG, FPUnaryOp_SQRT}; - -enumeration FPConvOp {FPConvOp_CVT_FtoI, FPConvOp_CVT_ItoF, - FPConvOp_MOV_FtoI, FPConvOp_MOV_ItoF - , FPConvOp_CVT_FtoI_JS -}; - -// HaveUA16Ext() -// ============= -// Returns TRUE if extended unaligned memory access support is implemented, and FALSE otherwise. - -boolean HaveUA16Ext() - return HasArchVersion(ARMv8p4); - -// AArch64.CheckAlignment() -// ======================== - -boolean AArch64.CheckAlignment(bits(64) address, integer alignment, AccType acctype, - boolean iswrite) - - aligned = (address == Align(address, alignment)); - atomic = acctype IN { AccType_ATOMIC, AccType_ATOMICRW, AccType_ORDEREDATOMIC, AccType_ORDEREDATOMICRW }; - ordered = acctype IN { AccType_ORDERED, AccType_ORDEREDRW, AccType_LIMITEDORDERED, AccType_ORDEREDATOMIC, AccType_ORDEREDATOMICRW }; - vector = acctype == AccType_VEC; - if SCTLR[].A == '1' then check = TRUE; - elsif HaveUA16Ext() then - check = (UInt(address[0+:4]) + alignment > 16) && ((ordered && SCTLR[].nAA == '0') || atomic); - else check = atomic || ordered; - - if check && !aligned then - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - - return aligned; - -// An optional IMPLEMENTATION DEFINED test for an exclusive access to a virtual -// address region of size bytes starting at address. -// -// It is permitted (but not required) for this function to return FALSE and -// cause a store exclusive to fail if the virtual address region is not -// totally included within the region recorded by MarkExclusiveVA(). -// -// It is always safe to return TRUE which will check the physical address only. -boolean AArch64.IsExclusiveVA(bits(64) address, integer processorid, integer size); - -// AArch64.ExclusiveMonitorsPass() -// =============================== - -// Return TRUE if the Exclusives monitors for the current PE include all of the addresses -// associated with the virtual address region of size bytes starting at address. -// The immediately following memory write must be to the same addresses. - -boolean AArch64.ExclusiveMonitorsPass(bits(64) address, integer size) - - // It is IMPLEMENTATION DEFINED whether the detection of memory aborts happens - // before or after the check on the local Exclusives monitor. As a result a failure - // of the local monitor can occur on some implementations even if the memory - // access would give an memory abort. - - acctype = AccType_ATOMIC; - iswrite = TRUE; - - aligned = AArch64.CheckAlignment(address, size, acctype, iswrite); - - passed = AArch64.IsExclusiveVA(address, ProcessorID(), size); - if !passed then - return FALSE; - - memaddrdesc = AArch64.TranslateAddress(address, acctype, iswrite, aligned, size); - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - AArch64.Abort(address, memaddrdesc.fault); - - passed = IsExclusiveLocal(memaddrdesc.paddress, ProcessorID(), size); - ClearExclusiveLocal(ProcessorID()); - - if passed then - if memaddrdesc.memattrs.shareable then - passed = IsExclusiveGlobal(memaddrdesc.paddress, ProcessorID(), size); - - return passed; - -// Optionally record an exclusive access to the virtual address region of size bytes -// starting at address for processorid. -AArch64.MarkExclusiveVA(bits(64) address, integer processorid, integer size); - -// AArch64.SetExclusiveMonitors() -// ============================== - -// Sets the Exclusives monitors for the current PE to record the addresses associated -// with the virtual address region of size bytes starting at address. - -AArch64.SetExclusiveMonitors(bits(64) address, integer size) - - acctype = AccType_ATOMIC; - iswrite = FALSE; - aligned = (address == Align(address, size)); - - memaddrdesc = AArch64.TranslateAddress(address, acctype, iswrite, aligned, size); - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - return; - - if memaddrdesc.memattrs.shareable then - MarkExclusiveGlobal(memaddrdesc.paddress, ProcessorID(), size); - - MarkExclusiveLocal(memaddrdesc.paddress, ProcessorID(), size); - - AArch64.MarkExclusiveVA(address, ProcessorID(), size); - -// FPNeg() -// ======= - -bits(N) FPNeg(bits(N) op) - assert N IN {16,32,64}; - return NOT(op[N-1]) : op[N-2:0]; - -// FPOnePointFive() -// ================ - -bits(N) FPOnePointFive(bit sign) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - exp = '0':Ones(E-1); - frac = '1':Zeros(F-1); - return sign : exp : frac; - -// FPRSqrtStepFused() -// ================== - -bits(N) FPRSqrtStepFused(bits(N) op1, bits(N) op2) - assert N IN {16, 32, 64}; - bits(N) result; - op1 = FPNeg(op1); - (type1,sign1,value1) = FPUnpack(op1, FPCR); - (type2,sign2,value2) = FPUnpack(op2, FPCR); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, FPCR); - if !done then - inf1 = (type1 == FPType_Infinity); - inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); - zero2 = (type2 == FPType_Zero); - if (inf1 && zero2) || (zero1 && inf2) then - result = FPOnePointFive('0'); - elsif inf1 || inf2 then - result = FPInfinity(sign1 EOR sign2); - else - // Fully fused multiply-add and halve - result_value = (3.0 + (value1 * value2)) / 2.0; - if result_value == 0.0 then - // Sign of exact zero result depends on rounding mode - sign = if FPRoundingMode(FPCR) == FPRounding_NEGINF then '1' else '0'; - result = FPZero(sign); - else - result = FPRound(result_value, FPCR); - return result; - -// FPRecipStepFused() -// ================== - -bits(N) FPRecipStepFused(bits(N) op1, bits(N) op2) - assert N IN {16, 32, 64}; - bits(N) result; - op1 = FPNeg(op1); - (type1,sign1,value1) = FPUnpack(op1, FPCR); - (type2,sign2,value2) = FPUnpack(op2, FPCR); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, FPCR); - if !done then - inf1 = (type1 == FPType_Infinity); - inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); - zero2 = (type2 == FPType_Zero); - if (inf1 && zero2) || (zero1 && inf2) then - result = FPTwo('0'); - elsif inf1 || inf2 then - result = FPInfinity(sign1 EOR sign2); - else - // Fully fused multiply-add - result_value = 2.0 + (value1 * value2); - if result_value == 0.0 then - // Sign of exact zero result depends on rounding mode - sign = if FPRoundingMode(FPCR) == FPRounding_NEGINF then '1' else '0'; - result = FPZero(sign); - else - result = FPRound(result_value, FPCR); - return result; - -// AArch64.AddressWithAllocationTag() -// ================================== -// Generate a 64-bit value containing a Logical Address Tag from a 64-bit -// virtual address and an Allocation Tag. -// If the extension is disabled, treats the Allocation Tag as '0000'. - -bits(64) AArch64.AddressWithAllocationTag(bits(64) address, bits(4) allocation_tag) - bits(64) result = address; - bits(4) tag; - if AArch64.AllocationTagAccessIsEnabled() then - tag = allocation_tag; - else - tag = '0000'; - result[59:56] = tag; - return result; - -// AArch64.AllocationTagFromAddress() -// ================================== -// Generate an ALlocation Tag from a 64-bit value containing a Logical Address Tag. - -bits(4) AArch64.AllocationTagFromAddress(bits(64) tagged_address) - return tagged_address[59:56]; - -// AArch64.MemSingle[] - non-assignment (read) form -// ================================================ -// Perform an atomic, little-endian read of 'size' bytes. - -bits(size*8) AArch64.MemSingle[bits(64) address, integer size, AccType acctype, boolean wasaligned] - assert size IN {1, 2, 4, 8, 16}; - assert address == Align(address, size); - - AddressDescriptor memaddrdesc; - bits(size*8) value; - iswrite = FALSE; - - memaddrdesc = AArch64.TranslateAddress(address, acctype, iswrite, wasaligned, size); - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - AArch64.Abort(address, memaddrdesc.fault); - - // Memory array access - accdesc = CreateAccessDescriptor(acctype); - if HaveMTEExt() then - if AArch64.AccessIsTagChecked(ZeroExtend(address, 64), acctype) then - bits(4) ptag = AArch64.PhysicalTag(ZeroExtend(address, 64)); - if !AArch64.CheckTag(memaddrdesc, ptag, iswrite) then - AArch64.TagCheckFail(ZeroExtend(address, 64), iswrite); - value = _Mem[memaddrdesc, size, accdesc]; - return value; - -// AArch64.MemSingle[] - assignment (write) form -// ============================================= -// Perform an atomic, little-endian write of 'size' bytes. - -AArch64.MemSingle[bits(64) address, integer size, AccType acctype, boolean wasaligned] = bits(size*8) value - assert size IN {1, 2, 4, 8, 16}; - assert address == Align(address, size); - - AddressDescriptor memaddrdesc; - iswrite = TRUE; - - memaddrdesc = AArch64.TranslateAddress(address, acctype, iswrite, wasaligned, size); - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - AArch64.Abort(address, memaddrdesc.fault); - - // Effect on exclusives - if memaddrdesc.memattrs.shareable then - ClearExclusiveByAddress(memaddrdesc.paddress, ProcessorID(), size); - - // Memory array access - accdesc = CreateAccessDescriptor(acctype); - if HaveMTEExt() then - if AArch64.AccessIsTagChecked(ZeroExtend(address, 64), acctype) then - bits(4) ptag = AArch64.PhysicalTag(ZeroExtend(address, 64)); - if !AArch64.CheckTag(memaddrdesc, ptag, iswrite) then - AArch64.TagCheckFail(ZeroExtend(address, 64), iswrite); - _Mem[memaddrdesc, size, accdesc] = value; - return; - -constant integer LOG2_TAG_GRANULE = 4; - -constant integer TAG_GRANULE = 1 << LOG2_TAG_GRANULE; - -// AArch64.MemTag[] - non-assignment (read) form -// ============================================= -// Load an Allocation Tag from memory. - -bits(4) AArch64.MemTag[bits(64) address, AccType acctype] - assert acctype == AccType_NORMAL; - AddressDescriptor memaddrdesc; - bits(4) value; - iswrite = FALSE; - - memaddrdesc = AArch64.TranslateAddress(address, acctype, iswrite, TRUE, TAG_GRANULE); - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - AArch64.Abort(address, memaddrdesc.fault); - - // Return the granule tag if tagging is enabled... - if AArch64.AllocationTagAccessIsEnabled() && memaddrdesc.memattrs.tagged then - return _MemTag[memaddrdesc]; - else - // ...otherwise read tag as zero. - return '0000'; - -// AArch64.MemTag[] - assignment (write) form -// ========================================== -// Store an Allocation Tag to memory. - -AArch64.MemTag[bits(64) address, AccType acctype] = bits(4) value - assert acctype == AccType_NORMAL; - AddressDescriptor memaddrdesc; - iswrite = TRUE; - - // Stores of allocation tags must be aligned - if address != Align(address, TAG_GRANULE) then - boolean secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - - wasaligned = TRUE; - memaddrdesc = AArch64.TranslateAddress(address, acctype, iswrite, wasaligned, TAG_GRANULE); - - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - AArch64.Abort(address, memaddrdesc.fault); - - // Memory array access - if AArch64.AllocationTagAccessIsEnabled() && memaddrdesc.memattrs.tagged then - _MemTag[memaddrdesc] = value; - -// AArch64.TranslateAddressForAtomicAccess() -// ========================================= -// Performs an alignment check for atomic memory operations. -// Also translates 64-bit Virtual Address into Physical Address. - -AddressDescriptor AArch64.TranslateAddressForAtomicAccess(bits(64) address, integer sizeinbits) - boolean iswrite = FALSE; - size = sizeinbits DIV 8; - - assert size IN {1, 2, 4, 8, 16}; - - aligned = AArch64.CheckAlignment(address, size, AccType_ATOMICRW, iswrite); - - // MMU or MPU lookup - memaddrdesc = AArch64.TranslateAddress(address, AccType_ATOMICRW, iswrite, aligned, size); - - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - AArch64.Abort(address, memaddrdesc.fault); - - // Effect on exclusives - if memaddrdesc.memattrs.shareable then - ClearExclusiveByAddress(memaddrdesc.paddress, ProcessorID(), size); - - if HaveMTEExt() && AArch64.AccessIsTagChecked(address, AccType_ATOMICRW) then - bits(4) ptag = AArch64.PhysicalTag(address); - if !AArch64.CheckTag(memaddrdesc, ptag, iswrite) then - AArch64.TagCheckFail(address, iswrite); - - return memaddrdesc; - -// SP[] - assignment form -// ====================== -// Write to stack pointer from either a 32-bit or a 64-bit value. - -SP[] = bits(width) value - assert width IN {32,64}; - if PSTATE.SP == '0' then - SP_EL0 = ZeroExtend(value); - else - case PSTATE.EL of - when EL0 SP_EL0 = ZeroExtend(value); - when EL1 SP_EL1 = ZeroExtend(value); - when EL2 SP_EL2 = ZeroExtend(value); - when EL3 SP_EL3 = ZeroExtend(value); - return; - -// SP[] - non-assignment form -// ========================== -// Read stack pointer with implicit slice of 8, 16, 32 or 64 bits. - -bits(width) SP[] - assert width IN {8,16,32,64}; - if PSTATE.SP == '0' then - return SP_EL0[width-1:0]; - else - case PSTATE.EL of - when EL0 return SP_EL0[width-1:0]; - when EL1 return SP_EL1[width-1:0]; - when EL2 return SP_EL2[width-1:0]; - when EL3 return SP_EL3[width-1:0]; - -// CheckSPAlignment() -// ================== -// Check correct stack pointer alignment for AArch64 state. - -CheckSPAlignment() - bits(64) sp = SP[]; - if PSTATE.EL == EL0 then - stack_align_check = (SCTLR[].SA0 != '0'); - else - stack_align_check = (SCTLR[].SA != '0'); - - if stack_align_check && sp != Align(sp, 16) then - AArch64.SPAlignmentFault(); - - return; - -// Mem[] - non-assignment (read) form -// ================================== -// Perform a read of 'size' bytes. The access byte order is reversed for a big-endian access. -// Instruction fetches would call AArch64.MemSingle directly. - -bits(size*8) Mem[bits(64) address, integer size, AccType acctype] - assert size IN {1, 2, 4, 8, 16}; - bits(size*8) value; - boolean iswrite = FALSE; - - aligned = AArch64.CheckAlignment(address, size, acctype, iswrite); - if size != 16 || !(acctype IN {AccType_VEC, AccType_VECSTREAM}) then - atomic = aligned; - else - // 128-bit SIMD&FP loads are treated as a pair of 64-bit single-copy atomic accesses - // 64-bit aligned. - atomic = address == Align(address, 8); - - if !atomic then - assert size > 1; - value[7:0] = AArch64.MemSingle[address, 1, acctype, aligned]; - - // For subsequent bytes it is CONSTRAINED UNPREDICTABLE whether an unaligned Device memory - // access will generate an Alignment Fault, as to get this far means the first byte did - // not, so we must be changing to a new translation page. - if !aligned then - c = ConstrainUnpredictable(Unpredictable_DEVPAGE2); - assert c IN {Constraint_FAULT, Constraint_NONE}; - if c == Constraint_NONE then aligned = TRUE; - - for i = 1 to size-1 - value[8*i+7:8*i] = AArch64.MemSingle[address+i, 1, acctype, aligned]; - elsif size == 16 && acctype IN {AccType_VEC, AccType_VECSTREAM} then - value[63:0] = AArch64.MemSingle[address, 8, acctype, aligned]; - value[127:64] = AArch64.MemSingle[address+8, 8, acctype, aligned]; - else - value = AArch64.MemSingle[address, size, acctype, aligned]; - - if (HaveNV2Ext() && acctype == AccType_NV2REGISTER && SCTLR_EL2.EE == '1') || BigEndian() then - value = BigEndianReverse(value); - return value; - -// Mem[] - assignment (write) form -// =============================== -// Perform a write of 'size' bytes. The byte order is reversed for a big-endian access. - -Mem[bits(64) address, integer size, AccType acctype] = bits(size*8) value - boolean iswrite = TRUE; - - if (HaveNV2Ext() && acctype == AccType_NV2REGISTER && SCTLR_EL2.EE == '1') || BigEndian() then - value = BigEndianReverse(value); - - aligned = AArch64.CheckAlignment(address, size, acctype, iswrite); - if size != 16 || !(acctype IN {AccType_VEC, AccType_VECSTREAM}) then - atomic = aligned; - else - // 128-bit SIMD&FP stores are treated as a pair of 64-bit single-copy atomic accesses - // 64-bit aligned. - atomic = address == Align(address, 8); - - if !atomic then - assert size > 1; - AArch64.MemSingle[address, 1, acctype, aligned] = value[7:0]; - - // For subsequent bytes it is CONSTRAINED UNPREDICTABLE whether an unaligned Device memory - // access will generate an Alignment Fault, as to get this far means the first byte did - // not, so we must be changing to a new translation page. - if !aligned then - c = ConstrainUnpredictable(Unpredictable_DEVPAGE2); - assert c IN {Constraint_FAULT, Constraint_NONE}; - if c == Constraint_NONE then aligned = TRUE; - - for i = 1 to size-1 - AArch64.MemSingle[address+i, 1, acctype, aligned] = value[8*i+7:8*i]; - elsif size == 16 && acctype IN {AccType_VEC, AccType_VECSTREAM} then - AArch64.MemSingle[address, 8, acctype, aligned] = value[63:0]; - AArch64.MemSingle[address+8, 8, acctype, aligned] = value[127:64]; - else - AArch64.MemSingle[address, size, acctype, aligned] = value; - return; - -enumeration MemAtomicOp {MemAtomicOp_ADD, - MemAtomicOp_BIC, - MemAtomicOp_EOR, - MemAtomicOp_ORR, - MemAtomicOp_SMAX, - MemAtomicOp_SMIN, - MemAtomicOp_UMAX, - MemAtomicOp_UMIN, - MemAtomicOp_SWP}; - -// MemAtomic() -// =========== -// Performs load and store memory operations for a given virtual address. - -bits(size) MemAtomic(bits(64) address, MemAtomicOp op, bits(size) value, AccType ldacctype, AccType stacctype) - bits(size) newvalue; - memaddrdesc = AArch64.TranslateAddressForAtomicAccess(address, size); - ldaccdesc = CreateAccessDescriptor(ldacctype); - staccdesc = CreateAccessDescriptor(stacctype); - - // All observers in the shareability domain observe the - // following load and store atomically. - oldvalue = _Mem[memaddrdesc, size DIV 8, ldaccdesc]; - if BigEndian() then - oldvalue = BigEndianReverse(oldvalue); - - case op of - when MemAtomicOp_ADD newvalue = oldvalue + value; - when MemAtomicOp_BIC newvalue = oldvalue AND NOT(value); - when MemAtomicOp_EOR newvalue = oldvalue EOR value; - when MemAtomicOp_ORR newvalue = oldvalue OR value; - when MemAtomicOp_SMAX newvalue = if SInt(oldvalue) > SInt(value) then oldvalue else value; - when MemAtomicOp_SMIN newvalue = if SInt(oldvalue) > SInt(value) then value else oldvalue; - when MemAtomicOp_UMAX newvalue = if UInt(oldvalue) > UInt(value) then oldvalue else value; - when MemAtomicOp_UMIN newvalue = if UInt(oldvalue) > UInt(value) then value else oldvalue; - when MemAtomicOp_SWP newvalue = value; - - if BigEndian() then - newvalue = BigEndianReverse(newvalue); - _Mem[memaddrdesc, size DIV 8, staccdesc] = newvalue; - - // Load operations return the old (pre-operation) value - return oldvalue; - -// MemAtomicCompareAndSwap() -// ========================= -// Compares the value stored at the passed-in memory address against the passed-in expected -// value. If the comparison is successful, the value at the passed-in memory address is swapped -// with the passed-in new_value. - -bits(size) MemAtomicCompareAndSwap(bits(64) address, bits(size) expectedvalue, - bits(size) newvalue, AccType ldacctype, AccType stacctype) - memaddrdesc = AArch64.TranslateAddressForAtomicAccess(address, size); - ldaccdesc = CreateAccessDescriptor(ldacctype); - staccdesc = CreateAccessDescriptor(stacctype); - - // All observers in the shareability domain observe the - // following load and store atomically. - oldvalue = _Mem[memaddrdesc, size DIV 8, ldaccdesc]; - if BigEndian() then - oldvalue = BigEndianReverse(oldvalue); - - if oldvalue == expectedvalue then - if BigEndian() then - newvalue = BigEndianReverse(newvalue); - _Mem[memaddrdesc, size DIV 8, staccdesc] = newvalue; - return oldvalue; - -// NVMem[] - non-assignment form -// ============================= -// This function is the load memory access for the transformed System register read access -// when Enhanced Nested Virtualisation is enabled with HCR_EL2.NV2 = 1. -// The address for the load memory access is calculated using -// the formula SignExtend(VNCR_EL2.BADDR : Offset[11:0], 64) where, -// * VNCR_EL2.BADDR holds the base address of the memory location, and -// * Offset is the unique offset value defined architecturally for each System register that -// supports transformation of register access to memory access. - -bits(64) NVMem[integer offset] - assert offset > 0; - bits(64) address = SignExtend(VNCR_EL2.BADDR:offset[11:0], 64); - return Mem[address, 8, AccType_NV2REGISTER]; - -// NVMem[] - assignment form -// ========================= -// This function is the store memory access for the transformed System register write access -// when Enhanced Nested Virtualisation is enabled with HCR_EL2.NV2 = 1. -// The address for the store memory access is calculated using -// the formula SignExtend(VNCR_EL2.BADDR : Offset[11:0], 64) where, -// * VNCR_EL2.BADDR holds the base address of the memory location, and -// * Offset is the unique offset value defined architecturally for each System register that -// supports transformation of register access to memory access. - -NVMem[integer offset] = bits(64) value - assert offset > 0; - bits(64) address = SignExtend(VNCR_EL2.BADDR:offset[11:0], 64); - Mem[address, 8, AccType_NV2REGISTER] = value; - return; - -// Flag the current instruction as using/not using memory tag checking. -SetTagCheckedInstruction(boolean checked); - -// PtrHasUpperAndLowerAddRanges() -// ============================== -// Returns TRUE if the pointer has upper and lower address ranges, FALSE otherwise. - -boolean PtrHasUpperAndLowerAddRanges() - return PSTATE.EL == EL1 || PSTATE.EL == EL0 || (PSTATE.EL == EL2 && HCR_EL2.E2H == '1'); - -// VAMax() -// ======= -// Returns the IMPLEMENTATION DEFINED upper limit on the virtual address -// size for this processor, as log2(). - -integer VAMax() - return integer IMPLEMENTATION_DEFINED "Maximum Virtual Address Size"; - -// CalculateBottomPACBit() -// ======================= - -integer CalculateBottomPACBit(bit top_bit) - integer tsz_field; - - if PtrHasUpperAndLowerAddRanges() then - assert S1TranslationRegime() IN {EL1, EL2}; - if S1TranslationRegime() == EL1 then - // EL1 translation regime registers - tsz_field = if top_bit == '1' then UInt(TCR_EL1.T1SZ) else UInt(TCR_EL1.T0SZ); - using64k = if top_bit == '1' then TCR_EL1.TG1 == '11' else TCR_EL1.TG0 == '01'; - else - // EL2 translation regime registers - assert HaveEL(EL2); - tsz_field = if top_bit == '1' then UInt(TCR_EL2.T1SZ) else UInt(TCR_EL2.T0SZ); - using64k = if top_bit == '1' then TCR_EL2.TG1 == '11' else TCR_EL2.TG0 == '01'; - else - tsz_field = if PSTATE.EL == EL2 then UInt(TCR_EL2.T0SZ) else UInt(TCR_EL3.T0SZ); - using64k = if PSTATE.EL == EL2 then TCR_EL2.TG0 == '01' else TCR_EL3.TG0 == '01'; - - max_limit_tsz_field = (if !HaveSmallPageTblExt() then 39 else if using64k then 47 else 48); - if tsz_field > max_limit_tsz_field then - // TCR_ELx.TySZ is out of range - c = ConstrainUnpredictable(Unpredictable_RESTnSZ); - assert c IN {Constraint_FORCE, Constraint_NONE}; - if c == Constraint_FORCE then tsz_field = max_limit_tsz_field; - tszmin = if using64k && VAMax() == 52 then 12 else 16; - if tsz_field < tszmin then - c = ConstrainUnpredictable(Unpredictable_RESTnSZ); - assert c IN {Constraint_FORCE, Constraint_NONE}; - if c == Constraint_FORCE then tsz_field = tszmin; - return (64-tsz_field); - -// CalculateTBI() -// ============== - -boolean CalculateTBI(bits(64) ptr, boolean data) - boolean tbi = FALSE; - - if PtrHasUpperAndLowerAddRanges() then - assert S1TranslationRegime() IN {EL1, EL2}; - if S1TranslationRegime() == EL1 then - // EL1 translation regime registers - if data then - tbi = if ptr[55] == '1' then TCR_EL1.TBI1 == '1' else TCR_EL1.TBI0 == '1'; - else - if ptr[55] == '1' then - tbi = TCR_EL1.TBI1 == '1' && TCR_EL1.TBID1 == '0'; - else - tbi = TCR_EL1.TBI0 == '1' && TCR_EL1.TBID0 == '0'; - else - // EL2 translation regime registers - if data then - tbi = if ptr[55] == '1' then TCR_EL2.TBI1 == '1' else TCR_EL2.TBI0 == '1'; - else - if ptr[55] == '1' then - tbi = TCR_EL2.TBI1 == '1' && TCR_EL2.TBID1 == '0'; - else - tbi = TCR_EL2.TBI0 == '1' && TCR_EL2.TBID0 == '0'; - elsif PSTATE.EL == EL2 then - tbi = if data then TCR_EL2.TBI=='1' else TCR_EL2.TBI=='1' && TCR_EL2.TBID=='0'; - elsif PSTATE.EL == EL3 then - tbi = if data then TCR_EL3.TBI=='1' else TCR_EL3.TBI=='1' && TCR_EL3.TBID=='0'; - - return tbi; - -// PACCellInvShuffle() -// =================== - -bits(64) PACCellInvShuffle(bits(64) indata) - bits(64) outdata; - outdata[3:0] = indata[15:12]; - outdata[7:4] = indata[27:24]; - outdata[11:8] = indata[51:48]; - outdata[15:12] = indata[39:36]; - outdata[19:16] = indata[59:56]; - outdata[23:20] = indata[47:44]; - outdata[27:24] = indata[7:4]; - outdata[31:28] = indata[19:16]; - outdata[35:32] = indata[35:32]; - outdata[39:36] = indata[55:52]; - outdata[43:40] = indata[31:28]; - outdata[47:44] = indata[11:8]; - outdata[51:48] = indata[23:20]; - outdata[55:52] = indata[3:0]; - outdata[59:56] = indata[43:40]; - outdata[63:60] = indata[63:60]; - return outdata; - -// PACCellShuffle() -// ================ - -bits(64) PACCellShuffle(bits(64) indata) - bits(64) outdata; - outdata[3:0] = indata[55:52]; - outdata[7:4] = indata[27:24]; - outdata[11:8] = indata[47:44]; - outdata[15:12] = indata[3:0]; - outdata[19:16] = indata[31:28]; - outdata[23:20] = indata[51:48]; - outdata[27:24] = indata[7:4]; - outdata[31:28] = indata[43:40]; - outdata[35:32] = indata[35:32]; - outdata[39:36] = indata[15:12]; - outdata[43:40] = indata[59:56]; - outdata[47:44] = indata[23:20]; - outdata[51:48] = indata[11:8]; - outdata[55:52] = indata[39:36]; - outdata[59:56] = indata[19:16]; - outdata[63:60] = indata[63:60]; - return outdata; - -// PACInvSub() -// =========== - -bits(64) PACInvSub(bits(64) Tinput) - // This is a 4-bit substitution from the PRINCE-family cipher - - bits(64) Toutput; - for i = 0 to 15 - case Tinput[4*i+3:4*i] of - when '0000' Toutput[4*i+3:4*i] = '0101'; - when '0001' Toutput[4*i+3:4*i] = '1110'; - when '0010' Toutput[4*i+3:4*i] = '1101'; - when '0011' Toutput[4*i+3:4*i] = '1000'; - when '0100' Toutput[4*i+3:4*i] = '1010'; - when '0101' Toutput[4*i+3:4*i] = '1011'; - when '0110' Toutput[4*i+3:4*i] = '0001'; - when '0111' Toutput[4*i+3:4*i] = '1001'; - when '1000' Toutput[4*i+3:4*i] = '0010'; - when '1001' Toutput[4*i+3:4*i] = '0110'; - when '1010' Toutput[4*i+3:4*i] = '1111'; - when '1011' Toutput[4*i+3:4*i] = '0000'; - when '1100' Toutput[4*i+3:4*i] = '0100'; - when '1101' Toutput[4*i+3:4*i] = '1100'; - when '1110' Toutput[4*i+3:4*i] = '0111'; - when '1111' Toutput[4*i+3:4*i] = '0011'; - return Toutput; - -// RotCell() -// ========= - -bits(4) RotCell(bits(4) incell, integer amount) - bits(8) tmp; - bits(4) outcell; - - // assert amount>3 || amount<1; - tmp[7:0] = incell[3:0]:incell[3:0]; - outcell = tmp[7-amount:4-amount]; - return outcell; - -// PACMult() -// ========= - -bits(64) PACMult(bits(64) Sinput) - bits(4) t0; - bits(4) t1; - bits(4) t2; - bits(4) t3; - bits(64) Soutput; - - for i = 0 to 3 - t0[3:0] = RotCell(Sinput[4*(i+8)+3:4*(i+8)], 1) EOR RotCell(Sinput[4*(i+4)+3:4*(i+4)], 2); - t0[3:0] = t0[3:0] EOR RotCell(Sinput[4*(i)+3:4*(i)], 1); - t1[3:0] = RotCell(Sinput[4*(i+12)+3:4*(i+12)], 1) EOR RotCell(Sinput[4*(i+4)+3:4*(i+4)], 1); - t1[3:0] = t1[3:0] EOR RotCell(Sinput[4*(i)+3:4*(i)], 2); - t2[3:0] = RotCell(Sinput[4*(i+12)+3:4*(i+12)], 2) EOR RotCell(Sinput[4*(i+8)+3:4*(i+8)], 1); - t2[3:0] = t2[3:0] EOR RotCell(Sinput[4*(i)+3:4*(i)], 1); - t3[3:0] = RotCell(Sinput[4*(i+12)+3:4*(i+12)], 1) EOR RotCell(Sinput[4*(i+8)+3:4*(i+8)], 2); - t3[3:0] = t3[3:0] EOR RotCell(Sinput[4*(i+4)+3:4*(i+4)], 1); - Soutput[4*i+3:4*i] = t3[3:0]; - Soutput[4*(i+4)+3:4*(i+4)] = t2[3:0]; - Soutput[4*(i+8)+3:4*(i+8)] = t1[3:0]; - Soutput[4*(i+12)+3:4*(i+12)] = t0[3:0]; - return Soutput; - -// PACSub() -// ======== - -bits(64) PACSub(bits(64) Tinput) - // This is a 4-bit substitution from the PRINCE-family cipher - bits(64) Toutput; - for i = 0 to 15 - case Tinput[4*i+3:4*i] of - when '0000' Toutput[4*i+3:4*i] = '1011'; - when '0001' Toutput[4*i+3:4*i] = '0110'; - when '0010' Toutput[4*i+3:4*i] = '1000'; - when '0011' Toutput[4*i+3:4*i] = '1111'; - when '0100' Toutput[4*i+3:4*i] = '1100'; - when '0101' Toutput[4*i+3:4*i] = '0000'; - when '0110' Toutput[4*i+3:4*i] = '1001'; - when '0111' Toutput[4*i+3:4*i] = '1110'; - when '1000' Toutput[4*i+3:4*i] = '0011'; - when '1001' Toutput[4*i+3:4*i] = '0111'; - when '1010' Toutput[4*i+3:4*i] = '0100'; - when '1011' Toutput[4*i+3:4*i] = '0101'; - when '1100' Toutput[4*i+3:4*i] = '1101'; - when '1101' Toutput[4*i+3:4*i] = '0010'; - when '1110' Toutput[4*i+3:4*i] = '0001'; - when '1111' Toutput[4*i+3:4*i] = '1010'; - return Toutput; - -// TweakCellRot() -// ============== - -bits(4) TweakCellRot(bits(4) incell) - bits(4) outcell; - outcell[3] = incell[0] EOR incell[1]; - outcell[2] = incell[3]; - outcell[1] = incell[2]; - outcell[0] = incell[1]; - return outcell; - -// TweakShuffle() -// ============== - -bits(64) TweakShuffle(bits(64) indata) - bits(64) outdata; - outdata[3:0] = indata[19:16]; - outdata[7:4] = indata[23:20]; - outdata[11:8] = TweakCellRot(indata[27:24]); - outdata[15:12] = indata[31:28]; - outdata[19:16] = TweakCellRot(indata[47:44]); - outdata[23:20] = indata[11:8]; - outdata[27:24] = indata[15:12]; - outdata[31:28] = TweakCellRot(indata[35:32]); - outdata[35:32] = indata[51:48]; - outdata[39:36] = indata[55:52]; - outdata[43:40] = indata[59:56]; - outdata[47:44] = TweakCellRot(indata[63:60]); - outdata[51:48] = TweakCellRot(indata[3:0]); - outdata[55:52] = indata[7:4]; - outdata[59:56] = TweakCellRot(indata[43:40]); - outdata[63:60] = TweakCellRot(indata[39:36]); - return outdata; - -array bits(64) RC[0..4]; - -bits(64) ComputePAC(bits(64) data, bits(64) modifier, bits(64) key0, bits(64) key1) - bits(64) workingval; - bits(64) runningmod; - bits(64) roundkey; - bits(64) modk0; - constant bits(64) Alpha = 0xC0AC29B7C97C50DD[63:0]; - - RC[0] = 0x0000000000000000[63:0]; - RC[1] = 0x13198A2E03707344[63:0]; - RC[2] = 0xA4093822299F31D0[63:0]; - RC[3] = 0x082EFA98EC4E6C89[63:0]; - RC[4] = 0x452821E638D01377[63:0]; - - modk0 = key0[0]:key0[63:2]:(key0[63] EOR key0[1]); - runningmod = modifier; - workingval = data EOR key0; - for i = 0 to 4 - roundkey = key1 EOR runningmod; - workingval = workingval EOR roundkey; - workingval = workingval EOR RC[i]; - if i > 0 then - workingval = PACCellShuffle(workingval); - workingval = PACMult(workingval); - workingval = PACSub(workingval); - runningmod = TweakShuffle(runningmod[63:0]); - roundkey = modk0 EOR runningmod; - workingval = workingval EOR roundkey; - workingval = PACCellShuffle(workingval); - workingval = PACMult(workingval); - workingval = PACSub(workingval); - workingval = PACCellShuffle(workingval); - workingval = PACMult(workingval); - workingval = key1 EOR workingval; - workingval = PACCellInvShuffle(workingval); - workingval = PACInvSub(workingval); - workingval = PACMult(workingval); - workingval = PACCellInvShuffle(workingval); - workingval = workingval EOR key0; - workingval = workingval EOR runningmod; - for i = 0 to 4 - workingval = PACInvSub(workingval); - if i < 4 then - workingval = PACMult(workingval); - workingval = PACCellInvShuffle(workingval); - runningmod = TweakInvShuffle(runningmod[63:0]); - roundkey = key1 EOR runningmod; - workingval = workingval EOR RC[4-i]; - workingval = workingval EOR roundkey; - workingval = workingval EOR Alpha; - workingval = workingval EOR modk0; - - return workingval; - -// HaveEnhancedPAC() -// ================= -// Returns TRUE if support for EnhancedPAC is implemented, FALSE otherwise. - -boolean HaveEnhancedPAC() - return ( HavePACExt() - && boolean IMPLEMENTATION_DEFINED "Has enhanced PAC functionality" ); - -// HaveEnhancedPAC2() -// ================== -// Returns TRUE if support for EnhancedPAC2 is implemented, FALSE otherwise. - -boolean HaveEnhancedPAC2() - return HasArchVersion(ARMv8p6) || (HasArchVersion(ARMv8p3) && boolean IMPLEMENTATION_DEFINED "Has enhanced PAC 2 functionality"); - -// AddPAC() -// ======== -// Calculates the pointer authentication code for a 64-bit quantity and then -// inserts that into pointer authentication code field of that 64-bit quantity. - -bits(64) AddPAC(bits(64) ptr, bits(64) modifier, bits(128) K, boolean data) - bits(64) PAC; - bits(64) result; - bits(64) ext_ptr; - bits(64) extfield; - bit selbit; - boolean tbi = CalculateTBI(ptr, data); - integer top_bit = if tbi then 55 else 63; - - // If tagged pointers are in use for a regime with two TTBRs, use bit[55] of - // the pointer to select between upper and lower ranges, and preserve this. - // This handles the awkward case where there is apparently no correct choice between - // the upper and lower address range - ie an addr of 1xxxxxxx0... with TBI0=0 and TBI1=1 - // and 0xxxxxxx1 with TBI1=0 and TBI0=1: - if PtrHasUpperAndLowerAddRanges() then - assert S1TranslationRegime() IN {EL1, EL2}; - if S1TranslationRegime() == EL1 then - // EL1 translation regime registers - if data then - if TCR_EL1.TBI1 == '1' || TCR_EL1.TBI0 == '1' then - selbit = ptr[55]; - else - selbit = ptr[63]; - else - if ((TCR_EL1.TBI1 == '1' && TCR_EL1.TBID1 == '0') || - (TCR_EL1.TBI0 == '1' && TCR_EL1.TBID0 == '0')) then - selbit = ptr[55]; - else - selbit = ptr[63]; - else - // EL2 translation regime registers - if data then - if TCR_EL2.TBI1 == '1' || TCR_EL2.TBI0 == '1' then - selbit = ptr[55]; - else - selbit = ptr[63]; - else - if ((TCR_EL2.TBI1 == '1' && TCR_EL2.TBID1 == '0') || - (TCR_EL2.TBI0 == '1' && TCR_EL2.TBID0 == '0')) then - selbit = ptr[55]; - else - selbit = ptr[63]; - else selbit = if tbi then ptr[55] else ptr[63]; - - integer bottom_PAC_bit = CalculateBottomPACBit(selbit); - - // The pointer authentication code field takes all the available bits in between - extfield = Replicate(selbit, 64); - - // Compute the pointer authentication code for a ptr with good extension bits - if tbi then - ext_ptr = ptr[63:56]:extfield[(56-bottom_PAC_bit)-1:0]:ptr[bottom_PAC_bit-1:0]; - else - ext_ptr = extfield[(64-bottom_PAC_bit)-1:0]:ptr[bottom_PAC_bit-1:0]; - - PAC = ComputePAC(ext_ptr, modifier, K[127:64], K[63:0]); - - // Check if the ptr has good extension bits and corrupt the pointer authentication code if not - if !IsZero(ptr[top_bit:bottom_PAC_bit]) && !IsOnes(ptr[top_bit:bottom_PAC_bit]) then - if HaveEnhancedPAC() then - PAC = 0x0000000000000000[63:0]; - elsif !HaveEnhancedPAC2() then - PAC[top_bit-1] = NOT(PAC[top_bit-1]); - - // preserve the determination between upper and lower address at bit[55] and insert PAC - if !HaveEnhancedPAC2() then - if tbi then - result = ptr[63:56]:selbit:PAC[54:bottom_PAC_bit]:ptr[bottom_PAC_bit-1:0]; - else - result = PAC[63:56]:selbit:PAC[54:bottom_PAC_bit]:ptr[bottom_PAC_bit-1:0]; - else - if tbi then - result = ptr[63:56]:selbit:(ptr[54:bottom_PAC_bit] EOR PAC[54:bottom_PAC_bit]):ptr[bottom_PAC_bit-1:0]; - else - result = (ptr[63:56] EOR PAC[63:56]):selbit:(ptr[54:bottom_PAC_bit] EOR - PAC[54:bottom_PAC_bit]):ptr[bottom_PAC_bit-1:0]; - return result; - -// TrapPACUse() -// ============ -// Used for the trapping of the pointer authentication functions by higher exception -// levels. - -TrapPACUse(bits(2) target_el) - assert HaveEL(target_el) && target_el != EL0 && UInt(target_el) >= UInt(PSTATE.EL); - - bits(64) preferred_exception_return = ThisInstrAddr(); - ExceptionRecord exception; - vect_offset = 0; - exception = ExceptionSyndrome(Exception_PACTrap); - AArch64.TakeException(target_el, exception, preferred_exception_return, vect_offset); - -// AddPACDA() -// ========== -// Returns a 64-bit value containing X, but replacing the pointer authentication code -// field bits with a pointer authentication code, where the pointer authentication -// code is derived using a cryptographic algorithm as a combination of X, Y and the -// APDAKey_EL1. - -bits(64) AddPACDA(bits(64) X, bits(64) Y) - boolean TrapEL2; - boolean TrapEL3; - bits(1) Enable; - bits(128) APDAKey_EL1; - - APDAKey_EL1 = APDAKeyHi_EL1[63:0] : APDAKeyLo_EL1[63:0]; - case PSTATE.EL of - when EL0 - boolean IsEL1Regime = S1TranslationRegime() == EL1; - Enable = if IsEL1Regime then SCTLR_EL1.EnDA else SCTLR_EL2.EnDA; - TrapEL2 = (EL2Enabled() && HCR_EL2.API == '0' && - (HCR_EL2.TGE == '0' || HCR_EL2.E2H == '0')); - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL1 - Enable = SCTLR_EL1.EnDA; - TrapEL2 = EL2Enabled() && HCR_EL2.API == '0'; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL2 - Enable = SCTLR_EL2.EnDA; - TrapEL2 = FALSE; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL3 - Enable = SCTLR_EL3.EnDA; - TrapEL2 = FALSE; - TrapEL3 = FALSE; - - if Enable == '0' then return X; - elsif TrapEL2 then TrapPACUse(EL2); - elsif TrapEL3 then TrapPACUse(EL3); - else return AddPAC(X, Y, APDAKey_EL1, TRUE); - -// AddPACDB() -// ========== -// Returns a 64-bit value containing X, but replacing the pointer authentication code -// field bits with a pointer authentication code, where the pointer authentication -// code is derived using a cryptographic algorithm as a combination of X, Y and the -// APDBKey_EL1. - -bits(64) AddPACDB(bits(64) X, bits(64) Y) - boolean TrapEL2; - boolean TrapEL3; - bits(1) Enable; - bits(128) APDBKey_EL1; - - APDBKey_EL1 = APDBKeyHi_EL1[63:0] : APDBKeyLo_EL1[63:0]; - case PSTATE.EL of - when EL0 - boolean IsEL1Regime = S1TranslationRegime() == EL1; - Enable = if IsEL1Regime then SCTLR_EL1.EnDB else SCTLR_EL2.EnDB; - TrapEL2 = (EL2Enabled() && HCR_EL2.API == '0' && - (HCR_EL2.TGE == '0' || HCR_EL2.E2H == '0')); - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL1 - Enable = SCTLR_EL1.EnDB; - TrapEL2 = EL2Enabled() && HCR_EL2.API == '0'; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL2 - Enable = SCTLR_EL2.EnDB; - TrapEL2 = FALSE; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL3 - Enable = SCTLR_EL3.EnDB; - TrapEL2 = FALSE; - TrapEL3 = FALSE; - - if Enable == '0' then return X; - elsif TrapEL2 then TrapPACUse(EL2); - elsif TrapEL3 then TrapPACUse(EL3); - else return AddPAC(X, Y, APDBKey_EL1, TRUE); - -// AddPACGA() -// ========== -// Returns a 64-bit value where the lower 32 bits are 0, and the upper 32 bits contain -// a 32-bit pointer authentication code which is derived using a cryptographic -// algorithm as a combination of X, Y and the APGAKey_EL1. - -bits(64) AddPACGA(bits(64) X, bits(64) Y) - boolean TrapEL2; - boolean TrapEL3; - bits(128) APGAKey_EL1; - - APGAKey_EL1 = APGAKeyHi_EL1[63:0] : APGAKeyLo_EL1[63:0]; - case PSTATE.EL of - when EL0 - TrapEL2 = (EL2Enabled() && HCR_EL2.API == '0' && - (HCR_EL2.TGE == '0' || HCR_EL2.E2H == '0')); - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL1 - TrapEL2 = EL2Enabled() && HCR_EL2.API == '0'; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL2 - TrapEL2 = FALSE; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL3 - TrapEL2 = FALSE; - TrapEL3 = FALSE; - - if TrapEL2 then TrapPACUse(EL2); - elsif TrapEL3 then TrapPACUse(EL3); - else return ComputePAC(X, Y, APGAKey_EL1[127:64], APGAKey_EL1[63:0])[63:32]:Zeros(32); - -// AddPACIA() -// ========== -// Returns a 64-bit value containing X, but replacing the pointer authentication code -// field bits with a pointer authentication code, where the pointer authentication -// code is derived using a cryptographic algorithm as a combination of X, Y, and the -// APIAKey_EL1. - -bits(64) AddPACIA(bits(64) X, bits(64) Y) - boolean TrapEL2; - boolean TrapEL3; - bits(1) Enable; - bits(128) APIAKey_EL1; - - APIAKey_EL1 = APIAKeyHi_EL1[63:0]:APIAKeyLo_EL1[63:0]; - case PSTATE.EL of - when EL0 - boolean IsEL1Regime = S1TranslationRegime() == EL1; - Enable = if IsEL1Regime then SCTLR_EL1.EnIA else SCTLR_EL2.EnIA; - TrapEL2 = (EL2Enabled() && HCR_EL2.API == '0' && - (HCR_EL2.TGE == '0' || HCR_EL2.E2H == '0')); - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL1 - Enable = SCTLR_EL1.EnIA; - TrapEL2 = EL2Enabled() && HCR_EL2.API == '0'; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL2 - Enable = SCTLR_EL2.EnIA; - TrapEL2 = FALSE; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL3 - Enable = SCTLR_EL3.EnIA; - TrapEL2 = FALSE; - TrapEL3 = FALSE; - - if Enable == '0' then return X; - elsif TrapEL2 then TrapPACUse(EL2); - elsif TrapEL3 then TrapPACUse(EL3); - else return AddPAC(X, Y, APIAKey_EL1, FALSE); - -// AddPACIB() -// ========== -// Returns a 64-bit value containing X, but replacing the pointer authentication code -// field bits with a pointer authentication code, where the pointer authentication -// code is derived using a cryptographic algorithm as a combination of X, Y and the -// APIBKey_EL1. - -bits(64) AddPACIB(bits(64) X, bits(64) Y) - boolean TrapEL2; - boolean TrapEL3; - bits(1) Enable; - bits(128) APIBKey_EL1; - - APIBKey_EL1 = APIBKeyHi_EL1[63:0] : APIBKeyLo_EL1[63:0]; - case PSTATE.EL of - when EL0 - boolean IsEL1Regime = S1TranslationRegime() == EL1; - Enable = if IsEL1Regime then SCTLR_EL1.EnIB else SCTLR_EL2.EnIB; - TrapEL2 = (EL2Enabled() && HCR_EL2.API == '0' && - (HCR_EL2.TGE == '0' || HCR_EL2.E2H == '0')); - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL1 - Enable = SCTLR_EL1.EnIB; - TrapEL2 = EL2Enabled() && HCR_EL2.API == '0'; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL2 - Enable = SCTLR_EL2.EnIB; - TrapEL2 = FALSE; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL3 - Enable = SCTLR_EL3.EnIB; - TrapEL2 = FALSE; - TrapEL3 = FALSE; - - if Enable == '0' then return X; - elsif TrapEL2 then TrapPACUse(EL2); - elsif TrapEL3 then TrapPACUse(EL3); - else return AddPAC(X, Y, APIBKey_EL1, FALSE); - -// AArch64.PACFailException() -// ========================== -// Generates a PAC Fail Exception - -AArch64.PACFailException(bits(2) syndrome) - route_to_el2 = PSTATE.EL == EL0 && EL2Enabled() && HCR_EL2.TGE == '1'; - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - exception = ExceptionSyndrome(Exception_PACFail); - exception.syndrome[1:0] = syndrome; - exception.syndrome[24:2] = Zeros(); // RES0 - - if UInt(PSTATE.EL) > UInt(EL0) then - AArch64.TakeException(PSTATE.EL, exception, preferred_exception_return, vect_offset); - elsif route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(EL1, exception, preferred_exception_return, vect_offset); - -// HaveFPAC() -// ========== -// Returns TRUE if support for FPAC is implemented, FALSE otherwise. - -boolean HaveFPAC() - return HaveEnhancedPAC2() && boolean IMPLEMENTATION_DEFINED "Has FPAC functionality"; - -// HaveFPACCombined() -// ================== -// Returns TRUE if support for FPACCombined is implemented, FALSE otherwise. - -boolean HaveFPACCombined() - return HaveFPAC() && boolean IMPLEMENTATION_DEFINED "Has FPAC Combined functionality"; - -// Auth() -// ====== -// Restores the upper bits of the address to be all zeros or all ones (based on the -// value of bit[55]) and computes and checks the pointer authentication code. If the -// check passes, then the restored address is returned. If the check fails, the -// second-top and third-top bits of the extension bits in the pointer authentication code -// field are corrupted to ensure that accessing the address will give a translation fault. - -bits(64) Auth(bits(64) ptr, bits(64) modifier, bits(128) K, boolean data, bit key_number, boolean is_combined) - bits(64) PAC; - bits(64) result; - bits(64) original_ptr; - bits(2) error_code; - bits(64) extfield; - - // Reconstruct the extension field used of adding the PAC to the pointer - boolean tbi = CalculateTBI(ptr, data); - integer bottom_PAC_bit = CalculateBottomPACBit(ptr[55]); - extfield = Replicate(ptr[55], 64); - - if tbi then - original_ptr = ptr[63:56]:extfield[56-bottom_PAC_bit-1:0]:ptr[bottom_PAC_bit-1:0]; - else - original_ptr = extfield[64-bottom_PAC_bit-1:0]:ptr[bottom_PAC_bit-1:0]; - - PAC = ComputePAC(original_ptr, modifier, K[127:64], K[63:0]); - // Check pointer authentication code - if tbi then - if !HaveEnhancedPAC2() then - if PAC[54:bottom_PAC_bit] == ptr[54:bottom_PAC_bit] then - result = original_ptr; - else - error_code = key_number:NOT(key_number); - result = original_ptr[63:55]:error_code:original_ptr[52:0]; - else - result = ptr; - result[54:bottom_PAC_bit] = result[54:bottom_PAC_bit] EOR PAC[54:bottom_PAC_bit]; - if HaveFPACCombined() || (HaveFPAC() && !is_combined) then - if result[54:bottom_PAC_bit] != Replicate(result[55], (55-bottom_PAC_bit)) then - error_code = (if data then '1' else '0'):key_number; - AArch64.PACFailException(error_code); - else - if !HaveEnhancedPAC2() then - if PAC[54:bottom_PAC_bit] == ptr[54:bottom_PAC_bit] && PAC[63:56] == ptr[63:56] then - result = original_ptr; - else - error_code = key_number:NOT(key_number); - result = original_ptr[63]:error_code:original_ptr[60:0]; - else - result = ptr; - result[54:bottom_PAC_bit] = result[54:bottom_PAC_bit] EOR PAC[54:bottom_PAC_bit]; - result[63:56] = result[63:56] EOR PAC[63:56]; - if HaveFPACCombined() || (HaveFPAC() && !is_combined) then - if result[63:bottom_PAC_bit] != Replicate(result[55], (64-bottom_PAC_bit)) then - error_code = (if data then '1' else '0'):key_number; - AArch64.PACFailException(error_code); - return result; - -// AuthDA() -// ======== -// Returns a 64-bit value containing X, but replacing the pointer authentication code -// field bits with the extension of the address bits. The instruction checks a pointer -// authentication code in the pointer authentication code field bits of X, using the same -// algorithm and key as AddPACDA(). - -bits(64) AuthDA(bits(64) X, bits(64) Y, boolean is_combined) - boolean TrapEL2; - boolean TrapEL3; - bits(1) Enable; - bits(128) APDAKey_EL1; - - APDAKey_EL1 = APDAKeyHi_EL1[63:0] : APDAKeyLo_EL1[63:0]; - case PSTATE.EL of - when EL0 - boolean IsEL1Regime = S1TranslationRegime() == EL1; - Enable = if IsEL1Regime then SCTLR_EL1.EnDA else SCTLR_EL2.EnDA; - TrapEL2 = (EL2Enabled() && HCR_EL2.API == '0' && - (HCR_EL2.TGE == '0' || HCR_EL2.E2H == '0')); - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL1 - Enable = SCTLR_EL1.EnDA; - TrapEL2 = EL2Enabled() && HCR_EL2.API == '0'; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL2 - Enable = SCTLR_EL2.EnDA; - TrapEL2 = FALSE; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL3 - Enable = SCTLR_EL3.EnDA; - TrapEL2 = FALSE; - TrapEL3 = FALSE; - - if Enable == '0' then return X; - elsif TrapEL2 then TrapPACUse(EL2); - elsif TrapEL3 then TrapPACUse(EL3); - else return Auth(X, Y, APDAKey_EL1, TRUE, '0', is_combined); - -// AuthDB() -// ======== -// Returns a 64-bit value containing X, but replacing the pointer authentication code -// field bits with the extension of the address bits. The instruction checks a -// pointer authentication code in the pointer authentication code field bits of X, using -// the same algorithm and key as AddPACDB(). - -bits(64) AuthDB(bits(64) X, bits(64) Y, boolean is_combined) - boolean TrapEL2; - boolean TrapEL3; - bits(1) Enable; - bits(128) APDBKey_EL1; - - APDBKey_EL1 = APDBKeyHi_EL1[63:0] : APDBKeyLo_EL1[63:0]; - case PSTATE.EL of - when EL0 - boolean IsEL1Regime = S1TranslationRegime() == EL1; - Enable = if IsEL1Regime then SCTLR_EL1.EnDB else SCTLR_EL2.EnDB; - TrapEL2 = (EL2Enabled() && HCR_EL2.API == '0' && - (HCR_EL2.TGE == '0' || HCR_EL2.E2H == '0')); - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL1 - Enable = SCTLR_EL1.EnDB; - TrapEL2 = EL2Enabled() && HCR_EL2.API == '0'; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL2 - Enable = SCTLR_EL2.EnDB; - TrapEL2 = FALSE; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL3 - Enable = SCTLR_EL3.EnDB; - TrapEL2 = FALSE; - TrapEL3 = FALSE; - - if Enable == '0' then return X; - elsif TrapEL2 then TrapPACUse(EL2); - elsif TrapEL3 then TrapPACUse(EL3); - else return Auth(X, Y, APDBKey_EL1, TRUE, '1', is_combined); - -// AuthIA() -// ======== -// Returns a 64-bit value containing X, but replacing the pointer authentication code -// field bits with the extension of the address bits. The instruction checks a pointer -// authentication code in the pointer authentication code field bits of X, using the same -// algorithm and key as AddPACIA(). - -bits(64) AuthIA(bits(64) X, bits(64) Y, boolean is_combined) - boolean TrapEL2; - boolean TrapEL3; - bits(1) Enable; - bits(128) APIAKey_EL1; - - APIAKey_EL1 = APIAKeyHi_EL1[63:0] : APIAKeyLo_EL1[63:0]; - case PSTATE.EL of - when EL0 - boolean IsEL1Regime = S1TranslationRegime() == EL1; - Enable = if IsEL1Regime then SCTLR_EL1.EnIA else SCTLR_EL2.EnIA; - TrapEL2 = (EL2Enabled() && HCR_EL2.API == '0' && - (HCR_EL2.TGE == '0' || HCR_EL2.E2H == '0')); - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL1 - Enable = SCTLR_EL1.EnIA; - TrapEL2 = EL2Enabled() && HCR_EL2.API == '0'; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL2 - Enable = SCTLR_EL2.EnIA; - TrapEL2 = FALSE; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL3 - Enable = SCTLR_EL3.EnIA; - TrapEL2 = FALSE; - TrapEL3 = FALSE; - - if Enable == '0' then return X; - elsif TrapEL2 then TrapPACUse(EL2); - elsif TrapEL3 then TrapPACUse(EL3); - else return Auth(X, Y, APIAKey_EL1, FALSE, '0', is_combined); - -// AuthIB() -// ======== -// Returns a 64-bit value containing X, but replacing the pointer authentication code -// field bits with the extension of the address bits. The instruction checks a pointer -// authentication code in the pointer authentication code field bits of X, using the same -// algorithm and key as AddPACIB(). - -bits(64) AuthIB(bits(64) X, bits(64) Y, boolean is_combined) - boolean TrapEL2; - boolean TrapEL3; - bits(1) Enable; - bits(128) APIBKey_EL1; - - APIBKey_EL1 = APIBKeyHi_EL1[63:0] : APIBKeyLo_EL1[63:0]; - case PSTATE.EL of - when EL0 - boolean IsEL1Regime = S1TranslationRegime() == EL1; - Enable = if IsEL1Regime then SCTLR_EL1.EnIB else SCTLR_EL2.EnIB; - TrapEL2 = (EL2Enabled() && HCR_EL2.API == '0' && - (HCR_EL2.TGE == '0' || HCR_EL2.E2H == '0')); - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL1 - Enable = SCTLR_EL1.EnIB; - TrapEL2 = EL2Enabled() && HCR_EL2.API == '0'; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL2 - Enable = SCTLR_EL2.EnIB; - TrapEL2 = FALSE; - TrapEL3 = HaveEL(EL3) && SCR_EL3.API == '0'; - when EL3 - Enable = SCTLR_EL3.EnIB; - TrapEL2 = FALSE; - TrapEL3 = FALSE; - - if Enable == '0' then return X; - elsif TrapEL2 then TrapPACUse(EL2); - elsif TrapEL3 then TrapPACUse(EL3); - else return Auth(X, Y, APIBKey_EL1, FALSE, '1', is_combined); - -// TweakCellInvRot() -// ================= - -bits(4) TweakCellInvRot(bits(4)incell) - bits(4) outcell; - outcell[3] = incell[2]; - outcell[2] = incell[1]; - outcell[1] = incell[0]; - outcell[0] = incell[0] EOR incell[3]; - return outcell; - -// TweakInvShuffle() -// ================= - -bits(64) TweakInvShuffle(bits(64)indata) - bits(64) outdata; - outdata[3:0] = TweakCellInvRot(indata[51:48]); - outdata[7:4] = indata[55:52]; - outdata[11:8] = indata[23:20]; - outdata[15:12] = indata[27:24]; - outdata[19:16] = indata[3:0]; - outdata[23:20] = indata[7:4]; - outdata[27:24] = TweakCellInvRot(indata[11:8]); - outdata[31:28] = indata[15:12]; - outdata[35:32] = TweakCellInvRot(indata[31:28]); - outdata[39:36] = TweakCellInvRot(indata[63:60]); - outdata[43:40] = TweakCellInvRot(indata[59:56]); - outdata[47:44] = TweakCellInvRot(indata[19:16]); - outdata[51:48] = indata[35:32]; - outdata[55:52] = indata[39:36]; - outdata[59:56] = indata[43:40]; - outdata[63:60] = TweakCellInvRot(indata[47:44]); - return outdata; - -// Strip() -// ======= -// Strip() returns a 64-bit value containing A, but replacing the pointer authentication -// code field bits with the extension of the address bits. This can apply to either -// instructions or data, where, as the use of tagged pointers is distinct, it might be -// handled differently. - -bits(64) Strip(bits(64) A, boolean data) - bits(64) original_ptr; - bits(64) extfield; - boolean tbi = CalculateTBI(A, data); - integer bottom_PAC_bit = CalculateBottomPACBit(A[55]); - extfield = Replicate(A[55], 64); - - if tbi then - original_ptr = A[63:56]:extfield[ 56-bottom_PAC_bit-1:0]:A[bottom_PAC_bit-1:0]; - else - original_ptr = extfield[ 64-bottom_PAC_bit-1:0]:A[bottom_PAC_bit-1:0]; - - return original_ptr; - -AArch64.ResetSystemRegisters(boolean cold_reset); - -// PC - non-assignment form -// ======================== -// Read program counter. - -bits(64) PC[] - return _PC; - -// Vpart[] - non-assignment form -// ============================= -// Reads a 128-bit SIMD&FP register in up to two parts: -// part 0 returns the bottom 8, 16, 32 or 64 bits of a value held in the register; -// part 1 returns the top half of the bottom 64 bits or the top half of the 128-bit -// value held in the register. - -bits(width) Vpart[integer n, integer part] - assert n >= 0 && n <= 31; - assert part IN {0, 1}; - if part == 0 then - assert width < 128; - return V[n]; - else - assert width IN {32,64}; - bits(128) vreg = V[n]; - return vreg[(width * 2)-1:width]; - -// Vpart[] - assignment form -// ========================= -// Writes a 128-bit SIMD&FP register in up to two parts: -// part 0 zero extends a 8, 16, 32, or 64-bit value to fill the whole register; -// part 1 inserts a 64-bit value into the top half of the register. - -Vpart[integer n, integer part] = bits(width) value - assert n >= 0 && n <= 31; - assert part IN {0, 1}; - if part == 0 then - assert width < 128; - V[n] = value; - else - assert width == 64; - bits(64) vreg = V[n]; - V[n] = value[63:0] : vreg; - -// FloorPow2() -// =========== -// For a positive integer X, return the largest power of 2 <= X - -integer FloorPow2(integer x) - assert x >= 0; - integer n = 1; - if x == 0 then return 0; - while x >= 2^n do - n = n + 1; - return 2^(n - 1); - -// CeilPow2() -// ========== - -// For a positive integer X, return the smallest power of 2 >= X - -integer CeilPow2(integer x) - if x == 0 then return 0; - if x == 1 then return 2; - return FloorPow2(x - 1) * 2; - -// SVEAccessTrap() -// =============== -// Trapped access to SVE registers due to CPACR_EL1, CPTR_EL2, or CPTR_EL3. - -SVEAccessTrap(bits(2) target_el) - assert UInt(target_el) >= UInt(PSTATE.EL) && target_el != EL0 && HaveEL(target_el); - route_to_el2 = target_el == EL1 && EL2Enabled() && HCR_EL2.TGE == '1'; - - exception = ExceptionSyndrome(Exception_SVEAccessTrap); - bits(64) preferred_exception_return = ThisInstrAddr(); - vect_offset = 0x0; - - if route_to_el2 then - AArch64.TakeException(EL2, exception, preferred_exception_return, vect_offset); - else - AArch64.TakeException(target_el, exception, preferred_exception_return, vect_offset); - -// CheckSVEEnabled() -// ================= -// Checks for traps on SVE instructions and instructions that -// access SVE System registers. - -CheckSVEEnabled() - // Check if access disabled in CPACR_EL1 - if PSTATE.EL IN {EL0, EL1} && !IsInHost() then - // Check SVE at EL0/EL1 - case CPACR_EL1.ZEN of - when 'x0' disabled = TRUE; - when '01' disabled = PSTATE.EL == EL0; - when '11' disabled = FALSE; - if disabled then SVEAccessTrap(EL1); - - // Check SIMD&FP at EL0/EL1 - case CPACR_EL1.FPEN of - when 'x0' disabled = TRUE; - when '01' disabled = PSTATE.EL == EL0; - when '11' disabled = FALSE; - if disabled then AArch64.AdvSIMDFPAccessTrap(EL1); - - // Check if access disabled in CPTR_EL2 - if PSTATE.EL IN {EL0, EL1, EL2} && EL2Enabled() then - if HaveVirtHostExt() && HCR_EL2.E2H == '1' then - // Check SVE at EL2 - case CPTR_EL2.ZEN of - when 'x0' disabled = TRUE; - when '01' disabled = PSTATE.EL == EL0 && HCR_EL2.TGE == '1'; - when '11' disabled = FALSE; - if disabled then SVEAccessTrap(EL2); - - // Check SIMD&FP at EL2 - case CPTR_EL2.FPEN of - when 'x0' disabled = TRUE; - when '01' disabled = PSTATE.EL == EL0 && HCR_EL2.TGE == '1'; - when '11' disabled = FALSE; - if disabled then AArch64.AdvSIMDFPAccessTrap(EL2); - else - if CPTR_EL2.TZ == '1' then SVEAccessTrap(EL2); - if CPTR_EL2.TFP == '1' then AArch64.AdvSIMDFPAccessTrap(EL2); - - // Check if access disabled in CPTR_EL3 - if HaveEL(EL3) then - if CPTR_EL3.EZ == '0' then SVEAccessTrap(EL3); - if CPTR_EL3.TFP == '1' then AArch64.AdvSIMDFPAccessTrap(EL3); - -// DecodePredCount() -// ================= - -integer DecodePredCount(bits(5) pattern, integer esize) - integer elements = VL DIV esize; - integer numElem; - case pattern of - when '00000' numElem = FloorPow2(elements); - when '00001' numElem = if elements >= 1 then 1 else 0; - when '00010' numElem = if elements >= 2 then 2 else 0; - when '00011' numElem = if elements >= 3 then 3 else 0; - when '00100' numElem = if elements >= 4 then 4 else 0; - when '00101' numElem = if elements >= 5 then 5 else 0; - when '00110' numElem = if elements >= 6 then 6 else 0; - when '00111' numElem = if elements >= 7 then 7 else 0; - when '01000' numElem = if elements >= 8 then 8 else 0; - when '01001' numElem = if elements >= 16 then 16 else 0; - when '01010' numElem = if elements >= 32 then 32 else 0; - when '01011' numElem = if elements >= 64 then 64 else 0; - when '01100' numElem = if elements >= 128 then 128 else 0; - when '01101' numElem = if elements >= 256 then 256 else 0; - when '11101' numElem = elements - (elements MOD 4); - when '11110' numElem = elements - (elements MOD 3); - when '11111' numElem = elements; - otherwise numElem = 0; - return numElem; - -// ElemP[] - non-assignment form -// ============================= - -bit ElemP[bits(N) pred, integer e, integer esize] - integer n = e * (esize DIV 8); - assert n >= 0 && n < N; - return pred[n]; - -// ElemP[] - assignment form -// ========================= - -ElemP[bits(N) &pred, integer e, integer esize] = bit value - integer psize = esize DIV 8; - integer n = e * psize; - assert n >= 0 && (n + psize) <= N; - pred[n+psize-1:n] = ZeroExtend(value, psize); - return; - -// PL - non-assignment form -// ======================== - -integer PL - return VL DIV 8; - -// ElemFFR[] - non-assignment form -// =============================== - -bit ElemFFR[integer e, integer esize] - return ElemP[_FFR, e, esize]; - -// ElemFFR[] - assignment form -// =========================== - -ElemFFR[integer e, integer esize] = bit value - integer psize = esize DIV 8; - integer n = e * psize; - assert n >= 0 && (n + psize) <= PL; - _FFR[n+psize-1:n] = ZeroExtend(value, psize); - return; - -// FFR[] - non-assignment form -// =========================== - -bits(width) FFR[] - assert width == PL; - return _FFR[width-1:0]; - -// FFR[] - assignment form -// ======================= - -FFR[] = bits(width) value - assert width == PL; - if ConstrainUnpredictableBool(Unpredictable_SVEZEROUPPER) then - _FFR = ZeroExtend(value); - else - _FFR[width-1:0] = value; - -// FPCompareNE() -// ============= - -boolean FPCompareNE(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - if type1==FPType_SNaN || type1==FPType_QNaN || type2==FPType_SNaN || type2==FPType_QNaN then - result = TRUE; - if type1==FPType_SNaN || type2==FPType_SNaN then - FPProcessException(FPExc_InvalidOp, fpcr); - else // All non-NaN cases can be evaluated on the values produced by FPUnpack() - result = (value1 != value2); - return result; - -// FPCompareUN() -// ============= - -boolean FPCompareUN(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - if type1==FPType_SNaN || type2==FPType_SNaN then - FPProcessException(FPExc_InvalidOp, fpcr); - return (type1==FPType_SNaN || type1==FPType_QNaN || type2==FPType_SNaN || type2==FPType_QNaN); - -// FPConvertNaN() -// ============== -// Converts a NaN of one floating-point type1 to another - -bits(M) FPConvertNaN(bits(N) op) - assert N IN {16,32,64}; - assert M IN {16,32,64}; - bits(M) result; - bits(51) frac; - - sign = op[N-1]; - - // Unpack payload from input NaN - case N of - when 64 frac = op[50:0]; - when 32 frac = op[21:0]:Zeros(29); - when 16 frac = op[8:0]:Zeros(42); - - // Repack payload into output NaN, while - // converting an SNaN to a QNaN. - case M of - when 64 result = sign:Ones(M-52):frac; - when 32 result = sign:Ones(M-23):frac[50:29]; - when 16 result = sign:Ones(M-10):frac[50:42]; - - return result; - -// FPRoundCV() -// =========== -// Used for FP [-] FP conversion instructions. -// For half-precision data ignores FZ16 and observes AHP. - -bits(N) FPRoundCV(real op, FPCRType fpcr, FPRounding rounding) - fpcr.FZ16 = '0'; - boolean isbfloat = FALSE; - return FPRoundBase(op, fpcr, rounding, isbfloat); - -// FPUnpackCV() -// ============ -// -// Used for FP [-] FP conversion instructions. -// For half-precision data ignores FZ16 and observes AHP. - -(FPType, bit, real) FPUnpackCV(bits(N) fpval, FPCRType fpcr) - fpcr.FZ16 = '0'; - (fp_type, sign, value) = FPUnpackBase(fpval, fpcr); - return (fp_type, sign, value); - -// FPConvert() -// =========== - -// Convert floating point OP with N-bit precision to M-bit precision, -// with rounding controlled by ROUNDING. -// This is used by the FP-to-FP conversion instructions and so for -// half-precision data ignores FZ16, but observes AHP. - -bits(M) FPConvert(bits(N) op, FPCRType fpcr, FPRounding rounding) - assert M IN {16,32,64}; - assert N IN {16,32,64}; - bits(M) result; - - // Unpack floating-point operand optionally with flush-to-zero. - (fptype,sign,value) = FPUnpackCV(op, fpcr); - - alt_hp = (M == 16) && (fpcr.AHP == '1'); - - if fptype == FPType_SNaN || fptype == FPType_QNaN then - if alt_hp then - result = FPZero(sign); - elsif fpcr.DN == '1' then - result = FPDefaultNaN(); - else - result = FPConvertNaN(op); - if fptype == FPType_SNaN || alt_hp then - FPProcessException(FPExc_InvalidOp,fpcr); - elsif fptype == FPType_Infinity then - if alt_hp then - result = sign:Ones(M-1); - FPProcessException(FPExc_InvalidOp, fpcr); - else - result = FPInfinity(sign); - elsif fptype == FPType_Zero then - result = FPZero(sign); - else - result = FPRoundCV(value, fpcr, rounding); - return result; - -// FPConvert() -// =========== - -bits(M) FPConvert(bits(N) op, FPCRType fpcr) - return FPConvert(op, fpcr, FPRoundingMode(fpcr)); - -// FPConvertSVE() -// ============== - -bits(M) FPConvertSVE(bits(N) op, FPCRType fpcr, FPRounding rounding) - fpcr.AHP = '0'; - return FPConvert(op, fpcr, rounding); - -// FPConvertSVE() -// ============== - -bits(M) FPConvertSVE(bits(N) op, FPCRType fpcr) - fpcr.AHP = '0'; - return FPConvert(op, fpcr, FPRoundingMode(fpcr)); - -// FPExpCoefficient() -// ================== - -bits(N) FPExpCoefficient[integer index] - assert N IN {16,32,64}; - integer result; - - if N == 16 then - case index of - when 0 result = 0x0000; - when 1 result = 0x0016; - when 2 result = 0x002d; - when 3 result = 0x0045; - when 4 result = 0x005d; - when 5 result = 0x0075; - when 6 result = 0x008e; - when 7 result = 0x00a8; - when 8 result = 0x00c2; - when 9 result = 0x00dc; - when 10 result = 0x00f8; - when 11 result = 0x0114; - when 12 result = 0x0130; - when 13 result = 0x014d; - when 14 result = 0x016b; - when 15 result = 0x0189; - when 16 result = 0x01a8; - when 17 result = 0x01c8; - when 18 result = 0x01e8; - when 19 result = 0x0209; - when 20 result = 0x022b; - when 21 result = 0x024e; - when 22 result = 0x0271; - when 23 result = 0x0295; - when 24 result = 0x02ba; - when 25 result = 0x02e0; - when 26 result = 0x0306; - when 27 result = 0x032e; - when 28 result = 0x0356; - when 29 result = 0x037f; - when 30 result = 0x03a9; - when 31 result = 0x03d4; - - elsif N == 32 then - case index of - when 0 result = 0x000000; - when 1 result = 0x0164d2; - when 2 result = 0x02cd87; - when 3 result = 0x043a29; - when 4 result = 0x05aac3; - when 5 result = 0x071f62; - when 6 result = 0x08980f; - when 7 result = 0x0a14d5; - when 8 result = 0x0b95c2; - when 9 result = 0x0d1adf; - when 10 result = 0x0ea43a; - when 11 result = 0x1031dc; - when 12 result = 0x11c3d3; - when 13 result = 0x135a2b; - when 14 result = 0x14f4f0; - when 15 result = 0x16942d; - when 16 result = 0x1837f0; - when 17 result = 0x19e046; - when 18 result = 0x1b8d3a; - when 19 result = 0x1d3eda; - when 20 result = 0x1ef532; - when 21 result = 0x20b051; - when 22 result = 0x227043; - when 23 result = 0x243516; - when 24 result = 0x25fed7; - when 25 result = 0x27cd94; - when 26 result = 0x29a15b; - when 27 result = 0x2b7a3a; - when 28 result = 0x2d583f; - when 29 result = 0x2f3b79; - when 30 result = 0x3123f6; - when 31 result = 0x3311c4; - when 32 result = 0x3504f3; - when 33 result = 0x36fd92; - when 34 result = 0x38fbaf; - when 35 result = 0x3aff5b; - when 36 result = 0x3d08a4; - when 37 result = 0x3f179a; - when 38 result = 0x412c4d; - when 39 result = 0x4346cd; - when 40 result = 0x45672a; - when 41 result = 0x478d75; - when 42 result = 0x49b9be; - when 43 result = 0x4bec15; - when 44 result = 0x4e248c; - when 45 result = 0x506334; - when 46 result = 0x52a81e; - when 47 result = 0x54f35b; - when 48 result = 0x5744fd; - when 49 result = 0x599d16; - when 50 result = 0x5bfbb8; - when 51 result = 0x5e60f5; - when 52 result = 0x60ccdf; - when 53 result = 0x633f89; - when 54 result = 0x65b907; - when 55 result = 0x68396a; - when 56 result = 0x6ac0c7; - when 57 result = 0x6d4f30; - when 58 result = 0x6fe4ba; - when 59 result = 0x728177; - when 60 result = 0x75257d; - when 61 result = 0x77d0df; - when 62 result = 0x7a83b3; - when 63 result = 0x7d3e0c; - - else // N == 64 - case index of - when 0 result = 0x0000000000000; - when 1 result = 0x02C9A3E778061; - when 2 result = 0x059B0D3158574; - when 3 result = 0x0874518759BC8; - when 4 result = 0x0B5586CF9890F; - when 5 result = 0x0E3EC32D3D1A2; - when 6 result = 0x11301D0125B51; - when 7 result = 0x1429AAEA92DE0; - when 8 result = 0x172B83C7D517B; - when 9 result = 0x1A35BEB6FCB75; - when 10 result = 0x1D4873168B9AA; - when 11 result = 0x2063B88628CD6; - when 12 result = 0x2387A6E756238; - when 13 result = 0x26B4565E27CDD; - when 14 result = 0x29E9DF51FDEE1; - when 15 result = 0x2D285A6E4030B; - when 16 result = 0x306FE0A31B715; - when 17 result = 0x33C08B26416FF; - when 18 result = 0x371A7373AA9CB; - when 19 result = 0x3A7DB34E59FF7; - when 20 result = 0x3DEA64C123422; - when 21 result = 0x4160A21F72E2A; - when 22 result = 0x44E086061892D; - when 23 result = 0x486A2B5C13CD0; - when 24 result = 0x4BFDAD5362A27; - when 25 result = 0x4F9B2769D2CA7; - when 26 result = 0x5342B569D4F82; - when 27 result = 0x56F4736B527DA; - when 28 result = 0x5AB07DD485429; - when 29 result = 0x5E76F15AD2148; - when 30 result = 0x6247EB03A5585; - when 31 result = 0x6623882552225; - when 32 result = 0x6A09E667F3BCD; - when 33 result = 0x6DFB23C651A2F; - when 34 result = 0x71F75E8EC5F74; - when 35 result = 0x75FEB564267C9; - when 36 result = 0x7A11473EB0187; - when 37 result = 0x7E2F336CF4E62; - when 38 result = 0x82589994CCE13; - when 39 result = 0x868D99B4492ED; - when 40 result = 0x8ACE5422AA0DB; - when 41 result = 0x8F1AE99157736; - when 42 result = 0x93737B0CDC5E5; - when 43 result = 0x97D829FDE4E50; - when 44 result = 0x9C49182A3F090; - when 45 result = 0xA0C667B5DE565; - when 46 result = 0xA5503B23E255D; - when 47 result = 0xA9E6B5579FDBF; - when 48 result = 0xAE89F995AD3AD; - when 49 result = 0xB33A2B84F15FB; - when 50 result = 0xB7F76F2FB5E47; - when 51 result = 0xBCC1E904BC1D2; - when 52 result = 0xC199BDD85529C; - when 53 result = 0xC67F12E57D14B; - when 54 result = 0xCB720DCEF9069; - when 55 result = 0xD072D4A07897C; - when 56 result = 0xD5818DCFBA487; - when 57 result = 0xDA9E603DB3285; - when 58 result = 0xDFC97337B9B5F; - when 59 result = 0xE502EE78B3FF6; - when 60 result = 0xEA4AFA2A490DA; - when 61 result = 0xEFA1BEE615A27; - when 62 result = 0xF50765B6E4540; - when 63 result = 0xFA7C1819E90D8; - - return result[N-1:0]; - -// FPExpA() -// ======== - -bits(N) FPExpA(bits(N) op) - assert N IN {16,32,64}; - bits(N) result; - bits(N) coeff; - integer idx = if N == 16 then UInt(op[4:0]) else UInt(op[5:0]); - coeff = FPExpCoefficient[idx]; - if N == 16 then - result[15:0] = '0':op[9:5]:coeff[9:0]; - elsif N == 32 then - result[31:0] = '0':op[13:6]:coeff[22:0]; - else // N == 64 - result[63:0] = '0':op[16:6]:coeff[51:0]; - - return result; - -// FPMinNormal() -// ============= - -bits(N) FPMinNormal(bit sign) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - exp = Zeros(E-1):'1'; - frac = Zeros(F); - return sign : exp : frac; - -// FPOne() -// ======= - -bits(N) FPOne(bit sign) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - exp = '0':Ones(E-1); - frac = Zeros(F); - return sign : exp : frac; - -// FPPointFive() -// ============= - -bits(N) FPPointFive(bit sign) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - (E + 1); - exp = '0':Ones(E-2):'0'; - frac = Zeros(F); - return sign : exp : frac; - -// FPProcess() -// =========== - -bits(N) FPProcess(bits(N) input) - bits(N) result; - assert N IN {16,32,64}; - (fptype,sign,value) = FPUnpack(input, FPCR); - if fptype == FPType_SNaN || fptype == FPType_QNaN then - result = FPProcessNaN(fptype, input, FPCR); - elsif fptype == FPType_Infinity then - result = FPInfinity(sign); - elsif fptype == FPType_Zero then - result = FPZero(sign); - else - result = FPRound(value, FPCR); - return result; - -// FPScale() -// ========= - -bits(N) FPScale(bits (N) op, integer scale, FPCRType fpcr) - assert N IN {16,32,64}; - (fptype,sign,value) = FPUnpack(op, fpcr); - if fptype == FPType_SNaN || fptype == FPType_QNaN then - result = FPProcessNaN(fptype, op, fpcr); - elsif fptype == FPType_Zero then - result = FPZero(sign); - elsif fptype == FPType_Infinity then - result = FPInfinity(sign); - else - result = FPRound(value * (2.0^scale), fpcr); - return result; - -// FPProcessNaNs3() -// ================ -// -// The boolean part of the return value says whether a NaN has been found and -// processed. The bits(N) part is only relevant if it has and supplies the -// result of the operation. -// -// The 'fpcr' argument supplies FPCR control bits. Status information is -// updated directly in the FPSR where appropriate. - -(boolean, bits(N)) FPProcessNaNs3(FPType type1, FPType type2, FPType type3, - bits(N) op1, bits(N) op2, bits(N) op3, - FPCRType fpcr) - assert N IN {16,32,64}; - if type1 == FPType_SNaN then - done = TRUE; result = FPProcessNaN(type1, op1, fpcr); - elsif type2 == FPType_SNaN then - done = TRUE; result = FPProcessNaN(type2, op2, fpcr); - elsif type3 == FPType_SNaN then - done = TRUE; result = FPProcessNaN(type3, op3, fpcr); - elsif type1 == FPType_QNaN then - done = TRUE; result = FPProcessNaN(type1, op1, fpcr); - elsif type2 == FPType_QNaN then - done = TRUE; result = FPProcessNaN(type2, op2, fpcr); - elsif type3 == FPType_QNaN then - done = TRUE; result = FPProcessNaN(type3, op3, fpcr); - else - done = FALSE; result = Zeros(); // 'Don't care' result - return (done, result); - -// FPMulAdd() -// ========== -// -// Calculates addend + op1*op2 with a single rounding. - -bits(N) FPMulAdd(bits(N) addend, bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - rounding = FPRoundingMode(fpcr); - (typeA,signA,valueA) = FPUnpack(addend, fpcr); - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - inf1 = (type1 == FPType_Infinity); zero1 = (type1 == FPType_Zero); - inf2 = (type2 == FPType_Infinity); zero2 = (type2 == FPType_Zero); - (done,result) = FPProcessNaNs3(typeA, type1, type2, addend, op1, op2, fpcr); - - if typeA == FPType_QNaN && ((inf1 && zero2) || (zero1 && inf2)) then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - - if !done then - infA = (typeA == FPType_Infinity); zeroA = (typeA == FPType_Zero); - - // Determine sign and type1 product will have if it does not cause an Invalid - // Operation. - signP = sign1 EOR sign2; - infP = inf1 || inf2; - zeroP = zero1 || zero2; - - // Non SNaN-generated Invalid Operation cases are multiplies of zero by infinity and - // additions of opposite-signed infinities. - if (inf1 && zero2) || (zero1 && inf2) || (infA && infP && signA != signP) then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - - // Other cases involving infinities produce an infinity of the same sign. - elsif (infA && signA == '0') || (infP && signP == '0') then - result = FPInfinity('0'); - elsif (infA && signA == '1') || (infP && signP == '1') then - result = FPInfinity('1'); - - // Cases where the result is exactly zero and its sign is not determined by the - // rounding mode are additions of same-signed zeros. - elsif zeroA && zeroP && signA == signP then - result = FPZero(signA); - - // Otherwise calculate numerical result and round it. - else - result_value = valueA + (value1 * value2); - if result_value == 0.0 then // Sign of exact zero result depends on rounding mode - result_sign = if rounding == FPRounding_NEGINF then '1' else '0'; - result = FPZero(result_sign); - else - result = FPRound(result_value, fpcr); - - return result; - -// FPTrigMAddCoefficient() -// ======================= - -bits(N) FPTrigMAddCoefficient[integer index] - assert N IN {16,32,64}; - integer result; - - if N == 16 then - case index of - when 0 result = 0x3c00; - when 1 result = 0xb155; - when 2 result = 0x2030; - when 3 result = 0x0000; - when 4 result = 0x0000; - when 5 result = 0x0000; - when 6 result = 0x0000; - when 7 result = 0x0000; - when 8 result = 0x3c00; - when 9 result = 0xb800; - when 10 result = 0x293a; - when 11 result = 0x0000; - when 12 result = 0x0000; - when 13 result = 0x0000; - when 14 result = 0x0000; - when 15 result = 0x0000; - elsif N == 32 then - case index of - when 0 result = 0x3f800000; - when 1 result = 0xbe2aaaab; - when 2 result = 0x3c088886; - when 3 result = 0xb95008b9; - when 4 result = 0x36369d6d; - when 5 result = 0x00000000; - when 6 result = 0x00000000; - when 7 result = 0x00000000; - when 8 result = 0x3f800000; - when 9 result = 0xbf000000; - when 10 result = 0x3d2aaaa6; - when 11 result = 0xbab60705; - when 12 result = 0x37cd37cc; - when 13 result = 0x00000000; - when 14 result = 0x00000000; - when 15 result = 0x00000000; - else // N == 64 - case index of - when 0 result = 0x3ff0000000000000; - when 1 result = 0xbfc5555555555543; - when 2 result = 0x3f8111111110f30c; - when 3 result = 0xbf2a01a019b92fc6; - when 4 result = 0x3ec71de351f3d22b; - when 5 result = 0xbe5ae5e2b60f7b91; - when 6 result = 0x3de5d8408868552f; - when 7 result = 0x0000000000000000; - when 8 result = 0x3ff0000000000000; - when 9 result = 0xbfe0000000000000; - when 10 result = 0x3fa5555555555536; - when 11 result = 0xbf56c16c16c13a0b; - when 12 result = 0x3efa01a019b1e8d8; - when 13 result = 0xbe927e4f7282f468; - when 14 result = 0x3e21ee96d2641b13; - when 15 result = 0xbda8f76380fbb401; - - return result[N-1:0]; - -// FPTrigMAdd() -// ============ - -bits(N) FPTrigMAdd(integer x, bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - assert x >= 0; - assert x < 8; - bits(N) coeff; - - if op2[N-1] == '1' then - x = x + 8; - op2[N-1] = '0'; - - coeff = FPTrigMAddCoefficient[x]; - result = FPMulAdd(coeff, op1, op2, fpcr); - - return result; - -// FPTrigSMul() -// ============ - -bits(N) FPTrigSMul(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - result = FPMul(op1, op1, fpcr); - (fptype, sign, value) = FPUnpack(result, fpcr); - if (fptype != FPType_QNaN) && (fptype != FPType_SNaN) then - result[N-1] = op2[0]; - - return result; - -// FPTrigSSel() -// ============ - -bits(N) FPTrigSSel(bits(N) op1, bits(N) op2) - assert N IN {16,32,64}; - bits(N) result; - - if op2[0] == '1' then - result = FPOne(op2[1]); - else - result = op1; - result[N-1] = result[N-1] EOR op2[1]; - - return result; - -// FirstActive() -// ============= - -bit FirstActive(bits(N) mask, bits(N) x, integer esize) - integer elements = N DIV (esize DIV 8); - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then return ElemP[x, e, esize]; - return '0'; - -// HaveSVEFP32MatMulExt() -// ====================== -// Returns TRUE if single-precision floating-point matrix multiply instruction support implemented and FALSE otherwise. - -boolean HaveSVEFP32MatMulExt() - return HaveSVE() && boolean IMPLEMENTATION_DEFINED "Have SVE FP32 Matrix Multiply extension"; - -// HaveSVEFP64MatMulExt() -// ====================== -// Returns TRUE if double-precision floating-point matrix multiply instruction support implemented and FALSE otherwise. - -boolean HaveSVEFP64MatMulExt() - return HaveSVE() && boolean IMPLEMENTATION_DEFINED "Have SVE FP64 Matrix Multiply extension"; - -// IsEven() -// ======== - -boolean IsEven(integer val) - return val MOD 2 == 0; - -// LastActive() -// ============ - -bit LastActive(bits(N) mask, bits(N) x, integer esize) - integer elements = N DIV (esize DIV 8); - for e = elements-1 downto 0 - if ElemP[mask, e, esize] == '1' then return ElemP[x, e, esize]; - return '0'; - -// LastActiveElement() -// =================== - -integer LastActiveElement(bits(N) mask, integer esize) - assert esize IN {8, 16, 32, 64}; - integer elements = VL DIV esize; - for e = elements-1 downto 0 - if ElemP[mask, e, esize] == '1' then return e; - return -1; - -// MemNF[] - non-assignment form -// ============================= - -(bits(8*size), boolean) MemNF[bits(64) address, integer size, AccType acctype] - assert size IN {1, 2, 4, 8, 16}; - bits(8*size) value; - - aligned = (address == Align(address, size)); - A = SCTLR[].A; - - if !aligned && (A == '1') then - return (bits(8*size) UNKNOWN, TRUE); - - atomic = aligned || size == 1; - - if !atomic then - (value[7:0], bad) = MemSingleNF[address, 1, acctype, aligned]; - - if bad then - return (bits(8*size) UNKNOWN, TRUE); - - // For subsequent bytes it is CONSTRAINED UNPREDICTABLE whether an unaligned Device memory - // access will generate an Alignment Fault, as to get this far means the first byte did - // not, so we must be changing to a new translation page. - if !aligned then - c = ConstrainUnpredictable(Unpredictable_DEVPAGE2); - assert c IN {Constraint_FAULT, Constraint_NONE}; - if c == Constraint_NONE then aligned = TRUE; - - for i = 1 to size-1 - (value[8*i+7:8*i], bad) = MemSingleNF[address+i, 1, acctype, aligned]; - - if bad then - return (bits(8*size) UNKNOWN, TRUE); - else - (value, bad) = MemSingleNF[address, size, acctype, aligned]; - if bad then - return (bits(8*size) UNKNOWN, TRUE); - - if BigEndian() then - value = BigEndianReverse(value); - - return (value, FALSE); - -// MemSingleNF[] - non-assignment form -// =================================== - -(bits(8*size), boolean) MemSingleNF[bits(64) address, integer size, AccType acctype, boolean wasaligned] - bits(8*size) value; - boolean iswrite = FALSE; - AddressDescriptor memaddrdesc; - - // Implementation may suppress NF load for any reason - if ConstrainUnpredictableBool(Unpredictable_NONFAULT) then - return (bits(8*size) UNKNOWN, TRUE); - - // MMU or MPU - memaddrdesc = AArch64.TranslateAddress(address, acctype, iswrite, wasaligned, size); - - // Non-fault load from Device memory must not be performed externally - if memaddrdesc.memattrs.memtype == MemType_Device then - return (bits(8*size) UNKNOWN, TRUE); - - // Check for aborts or debug exceptions - if IsFault(memaddrdesc) then - return (bits(8*size) UNKNOWN, TRUE); - - // Memory array access - accdesc = CreateAccessDescriptor(acctype); - if HaveMTEExt() then - if AArch64.AccessIsTagChecked(address, acctype) then - bits(4) ptag = AArch64.PhysicalTag(address); - if !AArch64.CheckTag(memaddrdesc, ptag, iswrite) then - return (bits(8*size) UNKNOWN, TRUE); - value = _Mem[memaddrdesc, size, accdesc]; - - return (value, FALSE); - -// NoneActive() -// ============ - -bit NoneActive(bits(N) mask, bits(N) x, integer esize) - integer elements = N DIV (esize DIV 8); - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' && ElemP[x, e, esize] == '1' then return '0'; - return '1'; - -// P[] - non-assignment form -// ========================= - -bits(width) P[integer n] - assert n >= 0 && n <= 31; - assert width == PL; - return _P[n][width-1:0]; - -// P[] - assignment form -// ===================== - -P[integer n] = bits(width) value - assert n >= 0 && n <= 31; - assert width == PL; - if ConstrainUnpredictableBool(Unpredictable_SVEZEROUPPER) then - _P[n] = ZeroExtend(value); - else - _P[n][width-1:0] = value; - -// PredTest() -// ========== - -bits(4) PredTest(bits(N) mask, bits(N) result, integer esize) - bit n = FirstActive(mask, result, esize); - bit z = NoneActive(mask, result, esize); - bit c = NOT LastActive(mask, result, esize); - bit v = '0'; - return n:z:c:v; - -// Elem[] - non-assignment form -// ============================ - -bits(size) Elem[bits(N) vector, integer e, integer size] - assert e >= 0 && (e+1)*size <= N; - return vector[e*size+size-1 : e*size]; - -// Elem[] - non-assignment form -// ============================ - -bits(size) Elem[bits(N) vector, integer e] - return Elem[vector, e, size]; - -// Elem[] - assignment form -// ======================== - -Elem[bits(N) &vector, integer e, integer size] = bits(size) value - assert e >= 0 && (e+1)*size <= N; - vector[(e+1)*size-1:e*size] = value; - return; - -// Elem[] - assignment form -// ======================== - -Elem[bits(N) &vector, integer e] = bits(size) value - Elem[vector, e, size] = value; - return; - -// FPAdd() -// ======= - -bits(N) FPAdd(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - rounding = FPRoundingMode(fpcr); - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - inf1 = (type1 == FPType_Infinity); inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); zero2 = (type2 == FPType_Zero); - if inf1 && inf2 && sign1 == NOT(sign2) then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - elsif (inf1 && sign1 == '0') || (inf2 && sign2 == '0') then - result = FPInfinity('0'); - elsif (inf1 && sign1 == '1') || (inf2 && sign2 == '1') then - result = FPInfinity('1'); - elsif zero1 && zero2 && sign1 == sign2 then - result = FPZero(sign1); - else - result_value = value1 + value2; - if result_value == 0.0 then // Sign of exact zero result depends on rounding mode - result_sign = if rounding == FPRounding_NEGINF then '1' else '0'; - result = FPZero(result_sign); - else - result = FPRound(result_value, fpcr, rounding); - return result; - -// FPMax() -// ======= - -bits(N) FPMax(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - if value1 > value2 then - (fptype,sign,value) = (type1,sign1,value1); - else - (fptype,sign,value) = (type2,sign2,value2); - if fptype == FPType_Infinity then - result = FPInfinity(sign); - elsif fptype == FPType_Zero then - sign = sign1 AND sign2; // Use most positive sign - result = FPZero(sign); - else - // The use of FPRound() covers the case where there is a trapped underflow exception - // for a denormalized number even though the result is exact. - result = FPRound(value, fpcr); - return result; - -// FPMaxNum() -// ========== - -bits(N) FPMaxNum(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,-,-) = FPUnpack(op1, fpcr); - (type2,-,-) = FPUnpack(op2, fpcr); - - // treat a single quiet-NaN as -Infinity - if type1 == FPType_QNaN && type2 != FPType_QNaN then - op1 = FPInfinity('1'); - elsif type1 != FPType_QNaN && type2 == FPType_QNaN then - op2 = FPInfinity('1'); - - return FPMax(op1, op2, fpcr); - -// FPMin() -// ======= - -bits(N) FPMin(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - if value1 < value2 then - (fptype,sign,value) = (type1,sign1,value1); - else - (fptype,sign,value) = (type2,sign2,value2); - if fptype == FPType_Infinity then - result = FPInfinity(sign); - elsif fptype == FPType_Zero then - sign = sign1 OR sign2; // Use most negative sign - result = FPZero(sign); - else - // The use of FPRound() covers the case where there is a trapped underflow exception - // for a denormalized number even though the result is exact. - result = FPRound(value, fpcr); - return result; - -// FPMinNum() -// ========== - -bits(N) FPMinNum(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,-,-) = FPUnpack(op1, fpcr); - (type2,-,-) = FPUnpack(op2, fpcr); - - // Treat a single quiet-NaN as +Infinity - if type1 == FPType_QNaN && type2 != FPType_QNaN then - op1 = FPInfinity('0'); - elsif type1 != FPType_QNaN && type2 == FPType_QNaN then - op2 = FPInfinity('0'); - - return FPMin(op1, op2, fpcr); - -enumeration ReduceOp {ReduceOp_FMINNUM, ReduceOp_FMAXNUM, - ReduceOp_FMIN, ReduceOp_FMAX, - ReduceOp_FADD, ReduceOp_ADD}; - -// Reduce() -// ======== - -bits(esize) Reduce(ReduceOp op, bits(N) input, integer esize) - integer half; - bits(esize) hi; - bits(esize) lo; - bits(esize) result; - - if N == esize then - return input[esize-1:0]; - - half = N DIV 2; - hi = Reduce(op, input[N-1:half], esize); - lo = Reduce(op, input[half-1:0], esize); - - case op of - when ReduceOp_FMINNUM - result = FPMinNum(lo, hi, FPCR); - when ReduceOp_FMAXNUM - result = FPMaxNum(lo, hi, FPCR); - when ReduceOp_FMIN - result = FPMin(lo, hi, FPCR); - when ReduceOp_FMAX - result = FPMax(lo, hi, FPCR); - when ReduceOp_FADD - result = FPAdd(lo, hi, FPCR); - when ReduceOp_ADD - result = lo + hi; - - return result; - -// ReducePredicated() -// ================== - -bits(esize) ReducePredicated(ReduceOp op, bits(N) input, bits(M) mask, bits(esize) identity) - assert(N == M * 8); - integer p2bits = CeilPow2(N); - bits(p2bits) operand; - integer elements = p2bits DIV esize; - - for e = 0 to elements-1 - if e * esize < N && ElemP[mask, e, esize] == '1' then - Elem[operand, e, esize] = Elem[input, e, esize]; - else - Elem[operand, e, esize] = identity; - - return Reduce(op, operand, esize); - -// Reverse() -// ========= -// Reverse subwords of M bits in an N-bit word - -bits(N) Reverse(bits(N) word, integer M) - bits(N) result; - integer sw = N DIV M; - assert N == sw * M; - for s = 0 to sw-1 - Elem[result, sw - 1 - s, M] = Elem[word, s, M]; - return result; - -enumeration SVECmp { Cmp_EQ, Cmp_NE, Cmp_GE, Cmp_GT, Cmp_LT, Cmp_LE, Cmp_UN }; - -// HighestSetBit() -// =============== - -integer HighestSetBit(bits(N) x) - for i = N-1 downto 0 - if x[i] == '1' then return i; - return -1; - -// DecodeBitMasks() -// ================ - -// Decode AArch64 bitfield and logical immediate masks which use a similar encoding structure - -(bits(M), bits(M)) DecodeBitMasks(bit immN, bits(6) imms, bits(6) immr, boolean immediate) - bits(64) tmask, wmask; - bits(6) tmask_and, wmask_and; - bits(6) tmask_or, wmask_or; - bits(6) levels; - - // Compute log2 of element size - // 2^len must be in range [2, M] - len = HighestSetBit(immN:NOT(imms)); - if len < 1 then UNDEFINED; - assert M >= (1 << len); - - // Determine S, R and S - R parameters - levels = ZeroExtend(Ones(len), 6); - - // For logical immediates an all-ones value of S is reserved - // since it would generate a useless all-ones result (many times) - if immediate && (imms AND levels) == levels then - UNDEFINED; - - S = UInt(imms AND levels); - R = UInt(immr AND levels); - diff = S - R; // 6-bit subtract with borrow - - // From a software perspective, the remaining code is equivalant to: - // esize = 1 << len; - // d = UInt(diff[len-1:0]); - // welem = ZeroExtend(Ones(S + 1), esize); - // telem = ZeroExtend(Ones(d + 1), esize); - // wmask = Replicate(ROR(welem, R)); - // tmask = Replicate(telem); - // return (wmask, tmask); - - // Compute "top mask" - tmask_and = diff[5:0] OR NOT(levels); - tmask_or = diff[5:0] AND levels; - - tmask = Ones(64); - tmask = ((tmask - AND Replicate(Replicate(tmask_and[0], 1) : Ones(1), 32)) - OR Replicate(Zeros(1) : Replicate(tmask_or[0], 1), 32)); - // optimization of first step: - // tmask = Replicate(tmask_and[0] : '1', 32); - tmask = ((tmask - AND Replicate(Replicate(tmask_and[1], 2) : Ones(2), 16)) - OR Replicate(Zeros(2) : Replicate(tmask_or[1], 2), 16)); - tmask = ((tmask - AND Replicate(Replicate(tmask_and[2], 4) : Ones(4), 8)) - OR Replicate(Zeros(4) : Replicate(tmask_or[2], 4), 8)); - tmask = ((tmask - AND Replicate(Replicate(tmask_and[3], 8) : Ones(8), 4)) - OR Replicate(Zeros(8) : Replicate(tmask_or[3], 8), 4)); - tmask = ((tmask - AND Replicate(Replicate(tmask_and[4], 16) : Ones(16), 2)) - OR Replicate(Zeros(16) : Replicate(tmask_or[4], 16), 2)); - tmask = ((tmask - AND Replicate(Replicate(tmask_and[5], 32) : Ones(32), 1)) - OR Replicate(Zeros(32) : Replicate(tmask_or[5], 32), 1)); - - // Compute "wraparound mask" - wmask_and = immr OR NOT(levels); - wmask_or = immr AND levels; - - wmask = Zeros(64); - wmask = ((wmask - AND Replicate(Ones(1) : Replicate(wmask_and[0], 1), 32)) - OR Replicate(Replicate(wmask_or[0], 1) : Zeros(1), 32)); - // optimization of first step: - // wmask = Replicate(wmask_or[0] : '0', 32); - wmask = ((wmask - AND Replicate(Ones(2) : Replicate(wmask_and[1], 2), 16)) - OR Replicate(Replicate(wmask_or[1], 2) : Zeros(2), 16)); - wmask = ((wmask - AND Replicate(Ones(4) : Replicate(wmask_and[2], 4), 8)) - OR Replicate(Replicate(wmask_or[2], 4) : Zeros(4), 8)); - wmask = ((wmask - AND Replicate(Ones(8) : Replicate(wmask_and[3], 8), 4)) - OR Replicate(Replicate(wmask_or[3], 8) : Zeros(8), 4)); - wmask = ((wmask - AND Replicate(Ones(16) : Replicate(wmask_and[4], 16), 2)) - OR Replicate(Replicate(wmask_or[4], 16) : Zeros(16), 2)); - wmask = ((wmask - AND Replicate(Ones(32) : Replicate(wmask_and[5], 32), 1)) - OR Replicate(Replicate(wmask_or[5], 32) : Zeros(32), 1)); - - if diff[6] != '0' then // borrow from S - R - wmask = wmask AND tmask; - else - wmask = wmask OR tmask; - - return (wmask[M-1:0], tmask[M-1:0]); - -// SVEMoveMaskPreferred() -// ====================== -// Return FALSE if a bitmask immediate encoding would generate an immediate -// value that could also be represented by a single DUP instruction. -// Used as a condition for the preferred MOV<-DUPM alias. - -boolean SVEMoveMaskPreferred(bits(13) imm13) - bits(64) imm; - (imm, -) = DecodeBitMasks(imm13[12], imm13[5:0], imm13[11:6], TRUE); - - // Check for 8 bit immediates - if !IsZero(imm[7:0]) then - // Check for 'ffffffffffffffxy' or '00000000000000xy' - if IsZero(imm[63:7]) || IsOnes(imm[63:7]) then - return FALSE; - - // Check for 'ffffffxyffffffxy' or '000000xy000000xy' - if imm[63:32] == imm[31:0] && (IsZero(imm[31:7]) || IsOnes(imm[31:7])) then - return FALSE; - - // Check for 'ffxyffxyffxyffxy' or '00xy00xy00xy00xy' - if imm[63:32] == imm[31:0] && imm[31:16] == imm[15:0] && (IsZero(imm[15:7]) || IsOnes(imm[15:7])) then - return FALSE; - - // Check for 'xyxyxyxyxyxyxyxy' - if imm[63:32] == imm[31:0] && imm[31:16] == imm[15:0] && (imm[15:8] == imm[7:0]) then - return FALSE; - - // Check for 16 bit immediates - else - // Check for 'ffffffffffffxy00' or '000000000000xy00' - if IsZero(imm[63:15]) || IsOnes(imm[63:15]) then - return FALSE; - - // Check for 'ffffxy00ffffxy00' or '0000xy000000xy00' - if imm[63:32] == imm[31:0] && (IsZero(imm[31:7]) || IsOnes(imm[31:7])) then - return FALSE; - - // Check for 'xy00xy00xy00xy00' - if imm[63:32] == imm[31:0] && imm[31:16] == imm[15:0] then - return FALSE; - - return TRUE; - -// Z[] - non-assignment form -// ========================= - -bits(width) Z[integer n] - assert n >= 0 && n <= 31; - assert width == VL; - return _Z[n][width-1:0]; - -// Z[] - assignment form -// ===================== - -Z[integer n] = bits(width) value - assert n >= 0 && n <= 31; - assert width == VL; - if ConstrainUnpredictableBool(Unpredictable_SVEZEROUPPER) then - _Z[n] = ZeroExtend(value); - else - _Z[n][width-1:0] = value; - -type CNTKCTLType; - -// CNTKCTL[] - non-assignment form -// =============================== - -CNTKCTLType CNTKCTL[] - bits(32) r; - if IsInHost() then - r = CNTHCTL_EL2; - return r; - r = CNTKCTL_EL1; - return r; - -type CPACRType; - -// CPACR[] - non-assignment form -// ============================= - -CPACRType CPACR[] - bits(32) r; - if IsInHost() then - r = CPTR_EL2; - return r; - r = CPACR_EL1; - return r; - -// AArch64.CheckSystemAccess() -// =========================== -// Checks for traps by NV access. - -AArch64.CheckSystemAccess(bits(2) op0, bits(3) op1, bits(4) crn, - bits(4) crm, bits(3) op2, bits(5) rt, bit read) - - return; - -// AArch64.ChooseNonExcludedTag() -// ============================== -// Return a tag derived from the start and the offset values, excluding -// any tags in the given mask. - -bits(4) AArch64.ChooseNonExcludedTag(bits(4) tag, bits(4) offset, bits(16) exclude) - if IsOnes(exclude) then - return '0000'; - - if offset == '0000' then - while exclude[UInt(tag)] == '1' do - tag = tag + '0001'; - - while offset != '0000' do - offset = offset - '0001'; - tag = tag + '0001'; - while exclude[UInt(tag)] == '1' do - tag = tag + '0001'; - - return tag; - -// AArch64.ExecutingBROrBLROrRetInstr() -// ==================================== -// Returns TRUE if current instruction is a BR, BLR, RET, B[L]RA[B][Z], or RETA[B]. - -boolean AArch64.ExecutingBROrBLROrRetInstr() - if !HaveBTIExt() then return FALSE; - - instr = ThisInstr(); - if instr[31:25] == '1101011' && instr[20:16] == '11111' then - opc = instr[24:21]; - return opc != '0101'; - else - return FALSE; - -// AArch64.ExecutingBTIInstr() -// =========================== -// Returns TRUE if current instruction is a BTI. - -boolean AArch64.ExecutingBTIInstr() - if !HaveBTIExt() then return FALSE; - - instr = ThisInstr(); - if instr[31:22] == '1101010100' && instr[21:12] == '0000110010' && instr[4:0] == '11111' then - CRm = instr[11:8]; - op2 = instr[7:5]; - return (CRm == '0100' && op2[0] == '0'); - else - return FALSE; - -// AArch64.ExecutingERETInstr() -// ============================ -// Returns TRUE if current instruction is ERET. - -boolean AArch64.ExecutingERETInstr() - instr = ThisInstr(); - return instr[31:12] == '11010110100111110000'; - -// AArch64.GetMinELSecurityState() -// =============================== -// Return the minimum exception level and security state required. - -(bits(2), boolean) AArch64.GetMinELSecurityState(bits(3) op1) - boolean need_secure = FALSE; - bits(2) min_EL; - - case op1 of - when '00x', '010' - min_EL = EL1; - when '011' - min_EL = EL0; - when '100' - min_EL = EL2; - when '101' - if !HaveVirtHostExt() then - UNDEFINED; - min_EL = EL2; - when '110' - min_EL = EL3; - when '111' - min_EL = EL1; - need_secure = TRUE; - return (min_EL, need_secure); - -// AArch64.NextRandomTagBit() -// ========================== -// Generate a random bit suitable for generating a random Allocation Tag. - -bit AArch64.NextRandomTagBit() - bits(16) lfsr = RGSR_EL1.SEED; - bit top = lfsr[5] EOR lfsr[3] EOR lfsr[2] EOR lfsr[0]; - RGSR_EL1.SEED = top:lfsr[15:1]; - return top; - -// AArch64.RandomTag() -// =================== -// Generate a random Allocation Tag. - -bits(4) AArch64.RandomTag() - bits(4) tag; - for i = 0 to 3 - tag[i] = AArch64.NextRandomTagBit(); - return tag; - -// Execute a system instruction with write (source operand). -AArch64.SysInstr(integer op0, integer op1, integer crn, integer crm, integer op2, bits(64) val); - -// Execute a system instruction with read (result operand). -// Returns the result of the instruction. -bits(64) AArch64.SysInstrWithResult(integer op0, integer op1, integer crn, integer crm, integer op2); - -// Read from a system register and return the contents of the register. -bits(64) AArch64.SysRegRead(integer op0, integer op1, integer crn, integer crm, integer op2); - -// Write to a system register. -AArch64.SysRegWrite(integer op0, integer op1, integer crn, integer crm, integer op2, bits(64) val); - -boolean BTypeCompatible; - -// BTypeCompatible_BTI -// =================== -// This function determines whether a given hint encoding is compatible with the current value of -// PSTATE.BTYPE. A value of TRUE here indicates a valid Branch Target Identification instruction. - -boolean BTypeCompatible_BTI(bits(2) hintcode) - case hintcode of - when '00' - return FALSE; - when '01' - return PSTATE.BTYPE != '11'; - when '10' - return PSTATE.BTYPE != '10'; - when '11' - return TRUE; - -// BTypeCompatible_PACIXSP() -// ========================= -// Returns TRUE if PACIASP, PACIBSP instruction is implicit compatible with PSTATE.BTYPE, -// FALSE otherwise. - -boolean BTypeCompatible_PACIXSP() - if PSTATE.BTYPE IN {'01', '10'} then - return TRUE; - elsif PSTATE.BTYPE == '11' then - index = if PSTATE.EL == EL0 then 35 else 36; - return SCTLR[][index] == '0'; - else - return FALSE; - -bits(2) BTypeNext; - -// SetBTypeCompatible() -// ==================== -// Sets the value of BTypeCompatible global variable used by BTI - -SetBTypeCompatible(boolean x) - BTypeCompatible = x; - -// SetBTypeNext() -// ============== -// Set the value of BTypeNext global variable used by BTI - -SetBTypeNext(bits(2) x) - BTypeNext = x; - -// The _ChooseRandomNonExcludedTag function is used when GCR_EL1.RRND == '1' to generate random -// Allocation Tags. -// -// The resulting Allocation Tag is selected from the set [0,15], excluding any Allocation Tag where -// exclude[tag_value] == 1. If 'exclude' is all ones, the returned Allocation Tag is '0000'. -// -// This function is expected to generate a non-deterministic selection from the set of non-excluded -// Allocation Tags. A reasonable implementation is described by the Pseudocode used when -// GCR_EL1.RRND is 0, but with a non-deterministic implementation of NextRandomTagBit(). -bits(4) _ChooseRandomNonExcludedTag(bits(16) exclude); - -// BFXPreferred() -// ============== -// -// Return TRUE if UBFX or SBFX is the preferred disassembly of a -// UBFM or SBFM bitfield instruction. Must exclude more specific -// aliases UBFIZ, SBFIZ, UXT[BH], SXT[BHW], LSL, LSR and ASR. - -boolean BFXPreferred(bit sf, bit uns, bits(6) imms, bits(6) immr) - integer S = UInt(imms); - integer R = UInt(immr); - - // must not match UBFIZ/SBFIX alias - if UInt(imms) < UInt(immr) then - return FALSE; - - // must not match LSR/ASR/LSL alias (imms == 31 or 63) - if imms == sf:'11111' then - return FALSE; - - // must not match UXTx/SXTx alias - if immr == '000000' then - // must not match 32-bit UXT[BH] or SXT[BH] - if sf == '0' && imms IN {'000111', '001111'} then - return FALSE; - // must not match 64-bit SXT[BHW] - if sf:uns == '10' && imms IN {'000111', '001111', '011111'} then - return FALSE; - - // must be UBFX/SBFX alias - return TRUE; - -enumeration MoveWideOp {MoveWideOp_N, MoveWideOp_Z, MoveWideOp_K}; - -// MoveWidePreferred() -// =================== -// -// Return TRUE if a bitmask immediate encoding would generate an immediate -// value that could also be represented by a single MOVZ or MOVN instruction. -// Used as a condition for the preferred MOV<-ORR alias. - -boolean MoveWidePreferred(bit sf, bit immN, bits(6) imms, bits(6) immr) - integer S = UInt(imms); - integer R = UInt(immr); - integer width = if sf == '1' then 64 else 32; - - // element size must equal total immediate size - if sf == '1' && immN:imms != '1xxxxxx' then - return FALSE; - if sf == '0' && immN:imms != '00xxxxx' then - return FALSE; - - // for MOVZ must contain no more than 16 ones - if S < 16 then - // ones must not span halfword boundary when rotated - return (-R MOD 16) <= (15 - S); - - // for MOVN must contain no more than 16 zeros - if S >= width - 15 then - // zeros must not span halfword boundary when rotated - return (R MOD 16) <= (S - (width - 15)); - - return FALSE; - -enumeration ShiftType {ShiftType_LSL, ShiftType_LSR, ShiftType_ASR, ShiftType_ROR}; - -// DecodeShift() -// ============= -// Decode shift encodings - -ShiftType DecodeShift(bits(2) op) - case op of - when '00' return ShiftType_LSL; - when '01' return ShiftType_LSR; - when '10' return ShiftType_ASR; - when '11' return ShiftType_ROR; - -// ASR() -// ===== - -bits(N) ASR(bits(N) x, integer shift) - assert shift >= 0; - if shift == 0 then - result = x; - else - (result, -) = ASR_C(x, shift); - return result; - -// ROR() -// ===== - -bits(N) ROR(bits(N) x, integer shift) - assert shift >= 0; - if shift == 0 then - result = x; - else - (result, -) = ROR_C(x, shift); - return result; - -// ShiftReg() -// ========== -// Perform shift of a register operand - -bits(N) ShiftReg(integer reg, ShiftType shiftype, integer amount) - bits(N) result = X[reg]; - case shiftype of - when ShiftType_LSL result = LSL(result, amount); - when ShiftType_LSR result = LSR(result, amount); - when ShiftType_ASR result = ASR(result, amount); - when ShiftType_ROR result = ROR(result, amount); - return result; - -enumeration LogicalOp {LogicalOp_AND, LogicalOp_EOR, LogicalOp_ORR}; - -enumeration MemOp {MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH}; - -enumeration PrefetchHint {Prefetch_READ, Prefetch_WRITE, Prefetch_EXEC}; - -// Signals the memory system that memory accesses of type1 HINT to or from the specified address are -// likely in the near future. The memory system may take some action to speed up the memory -// accesses when they do occur, such as pre-loading the the specified address into one or more -// caches as indicated by the innermost cache level target (0=L1, 1=L2, etc) and non-temporal hint -// stream. Any or all prefetch hints may be treated as a NOP. A prefetch hint must not cause a -// synchronous abort due to Alignment or Translation faults and the like. Its only effect on -// software-visible state should be on caches and TLBs associated with address, which must be -// accessible by reads, writes or execution, as defined in the translation regime of the current -// Exception level. It is guaranteed not to access Device memory. -// A Prefetch_EXEC hint must not result in an access that could not be performed by a speculative -// instruction fetch, therefore if all associated MMUs are disabled, then it cannot access any -// memory location that cannot be accessed by instruction fetches. -Hint_Prefetch(bits(64) address, PrefetchHint hint, integer target, boolean stream); - -// Prefetch() -// ========== - -// Decode and execute the prefetch hint on ADDRESS specified by PRFOP - -Prefetch(bits(64) address, bits(5) prfop) - PrefetchHint hint; - integer target; - boolean stream; - - case prfop[4:3] of - when '00' hint = Prefetch_READ; // PLD: prefetch for load - when '01' hint = Prefetch_EXEC; // PLI: preload instructions - when '10' hint = Prefetch_WRITE; // PST: prepare for store - when '11' return; // unallocated hint - target = UInt(prfop[2:1]); // target cache level - stream = (prfop[0] != '0'); // streaming (non-temporal) - Hint_Prefetch(address, hint, target, stream); - return; - -enumeration MemBarrierOp { MemBarrierOp_DSB // Data Synchronization Barrier - , MemBarrierOp_DMB // Data Memory Barrier - , MemBarrierOp_ISB // Instruction Synchronization Barrier - , MemBarrierOp_SSBB // Speculative Synchronization Barrier to VA - , MemBarrierOp_PSSBB // Speculative Synchronization Barrier to PA - , MemBarrierOp_SB // Speculation Barrier - }; - -enumeration SystemHintOp { - SystemHintOp_NOP, - SystemHintOp_YIELD, - SystemHintOp_WFE, - SystemHintOp_WFI, - SystemHintOp_SEV, - SystemHintOp_SEVL, - SystemHintOp_DGH, - SystemHintOp_ESB, - SystemHintOp_PSB, - SystemHintOp_TSB, - SystemHintOp_BTI, - SystemHintOp_CSDB -}; - -enumeration PSTATEField {PSTATEField_DAIFSet, PSTATEField_DAIFClr, - PSTATEField_PAN, // Armv8.1 - PSTATEField_UAO, // Armv8.2 - PSTATEField_DIT, // Armv8.4 - PSTATEField_SSBS, - PSTATEField_TCO, // Armv8.5 - PSTATEField_SP - }; - -enumeration SystemOp {Sys_AT, Sys_DC, Sys_IC, Sys_TLBI, Sys_SYS}; - -// SysOp() -// ======= - -SystemOp SysOp(bits(3) op1, bits(4) CRn, bits(4) CRm, bits(3) op2) - case op1:CRn:CRm:op2 of - when '000 0111 1000 000' return Sys_AT; // S1E1R - when '100 0111 1000 000' return Sys_AT; // S1E2R - when '110 0111 1000 000' return Sys_AT; // S1E3R - when '000 0111 1000 001' return Sys_AT; // S1E1W - when '100 0111 1000 001' return Sys_AT; // S1E2W - when '110 0111 1000 001' return Sys_AT; // S1E3W - when '000 0111 1000 010' return Sys_AT; // S1E0R - when '000 0111 1000 011' return Sys_AT; // S1E0W - when '100 0111 1000 100' return Sys_AT; // S12E1R - when '100 0111 1000 101' return Sys_AT; // S12E1W - when '100 0111 1000 110' return Sys_AT; // S12E0R - when '100 0111 1000 111' return Sys_AT; // S12E0W - when '011 0111 0100 001' return Sys_DC; // ZVA - when '000 0111 0110 001' return Sys_DC; // IVAC - when '000 0111 0110 010' return Sys_DC; // ISW - when '011 0111 1010 001' return Sys_DC; // CVAC - when '000 0111 1010 010' return Sys_DC; // CSW - when '011 0111 1011 001' return Sys_DC; // CVAU - when '011 0111 1110 001' return Sys_DC; // CIVAC - when '000 0111 1110 010' return Sys_DC; // CISW - when '011 0111 1101 001' return Sys_DC; // CVADP - when '000 0111 0001 000' return Sys_IC; // IALLUIS - when '000 0111 0101 000' return Sys_IC; // IALLU - when '011 0111 0101 001' return Sys_IC; // IVAU - when '100 1000 0000 001' return Sys_TLBI; // IPAS2E1IS - when '100 1000 0000 101' return Sys_TLBI; // IPAS2LE1IS - when '000 1000 0011 000' return Sys_TLBI; // VMALLE1IS - when '100 1000 0011 000' return Sys_TLBI; // ALLE2IS - when '110 1000 0011 000' return Sys_TLBI; // ALLE3IS - when '000 1000 0011 001' return Sys_TLBI; // VAE1IS - when '100 1000 0011 001' return Sys_TLBI; // VAE2IS - when '110 1000 0011 001' return Sys_TLBI; // VAE3IS - when '000 1000 0011 010' return Sys_TLBI; // ASIDE1IS - when '000 1000 0011 011' return Sys_TLBI; // VAAE1IS - when '100 1000 0011 100' return Sys_TLBI; // ALLE1IS - when '000 1000 0011 101' return Sys_TLBI; // VALE1IS - when '100 1000 0011 101' return Sys_TLBI; // VALE2IS - when '110 1000 0011 101' return Sys_TLBI; // VALE3IS - when '100 1000 0011 110' return Sys_TLBI; // VMALLS12E1IS - when '000 1000 0011 111' return Sys_TLBI; // VAALE1IS - when '100 1000 0100 001' return Sys_TLBI; // IPAS2E1 - when '100 1000 0100 101' return Sys_TLBI; // IPAS2LE1 - when '000 1000 0111 000' return Sys_TLBI; // VMALLE1 - when '100 1000 0111 000' return Sys_TLBI; // ALLE2 - when '110 1000 0111 000' return Sys_TLBI; // ALLE3 - when '000 1000 0111 001' return Sys_TLBI; // VAE1 - when '100 1000 0111 001' return Sys_TLBI; // VAE2 - when '110 1000 0111 001' return Sys_TLBI; // VAE3 - when '000 1000 0111 010' return Sys_TLBI; // ASIDE1 - when '000 1000 0111 011' return Sys_TLBI; // VAAE1 - when '100 1000 0111 100' return Sys_TLBI; // ALLE1 - when '000 1000 0111 101' return Sys_TLBI; // VALE1 - when '100 1000 0111 101' return Sys_TLBI; // VALE2 - when '110 1000 0111 101' return Sys_TLBI; // VALE3 - when '100 1000 0111 110' return Sys_TLBI; // VMALLS12E1 - when '000 1000 0111 111' return Sys_TLBI; // VAALE1 - return Sys_SYS; - -// AArch64.AsynchExternalAbort() -// ============================= -// Wrapper function for asynchronous external aborts - -FaultRecord AArch64.AsynchExternalAbort(boolean parity, bits(2) errortype, bit extflag) - - faulttype = if parity then Fault_AsyncParity else Fault_AsyncExternal; - ipaddress = bits(52) UNKNOWN; - level = integer UNKNOWN; - acctype = AccType_NORMAL; - iswrite = boolean UNKNOWN; - secondstage = FALSE; - s2fs1walk = FALSE; - - return AArch64.CreateFaultRecord(faulttype, ipaddress, boolean UNKNOWN, level, acctype, iswrite, extflag, - errortype, secondstage, s2fs1walk); - -enumeration VBitOp {VBitOp_VBIF, VBitOp_VBIT, VBitOp_VBSL, VBitOp_VEOR}; - -enumeration CompareOp {CompareOp_GT, CompareOp_GE, CompareOp_EQ, - CompareOp_LE, CompareOp_LT}; - -enumeration ImmediateOp {ImmediateOp_MOVI, ImmediateOp_MVNI, - ImmediateOp_ORR, ImmediateOp_BIC}; - -// ClearStickyErrors() -// =================== - -ClearStickyErrors() - EDSCR.TXU = '0'; // Clear TX underrun flag - EDSCR.RXO = '0'; // Clear RX overrun flag - - if Halted() then // in Debug state - EDSCR.ITO = '0'; // Clear ITR overrun flag - - // If halted and the ITR is not empty then it is UNPREDICTABLE whether the EDSCR.ERR is cleared. - // The UNPREDICTABLE behavior also affects the instructions in flight, but this is not described - // in the pseudocode. - if Halted() && EDSCR.ITE == '0' && ConstrainUnpredictableBool(Unpredictable_CLEARERRITEZERO) then - return; - EDSCR.ERR = '0'; // Clear cumulative error flag - - return; - -// HaveSecureExtDebugView() -// ======================== -// Returns TRUE if support for Secure and Non-secure views of debug peripherals is implemented. - -boolean HaveSecureExtDebugView() - return HasArchVersion(ARMv8p4); - -// Returns TRUE when an access is Secure -boolean IsAccessSecure(); - -// AllowExternalDebugAccess() -// ========================== -// Returns TRUE if an external debug interface access to the External debug registers -// is allowed, FALSE otherwise. - -boolean AllowExternalDebugAccess() - // The access may also be subject to OS Lock, power-down, etc. - if HaveSecureExtDebugView() then - return AllowExternalDebugAccess(IsAccessSecure()); - else - return AllowExternalDebugAccess(ExternalSecureInvasiveDebugEnabled()); - -// AllowExternalDebugAccess() -// ========================== -// Returns TRUE if an external debug interface access to the External debug registers -// is allowed for the given Security state, FALSE otherwise. - -boolean AllowExternalDebugAccess(boolean allow_secure) - // The access may also be subject to OS Lock, power-down, etc. - if HaveSecureExtDebugView() || ExternalInvasiveDebugEnabled() then - if allow_secure then - return TRUE; - elsif HaveEL(EL3) then - if ELUsingAArch32(EL3) then - return SDCR.EDAD == '0'; - else - return MDCR_EL3.EDAD == '0'; - else - return !IsSecure(); - else - return FALSE; - -// AllowExternalPMUAccess() -// ======================== -// Returns TRUE if an external debug interface access to the PMU registers is allowed, FALSE otherwise. - -boolean AllowExternalPMUAccess() - // The access may also be subject to OS Lock, power-down, etc. - if HaveSecureExtDebugView() then - return AllowExternalPMUAccess(IsAccessSecure()); - else - return AllowExternalPMUAccess(ExternalSecureNoninvasiveDebugEnabled()); - -// AllowExternalPMUAccess() -// ======================== -// Returns TRUE if an external debug interface access to the PMU registers is allowed for the given -// Security state, FALSE otherwise. - -boolean AllowExternalPMUAccess(boolean allow_secure) - // The access may also be subject to OS Lock, power-down, etc. - if HaveSecureExtDebugView() || ExternalNoninvasiveDebugEnabled() then - if allow_secure then - return TRUE; - elsif HaveEL(EL3) then - if ELUsingAArch32(EL3) then - return SDCR.EPMAD == '0'; - else - return MDCR_EL3.EPMAD == '0'; - else - return !IsSecure(); - else - return FALSE; - -// ExternalNoninvasiveDebugAllowed() -// ================================= -// Returns TRUE if Trace and PC Sample-based Profiling are allowed - -boolean ExternalNoninvasiveDebugAllowed() - return (ExternalNoninvasiveDebugEnabled() && - (!IsSecure() || ExternalSecureNoninvasiveDebugEnabled() || - (ELUsingAArch32(EL1) && PSTATE.EL == EL0 && SDER.SUNIDEN == '1'))); - -// Returns TRUE if the Core power domain is powered on, FALSE otherwise. -boolean IsCorePowered(); - -// Set a Cross Trigger multi-cycle input event trigger to the specified level. -CTI_SetEventLevel(CrossTriggerIn id, signal level); - -// CheckForDCCInterrupts() -// ======================= - -CheckForDCCInterrupts() - commrx = (EDSCR.RXfull == '1'); - commtx = (EDSCR.TXfull == '0'); - - // COMMRX and COMMTX support is optional and not recommended for new designs. - // SetInterruptRequestLevel(InterruptID_COMMRX, if commrx then HIGH else LOW); - // SetInterruptRequestLevel(InterruptID_COMMTX, if commtx then HIGH else LOW); - - // The value to be driven onto the common COMMIRQ signal. - if ELUsingAArch32(EL1) then - commirq = ((commrx && DBGDCCINT.RX == '1') || - (commtx && DBGDCCINT.TX == '1')); - else - commirq = ((commrx && MDCCINT_EL1.RX == '1') || - (commtx && MDCCINT_EL1.TX == '1')); - SetInterruptRequestLevel(InterruptID_COMMIRQ, if commirq then HIGH else LOW); - - return; - -bits(32) DTRRX; -bits(32) DTRTX; - -// Execute an A64 instruction in Debug state. -ExecuteA64(bits(32) instr); - -// Execute a T32 instruction in Debug state. -ExecuteT32(bits(16) hw1, bits(16) hw2); - -// DBGDTRRX_EL0[] (external write) -// =============================== -// Called on writes to debug register 0x08C. - -DBGDTRRX_EL0[boolean memory_mapped] = bits(32) value - - if EDPRSR[6:5,0] != '001' then // Check DLK, OSLK and PU bits - IMPLEMENTATION_DEFINED "signal slave-generated error"; - return; - - if EDSCR.ERR == '1' then return; // Error flag set: ignore write - - // The Software lock is OPTIONAL. - if memory_mapped && EDLSR.SLK == '1' then return; // Software lock locked: ignore write - - if EDSCR.RXfull == '1' || (Halted() && EDSCR.MA == '1' && EDSCR.ITE == '0') then - EDSCR.RXO = '1'; EDSCR.ERR = '1'; // Overrun condition: ignore write - return; - - EDSCR.RXfull = '1'; - DTRRX = value; - - if Halted() && EDSCR.MA == '1' then - EDSCR.ITE = '0'; // See comments in EDITR[] (external write) - if !UsingAArch32() then - ExecuteA64(0xD5330501[31:0]); // A64 "MRS X1,DBGDTRRX_EL0" - ExecuteA64(0xB8004401[31:0]); // A64 "STR W1,[X0],#4" - X[1] = bits(64) UNKNOWN; - else - ExecuteT32(0xEE10[15:0] /*hw1*/, 0x1E15[15:0] /*hw2*/); // T32 "MRS R1,DBGDTRRXint" - ExecuteT32(0xF840[15:0] /*hw1*/, 0x1B04[15:0] /*hw2*/); // T32 "STR R1,[R0],#4" - R[1] = bits(32) UNKNOWN; - // If the store aborts, the Data Abort exception is taken and EDSCR.ERR is set to 1 - if EDSCR.ERR == '1' then - EDSCR.RXfull = bit UNKNOWN; - DBGDTRRX_EL0 = bits(32) UNKNOWN; - else - // "MRS X1,DBGDTRRX_EL0" calls DBGDTR_EL0[] (read) which clears RXfull. - assert EDSCR.RXfull == '0'; - - EDSCR.ITE = '1'; // See comments in EDITR[] (external write) - return; - -// DBGDTRRX_EL0[] (external read) -// ============================== - -bits(32) DBGDTRRX_EL0[boolean memory_mapped] - return DTRRX; - -// DBGDTRTX_EL0[] (external read) -// ============================== -// Called on reads of debug register 0x080. - -bits(32) DBGDTRTX_EL0[boolean memory_mapped] - - if EDPRSR[6:5,0] != '001' then // Check DLK, OSLK and PU bits - IMPLEMENTATION_DEFINED "signal slave-generated error"; - return bits(32) UNKNOWN; - - underrun = EDSCR.TXfull == '0' || (Halted() && EDSCR.MA == '1' && EDSCR.ITE == '0'); - value = if underrun then bits(32) UNKNOWN else DTRTX; - - if EDSCR.ERR == '1' then return value; // Error flag set: no side-effects - - // The Software lock is OPTIONAL. - if memory_mapped && EDLSR.SLK == '1' then // Software lock locked: no side-effects - return value; - - if underrun then - EDSCR.TXU = '1'; EDSCR.ERR = '1'; // Underrun condition: block side-effects - return value; // Return UNKNOWN - - EDSCR.TXfull = '0'; - if Halted() && EDSCR.MA == '1' then - EDSCR.ITE = '0'; // See comments in EDITR[] (external write) - - if !UsingAArch32() then - ExecuteA64(0xB8404401[31:0]); // A64 "LDR W1,[X0],#4" - else - ExecuteT32(0xF850[15:0] /*hw1*/, 0x1B04[15:0] /*hw2*/); // T32 "LDR R1,[R0],#4" - // If the load aborts, the Data Abort exception is taken and EDSCR.ERR is set to 1 - if EDSCR.ERR == '1' then - EDSCR.TXfull = bit UNKNOWN; - DBGDTRTX_EL0 = bits(32) UNKNOWN; - else - if !UsingAArch32() then - ExecuteA64(0xD5130501[31:0]); // A64 "MSR DBGDTRTX_EL0,X1" - else - ExecuteT32(0xEE00[15:0] /*hw1*/, 0x1E15[15:0] /*hw2*/); // T32 "MSR DBGDTRTXint,R1" - // "MSR DBGDTRTX_EL0,X1" calls DBGDTR_EL0[] (write) which sets TXfull. - assert EDSCR.TXfull == '1'; - if !UsingAArch32() then - X[1] = bits(64) UNKNOWN; - else - R[1] = bits(32) UNKNOWN; - EDSCR.ITE = '1'; // See comments in EDITR[] (external write) - - return value; - -// DBGDTRTX_EL0[] (external write) -// =============================== - -DBGDTRTX_EL0[boolean memory_mapped] = bits(32) value - // The Software lock is OPTIONAL. - if memory_mapped && EDLSR.SLK == '1' then return; // Software lock locked: ignore write - DTRTX = value; - return; - -// DBGDTR_EL0[] (write) -// ==================== -// System register writes to DBGDTR_EL0, DBGDTRTX_EL0 (AArch64) and DBGDTRTXint (AArch32) - -DBGDTR_EL0[] = bits(N) value - // For MSR DBGDTRTX_EL0,[Rt] N=32, value=X[t][31:0], X[t][63:32] is ignored - // For MSR DBGDTR_EL0,[Xt] N=64, value=X[t][63:0] - assert N IN {32,64}; - if EDSCR.TXfull == '1' then - value = bits(N) UNKNOWN; - // On a 64-bit write, implement a half-duplex channel - if N == 64 then DTRRX = value[63:32]; - DTRTX = value[31:0]; // 32-bit or 64-bit write - EDSCR.TXfull = '1'; - return; - -// DBGDTR_EL0[] (read) -// =================== -// System register reads of DBGDTR_EL0, DBGDTRRX_EL0 (AArch64) and DBGDTRRXint (AArch32) - -bits(N) DBGDTR_EL0[] - // For MRS [Rt],DBGDTRTX_EL0 N=32, X[t]=Zeros(32):result - // For MRS [Xt],DBGDTR_EL0 N=64, X[t]=result - assert N IN {32,64}; - bits(N) result; - if EDSCR.RXfull == '0' then - result = bits(N) UNKNOWN; - else - // On a 64-bit read, implement a half-duplex channel - // NOTE: the word order is reversed on reads with regards to writes - if N == 64 then result[63:32] = DTRTX; - result[31:0] = DTRRX; - EDSCR.RXfull = '0'; - return result; - -// EDITR[] (external write) -// ======================== -// Called on writes to debug register 0x084. - -EDITR[boolean memory_mapped] = bits(32) value - if EDPRSR[6:5,0] != '001' then // Check DLK, OSLK and PU bits - IMPLEMENTATION_DEFINED "signal slave-generated error"; - return; - - if EDSCR.ERR == '1' then return; // Error flag set: ignore write - - // The Software lock is OPTIONAL. - if memory_mapped && EDLSR.SLK == '1' then return; // Software lock locked: ignore write - - if !Halted() then return; // Non-debug state: ignore write - - if EDSCR.ITE == '0' || EDSCR.MA == '1' then - EDSCR.ITO = '1'; EDSCR.ERR = '1'; // Overrun condition: block write - return; - - // ITE indicates whether the processor is ready to accept another instruction; the processor - // may support multiple outstanding instructions. Unlike the "InstrCompl" flag in [v7A] there - // is no indication that the pipeline is empty (all instructions have completed). In this - // pseudocode, the assumption is that only one instruction can be executed at a time, - // meaning ITE acts like "InstrCompl". - EDSCR.ITE = '0'; - - if !UsingAArch32() then - ExecuteA64(value); - else - ExecuteT32(value[15:0]/*hw1*/, value[31:16] /*hw2*/); - - EDSCR.ITE = '1'; - - return; - -// DCPSInstruction() -// ================= -// Operation of the DCPS instruction in Debug state - -DCPSInstruction(bits(2) target_el) - - SynchronizeContext(); - - case target_el of - when EL1 - if PSTATE.EL == EL2 || (PSTATE.EL == EL3 && !UsingAArch32()) then handle_el = PSTATE.EL; - elsif EL2Enabled() && HCR_EL2.TGE == '1' then UNDEFINED; - else handle_el = EL1; - - when EL2 - if !HaveEL(EL2) then UNDEFINED; - elsif PSTATE.EL == EL3 && !UsingAArch32() then handle_el = EL3; - elsif !IsSecureEL2Enabled() && IsSecure() then UNDEFINED; - else handle_el = EL2; - when EL3 - if EDSCR.SDD == '1' || !HaveEL(EL3) then UNDEFINED; - handle_el = EL3; - otherwise - Unreachable(); - - from_secure = IsSecure(); - if ELUsingAArch32(handle_el) then - if PSTATE.M == M32_Monitor then SCR.NS = '0'; - assert UsingAArch32(); // Cannot move from AArch64 to AArch32 - case handle_el of - when EL1 - AArch32.WriteMode(M32_Svc); - if HavePANExt() && SCTLR.SPAN == '0' then - PSTATE.PAN = '1'; - when EL2 AArch32.WriteMode(M32_Hyp); - when EL3 - AArch32.WriteMode(M32_Monitor); - if HavePANExt() then - if !from_secure then - PSTATE.PAN = '0'; - elsif SCTLR.SPAN == '0' then - PSTATE.PAN = '1'; - if handle_el == EL2 then - ELR_hyp = bits(32) UNKNOWN; HSR = bits(32) UNKNOWN; - else - LR = bits(32) UNKNOWN; - SPSR[] = bits(32) UNKNOWN; - PSTATE.E = SCTLR[].EE; - DLR = bits(32) UNKNOWN; DSPSR = bits(32) UNKNOWN; - - else // Targeting AArch64 - if UsingAArch32() then - AArch64.MaybeZeroRegisterUppers(); - MaybeZeroSVEUppers(target_el); - PSTATE.nRW = '0'; PSTATE.SP = '1'; PSTATE.EL = handle_el; - if HavePANExt() && ((handle_el == EL1 && SCTLR_EL1.SPAN == '0') || - (handle_el == EL2 && HCR_EL2.E2H == '1' && - HCR_EL2.TGE == '1' && SCTLR_EL2.SPAN == '0')) then - PSTATE.PAN = '1'; - ELR[] = bits(64) UNKNOWN; SPSR[] = bits(32) UNKNOWN; ESR[] = bits(32) UNKNOWN; - DLR_EL0 = bits(64) UNKNOWN; DSPSR_EL0 = bits(32) UNKNOWN; - if HaveUAOExt() then PSTATE.UAO = '0'; - if HaveMTEExt() then PSTATE.TCO = '1'; - - UpdateEDSCRFields(); // Update EDSCR PE state flags - sync_errors = HaveIESB() && SCTLR[].IESB == '1'; - if HaveDoubleFaultExt() && !UsingAArch32() then - sync_errors = sync_errors || (SCR_EL3.EA == '1' && SCR_EL3.NMEA == '1' && PSTATE.EL == EL3); - // SCTLR[].IESB might be ignored in Debug state. - if !ConstrainUnpredictableBool(Unpredictable_IESBinDebug) then - sync_errors = FALSE; - if sync_errors then - SynchronizeErrors(); - return; - -// DRPSInstruction() -// ================= -// Operation of the A64 DRPS and T32 ERET instructions in Debug state - -DRPSInstruction() - - SynchronizeContext(); - - sync_errors = HaveIESB() && SCTLR[].IESB == '1'; - if HaveDoubleFaultExt() && !UsingAArch32() then - sync_errors = sync_errors || (SCR_EL3.EA == '1' && SCR_EL3.NMEA == '1' && PSTATE.EL == EL3); - // SCTLR[].IESB might be ignored in Debug state. - if !ConstrainUnpredictableBool(Unpredictable_IESBinDebug) then - sync_errors = FALSE; - if sync_errors then - SynchronizeErrors(); - - SetPSTATEFromPSR(SPSR[]); - - // PSTATE.{N,Z,C,V,Q,GE,SS,D,A,I,F} are not observable and ignored in Debug state, so - // behave as if UNKNOWN. - if UsingAArch32() then - PSTATE.[N,Z,C,V,Q,GE,SS,A,I,F] = bits(13) UNKNOWN; - // In AArch32, all instructions are T32 and unconditional. - PSTATE.IT = '00000000'; PSTATE.T = '1'; // PSTATE.J is RES0 - DLR = bits(32) UNKNOWN; DSPSR = bits(32) UNKNOWN; - else - PSTATE.[N,Z,C,V,SS,D,A,I,F] = bits(9) UNKNOWN; - DLR_EL0 = bits(64) UNKNOWN; DSPSR_EL0 = bits(32) UNKNOWN; - - UpdateEDSCRFields(); // Update EDSCR PE state flags - - return; - -DisableITRAndResumeInstructionPrefetch(); - -// ExitDebugState() -// ================ - -ExitDebugState() - assert Halted(); - SynchronizeContext(); - - // Although EDSCR.STATUS signals that the PE is restarting, debuggers must use EDPRSR.SDR to - // detect that the PE has restarted. - EDSCR.STATUS = '000001'; // Signal restarting - EDESR[2:0] = '000'; // Clear any pending Halting debug events - - bits(64) new_pc; - bits(32) spsr; - - if UsingAArch32() then - new_pc = ZeroExtend(DLR); - spsr = DSPSR; - else - new_pc = DLR_EL0; - spsr = DSPSR_EL0; - // If this is an illegal return, SetPSTATEFromPSR() will set PSTATE.IL. - SetPSTATEFromPSR(spsr); // Can update privileged bits, even at EL0 - - if UsingAArch32() then - if ConstrainUnpredictableBool(Unpredictable_RESTARTALIGNPC) then new_pc[0] = '0'; - BranchTo(new_pc[31:0], BranchType_DBGEXIT); // AArch32 branch - else - // If targeting AArch32 then possibly zero the 32 most significant bits of the target PC - if spsr[4] == '1' && ConstrainUnpredictableBool(Unpredictable_RESTARTZEROUPPERPC) then - new_pc[63:32] = Zeros(); - BranchTo(new_pc, BranchType_DBGEXIT); // A type1 of branch that is never predicted - - (EDSCR.STATUS,EDPRSR.SDR) = ('000010','1'); // Atomically signal restarted - UpdateEDSCRFields(); // Stop signalling PE state - DisableITRAndResumeInstructionPrefetch(); - - return; - -// HaveExtendedECDebugEvents() -// =========================== - -boolean HaveExtendedECDebugEvents() - return HasArchVersion(ARMv8p2); - -// CheckExceptionCatch() -// ===================== -// Check whether an Exception Catch debug event is set on the current Exception level - -CheckExceptionCatch(boolean exception_entry) - // Called after an exception entry or exit, that is, such that IsSecure() and PSTATE.EL are correct - // for the exception target. - base = if IsSecure() then 0 else 4; - if HaltingAllowed() then - if HaveExtendedECDebugEvents() then - exception_exit = !exception_entry; - ctrl = EDECCR[UInt(PSTATE.EL) + base + 8]:EDECCR[UInt(PSTATE.EL) + base]; - case ctrl of - when '00' halt = FALSE; - when '01' halt = TRUE; - when '10' halt = (exception_exit == TRUE); - when '11' halt = (exception_entry == TRUE); - else - halt = (EDECCR[UInt(PSTATE.EL) + base] == '1'); - if halt then Halt(DebugHalt_ExceptionCatch); - -// Returns TRUE if the previously executed instruction was executed in the inactive state, that is, -// if it was not itself stepped. -boolean HaltingStep_DidNotStep(); - -// Returns TRUE if the previously executed instruction was a Load-Exclusive class instruction -// executed in the active-not-pending state. -boolean HaltingStep_SteppedEX(); - -// CheckHaltingStep() -// ================== -// Check whether EDESR.SS has been set by Halting Step - -CheckHaltingStep() - if HaltingAllowed() && EDESR.SS == '1' then - // The STATUS code depends on how we arrived at the state where EDESR.SS == 1. - if HaltingStep_DidNotStep() then - Halt(DebugHalt_Step_NoSyndrome); - elsif HaltingStep_SteppedEX() then - Halt(DebugHalt_Step_Exclusive); - else - Halt(DebugHalt_Step_Normal); - -// HaveDoPD() -// ========== -// Returns TRUE if Debug Over Power Down extension -// support is implemented and FALSE otherwise. - -boolean HaveDoPD() - return HasArchVersion(ARMv8p2) && boolean IMPLEMENTATION_DEFINED "Has DoPD extension"; - -// CheckOSUnlockCatch() -// ==================== -// Called on unlocking the OS Lock to pend an OS Unlock Catch debug event - -CheckOSUnlockCatch() - - if (HaveDoPD() && CTIDEVCTL.OSUCE == '1') - || (!HaveDoPD() && EDECR.OSUCE == '1') - then - if !Halted() then EDESR.OSUC = '1'; - -// CheckPendingOSUnlockCatch() -// =========================== -// Check whether EDESR.OSUC has been set by an OS Unlock Catch debug event - -CheckPendingOSUnlockCatch() - if HaltingAllowed() && EDESR.OSUC == '1' then - Halt(DebugHalt_OSUnlockCatch); - -// CheckPendingResetCatch() -// ======================== -// Check whether EDESR.RC has been set by a Reset Catch debug event - -CheckPendingResetCatch() - if HaltingAllowed() && EDESR.RC == '1' then - Halt(DebugHalt_ResetCatch); - -// CheckResetCatch() -// ================= -// Called after reset - -CheckResetCatch() - if (HaveDoPD() && CTIDEVCTL.RCE == '1') || (!HaveDoPD() && EDECR.RCE == '1') then - EDESR.RC = '1'; - // If halting is allowed then halt immediately - if HaltingAllowed() then Halt(DebugHalt_ResetCatch); - -// CheckSoftwareAccessToDebugRegisters() -// ===================================== -// Check for access to Breakpoint and Watchpoint registers. - -CheckSoftwareAccessToDebugRegisters() - os_lock = (if ELUsingAArch32(EL1) then DBGOSLSR.OSLK else OSLSR_EL1.OSLK); - if HaltingAllowed() && EDSCR.TDA == '1' && os_lock == '0' then - Halt(DebugHalt_SoftwareAccess); - -// ExternalDebugRequest() -// ====================== - -ExternalDebugRequest() - if HaltingAllowed() then - Halt(DebugHalt_EDBGRQ); - // Otherwise the CTI continues to assert the debug request until it is taken. - -// RunHaltingStep() -// ================ - -RunHaltingStep(boolean exception_generated, bits(2) exception_target, boolean syscall, - boolean reset) - // "exception_generated" is TRUE if the previous instruction generated a synchronous exception - // or was cancelled by an asynchronous exception. - // - // if "exception_generated" is TRUE then "exception_target" is the target of the exception, and - // "syscall" is TRUE if the exception is a synchronous exception where the preferred return - // address is the instruction following that which generated the exception. - // - // "reset" is TRUE if exiting reset state into the highest EL. - - if reset then assert !Halted(); // Cannot come out of reset halted - active = EDECR.SS == '1' && !Halted(); - - if active && reset then // Coming out of reset with EDECR.SS set - EDESR.SS = '1'; - elsif active && HaltingAllowed() then - if exception_generated && exception_target == EL3 then - advance = syscall || ExternalSecureInvasiveDebugEnabled(); - else - advance = TRUE; - if advance then EDESR.SS = '1'; - - return; - -// Set a level-sensitive interrupt to the specified level. -SetInterruptRequestLevel(InterruptID id, signal level); - -// CreatePCSample() -// ================ - -CreatePCSample() - // In a simple sequential execution of the program, CreatePCSample is executed each time the PE - // executes an instruction that can be sampled. An implementation is not constrained such that - // reads of EDPCSRlo return the current values of PC, etc. - - pc_sample.valid = ExternalNoninvasiveDebugAllowed() && !Halted(); - pc_sample.pc = ThisInstrAddr(); - pc_sample.el = PSTATE.EL; - pc_sample.rw = if UsingAArch32() then '0' else '1'; - pc_sample.ns = if IsSecure() then '0' else '1'; - pc_sample.contextidr = if ELUsingAArch32(EL1) then CONTEXTIDR else CONTEXTIDR_EL1; - pc_sample.has_el2 = EL2Enabled(); - - if EL2Enabled() then - if ELUsingAArch32(EL2) then - pc_sample.vmid = ZeroExtend(VTTBR.VMID, 16); - elsif !Have16bitVMID() || VTCR_EL2.VS == '0' then - pc_sample.vmid = ZeroExtend(VTTBR_EL2.VMID[7:0], 16); - else - pc_sample.vmid = VTTBR_EL2.VMID; - if HaveVirtHostExt() && !ELUsingAArch32(EL2) then - pc_sample.contextidr_el2 = CONTEXTIDR_EL2; - else - pc_sample.contextidr_el2 = bits(32) UNKNOWN; - pc_sample.el0h = PSTATE.EL == EL0 && IsInHost(); - return; - -// EDPCSRlo[] (read) -// ================= - -bits(32) EDPCSRlo[boolean memory_mapped] - - if EDPRSR[6:5,0] != '001' then // Check DLK, OSLK and PU bits - IMPLEMENTATION_DEFINED "signal slave-generated error"; - return bits(32) UNKNOWN; - - // The Software lock is OPTIONAL. - update = !memory_mapped || EDLSR.SLK == '0'; // Software locked: no side-effects - - if pc_sample.valid then - sample = pc_sample.pc[31:0]; - if update then - if HaveVirtHostExt() && EDSCR.SC2 == '1' then - EDPCSRhi.PC = (if pc_sample.rw == '0' then Zeros(24) else pc_sample.pc[55:32]); - EDPCSRhi.EL = pc_sample.el; - EDPCSRhi.NS = pc_sample.ns; - else - EDPCSRhi = (if pc_sample.rw == '0' then Zeros(32) else pc_sample.pc[63:32]); - EDCIDSR = pc_sample.contextidr; - if HaveVirtHostExt() && EDSCR.SC2 == '1' then - EDVIDSR = (if HaveEL(EL2) && pc_sample.ns == '1' then pc_sample.contextidr_el2 - else bits(32) UNKNOWN); - else - if HaveEL(EL2) && pc_sample.ns == '1' && pc_sample.el IN {EL1,EL0} then - EDVIDSR.VMID = pc_sample.vmid; - else - EDVIDSR.VMID = Zeros(); - EDVIDSR.NS = pc_sample.ns; - EDVIDSR.E2 = (if pc_sample.el == EL2 then '1' else '0'); - EDVIDSR.E3 = (if pc_sample.el == EL3 then '1' else '0') AND pc_sample.rw; - // The conditions for setting HV are not specified if PCSRhi is zero. - // An example implementation may be "pc_sample.rw". - EDVIDSR.HV = (if !IsZero(EDPCSRhi) then '1' else bit IMPLEMENTATION_DEFINED "0 or 1"); - else - sample = Ones(32); - if update then - EDPCSRhi = bits(32) UNKNOWN; - EDCIDSR = bits(32) UNKNOWN; - EDVIDSR = bits(32) UNKNOWN; - - return sample; - -type PCSample is ( - boolean valid, - bits(64) pc, - bits(2) el, - bit rw, - bit ns, - boolean has_el2, - bits(32) contextidr, - bits(32) contextidr_el2, - boolean el0h, - bits(16) vmid -) - -PCSample pc_sample; - -// PMPCSR[] (read) -// =============== - -bits(32) PMPCSR[boolean memory_mapped] - - if EDPRSR[6:5,0] != '001' then // Check DLK, OSLK and PU bits - IMPLEMENTATION_DEFINED "signal slave-generated error"; - return bits(32) UNKNOWN; - - // The Software lock is OPTIONAL. - update = !memory_mapped || PMLSR.SLK == '0'; // Software locked: no side-effects - - if pc_sample.valid then - sample = pc_sample.pc[31:0]; - if update then - PMPCSR[55:32] = (if pc_sample.rw == '0' then Zeros(24) else pc_sample.pc[55:32]); - PMPCSR.EL = pc_sample.el; - PMPCSR.NS = pc_sample.ns; - - PMCID1SR = pc_sample.contextidr; - PMCID2SR = if pc_sample.has_el2 then pc_sample.contextidr_el2 else bits(32) UNKNOWN; - - PMVIDSR.VMID = (if pc_sample.has_el2 && pc_sample.el IN {EL1,EL0} && !pc_sample.el0h - then pc_sample.vmid else bits(16) UNKNOWN); - else - sample = Ones(32); - if update then - PMPCSR[55:32] = bits(24) UNKNOWN; - PMPCSR.EL = bits(2) UNKNOWN; - PMPCSR.NS = bit UNKNOWN; - - PMCID1SR = bits(32) UNKNOWN; - PMCID2SR = bits(32) UNKNOWN; - - PMVIDSR.VMID = bits(16) UNKNOWN; - - return sample; - -// CheckSoftwareStep() -// =================== -// Take a Software Step exception if in the active-pending state - -CheckSoftwareStep() - - // Other self-hosted debug functions will call AArch32.GenerateDebugExceptions() if called from - // AArch32 state. However, because Software Step is only active when the debug target Exception - // level is using AArch64, CheckSoftwareStep only calls AArch64.GenerateDebugExceptions(). - if !ELUsingAArch32(DebugTarget()) && AArch64.GenerateDebugExceptions() then - if MDSCR_EL1.SS == '1' && PSTATE.SS == '0' then - AArch64.SoftwareStepException(); - -// ReservedValue() -// =============== - -ReservedValue() - if UsingAArch32() && !AArch32.GeneralExceptionsToAArch64() then - AArch32.TakeUndefInstrException(); - else - AArch64.UndefinedFault(); - -// UnallocatedEncoding() -// ===================== - -UnallocatedEncoding() - if UsingAArch32() && AArch32.ExecutingCP10or11Instr() then - FPEXC.DEX = '0'; - if UsingAArch32() && !AArch32.GeneralExceptionsToAArch64() then - AArch32.TakeUndefInstrException(); - else - AArch64.UndefinedFault(); - -// Abs() -// ===== - -integer Abs(integer x) - return if x >= 0 then x else -x; - -// Abs() -// ===== - -real Abs(real x) - return if x >= 0.0 then x else -x; - -// BitCount() -// ========== - -integer BitCount(bits(N) x) - integer result = 0; - for i = 0 to N-1 - if x[i] == '1' then - result = result + 1; - return result; - -// CountLeadingZeroBits() -// ====================== - -integer CountLeadingZeroBits(bits(N) x) - return N - (HighestSetBit(x) + 1); - -// CountLeadingSignBits() -// ====================== - -integer CountLeadingSignBits(bits(N) x) - return CountLeadingZeroBits(x[N-1:1] EOR x[N-2:0]); - -// Int() -// ===== - -integer Int(bits(N) x, boolean unsigned) - result = if unsigned then UInt(x) else SInt(x); - return result; - -// IsZeroBit() -// =========== - -bit IsZeroBit(bits(N) x) - return if IsZero(x) then '1' else '0'; - -// LowestSetBit() -// ============== - -integer LowestSetBit(bits(N) x) - for i = 0 to N-1 - if x[i] == '1' then return i; - return N; - -// BitReverse() -// ============ - -bits(N) BitReverse(bits(N) data) - bits(N) result; - for i = 0 to N-1 - result[N-i-1] = data[i]; - return result; - -// HaveCRCExt() -// ============ - -boolean HaveCRCExt() - return HasArchVersion(ARMv8p1) || boolean IMPLEMENTATION_DEFINED "Have CRC extension"; - -// Poly32Mod2() -// ============ - -// Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation - -bits(32) Poly32Mod2(bits(N) data, bits(32) poly) - assert N > 32; - for i = N-1 downto 32 - if data[i] == '1' then - data[i-1:0] = data[i-1:0] EOR (poly:Zeros(i-32)); - return data[31:0]; - -// FFmul09() -// ========= - -bits(8) FFmul09(bits(8) b) - bits(256*8) FFmul_09 = ( - /* F E D C B A 9 8 7 6 5 4 3 2 1 0 */ - /*F*/ 0x464F545D626B70790E071C152A233831[127:0] : - /*E*/ 0xD6DFC4CDF2FBE0E99E978C85BAB3A8A1[127:0] : - /*D*/ 0x7D746F6659504B42353C272E1118030A[127:0] : - /*C*/ 0xEDE4FFF6C9C0DBD2A5ACB7BE8188939A[127:0] : - /*B*/ 0x3039222B141D060F78716A635C554E47[127:0] : - /*A*/ 0xA0A9B2BB848D969FE8E1FAF3CCC5DED7[127:0] : - /*9*/ 0x0B0219102F263D34434A5158676E757C[127:0] : - /*8*/ 0x9B928980BFB6ADA4D3DAC1C8F7FEE5EC[127:0] : - /*7*/ 0xAAA3B8B18E879C95E2EBF0F9C6CFD4DD[127:0] : - /*6*/ 0x3A3328211E170C05727B6069565F444D[127:0] : - /*5*/ 0x9198838AB5BCA7AED9D0CBC2FDF4EFE6[127:0] : - /*4*/ 0x0108131A252C373E49405B526D647F76[127:0] : - /*3*/ 0xDCD5CEC7F8F1EAE3949D868FB0B9A2AB[127:0] : - /*2*/ 0x4C455E5768617A73040D161F2029323B[127:0] : - /*1*/ 0xE7EEF5FCC3CAD1D8AFA6BDB48B829990[127:0] : - /*0*/ 0x777E656C535A41483F362D241B120900[127:0] - ); - return FFmul_09[UInt(b)*8+:8]; - -// FFmul0B() -// ========= - -bits(8) FFmul0B(bits(8) b) - bits(256*8) FFmul_0B = ( - /* F E D C B A 9 8 7 6 5 4 3 2 1 0 */ - /*F*/ 0xA3A8B5BE8F849992FBF0EDE6D7DCC1CA[127:0] : - /*E*/ 0x1318050E3F3429224B405D56676C717A[127:0] : - /*D*/ 0xD8D3CEC5F4FFE2E9808B969DACA7BAB1[127:0] : - /*C*/ 0x68637E75444F5259303B262D1C170A01[127:0] : - /*B*/ 0x555E434879726F640D061B10212A373C[127:0] : - /*A*/ 0xE5EEF3F8C9C2DFD4BDB6ABA0919A878C[127:0] : - /*9*/ 0x2E2538330209141F767D606B5A514C47[127:0] : - /*8*/ 0x9E958883B2B9A4AFC6CDD0DBEAE1FCF7[127:0] : - /*7*/ 0x545F424978736E650C071A11202B363D[127:0] : - /*6*/ 0xE4EFF2F9C8C3DED5BCB7AAA1909B868D[127:0] : - /*5*/ 0x2F2439320308151E777C616A5B504D46[127:0] : - /*4*/ 0x9F948982B3B8A5AEC7CCD1DAEBE0FDF6[127:0] : - /*3*/ 0xA2A9B4BF8E859893FAF1ECE7D6DDC0CB[127:0] : - /*2*/ 0x1219040F3E3528234A415C57666D707B[127:0] : - /*1*/ 0xD9D2CFC4F5FEE3E8818A979CADA6BBB0[127:0] : - /*0*/ 0x69627F74454E5358313A272C1D160B00[127:0] - ); - return FFmul_0B[UInt(b)*8+:8]; - -// FFmul0D() -// ========= - -bits(8) FFmul0D(bits(8) b) - bits(256*8) FFmul_0D = ( - /* F E D C B A 9 8 7 6 5 4 3 2 1 0 */ - /*F*/ 0x979A8D80A3AEB9B4FFF2E5E8CBC6D1DC[127:0] : - /*E*/ 0x474A5D50737E69642F2235381B16010C[127:0] : - /*D*/ 0x2C21363B1815020F44495E53707D6A67[127:0] : - /*C*/ 0xFCF1E6EBC8C5D2DF94998E83A0ADBAB7[127:0] : - /*B*/ 0xFAF7E0EDCEC3D4D9929F8885A6ABBCB1[127:0] : - /*A*/ 0x2A27303D1E130409424F5855767B6C61[127:0] : - /*9*/ 0x414C5B5675786F622924333E1D10070A[127:0] : - /*8*/ 0x919C8B86A5A8BFB2F9F4E3EECDC0D7DA[127:0] : - /*7*/ 0x4D40575A7974636E25283F32111C0B06[127:0] : - /*6*/ 0x9D90878AA9A4B3BEF5F8EFE2C1CCDBD6[127:0] : - /*5*/ 0xF6FBECE1C2CFD8D59E938489AAA7B0BD[127:0] : - /*4*/ 0x262B3C31121F08054E4354597A77606D[127:0] : - /*3*/ 0x202D3A3714190E034845525F7C71666B[127:0] : - /*2*/ 0xF0FDEAE7C4C9DED39895828FACA1B6BB[127:0] : - /*1*/ 0x9B96818CAFA2B5B8F3FEE9E4C7CADDD0[127:0] : - /*0*/ 0x4B46515C7F726568232E3934171A0D00[127:0] - ); - return FFmul_0D[UInt(b)*8+:8]; - -// FFmul0E() -// ========= - -bits(8) FFmul0E(bits(8) b) - bits(256*8) FFmul_0E = ( - /* F E D C B A 9 8 7 6 5 4 3 2 1 0 */ - /*F*/ 0x8D83919FB5BBA9A7FDF3E1EFC5CBD9D7[127:0] : - /*E*/ 0x6D63717F555B49471D13010F252B3937[127:0] : - /*D*/ 0x56584A446E60727C26283A341E10020C[127:0] : - /*C*/ 0xB6B8AAA48E80929CC6C8DAD4FEF0E2EC[127:0] : - /*B*/ 0x202E3C321816040A505E4C426866747A[127:0] : - /*A*/ 0xC0CEDCD2F8F6E4EAB0BEACA28886949A[127:0] : - /*9*/ 0xFBF5E7E9C3CDDFD18B859799B3BDAFA1[127:0] : - /*8*/ 0x1B150709232D3F316B657779535D4F41[127:0] : - /*7*/ 0xCCC2D0DEF4FAE8E6BCB2A0AE848A9896[127:0] : - /*6*/ 0x2C22303E141A08065C52404E646A7876[127:0] : - /*5*/ 0x17190B052F21333D67697B755F51434D[127:0] : - /*4*/ 0xF7F9EBE5CFC1D3DD87899B95BFB1A3AD[127:0] : - /*3*/ 0x616F7D735957454B111F0D032927353B[127:0] : - /*2*/ 0x818F9D93B9B7A5ABF1FFEDE3C9C7D5DB[127:0] : - /*1*/ 0xBAB4A6A8828C9E90CAC4D6D8F2FCEEE0[127:0] : - /*0*/ 0x5A544648626C7E702A243638121C0E00[127:0] - ); - return FFmul_0E[UInt(b)*8+:8]; - -// AESInvMixColumns() -// ================== -// Transformation in the Inverse Cipher that is the inverse of AESMixColumns. - -bits(128) AESInvMixColumns(bits (128) op) - bits(4*8) in0 = op[ 96+:8] : op[ 64+:8] : op[ 32+:8] : op[ 0+:8]; - bits(4*8) in1 = op[104+:8] : op[ 72+:8] : op[ 40+:8] : op[ 8+:8]; - bits(4*8) in2 = op[112+:8] : op[ 80+:8] : op[ 48+:8] : op[ 16+:8]; - bits(4*8) in3 = op[120+:8] : op[ 88+:8] : op[ 56+:8] : op[ 24+:8]; - - bits(4*8) out0; - bits(4*8) out1; - bits(4*8) out2; - bits(4*8) out3; - - for c = 0 to 3 - out0[c*8+:8] = FFmul0E(in0[c*8+:8]) EOR FFmul0B(in1[c*8+:8]) EOR FFmul0D(in2[c*8+:8]) EOR FFmul09(in3[c*8+:8]); - out1[c*8+:8] = FFmul09(in0[c*8+:8]) EOR FFmul0E(in1[c*8+:8]) EOR FFmul0B(in2[c*8+:8]) EOR FFmul0D(in3[c*8+:8]); - out2[c*8+:8] = FFmul0D(in0[c*8+:8]) EOR FFmul09(in1[c*8+:8]) EOR FFmul0E(in2[c*8+:8]) EOR FFmul0B(in3[c*8+:8]); - out3[c*8+:8] = FFmul0B(in0[c*8+:8]) EOR FFmul0D(in1[c*8+:8]) EOR FFmul09(in2[c*8+:8]) EOR FFmul0E(in3[c*8+:8]); - - return ( - out3[3*8+:8] : out2[3*8+:8] : out1[3*8+:8] : out0[3*8+:8] : - out3[2*8+:8] : out2[2*8+:8] : out1[2*8+:8] : out0[2*8+:8] : - out3[1*8+:8] : out2[1*8+:8] : out1[1*8+:8] : out0[1*8+:8] : - out3[0*8+:8] : out2[0*8+:8] : out1[0*8+:8] : out0[0*8+:8] - ); - -// AESInvShiftRows() -// ================= -// Transformation in the Inverse Cipher that is inverse of AESShiftRows. - -bits(128) AESInvShiftRows(bits(128) op) - return ( - op[ 24+:8] : op[ 48+:8] : op[ 72+:8] : op[ 96+:8] : - op[120+:8] : op[ 16+:8] : op[ 40+:8] : op[ 64+:8] : - op[ 88+:8] : op[112+:8] : op[ 8+:8] : op[ 32+:8] : - op[ 56+:8] : op[ 80+:8] : op[104+:8] : op[ 0+:8] - ); - -// AESInvSubBytes() -// ================ -// Transformation in the Inverse Cipher that is the inverse of AESSubBytes. - -bits(128) AESInvSubBytes(bits(128) op) - // Inverse S-box values - bits(16*16*8) GF2_inv = ( - /* F E D C B A 9 8 7 6 5 4 3 2 1 0 */ - /*F*/ 0x7d0c2155631469e126d677ba7e042b17[127:0] : - /*E*/ 0x619953833cbbebc8b0f52aae4d3be0a0[127:0] : - /*D*/ 0xef9cc9939f7ae52d0d4ab519a97f5160[127:0] : - /*C*/ 0x5fec8027591012b131c7078833a8dd1f[127:0] : - /*B*/ 0xf45acd78fec0db9a2079d2c64b3e56fc[127:0] : - /*A*/ 0x1bbe18aa0e62b76f89c5291d711af147[127:0] : - /*9*/ 0x6edf751ce837f9e28535ade72274ac96[127:0] : - /*8*/ 0x73e6b4f0cecff297eadc674f4111913a[127:0] : - /*7*/ 0x6b8a130103bdafc1020f3fca8f1e2cd0[127:0] : - /*6*/ 0x0645b3b80558e4f70ad3bc8c00abd890[127:0] : - /*5*/ 0x849d8da75746155edab9edfd5048706c[127:0] : - /*4*/ 0x92b6655dcc5ca4d41698688664f6f872[127:0] : - /*3*/ 0x25d18b6d49a25b76b224d92866a12e08[127:0] : - /*2*/ 0x4ec3fa420b954cee3d23c2a632947b54[127:0] : - /*1*/ 0xcbe9dec444438e3487ff2f9b8239e37c[127:0] : - /*0*/ 0xfbd7f3819ea340bf38a53630d56a0952[127:0] - ); - bits(128) out; - for i = 0 to 15 - out[i*8+:8] = GF2_inv[UInt(op[i*8+:8])*8+:8]; - return out; - -// FFmul02() -// ========= - -bits(8) FFmul02(bits(8) b) - bits(256*8) FFmul_02 = ( - /* F E D C B A 9 8 7 6 5 4 3 2 1 0 */ - /*F*/ 0xE5E7E1E3EDEFE9EBF5F7F1F3FDFFF9FB[127:0] : - /*E*/ 0xC5C7C1C3CDCFC9CBD5D7D1D3DDDFD9DB[127:0] : - /*D*/ 0xA5A7A1A3ADAFA9ABB5B7B1B3BDBFB9BB[127:0] : - /*C*/ 0x858781838D8F898B959791939D9F999B[127:0] : - /*B*/ 0x656761636D6F696B757771737D7F797B[127:0] : - /*A*/ 0x454741434D4F494B555751535D5F595B[127:0] : - /*9*/ 0x252721232D2F292B353731333D3F393B[127:0] : - /*8*/ 0x050701030D0F090B151711131D1F191B[127:0] : - /*7*/ 0xFEFCFAF8F6F4F2F0EEECEAE8E6E4E2E0[127:0] : - /*6*/ 0xDEDCDAD8D6D4D2D0CECCCAC8C6C4C2C0[127:0] : - /*5*/ 0xBEBCBAB8B6B4B2B0AEACAAA8A6A4A2A0[127:0] : - /*4*/ 0x9E9C9A98969492908E8C8A8886848280[127:0] : - /*3*/ 0x7E7C7A78767472706E6C6A6866646260[127:0] : - /*2*/ 0x5E5C5A58565452504E4C4A4846444240[127:0] : - /*1*/ 0x3E3C3A38363432302E2C2A2826242220[127:0] : - /*0*/ 0x1E1C1A18161412100E0C0A0806040200[127:0] - ); - return FFmul_02[UInt(b)*8+:8]; - -// FFmul03() -// ========= - -bits(8) FFmul03(bits(8) b) - bits(256*8) FFmul_03 = ( - /* F E D C B A 9 8 7 6 5 4 3 2 1 0 */ - /*F*/ 0x1A191C1F16151013020104070E0D080B[127:0] : - /*E*/ 0x2A292C2F26252023323134373E3D383B[127:0] : - /*D*/ 0x7A797C7F76757073626164676E6D686B[127:0] : - /*C*/ 0x4A494C4F46454043525154575E5D585B[127:0] : - /*B*/ 0xDAD9DCDFD6D5D0D3C2C1C4C7CECDC8CB[127:0] : - /*A*/ 0xEAE9ECEFE6E5E0E3F2F1F4F7FEFDF8FB[127:0] : - /*9*/ 0xBAB9BCBFB6B5B0B3A2A1A4A7AEADA8AB[127:0] : - /*8*/ 0x8A898C8F86858083929194979E9D989B[127:0] : - /*7*/ 0x818287848D8E8B88999A9F9C95969390[127:0] : - /*6*/ 0xB1B2B7B4BDBEBBB8A9AAAFACA5A6A3A0[127:0] : - /*5*/ 0xE1E2E7E4EDEEEBE8F9FAFFFCF5F6F3F0[127:0] : - /*4*/ 0xD1D2D7D4DDDEDBD8C9CACFCCC5C6C3C0[127:0] : - /*3*/ 0x414247444D4E4B48595A5F5C55565350[127:0] : - /*2*/ 0x717277747D7E7B78696A6F6C65666360[127:0] : - /*1*/ 0x212227242D2E2B28393A3F3C35363330[127:0] : - /*0*/ 0x111217141D1E1B18090A0F0C05060300[127:0] - ); - return FFmul_03[UInt(b)*8+:8]; - -// AESMixColumns() -// =============== -// Transformation in the Cipher that takes all of the columns of the -// State and mixes their data (independently of one another) to -// produce new columns. - -bits(128) AESMixColumns(bits (128) op) - bits(4*8) in0 = op[ 96+:8] : op[ 64+:8] : op[ 32+:8] : op[ 0+:8]; - bits(4*8) in1 = op[104+:8] : op[ 72+:8] : op[ 40+:8] : op[ 8+:8]; - bits(4*8) in2 = op[112+:8] : op[ 80+:8] : op[ 48+:8] : op[ 16+:8]; - bits(4*8) in3 = op[120+:8] : op[ 88+:8] : op[ 56+:8] : op[ 24+:8]; - - bits(4*8) out0; - bits(4*8) out1; - bits(4*8) out2; - bits(4*8) out3; - - for c = 0 to 3 - out0[c*8+:8] = FFmul02(in0[c*8+:8]) EOR FFmul03(in1[c*8+:8]) EOR in2[c*8+:8] EOR in3[c*8+:8]; - out1[c*8+:8] = in0[c*8+:8] EOR FFmul02(in1[c*8+:8]) EOR FFmul03(in2[c*8+:8]) EOR in3[c*8+:8]; - out2[c*8+:8] = in0[c*8+:8] EOR in1[c*8+:8] EOR FFmul02(in2[c*8+:8]) EOR FFmul03(in3[c*8+:8]); - out3[c*8+:8] = FFmul03(in0[c*8+:8]) EOR in1[c*8+:8] EOR in2[c*8+:8] EOR FFmul02(in3[c*8+:8]); - - return ( - out3[3*8+:8] : out2[3*8+:8] : out1[3*8+:8] : out0[3*8+:8] : - out3[2*8+:8] : out2[2*8+:8] : out1[2*8+:8] : out0[2*8+:8] : - out3[1*8+:8] : out2[1*8+:8] : out1[1*8+:8] : out0[1*8+:8] : - out3[0*8+:8] : out2[0*8+:8] : out1[0*8+:8] : out0[0*8+:8] - ); - -// AESShiftRows() -// ============== -// Transformation in the Cipher that processes the State by cyclically -// shifting the last three rows of the State by different offsets. - -bits(128) AESShiftRows(bits(128) op) - return ( - op[ 88+:8] : op[ 48+:8] : op[ 8+:8] : op[ 96+:8] : - op[ 56+:8] : op[ 16+:8] : op[104+:8] : op[ 64+:8] : - op[ 24+:8] : op[112+:8] : op[ 72+:8] : op[ 32+:8] : - op[120+:8] : op[ 80+:8] : op[ 40+:8] : op[ 0+:8] - ); - -// AESSubBytes() -// ============= -// Transformation in the Cipher that processes the State using a nonlinear -// byte substitution table (S-box) that operates on each of the State bytes -// independently. - -bits(128) AESSubBytes(bits(128) op) - // S-box values - bits(16*16*8) GF2 = ( - /* F E D C B A 9 8 7 6 5 4 3 2 1 0 */ - /*F*/ 0x16bb54b00f2d99416842e6bf0d89a18c[127:0] : - /*E*/ 0xdf2855cee9871e9b948ed9691198f8e1[127:0] : - /*D*/ 0x9e1dc186b95735610ef6034866b53e70[127:0] : - /*C*/ 0x8a8bbd4b1f74dde8c6b4a61c2e2578ba[127:0] : - /*B*/ 0x08ae7a65eaf4566ca94ed58d6d37c8e7[127:0] : - /*A*/ 0x79e4959162acd3c25c2406490a3a32e0[127:0] : - /*9*/ 0xdb0b5ede14b8ee4688902a22dc4f8160[127:0] : - /*8*/ 0x73195d643d7ea7c41744975fec130ccd[127:0] : - /*7*/ 0xd2f3ff1021dab6bcf5389d928f40a351[127:0] : - /*6*/ 0xa89f3c507f02f94585334d43fbaaefd0[127:0] : - /*5*/ 0xcf584c4a39becb6a5bb1fc20ed00d153[127:0] : - /*4*/ 0x842fe329b3d63b52a05a6e1b1a2c8309[127:0] : - /*3*/ 0x75b227ebe28012079a059618c323c704[127:0] : - /*2*/ 0x1531d871f1e5a534ccf73f362693fdb7[127:0] : - /*1*/ 0xc072a49cafa2d4adf04759fa7dc982ca[127:0] : - /*0*/ 0x76abd7fe2b670130c56f6bf27b777c63[127:0] - ); - bits(128) out; - for i = 0 to 15 - out[i*8+:8] = GF2[UInt(op[i*8+:8])*8+:8]; - return out; - -// HaveAESExt() -// ============ -// TRUE if AES cryptographic instructions support is implemented, -// FALSE otherwise. - -boolean HaveAESExt() - return boolean IMPLEMENTATION_DEFINED "Has AES Crypto instructions"; - -// HaveBit128PMULLExt() -// ==================== -// TRUE if 128 bit form of PMULL instructions support is implemented, -// FALSE otherwise. - -boolean HaveBit128PMULLExt() - return boolean IMPLEMENTATION_DEFINED "Has 128-bit form of PMULL instructions"; - -// HaveSHA1Ext() -// ============= -// TRUE if SHA1 cryptographic instructions support is implemented, -// FALSE otherwise. - -boolean HaveSHA1Ext() - return boolean IMPLEMENTATION_DEFINED "Has SHA1 Crypto instructions"; - -// HaveSHA256Ext() -// =============== -// TRUE if SHA256 cryptographic instructions support is implemented, -// FALSE otherwise. - -boolean HaveSHA256Ext() - return boolean IMPLEMENTATION_DEFINED "Has SHA256 Crypto instructions"; - -// HaveSHA3Ext() -// ============= -// TRUE if SHA3 cryptographic instructions support is implemented, -// and when SHA1 and SHA2 basic cryptographic instructions support is implemented, -// FALSE otherwise. - -boolean HaveSHA3Ext() - if !HasArchVersion(ARMv8p2) || !(HaveSHA1Ext() && HaveSHA256Ext()) then - return FALSE; - return boolean IMPLEMENTATION_DEFINED "Has SHA3 Crypto instructions"; - -// HaveSHA512Ext() -// =============== -// TRUE if SHA512 cryptographic instructions support is implemented, -// and when SHA1 and SHA2 basic cryptographic instructions support is implemented, -// FALSE otherwise. - -boolean HaveSHA512Ext() - if !HasArchVersion(ARMv8p2) || !(HaveSHA1Ext() && HaveSHA256Ext()) then - return FALSE; - return boolean IMPLEMENTATION_DEFINED "Has SHA512 Crypto instructions"; - -// HaveSM3Ext() -// ============ -// TRUE if SM3 cryptographic instructions support is implemented, -// FALSE otherwise. - -boolean HaveSM3Ext() - if !HasArchVersion(ARMv8p2) then - return FALSE; - return boolean IMPLEMENTATION_DEFINED "Has SM3 Crypto instructions"; - -// HaveSM4Ext() -// ============ -// TRUE if SM4 cryptographic instructions support is implemented, -// FALSE otherwise. - -boolean HaveSM4Ext() - if !HasArchVersion(ARMv8p2) then - return FALSE; - return boolean IMPLEMENTATION_DEFINED "Has SM4 Crypto instructions"; - -// ROL() -// ===== - -bits(N) ROL(bits(N) x, integer shift) - assert shift >= 0 && shift <= N; - if (shift == 0) then - return x; - return ROR(x, N-shift); - -// SHAchoose() -// =========== - -bits(32) SHAchoose(bits(32) x, bits(32) y, bits(32) z) - return (((y EOR z) AND x) EOR z); - -// SHAhashSIGMA0() -// =============== - -bits(32) SHAhashSIGMA0(bits(32) x) - return ROR(x, 2) EOR ROR(x, 13) EOR ROR(x, 22); - -// SHAhashSIGMA1() -// =============== - -bits(32) SHAhashSIGMA1(bits(32) x) - return ROR(x, 6) EOR ROR(x, 11) EOR ROR(x, 25); - -// SHAmajority() -// ============= - -bits(32) SHAmajority(bits(32) x, bits(32) y, bits(32) z) - return ((x AND y) OR ((x OR y) AND z)); - -// SHA256hash() -// ============ - -bits(128) SHA256hash(bits (128) X, bits(128) Y, bits(128) W, boolean part1) - bits(32) chs, maj, t; - - for e = 0 to 3 - chs = SHAchoose(Y[31:0], Y[63:32], Y[95:64]); - maj = SHAmajority(X[31:0], X[63:32], X[95:64]); - t = Y[127:96] + SHAhashSIGMA1(Y[31:0]) + chs + Elem[W, e, 32]; - X[127:96] = t + X[127:96]; - Y[127:96] = t + SHAhashSIGMA0(X[31:0]) + maj; - [Y, X] = ROL(Y : X, 32); - return (if part1 then X else Y); - -// SHAparity() -// =========== - -bits(32) SHAparity(bits(32) x, bits(32) y, bits(32) z) - return (x EOR y EOR z); - -// Sbox() -// ====== -// Used in SM4E crypto instruction - -bits(8) Sbox(bits(8) sboxin) - bits(8) sboxout; - bits(2048) sboxstring = 0xd690e9fecce13db716b614c228fb2c052b679a762abe04c3aa441326498606999c4250f491ef987a33540b43edcfac62e4b31ca9c908e89580df94fa758f3fa64707a7fcf37317ba83593c19e6854fa8686b81b27164da8bf8eb0f4b70569d351e240e5e6358d1a225227c3b01217887d40046579fd327524c3602e7a0c4c89eeabf8ad240c738b5a3f7f2cef96115a1e0ae5da49b341a55ad933230f58cb1e31df6e22e8266ca60c02923ab0d534e6fd5db3745defd8e2f03ff6a726d6c5b518d1baf92bbddbc7f11d95c411f105ad80ac13188a5cd7bbd2d74d012b8e5b4b08969974a0c96777e65b9f109c56ec68418f07dec3adc4d2079ee5f3ed7cb3948[2047:0]; - - sboxout = sboxstring[(255-UInt(sboxin))*8+7:(255-UInt(sboxin))*8]; - return sboxout; - -// ClearExclusiveMonitors() -// ======================== - -// Clear the local Exclusives monitor for the executing PE. - -ClearExclusiveMonitors() - ClearExclusiveLocal(ProcessorID()); - -// Returns '0' to indicate success if the last memory write by this PE was to -// the same physical address region endorsed by ExclusiveMonitorsPass(). -// Returns '1' to indicate failure if address translation resulted in a different -// physical address. -bit ExclusiveMonitorsStatus(); - -// HaveAArch32BF16Ext() -// ==================== -// Returns TRUE if AArch32 BFloat16 instruction support is implemented, and FALSE otherwise. - -boolean HaveAArch32BF16Ext() - return HasArchVersion(ARMv8p2) && boolean IMPLEMENTATION_DEFINED "Has AArch32 BFloat16 extension"; - -// HaveAArch32Int8MatMulExt() -// ========================== -// Returns TRUE if AArch32 8-bit integer matrix multiply instruction support -// implemented, and FALSE otherwise. - -boolean HaveAArch32Int8MatMulExt() - return HasArchVersion(ARMv8p2) && boolean IMPLEMENTATION_DEFINED "Has AArch32 Int8 Mat Mul extension"; - -// HaveAtomicExt() -// =============== - -boolean HaveAtomicExt() - return HasArchVersion(ARMv8p1); - -// HaveBF16Ext() -// ============= -// Returns TRUE if AArch64 BFloat16 instruction support is implemented, and FALSE otherwise. - -boolean HaveBF16Ext() - return HasArchVersion(ARMv8p6) || (HasArchVersion(ARMv8p2) && boolean IMPLEMENTATION_DEFINED "Has AArch64 BFloat16 extension"); - -// HaveDGHExt() -// ============ -// Returns TRUE if Data Gathering Hint instruction support is implemented, and FALSE otherwise. - -boolean HaveDGHExt() - return boolean IMPLEMENTATION_DEFINED "Has AArch64 DGH extension"; - -// HaveDOTPExt() -// ============= -// Returns TRUE if Dot Product feature support is implemented, and FALSE otherwise. - -boolean HaveDOTPExt() - return HasArchVersion(ARMv8p4) || (HasArchVersion(ARMv8p2) && boolean IMPLEMENTATION_DEFINED "Has Dot Product extension"); - -// HaveMPAMExt() -// ============= -// Returns TRUE if MPAM is implemented, and FALSE otherwise. - -boolean HaveMPAMExt() - return (HasArchVersion(ARMv8p2) && - boolean IMPLEMENTATION_DEFINED "Has MPAM extension"); - -// HaveEMPAMExt() -// ============== -// Returns TRUE if Enhanced MPAM is implemented, and FALSE otherwise. - -boolean HaveEMPAMExt() - return (HasArchVersion(ARMv8p6) && - HaveMPAMExt() && - boolean IMPLEMENTATION_DEFINED "Has enhanced MPAM extension"); - -// HaveExtendedCacheSets() -// ======================= - -boolean HaveExtendedCacheSets() - return HasArchVersion(ARMv8p3); - -// HaveFCADDExt() -// ============== - -boolean HaveFCADDExt() - return HasArchVersion(ARMv8p3); - -// HaveFJCVTZSExt() -// ================ - -boolean HaveFJCVTZSExt() - return HasArchVersion(ARMv8p3); - -// HaveFP16Ext() -// ============= -// Return TRUE if FP16 extension is supported - -boolean HaveFP16Ext() - return boolean IMPLEMENTATION_DEFINED; - -// HaveFP16MulNoRoundingToFP32Ext() -// ================================ -// Returns TRUE if has FP16 multiply with no intermediate rounding accumulate to FP32 instructions, -// and FALSE otherwise - -boolean HaveFP16MulNoRoundingToFP32Ext() - if !HaveFP16Ext() then return FALSE; - if HasArchVersion(ARMv8p4) then return TRUE; - return (HasArchVersion(ARMv8p2) && - boolean IMPLEMENTATION_DEFINED "Has accumulate FP16 product into FP32 extension"); - -// HaveFlagFormatExt() -// =================== -// Returns TRUE if flag format conversion instructions implemented. - -boolean HaveFlagFormatExt() - return HasArchVersion(ARMv8p5); - -// HaveFlagManipulateExt() -// ======================= -// Returns TRUE if flag manipulate instructions are implemented. - -boolean HaveFlagManipulateExt() - return HasArchVersion(ARMv8p4); - -// HaveFrintExt() -// ============== -// Returns TRUE if FRINT instructions are implemented. - -boolean HaveFrintExt() - return HasArchVersion(ARMv8p5); - -// HaveIDSExt() -// ============ -// Returns TRUE if ID register handling feature is implemented. - -boolean HaveIDSExt() - return HasArchVersion(ARMv8p4); - -// HaveInt8MatMulExt() -// =================== -// Returns TRUE if AArch64 8-bit integer matrix multiply instruction support -// implemented, and FALSE otherwise. - -boolean HaveInt8MatMulExt() - return HasArchVersion(ARMv8p6) || (HasArchVersion(ARMv8p2) && boolean IMPLEMENTATION_DEFINED "Has AArch64 Int8 Mat Mul extension"); - -// HavePageBasedHardwareAttributes() -// ================================= - -boolean HavePageBasedHardwareAttributes() - return HasArchVersion(ARMv8p2); - -// HaveRNG() -// ========= -// Returns TRUE if Random Number Generator extension -// support is implemented and FALSE otherwise. - -boolean HaveRNG() - return HasArchVersion(ARMv8p5) && boolean IMPLEMENTATION_DEFINED "Has RNG extension"; - -// HaveSBExt() -// =========== -// Returns TRUE if support for SB is implemented, and FALSE otherwise. - -boolean HaveSBExt() - return HasArchVersion(ARMv8p5) || boolean IMPLEMENTATION_DEFINED "Has SB extension"; - -// HaveSelfHostedTrace() -// ===================== - -boolean HaveSelfHostedTrace() - return HasArchVersion(ARMv8p4); - -// HaveTraceExt() -// ============== -// Returns TRUE if Trace functionality as described by the Trace Architecture -// is implemented. - -boolean HaveTraceExt() - return boolean IMPLEMENTATION_DEFINED "Has Trace Architecture functionality"; - -// BFRound() -// ========= -// Converts a real number OP into a single-precision value using the -// Round to Odd rounding mode and following BFloat16 computation behaviors. - -bits(32) BFRound(real op) - assert op != 0.0; - bits(32) result; - - // Format parameters - minimum exponent, numbers of exponent and fraction bits. - minimum_exp = -126; E = 8; F = 23; - - // Split value into sign, unrounded mantissa and exponent. - if op < 0.0 then - sign = '1'; mantissa = -op; - else - sign = '0'; mantissa = op; - exponent = 0; - while mantissa < 1.0 do - mantissa = mantissa * 2.0; exponent = exponent - 1; - while mantissa >= 2.0 do - mantissa = mantissa / 2.0; exponent = exponent + 1; - - // Fixed Flush-to-zero. - if exponent < minimum_exp then - return FPZero(sign); - - // Start creating the exponent value for the result. Start by biasing the actual exponent - // so that the minimum exponent becomes 1, lower values 0 (indicating possible underflow). - biased_exp = Max(exponent - minimum_exp + 1, 0); - if biased_exp == 0 then mantissa = mantissa / 2.0^(minimum_exp - exponent); - - // Get the unrounded mantissa as an integer, and the "units in last place" rounding error. - int_mant = RoundDown(mantissa * 2.0^F); // < 2.0^F if biased_exp == 0, >= 2.0^F if not - error = mantissa * 2.0^F - Real(int_mant); - - // Round to Odd - if error != 0.0 then - int_mant[0] = '1'; - - // Deal with overflow and generate result. - if biased_exp >= 2^E - 1 then - result = FPInfinity(sign); // Overflows generate appropriately-signed Infinity - else - result = sign : biased_exp[30-F:0] : int_mant[F-1:0]; - - return result; - -// BFUnpack() -// ========== -// Unpacks a BFloat16 or single-precision value into its type1, -// sign bit and real number that it represents. -// The real number result has the correct sign for numbers and infinities, -// is very large in magnitude for infinities, and is 0.0 for NaNs. -// (These values are chosen to simplify the description of -// comparisons and conversions.) - -(FPType, bit, real) BFUnpack(bits(N) fpval) - assert N IN {16,32}; - - if N == 16 then - sign = fpval[15]; - exp = fpval[14:7]; - frac = fpval[6:0] : Zeros(16); - else // N == 32 - sign = fpval[31]; - exp = fpval[30:23]; - frac = fpval[22:0]; - - if IsZero(exp) then - fptype = FPType_Zero; value = 0.0; // Fixed Flush to Zero - elsif IsOnes(exp) then - if IsZero(frac) then - fptype = FPType_Infinity; value = 2.0^1000000; - else // no SNaN for BF16 arithmetic - fptype = FPType_QNaN; value = 0.0; - else - fptype = FPType_Nonzero; - value = 2.0^(UInt(exp)-127) * (1.0 + Real(UInt(frac)) * 2.0^-23); - - if sign == '1' then value = -value; - - return (fptype, sign, value); - -// BFAdd() -// ======= -// Single-precision add following BFloat16 computation behaviors. - -bits(32) BFAdd(bits(32) op1, bits(32) op2) - bits(32) result; - - (type1,sign1,value1) = BFUnpack(op1); - (type2,sign2,value2) = BFUnpack(op2); - if type1 == FPType_QNaN || type2 == FPType_QNaN then - result = FPDefaultNaN(); - else - inf1 = (type1 == FPType_Infinity); - inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); - zero2 = (type2 == FPType_Zero); - if inf1 && inf2 && sign1 == NOT(sign2) then - result = FPDefaultNaN(); - elsif (inf1 && sign1 == '0') || (inf2 && sign2 == '0') then - result = FPInfinity('0'); - elsif (inf1 && sign1 == '1') || (inf2 && sign2 == '1') then - result = FPInfinity('1'); - elsif zero1 && zero2 && sign1 == sign2 then - result = FPZero(sign1); - else - result_value = value1 + value2; - if result_value == 0.0 then - result = FPZero('0'); // Positive sign when Round to Odd - else - result = BFRound(result_value); - - return result; - -// BFMul() -// ======= -// BFloat16 widening multiply to single-precision following BFloat16 -// computation behaviors. - -bits(32) BFMul(bits(16) op1, bits(16) op2) - bits(32) result; - - (type1,sign1,value1) = BFUnpack(op1); - (type2,sign2,value2) = BFUnpack(op2); - if type1 == FPType_QNaN || type2 == FPType_QNaN then - result = FPDefaultNaN(); - else - inf1 = (type1 == FPType_Infinity); - inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); - zero2 = (type2 == FPType_Zero); - if (inf1 && zero2) || (zero1 && inf2) then - result = FPDefaultNaN(); - elsif inf1 || inf2 then - result = FPInfinity(sign1 EOR sign2); - elsif zero1 || zero2 then - result = FPZero(sign1 EOR sign2); - else - result = BFRound(value1*value2); - - return result; - -// BFMatMulAdd() -// ============= -// BFloat16 matrix multiply and add to single-precision matrix -// result[2, 2] = addend[2, 2] + (op1[2, 4] * op2[4, 2]) - -bits(N) BFMatMulAdd(bits(N) addend, bits(N) op1, bits(N) op2) - assert N == 128; - - bits(N) result; - bits(32) sum, prod0, prod1; - - for i = 0 to 1 - for j = 0 to 1 - sum = Elem[addend, 2*i + j, 32]; - for k = 0 to 1 - prod0 = BFMul(Elem[op1, 4*i + 2*k + 0, 16], Elem[op2, 4*j + 2*k + 0, 16]); - prod1 = BFMul(Elem[op1, 4*i + 2*k + 1, 16], Elem[op2, 4*j + 2*k + 1, 16]); - sum = BFAdd(sum, BFAdd(prod0, prod1)); - Elem[result, 2*i + j, 32] = sum; - - return result; - -// FPRoundCVBF() -// ============= -// Converts a real number OP into a BFloat16 value using the supplied rounding mode RMODE. - -bits(32) FPRoundCVBF(real op, FPCRType fpcr, FPRounding rounding) - boolean isbfloat = TRUE; - return FPRoundBase(op, fpcr, rounding, isbfloat); - -// FPConvertBF() -// ============= -// Converts a single-precision OP to BFloat16 value with rounding controlled by ROUNDING. - -bits(16) FPConvertBF(bits(32) op, FPCRType fpcr, FPRounding rounding) - bits(32) result; // BF16 value in top 16 bits - - // Unpack floating-point operand optionally with flush-to-zero. - (fptype,sign,value) = FPUnpack(op, fpcr); - - if fptype == FPType_SNaN || fptype == FPType_QNaN then - if fpcr.DN == '1' then - result = FPDefaultNaN(); - else - result = FPConvertNaN(op); - if fptype == FPType_SNaN then - FPProcessException(FPExc_InvalidOp, fpcr); - elsif fptype == FPType_Infinity then - result = FPInfinity(sign); - elsif fptype == FPType_Zero then - result = FPZero(sign); - else - result = FPRoundCVBF(value, fpcr, rounding); - - // Returns correctly rounded BF16 value from top 16 bits - return result[31:16]; - -// FPConvertBF() -// ============= -// Converts a single-precision operand to BFloat16 value. - -bits(16) FPConvertBF(bits(32) op, FPCRType fpcr) - return FPConvertBF(op, fpcr, FPRoundingMode(fpcr)); - -// FixedToFP() -// =========== - -// Convert M-bit fixed point OP with FBITS fractional bits to -// N-bit precision floating point, controlled by UNSIGNED and ROUNDING. - -bits(N) FixedToFP(bits(M) op, integer fbits, boolean unsigned, FPCRType fpcr, FPRounding rounding) - assert N IN {16,32,64}; - assert M IN {16,32,64}; - bits(N) result; - assert fbits >= 0; - assert rounding != FPRounding_ODD; - - // Correct signed-ness - int_operand = Int(op, unsigned); - - // Scale by fractional bits and generate a real value - real_operand = Real(int_operand) / 2.0^fbits; - - if real_operand == 0.0 then - result = FPZero('0'); - else - result = FPRound(real_operand, fpcr, rounding); - - return result; - -// FPAbs() -// ======= - -bits(N) FPAbs(bits(N) op) - assert N IN {16,32,64}; - return '0' : op[N-2:0]; - -// FPCompare() -// =========== - -bits(4) FPCompare(bits(N) op1, bits(N) op2, boolean signal_nans, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - if type1==FPType_SNaN || type1==FPType_QNaN || type2==FPType_SNaN || type2==FPType_QNaN then - result = '0011'; - if type1==FPType_SNaN || type2==FPType_SNaN || signal_nans then - FPProcessException(FPExc_InvalidOp, fpcr); - else - // All non-NaN cases can be evaluated on the values produced by FPUnpack() - if value1 == value2 then - result = '0110'; - elsif value1 < value2 then - result = '1000'; - else // value1 > value2 - result = '0010'; - return result; - -// FPCompareEQ() -// ============= - -boolean FPCompareEQ(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - if type1==FPType_SNaN || type1==FPType_QNaN || type2==FPType_SNaN || type2==FPType_QNaN then - result = FALSE; - if type1==FPType_SNaN || type2==FPType_SNaN then - FPProcessException(FPExc_InvalidOp, fpcr); - else - // All non-NaN cases can be evaluated on the values produced by FPUnpack() - result = (value1 == value2); - return result; - -// FPCompareGE() -// ============= - -boolean FPCompareGE(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - if type1==FPType_SNaN || type1==FPType_QNaN || type2==FPType_SNaN || type2==FPType_QNaN then - result = FALSE; - FPProcessException(FPExc_InvalidOp, fpcr); - else - // All non-NaN cases can be evaluated on the values produced by FPUnpack() - result = (value1 >= value2); - return result; - -// FPCompareGT() -// ============= - -boolean FPCompareGT(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - if type1==FPType_SNaN || type1==FPType_QNaN || type2==FPType_SNaN || type2==FPType_QNaN then - result = FALSE; - FPProcessException(FPExc_InvalidOp, fpcr); - else - // All non-NaN cases can be evaluated on the values produced by FPUnpack() - result = (value1 > value2); - return result; - -// FPDecodeRM() -// ============ - -// Decode most common AArch32 floating-point rounding encoding. - -FPRounding FPDecodeRM(bits(2) rm) - case rm of - when '00' return FPRounding_TIEAWAY; // A - when '01' return FPRounding_TIEEVEN; // N - when '10' return FPRounding_POSINF; // P - when '11' return FPRounding_NEGINF; // M - -// FPDiv() -// ======= - -bits(N) FPDiv(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - inf1 = (type1 == FPType_Infinity); - inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); - zero2 = (type2 == FPType_Zero); - if (inf1 && inf2) || (zero1 && zero2) then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - elsif inf1 || zero2 then - result = FPInfinity(sign1 EOR sign2); - if !inf1 then FPProcessException(FPExc_DivideByZero, fpcr); - elsif zero1 || inf2 then - result = FPZero(sign1 EOR sign2); - else - result = FPRound(value1/value2, fpcr); - return result; - -// FPMatMulAdd() -// ============= -// -// Floating point matrix multiply and add to same precision matrix -// result[2, 2] = addend[2, 2] + (op1[2, 2] * op2[2, 2]) - -bits(N) FPMatMulAdd(bits(N) addend, bits(N) op1, bits(N) op2, integer esize, FPCRType fpcr) - assert N == esize * 2 * 2; - bits(N) result; - bits(esize) prod0, prod1, sum; - - for i = 0 to 1 - for j = 0 to 1 - sum = Elem[addend, 2*i + j, esize]; - prod0 = FPMul(Elem[op1, 2*i + 0, esize], - Elem[op2, 2*j + 0, esize], fpcr); - prod1 = FPMul(Elem[op1, 2*i + 1, esize], - Elem[op2, 2*j + 1, esize], fpcr); - sum = FPAdd(sum, FPAdd(prod0, prod1, fpcr), fpcr); - Elem[result, 2*i + j, esize] = sum; - - return result; - -// FPMulAddH() -// =========== - -bits(N) FPMulAddH(bits(N) addend, bits(N DIV 2) op1, bits(N DIV 2) op2, FPCRType fpcr) - assert N IN {32,64}; - rounding = FPRoundingMode(fpcr); - (typeA,signA,valueA) = FPUnpack(addend, fpcr); - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - inf1 = (type1 == FPType_Infinity); zero1 = (type1 == FPType_Zero); - inf2 = (type2 == FPType_Infinity); zero2 = (type2 == FPType_Zero); - (done,result) = FPProcessNaNs3H(typeA, type1, type2, addend, op1, op2, fpcr); - if typeA == FPType_QNaN && ((inf1 && zero2) || (zero1 && inf2)) then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - if !done then - infA = (typeA == FPType_Infinity); zeroA = (typeA == FPType_Zero); - // Determine sign and type1 product will have if it does not cause an Invalid - // Operation. - signP = sign1 EOR sign2; - infP = inf1 || inf2; - zeroP = zero1 || zero2; - // Non SNaN-generated Invalid Operation cases are multiplies of zero by infinity and - // additions of opposite-signed infinities. - if (inf1 && zero2) || (zero1 && inf2) || (infA && infP && signA != signP) then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - // Other cases involving infinities produce an infinity of the same sign. - elsif (infA && signA == '0') || (infP && signP == '0') then - result = FPInfinity('0'); - elsif (infA && signA == '1') || (infP && signP == '1') then - result = FPInfinity('1'); - // Cases where the result is exactly zero and its sign is not determined by the - // rounding mode are additions of same-signed zeros. - elsif zeroA && zeroP && signA == signP then - result = FPZero(signA); - // Otherwise calculate numerical result and round it. - else - result_value = valueA + (value1 * value2); - if result_value == 0.0 then // Sign of exact zero result depends on rounding mode - result_sign = if rounding == FPRounding_NEGINF then '1' else '0'; - result = FPZero(result_sign); - else - result = FPRound(result_value, fpcr); - return result; - -// FPProcessNaNs3H() -// ================= - -(boolean, bits(N)) FPProcessNaNs3H(FPType type1, FPType type2, FPType type3, bits(N) op1, bits(N DIV 2) op2, bits(N DIV 2) op3, FPCRType fpcr) - assert N IN {32,64}; - bits(N) result; - if type1 == FPType_SNaN then - done = TRUE; result = FPProcessNaN(type1, op1, fpcr); - elsif type2 == FPType_SNaN then - done = TRUE; result = FPConvertNaN(FPProcessNaN(type2, op2, fpcr)); - elsif type3 == FPType_SNaN then - done = TRUE; result = FPConvertNaN(FPProcessNaN(type3, op3, fpcr)); - elsif type1 == FPType_QNaN then - done = TRUE; result = FPProcessNaN(type1, op1, fpcr); - elsif type2 == FPType_QNaN then - done = TRUE; result = FPConvertNaN(FPProcessNaN(type2, op2, fpcr)); - elsif type3 == FPType_QNaN then - done = TRUE; result = FPConvertNaN(FPProcessNaN(type3, op3, fpcr)); - else - done = FALSE; result = Zeros(); // 'Don't care' result - return (done, result); - -// FPMulX() -// ======== - -bits(N) FPMulX(bits(N) op1, bits(N) op2, FPCRType fpcr) - assert N IN {16,32,64}; - bits(N) result; - (type1,sign1,value1) = FPUnpack(op1, fpcr); - (type2,sign2,value2) = FPUnpack(op2, fpcr); - (done,result) = FPProcessNaNs(type1, type2, op1, op2, fpcr); - if !done then - inf1 = (type1 == FPType_Infinity); - inf2 = (type2 == FPType_Infinity); - zero1 = (type1 == FPType_Zero); - zero2 = (type2 == FPType_Zero); - if (inf1 && zero2) || (zero1 && inf2) then - result = FPTwo(sign1 EOR sign2); - elsif inf1 || inf2 then - result = FPInfinity(sign1 EOR sign2); - elsif zero1 || zero2 then - result = FPZero(sign1 EOR sign2); - else - result = FPRound(value1*value2, fpcr); - return result; - -// Compute estimate of reciprocal of 9-bit fixed-point number -// -// a is in range 256 .. 511 representing a number in the range 0.5 <= x < 1.0. -// result is in the range 256 .. 511 representing a number in the range in the range 1.0 to 511/256. - -integer RecipEstimate(integer a) - assert 256 <= a && a < 512; - a = a*2+1; // round to nearest - integer b = (2 ^ 19) DIV a; - r = (b+1) DIV 2; // round to nearest - assert 256 <= r && r < 512; - return r; - -// FPRecipEstimate() -// ================= - -bits(N) FPRecipEstimate(bits(N) operand, FPCRType fpcr) - assert N IN {16,32,64}; - (fptype,sign,value) = FPUnpack(operand, fpcr); - if fptype == FPType_SNaN || fptype == FPType_QNaN then - result = FPProcessNaN(fptype, operand, fpcr); - elsif fptype == FPType_Infinity then - result = FPZero(sign); - elsif fptype == FPType_Zero then - result = FPInfinity(sign); - FPProcessException(FPExc_DivideByZero, fpcr); - elsif ( - (N == 16 && Abs(value) < 2.0^-16) || - (N == 32 && Abs(value) < 2.0^-128) || - (N == 64 && Abs(value) < 2.0^-1024) - ) then - case FPRoundingMode(fpcr) of - when FPRounding_TIEEVEN - overflow_to_inf = TRUE; - when FPRounding_POSINF - overflow_to_inf = (sign == '0'); - when FPRounding_NEGINF - overflow_to_inf = (sign == '1'); - when FPRounding_ZERO - overflow_to_inf = FALSE; - result = if overflow_to_inf then FPInfinity(sign) else FPMaxNormal(sign); - FPProcessException(FPExc_Overflow, fpcr); - FPProcessException(FPExc_Inexact, fpcr); - elsif ((fpcr.FZ == '1' && N != 16) || (fpcr.FZ16 == '1' && N == 16)) - && ( - (N == 16 && Abs(value) >= 2.0^14) || - (N == 32 && Abs(value) >= 2.0^126) || - (N == 64 && Abs(value) >= 2.0^1022) - ) then - // Result flushed to zero of correct sign - result = FPZero(sign); - if UsingAArch32() then - FPSCR.UFC = '1'; - else - FPSR.UFC = '1'; - else - // Scale to a fixed point value in the range 0.5 <= x < 1.0 in steps of 1/512, and - // calculate result exponent. Scaled value has copied sign bit, - // exponent = 1022 = double-precision biased version of -1, - // fraction = original fraction - case N of - when 16 - fraction = operand[9:0] : Zeros(42); - exp = UInt(operand[14:10]); - when 32 - fraction = operand[22:0] : Zeros(29); - exp = UInt(operand[30:23]); - when 64 - fraction = operand[51:0]; - exp = UInt(operand[62:52]); - - if exp == 0 then - if fraction[51] == '0' then - exp = -1; - fraction = fraction[49:0]:'00'; - else - fraction = fraction[50:0]:'0'; - - integer scaled = UInt('1':fraction[51:44]); - - case N of - when 16 result_exp = 29 - exp; // In range 29-30 = -1 to 29+1 = 30 - when 32 result_exp = 253 - exp; // In range 253-254 = -1 to 253+1 = 254 - when 64 result_exp = 2045 - exp; // In range 2045-2046 = -1 to 2045+1 = 2046 - - // scaled is in range 256..511 representing a fixed-point number in range [0.5..1.0) - estimate = RecipEstimate(scaled); - - // estimate is in the range 256..511 representing a fixed point result in the range [1.0..2.0) - // Convert to scaled floating point result with copied sign bit, - // high-order bits from estimate, and exponent calculated above. - - fraction = estimate[7:0] : Zeros(44); - if result_exp == 0 then - fraction = '1' : fraction[51:1]; - elsif result_exp == -1 then - fraction = '01' : fraction[51:2]; - result_exp = 0; - - case N of - when 16 result = sign : result_exp[N-12:0] : fraction[51:42]; - when 32 result = sign : result_exp[N-25:0] : fraction[51:29]; - when 64 result = sign : result_exp[N-54:0] : fraction[51:0]; - - return result; - -// FPRecpX() -// ========= - -bits(N) FPRecpX(bits(N) op, FPCRType fpcr) - assert N IN {16,32,64}; - - case N of - when 16 esize = 5; - when 32 esize = 8; - when 64 esize = 11; - - bits(N) result; - bits(esize) exp; - bits(esize) max_exp; - bits(N-(esize+1)) frac = Zeros(); - - case N of - when 16 exp = op[10+esize-1:10]; - when 32 exp = op[23+esize-1:23]; - when 64 exp = op[52+esize-1:52]; - - max_exp = Ones(esize) - 1; - - (fptype,sign,value) = FPUnpack(op, fpcr); - if fptype == FPType_SNaN || fptype == FPType_QNaN then - result = FPProcessNaN(fptype, op, fpcr); - else - if IsZero(exp) then // Zero and denormals - result = sign:max_exp:frac; - else // Infinities and normals - result = sign:NOT(exp):frac; - - return result; - -// FPRoundInt() -// ============ - -// Round OP to nearest integral floating point value using rounding mode ROUNDING. -// If EXACT is TRUE, set FPSR.IXC if result is not numerically equal to OP. - -bits(N) FPRoundInt(bits(N) op, FPCRType fpcr, FPRounding rounding, boolean exact) - assert rounding != FPRounding_ODD; - assert N IN {16,32,64}; - - // Unpack using FPCR to determine if subnormals are flushed-to-zero - (fptype,sign,value) = FPUnpack(op, fpcr); - - if fptype == FPType_SNaN || fptype == FPType_QNaN then - result = FPProcessNaN(fptype, op, fpcr); - elsif fptype == FPType_Infinity then - result = FPInfinity(sign); - elsif fptype == FPType_Zero then - result = FPZero(sign); - else - // extract integer component - int_result = RoundDown(value); - error = value - Real(int_result); - - // Determine whether supplied rounding mode requires an increment - case rounding of - when FPRounding_TIEEVEN - round_up = (error > 0.5 || (error == 0.5 && int_result[0] == '1')); - when FPRounding_POSINF - round_up = (error != 0.0); - when FPRounding_NEGINF - round_up = FALSE; - when FPRounding_ZERO - round_up = (error != 0.0 && int_result < 0); - when FPRounding_TIEAWAY - round_up = (error > 0.5 || (error == 0.5 && int_result >= 0)); - - if round_up then int_result = int_result + 1; - - // Convert integer value into an equivalent real value - real_result = Real(int_result); - - // Re-encode as a floating-point value, result is always exact - if real_result == 0.0 then - result = FPZero(sign); - else - result = FPRound(real_result, fpcr, FPRounding_ZERO); - - // Generate inexact exceptions - if error != 0.0 && exact then - FPProcessException(FPExc_Inexact, fpcr); - - return result; - -// FPRoundIntN() -// ============= - -bits(N) FPRoundIntN(bits(N) op, FPCRType fpcr, FPRounding rounding, integer intsize) - assert rounding != FPRounding_ODD; - assert N IN {32,64}; - assert intsize IN {32, 64}; - integer exp; - constant integer E = (if N == 32 then 8 else 11); - constant integer F = N - (E + 1); - - // Unpack using FPCR to determine if subnormals are flushed-to-zero - (fptype,sign,value) = FPUnpack(op, fpcr); - - if fptype IN {FPType_SNaN, FPType_QNaN, FPType_Infinity} then - if N == 32 then - exp = 126 + intsize; - result = '1':exp[(E-1):0]:Zeros(F); - else - exp = 1022+intsize; - result = '1':exp[(E-1):0]:Zeros(F); - FPProcessException(FPExc_InvalidOp, fpcr); - elsif fptype == FPType_Zero then - result = FPZero(sign); - else - // Extract integer component - int_result = RoundDown(value); - error = value - Real(int_result); - - // Determine whether supplied rounding mode requires an increment - case rounding of - when FPRounding_TIEEVEN - round_up = error > 0.5 || (error == 0.5 && int_result[0] == '1'); - when FPRounding_POSINF - round_up = error != 0.0; - when FPRounding_NEGINF - round_up = FALSE; - when FPRounding_ZERO - round_up = error != 0.0 && int_result < 0; - when FPRounding_TIEAWAY - round_up = error > 0.5 || (error == 0.5 && int_result >= 0); - - if round_up then int_result = int_result + 1; - - if int_result > 2^(intsize-1)-1 || int_result < -1*2^(intsize-1) then - if N == 32 then - exp = 126 + intsize; - result = '1':exp[(E-1):0]:Zeros(F); - else - exp = 1022 + intsize; - result = '1':exp[(E-1):0]:Zeros(F); - FPProcessException(FPExc_InvalidOp, fpcr); - // this case shouldn't set Inexact - error = 0.0; - - else - // Convert integer value into an equivalent real value - real_result = Real(int_result); - - // Re-encode as a floating-point value, result is always exact - if real_result == 0.0 then - result = FPZero(sign); - else - result = FPRound(real_result, fpcr, FPRounding_ZERO); - - // Generate inexact exceptions - if error != 0.0 then - FPProcessException(FPExc_Inexact, fpcr); - - return result; - -// Compute estimate of reciprocal square root of 9-bit fixed-point number -// -// a is in range 128 .. 511 representing a number in the range 0.25 <= x < 1.0. -// result is in the range 256 .. 511 representing a number in the range in the range 1.0 to 511/256. - -integer RecipSqrtEstimate(integer a) - assert 128 <= a && a < 512; - if a < 256 then // 0.25 .. 0.5 - a = a*2+1; // a in units of 1/512 rounded to nearest - else // 0.5 .. 1.0 - a = (a >> 1) << 1; // discard bottom bit - a = (a+1)*2; // a in units of 1/256 rounded to nearest - integer b = 512; - while a*(b+1)*(b+1) < 2^28 do - b = b+1; - // b = largest b such that b < 2^14 / sqrt(a) do - r = (b+1) DIV 2; // round to nearest - assert 256 <= r && r < 512; - return r; - -// FPRSqrtEstimate() -// ================= - -bits(N) FPRSqrtEstimate(bits(N) operand, FPCRType fpcr) - assert N IN {16,32,64}; - (fptype,sign,value) = FPUnpack(operand, fpcr); - if fptype == FPType_SNaN || fptype == FPType_QNaN then - result = FPProcessNaN(fptype, operand, fpcr); - elsif fptype == FPType_Zero then - result = FPInfinity(sign); - FPProcessException(FPExc_DivideByZero, fpcr); - elsif sign == '1' then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - elsif fptype == FPType_Infinity then - result = FPZero('0'); - else - // Scale to a fixed-point value in the range 0.25 <= x < 1.0 in steps of 512, with the - // evenness or oddness of the exponent unchanged, and calculate result exponent. - // Scaled value has copied sign bit, exponent = 1022 or 1021 = double-precision - // biased version of -1 or -2, fraction = original fraction extended with zeros. - - case N of - when 16 - fraction = operand[9:0] : Zeros(42); - exp = UInt(operand[14:10]); - when 32 - fraction = operand[22:0] : Zeros(29); - exp = UInt(operand[30:23]); - when 64 - fraction = operand[51:0]; - exp = UInt(operand[62:52]); - - if exp == 0 then - while fraction[51] == '0' do - fraction = fraction[50:0] : '0'; - exp = exp - 1; - fraction = fraction[50:0] : '0'; - - if exp[0] == '0' then - scaled = UInt('1':fraction[51:44]); - else - scaled = UInt('01':fraction[51:45]); - - case N of - when 16 result_exp = ( 44 - exp) DIV 2; - when 32 result_exp = ( 380 - exp) DIV 2; - when 64 result_exp = (3068 - exp) DIV 2; - - estimate = RecipSqrtEstimate(scaled); - - // estimate is in the range 256..511 representing a fixed point result in the range [1.0..2.0) - // Convert to scaled floating point result with copied sign bit and high-order - // fraction bits, and exponent calculated above. - case N of - when 16 result = '0' : result_exp[N-12:0] : estimate[7:0]:Zeros( 2); - when 32 result = '0' : result_exp[N-25:0] : estimate[7:0]:Zeros(15); - when 64 result = '0' : result_exp[N-54:0] : estimate[7:0]:Zeros(44); - return result; - -// FPSqrt() -// ======== - -bits(N) FPSqrt(bits(N) op, FPCRType fpcr) - assert N IN {16,32,64}; - (fptype,sign,value) = FPUnpack(op, fpcr); - if fptype == FPType_SNaN || fptype == FPType_QNaN then - result = FPProcessNaN(fptype, op, fpcr); - elsif fptype == FPType_Zero then - result = FPZero(sign); - elsif fptype == FPType_Infinity && sign == '0' then - result = FPInfinity(sign); - elsif sign == '1' then - result = FPDefaultNaN(); - FPProcessException(FPExc_InvalidOp, fpcr); - else - result = FPRound(Sqrt(value), fpcr); - return result; - -// SatQ() -// ====== - -(bits(N), boolean) SatQ(integer i, integer N, boolean unsigned) - (result, sat) = if unsigned then UnsignedSatQ(i, N) else SignedSatQ(i, N); - return (result, sat); - -// FPToFixed() -// =========== - -// Convert N-bit precision floating point OP to M-bit fixed point with -// FBITS fractional bits, controlled by UNSIGNED and ROUNDING. - -bits(M) FPToFixed(bits(N) op, integer fbits, boolean unsigned, FPCRType fpcr, FPRounding rounding) - assert N IN {16,32,64}; - assert M IN {16,32,64}; - assert fbits >= 0; - assert rounding != FPRounding_ODD; - - // Unpack using fpcr to determine if subnormals are flushed-to-zero - (fptype,sign,value) = FPUnpack(op, fpcr); - - // If NaN, set cumulative flag or take exception - if fptype == FPType_SNaN || fptype == FPType_QNaN then - FPProcessException(FPExc_InvalidOp, fpcr); - - // Scale by fractional bits and produce integer rounded towards minus-infinity - value = value * 2.0^fbits; - int_result = RoundDown(value); - error = value - Real(int_result); - - // Determine whether supplied rounding mode requires an increment - case rounding of - when FPRounding_TIEEVEN - round_up = (error > 0.5 || (error == 0.5 && int_result[0] == '1')); - when FPRounding_POSINF - round_up = (error != 0.0); - when FPRounding_NEGINF - round_up = FALSE; - when FPRounding_ZERO - round_up = (error != 0.0 && int_result < 0); - when FPRounding_TIEAWAY - round_up = (error > 0.5 || (error == 0.5 && int_result >= 0)); - - if round_up then int_result = int_result + 1; - - // Generate saturated result and exceptions - (result, overflow) = SatQ(int_result, M, unsigned); - if overflow then - FPProcessException(FPExc_InvalidOp, fpcr); - elsif error != 0.0 then - FPProcessException(FPExc_Inexact, fpcr); - - return result; - -// FPToFixedJS() -// ============= - -// Converts a double precision floating point input value -// to a signed integer, with rounding to zero. - -(bits(N), bit) FPToFixedJS(bits(M) op, FPCRType fpcr, boolean Is64) - - assert M == 64 && N == 32; - - // Unpack using fpcr to determine if subnormals are flushed-to-zero - (fptype,sign,value) = FPUnpack(op, fpcr); - - Z = '1'; - // If NaN, set cumulative flag or take exception - if fptype == FPType_SNaN || fptype == FPType_QNaN then - FPProcessException(FPExc_InvalidOp, fpcr); - Z = '0'; - - int_result = RoundDown(value); - error = value - Real(int_result); - - // Determine whether supplied rounding mode requires an increment - - round_it_up = (error != 0.0 && int_result < 0); - if round_it_up then int_result = int_result + 1; - - if int_result < 0 then - result = int_result - 2^32*RoundUp(Real(int_result)/Real(2^32)); - else - result = int_result - 2^32*RoundDown(Real(int_result)/Real(2^32)); - - // Generate exceptions - if int_result < -(2^31) || int_result > (2^31)-1 then - FPProcessException(FPExc_InvalidOp, fpcr); - Z = '0'; - elsif error != 0.0 then - FPProcessException(FPExc_Inexact, fpcr); - Z = '0'; - elsif sign == '1' && value == 0.0 then - Z = '0'; - elsif sign == '0' && value == 0.0 && !IsZero(op[51:0]) then - Z = '0'; - - if fptype == FPType_Infinity then result = 0; - - return (result[N-1:0], Z); - -// VFPExpandImm() -// ============== - -bits(N) VFPExpandImm(bits(8) imm8) - assert N IN {16,32,64}; - constant integer E = (if N == 16 then 5 elsif N == 32 then 8 else 11); - constant integer F = N - E - 1; - sign = imm8[7]; - exp = NOT(imm8[6]):Replicate(imm8[6],E-3):imm8[5:4]; - frac = imm8[3:0]:Zeros(F-4); - return sign : exp : frac; - -// AddWithCarry() -// ============== -// Integer addition with carry input, returning result and NZCV flags - -(bits(N), bits(4)) AddWithCarry(bits(N) x, bits(N) y, bit carry_in) - integer unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in); - integer signed_sum = SInt(x) + SInt(y) + UInt(carry_in); - bits(N) result = unsigned_sum[N-1:0]; // same value as signed_sum[N-1:0] - bit n = result[N-1]; - bit z = if IsZero(result) then '1' else '0'; - bit c = if UInt(result) == unsigned_sum then '0' else '1'; - bit v = if SInt(result) == signed_sum then '0' else '1'; - - return (result, n:z:c:v); - -enumeration MBReqDomain {MBReqDomain_Nonshareable, MBReqDomain_InnerShareable, - MBReqDomain_OuterShareable, MBReqDomain_FullSystem}; - -enumeration MBReqTypes {MBReqTypes_Reads, MBReqTypes_Writes, MBReqTypes_All}; - -DataMemoryBarrier(MBReqDomain domain, MBReqTypes types); - -DataSynchronizationBarrier(MBReqDomain domain, MBReqTypes types); - -SpeculativeStoreBypassBarrierToPA(); - -SpeculativeStoreBypassBarrierToVA(); - -constant PARTIDtype DefaultPARTID = 0[15:0]; - -constant PMGtype DefaultPMG = 0[7:0]; - -// DefaultMPAMinfo -// =============== -// Returns default MPAM info. If secure is TRUE return default Secure -// MPAMinfo, otherwise return default Non-secure MPAMinfo. - -MPAMinfo DefaultMPAMinfo(boolean secure) - MPAMinfo DefaultInfo; - DefaultInfo.mpam_ns = if secure then '0' else '1'; - DefaultInfo.partid = DefaultPARTID; - DefaultInfo.pmg = DefaultPMG; - return DefaultInfo; - -// MPAMisEnabled -// ============= -// Returns TRUE if MPAMisEnabled. - -boolean MPAMisEnabled() - el = HighestEL(); - case el of - when EL3 return MPAM3_EL3.MPAMEN == '1'; - when EL2 return MPAM2_EL2.MPAMEN == '1'; - when EL1 return MPAM1_EL1.MPAMEN == '1'; - -// mapvpmw -// ======= -// Map a virtual PARTID into a physical PARTID using -// the MPAMVPMn_EL2 registers. -// vpartid is now assumed in-range and valid (checked by caller) -// returns physical PARTID from mapping entry. - -PARTIDtype mapvpmw(integer vpartid) - bits(64) vpmw; - integer wd = vpartid DIV 4; - case wd of - when 0 vpmw = MPAMVPM0_EL2; - when 1 vpmw = MPAMVPM1_EL2; - when 2 vpmw = MPAMVPM2_EL2; - when 3 vpmw = MPAMVPM3_EL2; - when 4 vpmw = MPAMVPM4_EL2; - when 5 vpmw = MPAMVPM5_EL2; - when 6 vpmw = MPAMVPM6_EL2; - when 7 vpmw = MPAMVPM7_EL2; - otherwise vpmw = Zeros(64); - // vpme_lsb selects LSB of field within register - integer vpme_lsb = (vpartid MOD 4) * 16; - return vpmw[vpme_lsb +: 16]; - -// MAP_vPARTID -// =========== -// Performs conversion of virtual PARTID into physical PARTID -// Contains all of the error checking and implementation -// choices for the conversion. - -(PARTIDtype, boolean) MAP_vPARTID(PARTIDtype vpartid) - // should not ever be called if EL2 is not implemented - // or is implemented but not enabled in the current - // security state. - PARTIDtype ret; - boolean err; - integer virt = UInt( vpartid ); - integer vpmrmax = UInt( MPAMIDR_EL1.VPMR_MAX ); - - // vpartid_max is largest vpartid supported - integer vpartid_max = (4 * vpmrmax) + 3; - - // One of many ways to reduce vpartid to value less than vpartid_max. - if virt > vpartid_max then - virt = virt MOD (vpartid_max+1); - - // Check for valid mapping entry. - if MPAMVPMV_EL2[virt] == '1' then - // vpartid has a valid mapping so access the map. - ret = mapvpmw(virt); - err = FALSE; - - // Is the default virtual PARTID valid? - elsif MPAMVPMV_EL2[0] == '1' then - // Yes, so use default mapping for vpartid == 0. - ret = MPAMVPM0_EL2[0 +: 16]; - err = FALSE; - - // Neither is valid so use default physical PARTID. - else - ret = DefaultPARTID; - err = TRUE; - - // Check that the physical PARTID is in-range. - // This physical PARTID came from a virtual mapping entry. - integer partid_max = UInt( MPAMIDR_EL1.PARTID_MAX ); - if UInt(ret) > partid_max then - // Out of range, so return default physical PARTID - ret = DefaultPARTID; - err = TRUE; - return (ret, err); - -// MPAMisVirtual -// ============= -// Returns TRUE if MPAM is configured to be virtual at EL. - -boolean MPAMisVirtual(integer el) - return ( MPAMIDR_EL1.HAS_HCR == '1' && EL2Enabled() && - ( HCR_EL2.E2H == '0' || HCR_EL2.TGE == '0' ) && - (( el == 0 && MPAMHCR_EL2.EL0_VPMEN == '1' ) || - ( el == 1 && MPAMHCR_EL2.EL1_VPMEN == '1'))); - -// getMPAM_PARTID -// ============== -// Returns a PARTID from one of the MPAMn_ELx registers. -// MPAMn selects the MPAMn_ELx register used. -// If InD is TRUE, selects the PARTID_I field of that -// register. Otherwise, selects the PARTID_D field. - -PARTIDtype getMPAM_PARTID(integer MPAMn, boolean InD) - PARTIDtype partid; - boolean el2avail = EL2Enabled(); - - if InD then - case MPAMn of - when 3 partid = MPAM3_EL3.PARTID_I; - when 2 partid = if el2avail then MPAM2_EL2.PARTID_I else Zeros(); - when 1 partid = MPAM1_EL1.PARTID_I; - when 0 partid = MPAM0_EL1.PARTID_I; - otherwise partid = PARTIDtype UNKNOWN; - else - case MPAMn of - when 3 partid = MPAM3_EL3.PARTID_D; - when 2 partid = if el2avail then MPAM2_EL2.PARTID_D else Zeros(); - when 1 partid = MPAM1_EL1.PARTID_D; - when 0 partid = MPAM0_EL1.PARTID_D; - otherwise partid = PARTIDtype UNKNOWN; - return partid; - -// genPARTID -// ========= -// Returns physical PARTID and error boolean for exception level el. -// If InD is TRUE then PARTID is from MPAMel_ELx.PARTID_I and -// otherwise from MPAMel_ELx.PARTID_D. - -(PARTIDtype, boolean) genPARTID(integer el, boolean InD) - PARTIDtype partidel = getMPAM_PARTID(el, InD); - - integer partid_max = UInt(MPAMIDR_EL1.PARTID_MAX); - if UInt(partidel) > partid_max then - return (DefaultPARTID, TRUE); - - if MPAMisVirtual(el) then - return MAP_vPARTID(partidel); - else - return (partidel, FALSE); - -// getMPAM_PMG -// =========== -// Returns a PMG from one of the MPAMn_ELx registers. -// MPAMn selects the MPAMn_ELx register used. -// If InD is TRUE, selects the PMG_I field of that -// register. Otherwise, selects the PMG_D field. - -PMGtype getMPAM_PMG(integer MPAMn, boolean InD) - PMGtype pmg; - boolean el2avail = EL2Enabled(); - - if InD then - case MPAMn of - when 3 pmg = MPAM3_EL3.PMG_I; - when 2 pmg = if el2avail then MPAM2_EL2.PMG_I else Zeros(); - when 1 pmg = MPAM1_EL1.PMG_I; - when 0 pmg = MPAM0_EL1.PMG_I; - otherwise pmg = PMGtype UNKNOWN; - else - case MPAMn of - when 3 pmg = MPAM3_EL3.PMG_D; - when 2 pmg = if el2avail then MPAM2_EL2.PMG_D else Zeros(); - when 1 pmg = MPAM1_EL1.PMG_D; - when 0 pmg = MPAM0_EL1.PMG_D; - otherwise pmg = PMGtype UNKNOWN; - return pmg; - -// genPMG -// ====== -// Returns PMG for exception level el and I- or D-side (InD). -// If PARTID generation (genPARTID) encountered an error, genPMG() should be -// called with partid_err as TRUE. - -PMGtype genPMG(integer el, boolean InD, boolean partid_err) - integer pmg_max = UInt(MPAMIDR_EL1.PMG_MAX); - - // It is CONSTRAINED UNPREDICTABLE whether partid_err forces PMG to - // use the default or if it uses the PMG from getMPAM_PMG. - if partid_err then - return DefaultPMG; - PMGtype groupel = getMPAM_PMG(el, InD); - if UInt(groupel) <= pmg_max then - return groupel; - return DefaultPMG; - -// genMPAM -// ======= -// Returns MPAMinfo for exception level el. -// If InD is TRUE returns MPAM information using PARTID_I and PMG_I fields -// of MPAMel_ELx register and otherwise using PARTID_D and PMG_D fields. -// Produces a Secure PARTID if Secure is TRUE and a Non-secure PARTID otherwise. - -MPAMinfo genMPAM(integer el, boolean InD, boolean secure) - MPAMinfo returnInfo; - PARTIDtype partidel; - boolean perr; - boolean gstplk = (el == 0 && EL2Enabled() && - MPAMHCR_EL2.GSTAPP_PLK == '1' && HCR_EL2.TGE == '0'); - integer eff_el = if gstplk then 1 else el; - (partidel, perr) = genPARTID(eff_el, InD); - PMGtype groupel = genPMG(eff_el, InD, perr); - returnInfo.mpam_ns = if secure then '0' else '1'; - returnInfo.partid = partidel; - returnInfo.pmg = groupel; - return returnInfo; - -// GenMPAMcurEL -// ============ -// Returns MPAMinfo for the current EL and security state. -// InD is TRUE instruction access and FALSE otherwise. -// May be called if MPAM is not implemented (but in an version that supports -// MPAM), MPAM is disabled, or in AArch32. In AArch32, convert the mode to -// EL if can and use that to drive MPAM information generation. If mode -// cannot be converted, MPAM is not implemented, or MPAM is disabled return -// default MPAM information for the current security state. - -MPAMinfo GenMPAMcurEL(boolean InD) - bits(2) mpamel; - boolean validEL; - boolean securempam; - if HaveEMPAMExt() then - boolean secure = IsSecure(); - securempam = MPAM3_EL3.FORCE_NS == '0' && secure; - if MPAMisEnabled() && (!secure || MPAM3_EL3.SDEFLT == '0') then - if UsingAArch32() then - (validEL, mpamel) = ELFromM32(PSTATE.M); - else - validEL = TRUE; - mpamel = PSTATE.EL; - if validEL then - return genMPAM(UInt(mpamel), InD, securempam); - else - securempam = IsSecure(); - if HaveMPAMExt() && MPAMisEnabled() then - if UsingAArch32() then - (validEL, mpamel) = ELFromM32(PSTATE.M); - else - validEL = TRUE; - mpamel = PSTATE.EL; - if validEL then - return genMPAM(UInt(mpamel), InD, securempam); - return DefaultMPAMinfo(securempam); - -// genMPAMel -// ========= -// Returns MPAMinfo for specified EL in the current security state. -// InD is TRUE for instruction access and FALSE otherwise. - -MPAMinfo genMPAMel(bits(2) el, boolean InD) - boolean secure = IsSecure(); - boolean securempam = secure; - if HaveEMPAMExt() then - securempam = MPAM3_EL3.FORCE_NS == '0' && secure; - if HaveMPAMExt() && MPAMisEnabled() && (!secure || MPAM3_EL3.SDEFLT == '0') then - return genMPAM(UInt(el), InD, securempam); - else - if HaveMPAMExt() && MPAMisEnabled() then - return genMPAM(UInt(el), InD, securempam); - return DefaultMPAMinfo(securempam); - -// BranchTargetCheck() -// =================== -// This function is executed checks if the current instruction is a valid target for a branch -// taken into, or inside, a guarded page. It is executed on every cycle once the current -// instruction has been decoded and the values of InGuardedPage and BTypeCompatible have been -// determined for the current instruction. - -BranchTargetCheck() - assert HaveBTIExt() && !UsingAArch32(); - - // The branch target check considers two state variables: - // * InGuardedPage, which is evaluated during instruction fetch. - // * BTypeCompatible, which is evaluated during instruction decode. - if InGuardedPage && PSTATE.BTYPE != '00' && !BTypeCompatible && !Halted() then - bits(64) pc = ThisInstrAddr(); - AArch64.BranchTargetException(pc[51:0]); - - boolean branch_instr = AArch64.ExecutingBROrBLROrRetInstr(); - boolean bti_instr = AArch64.ExecutingBTIInstr(); - - // PSTATE.BTYPE defaults to 00 for instructions that do not explictly set BTYPE. - if !(branch_instr || bti_instr) then - BTypeNext = '00'; - -// ClearEventRegister() -// ==================== -// Clear the Event Register of this PE - -ClearEventRegister() - EventRegister = '0'; - return; - -ConsumptionOfSpeculativeDataBarrier(); - -enumeration PrivilegeLevel {PL3, PL2, PL1, PL0}; - -// PLOfEL() -// ======== - -PrivilegeLevel PLOfEL(bits(2) el) - case el of - when EL3 return if HighestELUsingAArch32() then PL1 else PL3; - when EL2 return PL2; - when EL1 return PL1; - when EL0 return PL0; - -// CurrentPL() -// =========== - -PrivilegeLevel CurrentPL() - return PLOfEL(PSTATE.EL); - -// PE enters a low-power state -EnterLowPowerState(); - -// HaveELUsingSecurityState() -// ========================== -// Returns TRUE if Exception level 'el' with Security state 'secure' is supported, -// FALSE otherwise. - -boolean HaveELUsingSecurityState(bits(2) el, boolean secure) - - case el of - when EL3 - assert secure; - return HaveEL(EL3); - when EL2 - if secure then - return HaveEL(EL2) && HaveSecureEL2Ext(); - else - return HaveEL(EL2); - otherwise - return (HaveEL(EL3) || - (secure == boolean IMPLEMENTATION_DEFINED "Secure-only implementation")); - -// Provides a hint to close any gathering occurring within the micro-architecture. -Hint_DGH(); - -// Provides a hint that the task performed by a thread is of low -// importance so that it could yield to improve overall performance. -Hint_Yield(); - -InstructionSynchronizationBarrier(); - -// InterruptPending() -// ================== -// Return TRUE if there are any pending physical or virtual -// interrupts, and FALSE otherwise. - -boolean InterruptPending() - pending_physical_interrupt = (IRQPending() || FIQPending() || - IsPhysicalSErrorPending()); - pending_virtual_interrupt = !IsInHost() && ((HCR_EL2.[VSE,VI,VF] AND - HCR_EL2.[AMO,IMO,FMO]) != '000'); - return pending_physical_interrupt || pending_virtual_interrupt; - -// IsEventRegisterSet() -// ==================== -// Return TRUE if the Event Register of this PE is set, and FALSE otherwise - -boolean IsEventRegisterSet() - return EventRegister == '1'; - -// IsHighestEL() -// ============= -// Returns TRUE if given exception level is the highest exception level implemented - -boolean IsHighestEL(bits(2) el) - return HighestEL() == el; - -// Return TRUE if a virtual SError interrupt is pending -boolean IsVirtualSErrorPending(); - -// Signal an event to all PEs in a multiprocessor system to set their Event Registers. -// When a PE executes the SEV instruction, it causes this function to be executed -SendEvent(); - -SpeculationBarrier(); - -// Take any pending unmasked physical SError interrupt or unmasked virtual SError -// interrupt. -TakeUnmaskedSErrorInterrupts(); - -// WaitForEvent() -// ============== -// PE suspends its operation and enters a low-power state -// if the Event Register is clear when the WFE is executed - -WaitForEvent() - if EventRegister == '0' then - EnterLowPowerState(); - return; - -// WaitForInterrupt() -// ================== -// PE suspends its operation to enter a low-power state -// until a WFI wake-up event occurs or the PE is reset - -WaitForInterrupt() - EnterLowPowerState(); - return; - -// AdvSIMDExpandImm() -// ================== - -bits(64) AdvSIMDExpandImm(bit op, bits(4) cmode, bits(8) imm8) - case cmode[3:1] of - when '000' - imm64 = Replicate(Zeros(24):imm8, 2); - when '001' - imm64 = Replicate(Zeros(16):imm8:Zeros(8), 2); - when '010' - imm64 = Replicate(Zeros(8):imm8:Zeros(16), 2); - when '011' - imm64 = Replicate(imm8:Zeros(24), 2); - when '100' - imm64 = Replicate(Zeros(8):imm8, 4); - when '101' - imm64 = Replicate(imm8:Zeros(8), 4); - when '110' - if cmode[0] == '0' then - imm64 = Replicate(Zeros(16):imm8:Ones(8), 2); - else - imm64 = Replicate(Zeros(8):imm8:Ones(16), 2); - when '111' - if cmode[0] == '0' && op == '0' then - imm64 = Replicate(imm8, 8); - if cmode[0] == '0' && op == '1' then - imm8a = Replicate(imm8[7], 8); imm8b = Replicate(imm8[6], 8); - imm8c = Replicate(imm8[5], 8); imm8d = Replicate(imm8[4], 8); - imm8e = Replicate(imm8[3], 8); imm8f = Replicate(imm8[2], 8); - imm8g = Replicate(imm8[1], 8); imm8h = Replicate(imm8[0], 8); - imm64 = imm8a:imm8b:imm8c:imm8d:imm8e:imm8f:imm8g:imm8h; - if cmode[0] == '1' && op == '0' then - imm32 = imm8[7]:NOT(imm8[6]):Replicate(imm8[6],5):imm8[5:0]:Zeros(19); - imm64 = Replicate(imm32, 2); - if cmode[0] == '1' && op == '1' then - if UsingAArch32() then ReservedEncoding(); - imm64 = imm8[7]:NOT(imm8[6]):Replicate(imm8[6],8):imm8[5:0]:Zeros(48); - - return imm64; - -// MatMulAdd() -// =========== -// -// Signed or unsigned 8-bit integer matrix multiply and add to 32-bit integer matrix -// result[2, 2] = addend[2, 2] + (op1[2, 8] * op2[8, 2]) - -bits(N) MatMulAdd(bits(N) addend, bits(N) op1, bits(N) op2, boolean op1_unsigned, boolean op2_unsigned) - assert N == 128; - - bits(N) result; - bits(32) sum; - integer prod; - - for i = 0 to 1 - for j = 0 to 1 - sum = Elem[addend, 2*i + j, 32]; - for k = 0 to 7 - prod = Int(Elem[op1, 8*i + k, 8], op1_unsigned) * Int(Elem[op2, 8*j + k, 8], op2_unsigned); - sum = sum + prod; - Elem[result, 2*i + j, 32] = sum; - - return result; - -// PolynomialMult() -// ================ - -bits(M+N) PolynomialMult(bits(M) op1, bits(N) op2) - result = Zeros(M+N); - extended_op2 = ZeroExtend(op2, M+N); - for i=0 to M-1 - if op1[i] == '1' then - result = result EOR LSL(extended_op2, i); - return result; - -// UnsignedRSqrtEstimate() -// ======================= - -bits(N) UnsignedRSqrtEstimate(bits(N) operand) - assert N IN {16,32}; - if operand[N-1:N-2] == '00' then // Operands <= 0x3FFFFFFF produce 0xFFFFFFFF - result = Ones(N); - else - // input is in the range 0x40000000 .. 0xffffffff representing [0.25 .. 1.0) - - // estimate is in the range 256 .. 511 representing [1.0 .. 2.0) - case N of - when 16 estimate = RecipSqrtEstimate(UInt(operand[15:7])); - when 32 estimate = RecipSqrtEstimate(UInt(operand[31:23])); - - // result is in the range 0x80000000 .. 0xff800000 representing [1.0 .. 2.0) - result = estimate[8:0] : Zeros(N-9); - - return result; - -// UnsignedRecipEstimate() -// ======================= - -bits(N) UnsignedRecipEstimate(bits(N) operand) - assert N IN {16,32}; - if operand[N-1] == '0' then // Operands <= 0x7FFFFFFF produce 0xFFFFFFFF - result = Ones(N); - else - // input is in the range 0x80000000 .. 0xffffffff representing [0.5 .. 1.0) - - // estimate is in the range 256 to 511 representing [1.0 .. 2.0) - case N of - when 16 estimate = RecipEstimate(UInt(operand[15:7])); - when 32 estimate = RecipEstimate(UInt(operand[31:23])); - - // result is in the range 0x80000000 .. 0xff800000 representing [1.0 .. 2.0) - result = estimate[8:0] : Zeros(N-9); - - return result; - -// SelfHostedTraceEnabled() -// ======================== -// Returns TRUE if Self-hosted Trace is enabled. - -boolean SelfHostedTraceEnabled() - if !HaveTraceExt() || !HaveSelfHostedTrace() then return FALSE; - if HaveEL(EL3) then - secure_trace_enable = (if ELUsingAArch32(EL3) then SDCR.STE else MDCR_EL3.STE); - niden = (secure_trace_enable == '0' || ExternalSecureNoninvasiveDebugEnabled()); - else - // If no EL3, IsSecure() returns the Effective value of (SCR_EL3.NS == '0') - niden = (!IsSecure() || ExternalSecureNoninvasiveDebugEnabled()); - return (EDSCR.TFO == '0' || !niden); - -// TraceAllowed() -// ============== -// Returns TRUE if Self-hosted Trace is allowed in the current Security state and Exception Level - -boolean TraceAllowed() - if !HaveTraceExt() then return FALSE; - if SelfHostedTraceEnabled() then - if IsSecure() && HaveEL(EL3) then - secure_trace_enable = (if ELUsingAArch32(EL3) then SDCR.STE else MDCR_EL3.STE); - if secure_trace_enable == '0' then return FALSE; - TGE_bit = if EL2Enabled() then HCR_EL2.TGE else '0'; - case PSTATE.EL of - when EL3 TRE_bit = if HighestELUsingAArch32() then TRFCR.E1TRE else '0'; - when EL2 TRE_bit = TRFCR_EL2.E2TRE; - when EL1 TRE_bit = TRFCR_EL1.E1TRE; - when EL0 TRE_bit = if TGE_bit == '1' then TRFCR_EL2.E0HTRE else TRFCR_EL1.E0TRE; - return TRE_bit == '1'; - else - return (!IsSecure() || ExternalSecureNoninvasiveDebugEnabled()); - -// TraceContextIDR2() -// ================== - -boolean TraceContextIDR2() - if !TraceAllowed()|| !HaveEL(EL2) then return FALSE; - return (!SelfHostedTraceEnabled() || TRFCR_EL2.CX == '1'); - -// Memory barrier instruction that preserves the relative order of memory accesses to System -// registers due to trace operations and other memory accesses to the same registers -TraceSynchronizationBarrier(); - -// TraceTimeStamp() -// ================ - -TimeStamp TraceTimeStamp() - if SelfHostedTraceEnabled() then - if HaveEL(EL2) then - TS_el2 = TRFCR_EL2.TS; - if TS_el2 == '10' then (-, TS_el2) = ConstrainUnpredictableBits(Unpredictable_EL2TIMESTAMP); // Reserved value - case TS_el2 of - when '00' /* falls through to check TRFCR_EL1.TS */ - when '01' return TimeStamp_Virtual; - when '11' return TimeStamp_Physical; - otherwise Unreachable(); // ConstrainUnpredictableBits removes this case - TS_el1 = TRFCR_EL1.TS; - if TS_el1 == 'x0' then (-, TS_el1) = ConstrainUnpredictableBits(Unpredictable_EL1TIMESTAMP); // Reserved values - case TS_el1 of - when '01' return TimeStamp_Virtual; - when '11' return TimeStamp_Physical; - otherwise Unreachable(); // ConstrainUnpredictableBits removes this case - else - return TimeStamp_CoreSight; - -//////////////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////////////// diff --git a/mra_tools/arch/arch_decode.asl b/mra_tools/arch/arch_decode.asl deleted file mode 100644 index a48ba4c0..00000000 --- a/mra_tools/arch/arch_decode.asl +++ /dev/null @@ -1,8951 +0,0 @@ -__decode A64 - // A64 - case (29 +: 3, 24 +: 5, 0 +: 24) of - when (_, '0000x', _) => - // reserved - case (29 +: 3, 25 +: 4, 16 +: 9, 0 +: 16) of - when ('000', _, '000000000', _) => // perm_undef - __field imm16 0 +: 16 - case () of - when () => __encoding aarch64_udf // UDF_only_perm_undef - when (_, _, !'000000000', _) => __UNPREDICTABLE - when (!'000', _, _, _) => __UNPREDICTABLE - when (_, '00011', _) => __UNPREDICTABLE - when (_, '0010x', _) => - // sve - case (29 +: 3, 25 +: 4, 23 +: 2, 22 +: 1, 17 +: 5, 16 +: 1, 10 +: 6, 0 +: 10) of - when ('000', _, '0x', _, '0xxxx', _, 'x1xxxx', _) => - // sve_int_muladd_pred - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 15 +: 1, 14 +: 1, 0 +: 14) of - when (_, _, _, _, '0', _, _) => // sve_int_mlas_vvv_pred - __field size 22 +: 2 - __field Zm 16 +: 5 - __field op 13 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (op) of - when ('0') => __encoding MLA_Z_P_ZZZ__ // mla_z_p_zzz_ - when ('1') => __encoding MLS_Z_P_ZZZ__ // mls_z_p_zzz_ - when (_, _, _, _, '1', _, _) => // sve_int_mladdsub_vvv_pred - __field size 22 +: 2 - __field Zm 16 +: 5 - __field op 13 +: 1 - __field Pg 10 +: 3 - __field Za 5 +: 5 - __field Zdn 0 +: 5 - case (op) of - when ('0') => __encoding MAD_Z_P_ZZZ__ // mad_z_p_zzz_ - when ('1') => __encoding MSB_Z_P_ZZZ__ // msb_z_p_zzz_ - when ('000', _, '0x', _, '0xxxx', _, '000xxx', _) => - // sve_int_pred_bin - case (24 +: 8, 22 +: 2, 21 +: 1, 18 +: 3, 16 +: 2, 13 +: 3, 0 +: 13) of - when (_, _, _, '00x', _, _, _) => // sve_int_bin_pred_arit_0 - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (opc) of - when ('000') => __encoding ADD_Z_P_ZZ__ // add_z_p_zz_ - when ('001') => __encoding SUB_Z_P_ZZ__ // sub_z_p_zz_ - when ('010') => __UNALLOCATED - when ('011') => __encoding SUBR_Z_P_ZZ__ // subr_z_p_zz_ - when ('1xx') => __UNALLOCATED - when (_, _, _, '01x', _, _, _) => // sve_int_bin_pred_arit_1 - __field size 22 +: 2 - __field opc 17 +: 2 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (opc, U) of - when ('00', '0') => __encoding SMAX_Z_P_ZZ__ // smax_z_p_zz_ - when ('00', '1') => __encoding UMAX_Z_P_ZZ__ // umax_z_p_zz_ - when ('01', '0') => __encoding SMIN_Z_P_ZZ__ // smin_z_p_zz_ - when ('01', '1') => __encoding UMIN_Z_P_ZZ__ // umin_z_p_zz_ - when ('10', '0') => __encoding SABD_Z_P_ZZ__ // sabd_z_p_zz_ - when ('10', '1') => __encoding UABD_Z_P_ZZ__ // uabd_z_p_zz_ - when ('11', _) => __UNALLOCATED - when (_, _, _, '100', _, _, _) => // sve_int_bin_pred_arit_2 - __field size 22 +: 2 - __field H 17 +: 1 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (H, U) of - when ('0', '0') => __encoding MUL_Z_P_ZZ__ // mul_z_p_zz_ - when ('0', '1') => __UNALLOCATED - when ('1', '0') => __encoding SMULH_Z_P_ZZ__ // smulh_z_p_zz_ - when ('1', '1') => __encoding UMULH_Z_P_ZZ__ // umulh_z_p_zz_ - when (_, _, _, '101', _, _, _) => // sve_int_bin_pred_div - __field size 22 +: 2 - __field R 17 +: 1 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (R, U) of - when ('0', '0') => __encoding SDIV_Z_P_ZZ__ // sdiv_z_p_zz_ - when ('0', '1') => __encoding UDIV_Z_P_ZZ__ // udiv_z_p_zz_ - when ('1', '0') => __encoding SDIVR_Z_P_ZZ__ // sdivr_z_p_zz_ - when ('1', '1') => __encoding UDIVR_Z_P_ZZ__ // udivr_z_p_zz_ - when (_, _, _, '11x', _, _, _) => // sve_int_bin_pred_log - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (opc) of - when ('000') => __encoding ORR_Z_P_ZZ__ // orr_z_p_zz_ - when ('001') => __encoding EOR_Z_P_ZZ__ // eor_z_p_zz_ - when ('010') => __encoding AND_Z_P_ZZ__ // and_z_p_zz_ - when ('011') => __encoding BIC_Z_P_ZZ__ // bic_z_p_zz_ - when ('1xx') => __UNALLOCATED - when ('000', _, '0x', _, '0xxxx', _, '001xxx', _) => - // sve_int_pred_red - case (24 +: 8, 22 +: 2, 21 +: 1, 19 +: 2, 16 +: 3, 13 +: 3, 0 +: 13) of - when (_, _, _, '00', _, _, _) => // sve_int_reduce_0 - __field size 22 +: 2 - __field opc 17 +: 2 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - case (opc, U) of - when ('00', '0') => __encoding SADDV_R_P_Z__ // saddv_r_p_z_ - when ('00', '1') => __encoding UADDV_R_P_Z__ // uaddv_r_p_z_ - when ('01', _) => __UNALLOCATED - when ('1x', _) => __UNALLOCATED - when (_, _, _, '01', _, _, _) => // sve_int_reduce_1 - __field size 22 +: 2 - __field opc 17 +: 2 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - case (opc, U) of - when ('00', '0') => __encoding SMAXV_R_P_Z__ // smaxv_r_p_z_ - when ('00', '1') => __encoding UMAXV_R_P_Z__ // umaxv_r_p_z_ - when ('01', '0') => __encoding SMINV_R_P_Z__ // sminv_r_p_z_ - when ('01', '1') => __encoding UMINV_R_P_Z__ // uminv_r_p_z_ - when ('1x', _) => __UNALLOCATED - when (_, _, _, '10', _, _, _) => // sve_int_movprfx_pred - __field size 22 +: 2 - __field opc 17 +: 2 - __field M 16 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('00') => __encoding MOVPRFX_Z_P_Z__ // movprfx_z_p_z_ - when ('01') => __UNALLOCATED - when ('1x') => __UNALLOCATED - when (_, _, _, '11', _, _, _) => // sve_int_reduce_2 - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - case (opc) of - when ('000') => __encoding ORV_R_P_Z__ // orv_r_p_z_ - when ('001') => __encoding EORV_R_P_Z__ // eorv_r_p_z_ - when ('010') => __encoding ANDV_R_P_Z__ // andv_r_p_z_ - when ('011') => __UNALLOCATED - when ('1xx') => __UNALLOCATED - when ('000', _, '0x', _, '0xxxx', _, '100xxx', _) => - // sve_int_pred_shift - case (24 +: 8, 22 +: 2, 21 +: 1, 19 +: 2, 16 +: 3, 13 +: 3, 0 +: 13) of - when (_, _, _, '0x', _, _, _) => // sve_int_bin_pred_shift_0 - __field tszh 22 +: 2 - __field opc 18 +: 2 - __field L 17 +: 1 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field tszl 8 +: 2 - __field imm3 5 +: 3 - __field Zdn 0 +: 5 - case (opc, L, U) of - when ('00', '0', '0') => __encoding ASR_Z_P_ZI__ // asr_z_p_zi_ - when ('00', '0', '1') => __encoding LSR_Z_P_ZI__ // lsr_z_p_zi_ - when ('00', '1', '0') => __UNALLOCATED - when ('00', '1', '1') => __encoding LSL_Z_P_ZI__ // lsl_z_p_zi_ - when ('01', '0', '0') => __encoding ASRD_Z_P_ZI__ // asrd_z_p_zi_ - when ('01', '0', '1') => __UNALLOCATED - when ('01', '1', _) => __UNALLOCATED - when ('1x', _, _) => __UNALLOCATED - when (_, _, _, '10', _, _, _) => // sve_int_bin_pred_shift_1 - __field size 22 +: 2 - __field R 18 +: 1 - __field L 17 +: 1 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (R, L, U) of - when (_, '1', '0') => __UNALLOCATED - when ('0', '0', '0') => __encoding ASR_Z_P_ZZ__ // asr_z_p_zz_ - when ('0', '0', '1') => __encoding LSR_Z_P_ZZ__ // lsr_z_p_zz_ - when ('0', '1', '1') => __encoding LSL_Z_P_ZZ__ // lsl_z_p_zz_ - when ('1', '0', '0') => __encoding ASRR_Z_P_ZZ__ // asrr_z_p_zz_ - when ('1', '0', '1') => __encoding LSRR_Z_P_ZZ__ // lsrr_z_p_zz_ - when ('1', '1', '1') => __encoding LSLR_Z_P_ZZ__ // lslr_z_p_zz_ - when (_, _, _, '11', _, _, _) => // sve_int_bin_pred_shift_2 - __field size 22 +: 2 - __field R 18 +: 1 - __field L 17 +: 1 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (R, L, U) of - when ('0', '0', '0') => __encoding ASR_Z_P_ZW__ // asr_z_p_zw_ - when ('0', '0', '1') => __encoding LSR_Z_P_ZW__ // lsr_z_p_zw_ - when ('0', '1', '0') => __UNALLOCATED - when ('0', '1', '1') => __encoding LSL_Z_P_ZW__ // lsl_z_p_zw_ - when ('1', _, _) => __UNALLOCATED - when ('000', _, '0x', _, '0xxxx', _, '101xxx', _) => - // sve_int_pred_un - case (24 +: 8, 22 +: 2, 21 +: 1, 19 +: 2, 16 +: 3, 13 +: 3, 0 +: 13) of - when (_, _, _, '0x', _, _, _) => __UNPREDICTABLE - when (_, _, _, '10', _, _, _) => // sve_int_un_pred_arit_0 - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('000') => __encoding SXTB_Z_P_Z__ // sxtb_z_p_z_ - when ('001') => __encoding UXTB_Z_P_Z__ // uxtb_z_p_z_ - when ('010') => __encoding SXTH_Z_P_Z__ // sxth_z_p_z_ - when ('011') => __encoding UXTH_Z_P_Z__ // uxth_z_p_z_ - when ('100') => __encoding SXTW_Z_P_Z__ // sxtw_z_p_z_ - when ('101') => __encoding UXTW_Z_P_Z__ // uxtw_z_p_z_ - when ('110') => __encoding ABS_Z_P_Z__ // abs_z_p_z_ - when ('111') => __encoding NEG_Z_P_Z__ // neg_z_p_z_ - when (_, _, _, '11', _, _, _) => // sve_int_un_pred_arit_1 - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('000') => __encoding CLS_Z_P_Z__ // cls_z_p_z_ - when ('001') => __encoding CLZ_Z_P_Z__ // clz_z_p_z_ - when ('010') => __encoding CNT_Z_P_Z__ // cnt_z_p_z_ - when ('011') => __encoding CNOT_Z_P_Z__ // cnot_z_p_z_ - when ('100') => __encoding FABS_Z_P_Z__ // fabs_z_p_z_ - when ('101') => __encoding FNEG_Z_P_Z__ // fneg_z_p_z_ - when ('110') => __encoding NOT_Z_P_Z__ // not_z_p_z_ - when ('111') => __UNALLOCATED - when ('000', _, '0x', _, '1xxxx', _, '000xxx', _) => // sve_int_bin_cons_arit_0 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field opc 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('000') => __encoding ADD_Z_ZZ__ // add_z_zz_ - when ('001') => __encoding SUB_Z_ZZ__ // sub_z_zz_ - when ('01x') => __UNALLOCATED - when ('100') => __encoding SQADD_Z_ZZ__ // sqadd_z_zz_ - when ('101') => __encoding UQADD_Z_ZZ__ // uqadd_z_zz_ - when ('110') => __encoding SQSUB_Z_ZZ__ // sqsub_z_zz_ - when ('111') => __encoding UQSUB_Z_ZZ__ // uqsub_z_zz_ - when ('000', _, '0x', _, '1xxxx', _, '001xxx', _) => - // sve_int_unpred_logical - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 13 +: 3, 12 +: 1, 10 +: 2, 0 +: 10) of - when (_, _, _, _, _, '0', _, _) => __UNPREDICTABLE - when (_, _, _, _, _, '1', '00', _) => // sve_int_bin_cons_log - __field opc 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('00') => __encoding AND_Z_ZZ__ // and_z_zz_ - when ('01') => __encoding ORR_Z_ZZ__ // orr_z_zz_ - when ('10') => __encoding EOR_Z_ZZ__ // eor_z_zz_ - when ('11') => __encoding BIC_Z_ZZ__ // bic_z_zz_ - when (_, _, _, _, _, '1', !'00', _) => __UNPREDICTABLE - when ('000', _, '0x', _, '1xxxx', _, '0100xx', _) => - // sve_index - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 12 +: 4, 10 +: 2, 0 +: 10) of - when (_, _, _, _, _, '00', _) => // sve_int_index_ii - __field size 22 +: 2 - __field imm5b 16 +: 5 - __field imm5 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding INDEX_Z_II__ // index_z_ii_ - when (_, _, _, _, _, '01', _) => // sve_int_index_ri - __field size 22 +: 2 - __field imm5 16 +: 5 - __field Rn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding INDEX_Z_RI__ // index_z_ri_ - when (_, _, _, _, _, '10', _) => // sve_int_index_ir - __field size 22 +: 2 - __field Rm 16 +: 5 - __field imm5 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding INDEX_Z_IR__ // index_z_ir_ - when (_, _, _, _, _, '11', _) => // sve_int_index_rr - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding INDEX_Z_RR__ // index_z_rr_ - when ('000', _, '0x', _, '1xxxx', _, '0101xx', _) => - // sve_alloca - case (24 +: 8, 23 +: 1, 22 +: 1, 21 +: 1, 16 +: 5, 12 +: 4, 11 +: 1, 0 +: 11) of - when (_, '0', _, _, _, _, '0', _) => // sve_int_arith_vl - __field op 22 +: 1 - __field Rn 16 +: 5 - __field imm6 5 +: 6 - __field Rd 0 +: 5 - case (op) of - when ('0') => __encoding ADDVL_R_RI__ // addvl_r_ri_ - when ('1') => __encoding ADDPL_R_RI__ // addpl_r_ri_ - when (_, '1', _, _, _, _, '0', _) => // sve_int_read_vl_a - __field op 22 +: 1 - __field opc2 16 +: 5 - __field imm6 5 +: 6 - __field Rd 0 +: 5 - case (op, opc2) of - when ('0', '0xxxx') => __UNALLOCATED - when ('0', '10xxx') => __UNALLOCATED - when ('0', '110xx') => __UNALLOCATED - when ('0', '1110x') => __UNALLOCATED - when ('0', '11110') => __UNALLOCATED - when ('0', '11111') => __encoding RDVL_R_I__ // rdvl_r_i_ - when ('1', _) => __UNALLOCATED - when (_, _, _, _, _, _, '1', _) => __UNPREDICTABLE - when ('000', _, '0x', _, '1xxxx', _, '011xxx', _) => __UNPREDICTABLE - when ('000', _, '0x', _, '1xxxx', _, '100xxx', _) => - // sve_int_unpred_shift - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 13 +: 3, 12 +: 1, 0 +: 12) of - when (_, _, _, _, _, '0', _) => // sve_int_bin_cons_shift_a - __field size 22 +: 2 - __field Zm 16 +: 5 - __field opc 10 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('00') => __encoding ASR_Z_ZW__ // asr_z_zw_ - when ('01') => __encoding LSR_Z_ZW__ // lsr_z_zw_ - when ('10') => __UNALLOCATED - when ('11') => __encoding LSL_Z_ZW__ // lsl_z_zw_ - when (_, _, _, _, _, '1', _) => // sve_int_bin_cons_shift_b - __field tszh 22 +: 2 - __field tszl 19 +: 2 - __field imm3 16 +: 3 - __field opc 10 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('00') => __encoding ASR_Z_ZI__ // asr_z_zi_ - when ('01') => __encoding LSR_Z_ZI__ // lsr_z_zi_ - when ('10') => __UNALLOCATED - when ('11') => __encoding LSL_Z_ZI__ // lsl_z_zi_ - when ('000', _, '0x', _, '1xxxx', _, '1010xx', _) => // sve_int_bin_cons_misc_0_a - __field opc 22 +: 2 - __field Zm 16 +: 5 - __field msz 10 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('00') => __encoding ADR_Z_AZ_D_s32_scaled // adr_z_az_d_s32_scaled - when ('01') => __encoding ADR_Z_AZ_D_u32_scaled // adr_z_az_d_u32_scaled - when ('1x') => __encoding ADR_Z_AZ_SD_same_scaled // adr_z_az_sd_same_scaled - when ('000', _, '0x', _, '1xxxx', _, '1011xx', _) => - // sve_int_unpred_misc - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 12 +: 4, 10 +: 2, 0 +: 10) of - when (_, _, _, _, _, '0x', _) => // sve_int_bin_cons_misc_0_b - __field size 22 +: 2 - __field Zm 16 +: 5 - __field op 10 +: 1 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (op) of - when ('0') => __encoding FTSSEL_Z_ZZ__ // ftssel_z_zz_ - when ('1') => __UNALLOCATED - when (_, _, _, _, _, '10', _) => // sve_int_bin_cons_misc_0_c - __field size 22 +: 2 - __field opc 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('00000') => __encoding FEXPA_Z_Z__ // fexpa_z_z_ - when ('00001') => __UNALLOCATED - when ('0001x') => __UNALLOCATED - when ('001xx') => __UNALLOCATED - when ('01xxx') => __UNALLOCATED - when ('1xxxx') => __UNALLOCATED - when (_, _, _, _, _, '11', _) => // sve_int_bin_cons_misc_0_d - __field opc 22 +: 2 - __field opc2 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc, opc2) of - when ('00', '00000') => __encoding MOVPRFX_Z_Z__ // movprfx_z_z_ - when ('00', '00001') => __UNALLOCATED - when ('00', '0001x') => __UNALLOCATED - when ('00', '001xx') => __UNALLOCATED - when ('00', '01xxx') => __UNALLOCATED - when ('00', '1xxxx') => __UNALLOCATED - when ('01', _) => __UNALLOCATED - when ('1x', _) => __UNALLOCATED - when ('000', _, '0x', _, '1xxxx', _, '11xxxx', _) => - // sve_countelt - case (24 +: 8, 22 +: 2, 21 +: 1, 20 +: 1, 16 +: 4, 14 +: 2, 11 +: 3, 0 +: 11) of - when (_, _, _, '0', _, _, '00x', _) => // sve_int_countvlv0 - __field size 22 +: 2 - __field imm4 16 +: 4 - __field D 11 +: 1 - __field U 10 +: 1 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - case (size, D, U) of - when ('00', _, _) => __UNALLOCATED - when ('01', '0', '0') => __encoding SQINCH_Z_ZS__ // sqinch_z_zs_ - when ('01', '0', '1') => __encoding UQINCH_Z_ZS__ // uqinch_z_zs_ - when ('01', '1', '0') => __encoding SQDECH_Z_ZS__ // sqdech_z_zs_ - when ('01', '1', '1') => __encoding UQDECH_Z_ZS__ // uqdech_z_zs_ - when ('10', '0', '0') => __encoding SQINCW_Z_ZS__ // sqincw_z_zs_ - when ('10', '0', '1') => __encoding UQINCW_Z_ZS__ // uqincw_z_zs_ - when ('10', '1', '0') => __encoding SQDECW_Z_ZS__ // sqdecw_z_zs_ - when ('10', '1', '1') => __encoding UQDECW_Z_ZS__ // uqdecw_z_zs_ - when ('11', '0', '0') => __encoding SQINCD_Z_ZS__ // sqincd_z_zs_ - when ('11', '0', '1') => __encoding UQINCD_Z_ZS__ // uqincd_z_zs_ - when ('11', '1', '0') => __encoding SQDECD_Z_ZS__ // sqdecd_z_zs_ - when ('11', '1', '1') => __encoding UQDECD_Z_ZS__ // uqdecd_z_zs_ - when (_, _, _, '0', _, _, '100', _) => // sve_int_count - __field size 22 +: 2 - __field imm4 16 +: 4 - __field op 10 +: 1 - __field pattern 5 +: 5 - __field Rd 0 +: 5 - case (size, op) of - when (_, '1') => __UNALLOCATED - when ('00', '0') => __encoding CNTB_R_S__ // cntb_r_s_ - when ('01', '0') => __encoding CNTH_R_S__ // cnth_r_s_ - when ('10', '0') => __encoding CNTW_R_S__ // cntw_r_s_ - when ('11', '0') => __encoding CNTD_R_S__ // cntd_r_s_ - when (_, _, _, '0', _, _, '101', _) => __UNPREDICTABLE - when (_, _, _, '1', _, _, '000', _) => // sve_int_countvlv1 - __field size 22 +: 2 - __field imm4 16 +: 4 - __field D 10 +: 1 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - case (size, D) of - when ('00', _) => __UNALLOCATED - when ('01', '0') => __encoding INCH_Z_ZS__ // inch_z_zs_ - when ('01', '1') => __encoding DECH_Z_ZS__ // dech_z_zs_ - when ('10', '0') => __encoding INCW_Z_ZS__ // incw_z_zs_ - when ('10', '1') => __encoding DECW_Z_ZS__ // decw_z_zs_ - when ('11', '0') => __encoding INCD_Z_ZS__ // incd_z_zs_ - when ('11', '1') => __encoding DECD_Z_ZS__ // decd_z_zs_ - when (_, _, _, '1', _, _, '100', _) => // sve_int_pred_pattern_a - __field size 22 +: 2 - __field imm4 16 +: 4 - __field D 10 +: 1 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - case (size, D) of - when ('00', '0') => __encoding INCB_R_RS__ // incb_r_rs_ - when ('00', '1') => __encoding DECB_R_RS__ // decb_r_rs_ - when ('01', '0') => __encoding INCH_R_RS__ // inch_r_rs_ - when ('01', '1') => __encoding DECH_R_RS__ // dech_r_rs_ - when ('10', '0') => __encoding INCW_R_RS__ // incw_r_rs_ - when ('10', '1') => __encoding DECW_R_RS__ // decw_r_rs_ - when ('11', '0') => __encoding INCD_R_RS__ // incd_r_rs_ - when ('11', '1') => __encoding DECD_R_RS__ // decd_r_rs_ - when (_, _, _, '1', _, _, 'x01', _) => __UNPREDICTABLE - when (_, _, _, _, _, _, '01x', _) => __UNPREDICTABLE - when (_, _, _, _, _, _, '11x', _) => // sve_int_pred_pattern_b - __field size 22 +: 2 - __field sf 20 +: 1 - __field imm4 16 +: 4 - __field D 11 +: 1 - __field U 10 +: 1 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - case (size, sf, D, U) of - when ('00', '0', '0', '0') => __encoding SQINCB_R_RS_SX // sqincb_r_rs_sx - when ('00', '0', '0', '1') => __encoding UQINCB_R_RS_UW // uqincb_r_rs_uw - when ('00', '0', '1', '0') => __encoding SQDECB_R_RS_SX // sqdecb_r_rs_sx - when ('00', '0', '1', '1') => __encoding UQDECB_R_RS_UW // uqdecb_r_rs_uw - when ('00', '1', '0', '0') => __encoding SQINCB_R_RS_X // sqincb_r_rs_x - when ('00', '1', '0', '1') => __encoding UQINCB_R_RS_X // uqincb_r_rs_x - when ('00', '1', '1', '0') => __encoding SQDECB_R_RS_X // sqdecb_r_rs_x - when ('00', '1', '1', '1') => __encoding UQDECB_R_RS_X // uqdecb_r_rs_x - when ('01', '0', '0', '0') => __encoding SQINCH_R_RS_SX // sqinch_r_rs_sx - when ('01', '0', '0', '1') => __encoding UQINCH_R_RS_UW // uqinch_r_rs_uw - when ('01', '0', '1', '0') => __encoding SQDECH_R_RS_SX // sqdech_r_rs_sx - when ('01', '0', '1', '1') => __encoding UQDECH_R_RS_UW // uqdech_r_rs_uw - when ('01', '1', '0', '0') => __encoding SQINCH_R_RS_X // sqinch_r_rs_x - when ('01', '1', '0', '1') => __encoding UQINCH_R_RS_X // uqinch_r_rs_x - when ('01', '1', '1', '0') => __encoding SQDECH_R_RS_X // sqdech_r_rs_x - when ('01', '1', '1', '1') => __encoding UQDECH_R_RS_X // uqdech_r_rs_x - when ('10', '0', '0', '0') => __encoding SQINCW_R_RS_SX // sqincw_r_rs_sx - when ('10', '0', '0', '1') => __encoding UQINCW_R_RS_UW // uqincw_r_rs_uw - when ('10', '0', '1', '0') => __encoding SQDECW_R_RS_SX // sqdecw_r_rs_sx - when ('10', '0', '1', '1') => __encoding UQDECW_R_RS_UW // uqdecw_r_rs_uw - when ('10', '1', '0', '0') => __encoding SQINCW_R_RS_X // sqincw_r_rs_x - when ('10', '1', '0', '1') => __encoding UQINCW_R_RS_X // uqincw_r_rs_x - when ('10', '1', '1', '0') => __encoding SQDECW_R_RS_X // sqdecw_r_rs_x - when ('10', '1', '1', '1') => __encoding UQDECW_R_RS_X // uqdecw_r_rs_x - when ('11', '0', '0', '0') => __encoding SQINCD_R_RS_SX // sqincd_r_rs_sx - when ('11', '0', '0', '1') => __encoding UQINCD_R_RS_UW // uqincd_r_rs_uw - when ('11', '0', '1', '0') => __encoding SQDECD_R_RS_SX // sqdecd_r_rs_sx - when ('11', '0', '1', '1') => __encoding UQDECD_R_RS_UW // uqdecd_r_rs_uw - when ('11', '1', '0', '0') => __encoding SQINCD_R_RS_X // sqincd_r_rs_x - when ('11', '1', '0', '1') => __encoding UQINCD_R_RS_X // uqincd_r_rs_x - when ('11', '1', '1', '0') => __encoding SQDECD_R_RS_X // sqdecd_r_rs_x - when ('11', '1', '1', '1') => __encoding UQDECD_R_RS_X // uqdecd_r_rs_x - when ('000', _, '1x', _, '00xxx', _, _, _) => - // sve_maskimm - case (24 +: 8, 22 +: 2, 20 +: 2, 18 +: 2, 0 +: 18) of - when (_, '11', _, '00', _) => // sve_int_dup_mask_imm - __field imm13 5 +: 13 - __field Zd 0 +: 5 - case () of - when () => __encoding DUPM_Z_I__ // dupm_z_i_ - when (_, !'11', _, '00', _) => // sve_int_log_imm - __field opc 22 +: 2 - __field imm13 5 +: 13 - __field Zdn 0 +: 5 - case (opc) of - when ('00') => __encoding ORR_Z_ZI__ // orr_z_zi_ - when ('01') => __encoding EOR_Z_ZI__ // eor_z_zi_ - when ('10') => __encoding AND_Z_ZI__ // and_z_zi_ - when (_, _, _, !'00', _) => __UNPREDICTABLE - when ('000', _, '1x', _, '01xxx', _, _, _) => - // sve_wideimm_pred - case (24 +: 8, 22 +: 2, 20 +: 2, 16 +: 4, 13 +: 3, 0 +: 13) of - when (_, _, _, _, '0xx', _) => // sve_int_dup_imm_pred - __field size 22 +: 2 - __field Pg 16 +: 4 - __field M 14 +: 1 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zd 0 +: 5 - case (M) of - when ('0') => __encoding CPY_Z_O_I__ // cpy_z_o_i_ - when ('1') => __encoding CPY_Z_P_I__ // cpy_z_p_i_ - when (_, _, _, _, '10x', _) => __UNPREDICTABLE - when (_, _, _, _, '110', _) => // sve_int_dup_fpimm_pred - __field size 22 +: 2 - __field Pg 16 +: 4 - __field imm8 5 +: 8 - __field Zd 0 +: 5 - case () of - when () => __encoding FCPY_Z_P_I__ // fcpy_z_p_i_ - when (_, _, _, _, '111', _) => __UNPREDICTABLE - when ('000', _, '1x', _, '1xxxx', _, '001xxx', _) => - // sve_perm_unpred - case (24 +: 8, 22 +: 2, 21 +: 1, 19 +: 2, 17 +: 2, 16 +: 1, 13 +: 3, 12 +: 1, 10 +: 2, 0 +: 10) of - when (_, _, _, '00', '00', '0', _, '1', '10', _) => // sve_int_perm_dup_r - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding DUP_Z_R__ // dup_z_r_ - when (_, _, _, '00', '10', '0', _, '1', '10', _) => // sve_int_perm_insrs - __field size 22 +: 2 - __field Rm 5 +: 5 - __field Zdn 0 +: 5 - case () of - when () => __encoding INSR_Z_R__ // insr_z_r_ - when (_, _, _, '00', 'x0', '0', _, '0', '01', _) => __UNPREDICTABLE - when (_, _, _, '00', 'x0', '0', _, '1', 'x1', _) => __UNPREDICTABLE - when (_, _, _, '00', 'x1', _, _, '1', '1x', _) => __UNPREDICTABLE - when (_, _, _, '00', 'x1', _, _, _, '01', _) => __UNPREDICTABLE - when (_, _, _, '00', _, '1', _, '1', '1x', _) => __UNPREDICTABLE - when (_, _, _, '00', _, '1', _, _, '01', _) => __UNPREDICTABLE - when (_, _, _, '00', _, _, _, '0', '1x', _) => __UNPREDICTABLE - when (_, _, _, '01', _, _, _, _, !'00', _) => __UNPREDICTABLE - when (_, _, _, '10', '0x', _, _, '0', '01', _) => __UNPREDICTABLE - when (_, _, _, '10', '0x', _, _, '1', '10', _) => // sve_int_perm_unpk - __field size 22 +: 2 - __field U 17 +: 1 - __field H 16 +: 1 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (U, H) of - when ('0', '0') => __encoding SUNPKLO_Z_Z__ // sunpklo_z_z_ - when ('0', '1') => __encoding SUNPKHI_Z_Z__ // sunpkhi_z_z_ - when ('1', '0') => __encoding UUNPKLO_Z_Z__ // uunpklo_z_z_ - when ('1', '1') => __encoding UUNPKHI_Z_Z__ // uunpkhi_z_z_ - when (_, _, _, '10', '0x', _, _, '1', 'x1', _) => __UNPREDICTABLE - when (_, _, _, '10', '10', '0', _, '0', '01', _) => __UNPREDICTABLE - when (_, _, _, '10', '10', '0', _, '1', '10', _) => // sve_int_perm_insrv - __field size 22 +: 2 - __field Vm 5 +: 5 - __field Zdn 0 +: 5 - case () of - when () => __encoding INSR_Z_V__ // insr_z_v_ - when (_, _, _, '10', '10', '0', _, '1', 'x1', _) => __UNPREDICTABLE - when (_, _, _, '10', '11', _, _, '1', '1x', _) => __UNPREDICTABLE - when (_, _, _, '10', '11', _, _, _, '01', _) => __UNPREDICTABLE - when (_, _, _, '10', '1x', '1', _, '1', '1x', _) => __UNPREDICTABLE - when (_, _, _, '10', '1x', '1', _, _, '01', _) => __UNPREDICTABLE - when (_, _, _, '11', '00', '0', _, '0', '01', _) => __UNPREDICTABLE - when (_, _, _, '11', '00', '0', _, '1', '10', _) => // sve_int_perm_reverse_z - __field size 22 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding REV_Z_Z__ // rev_z_z_ - when (_, _, _, '11', '00', '0', _, '1', 'x1', _) => __UNPREDICTABLE - when (_, _, _, '11', '0x', '1', _, '1', '1x', _) => __UNPREDICTABLE - when (_, _, _, '11', '0x', '1', _, _, '01', _) => __UNPREDICTABLE - when (_, _, _, '11', !'00', _, _, '1', '1x', _) => __UNPREDICTABLE - when (_, _, _, '11', !'00', _, _, _, '01', _) => __UNPREDICTABLE - when (_, _, _, '1x', _, _, _, '0', '1x', _) => __UNPREDICTABLE - when (_, _, _, _, _, _, _, '0', '00', _) => // sve_int_perm_dup_i - __field imm2 22 +: 2 - __field tsz 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding DUP_Z_Zi__ // dup_z_zi_ - when (_, _, _, _, _, _, _, '1', '00', _) => // sve_int_perm_tbl - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding TBL_Z_ZZ_1 // tbl_z_zz_1 - when ('000', _, '1x', _, '1xxxx', _, '010xxx', _) => - // sve_perm_predicates - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 13 +: 3, 9 +: 4, 5 +: 4, 4 +: 1, 0 +: 4) of - when (_, '00', _, '1000x', _, '0000', _, '0', _) => // sve_int_perm_punpk - __field H 16 +: 1 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - case (H) of - when ('0') => __encoding PUNPKLO_P_P__ // punpklo_p_p_ - when ('1') => __encoding PUNPKHI_P_P__ // punpkhi_p_p_ - when (_, '01', _, '1000x', _, '0000', _, '0', _) => __UNPREDICTABLE - when (_, '10', _, '1000x', _, '0000', _, '0', _) => __UNPREDICTABLE - when (_, '11', _, '1000x', _, '0000', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '0xxxx', _, 'xxx0', _, '0', _) => // sve_int_perm_bin_perm_pp - __field size 22 +: 2 - __field Pm 16 +: 4 - __field opc 11 +: 2 - __field H 10 +: 1 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - case (opc, H) of - when ('00', '0') => __encoding ZIP1_P_PP__ // zip1_p_pp_ - when ('00', '1') => __encoding ZIP2_P_PP__ // zip2_p_pp_ - when ('01', '0') => __encoding UZP1_P_PP__ // uzp1_p_pp_ - when ('01', '1') => __encoding UZP2_P_PP__ // uzp2_p_pp_ - when ('10', '0') => __encoding TRN1_P_PP__ // trn1_p_pp_ - when ('10', '1') => __encoding TRN2_P_PP__ // trn2_p_pp_ - when ('11', _) => __UNALLOCATED - when (_, _, _, '0xxxx', _, 'xxx1', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '10100', _, '0000', _, '0', _) => // sve_int_perm_reverse_p - __field size 22 +: 2 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - case () of - when () => __encoding REV_P_P__ // rev_p_p_ - when (_, _, _, '10101', _, '0000', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '10x0x', _, '1000', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '10x0x', _, 'x100', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '10x0x', _, 'xx10', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '10x0x', _, 'xxx1', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '10x1x', _, _, _, '0', _) => __UNPREDICTABLE - when (_, _, _, '11xxx', _, _, _, '0', _) => __UNPREDICTABLE - when (_, _, _, _, _, _, _, '1', _) => __UNPREDICTABLE - when ('000', _, '1x', _, '1xxxx', _, '011xxx', _) => // sve_int_perm_bin_perm_zz - __field size 22 +: 2 - __field Zm 16 +: 5 - __field opc 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('000') => __encoding ZIP1_Z_ZZ__ // zip1_z_zz_ - when ('001') => __encoding ZIP2_Z_ZZ__ // zip2_z_zz_ - when ('010') => __encoding UZP1_Z_ZZ__ // uzp1_z_zz_ - when ('011') => __encoding UZP2_Z_ZZ__ // uzp2_z_zz_ - when ('100') => __encoding TRN1_Z_ZZ__ // trn1_z_zz_ - when ('101') => __encoding TRN2_Z_ZZ__ // trn2_z_zz_ - when ('11x') => __UNALLOCATED - when ('000', _, '1x', _, '1xxxx', _, '10xxxx', _) => - // sve_perm_pred - case (24 +: 8, 22 +: 2, 21 +: 1, 20 +: 1, 17 +: 3, 16 +: 1, 14 +: 2, 13 +: 1, 0 +: 13) of - when (_, _, _, '0', '000', '0', _, '0', _) => // sve_int_perm_cpy_v - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Vn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding CPY_Z_P_V__ // cpy_z_p_v_ - when (_, _, _, '0', '000', '1', _, '0', _) => // sve_int_perm_compact - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding COMPACT_Z_P_Z__ // compact_z_p_z_ - when (_, _, _, '0', '000', _, _, '1', _) => // sve_int_perm_last_r - __field size 22 +: 2 - __field B 16 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Rd 0 +: 5 - case (B) of - when ('0') => __encoding LASTA_R_P_Z__ // lasta_r_p_z_ - when ('1') => __encoding LASTB_R_P_Z__ // lastb_r_p_z_ - when (_, _, _, '0', '001', _, _, '0', _) => // sve_int_perm_last_v - __field size 22 +: 2 - __field B 16 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - case (B) of - when ('0') => __encoding LASTA_V_P_Z__ // lasta_v_p_z_ - when ('1') => __encoding LASTB_V_P_Z__ // lastb_v_p_z_ - when (_, _, _, '0', '01x', _, _, '0', _) => // sve_int_perm_rev - __field size 22 +: 2 - __field opc 16 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('00') => __encoding REVB_Z_Z__ // revb_z_z_ - when ('01') => __encoding REVH_Z_Z__ // revh_z_z_ - when ('10') => __encoding REVW_Z_Z__ // revw_z_z_ - when ('11') => __encoding RBIT_Z_P_Z__ // rbit_z_p_z_ - when (_, _, _, '0', '01x', _, _, '1', _) => __UNPREDICTABLE - when (_, _, _, '0', '100', '0', _, '1', _) => // sve_int_perm_cpy_r - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding CPY_Z_P_R__ // cpy_z_p_r_ - when (_, _, _, '0', '100', '1', _, '1', _) => __UNPREDICTABLE - when (_, _, _, '0', '100', _, _, '0', _) => // sve_int_perm_clast_zz - __field size 22 +: 2 - __field B 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (B) of - when ('0') => __encoding CLASTA_Z_P_ZZ__ // clasta_z_p_zz_ - when ('1') => __encoding CLASTB_Z_P_ZZ__ // clastb_z_p_zz_ - when (_, _, _, '0', '101', _, _, '0', _) => // sve_int_perm_clast_vz - __field size 22 +: 2 - __field B 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Vdn 0 +: 5 - case (B) of - when ('0') => __encoding CLASTA_V_P_Z__ // clasta_v_p_z_ - when ('1') => __encoding CLASTB_V_P_Z__ // clastb_v_p_z_ - when (_, _, _, '0', '110', '0', _, '0', _) => // sve_int_perm_splice - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case () of - when () => __encoding SPLICE_Z_P_ZZ_Des // splice_z_p_zz_des - when (_, _, _, '0', '110', '0', _, '1', _) => __UNPREDICTABLE - when (_, _, _, '0', '110', '1', _, _, _) => __UNPREDICTABLE - when (_, _, _, '0', '111', '0', _, _, _) => __UNPREDICTABLE - when (_, _, _, '0', '111', '1', _, _, _) => __UNPREDICTABLE - when (_, _, _, '0', 'x01', _, _, '1', _) => __UNPREDICTABLE - when (_, _, _, '1', '000', _, _, '0', _) => __UNPREDICTABLE - when (_, _, _, '1', '000', _, _, '1', _) => // sve_int_perm_clast_rz - __field size 22 +: 2 - __field B 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Rdn 0 +: 5 - case (B) of - when ('0') => __encoding CLASTA_R_P_Z__ // clasta_r_p_z_ - when ('1') => __encoding CLASTB_R_P_Z__ // clastb_r_p_z_ - when (_, _, _, '1', !'000', _, _, _, _) => __UNPREDICTABLE - when ('000', _, '1x', _, '1xxxx', _, '11xxxx', _) => // sve_int_sel_vvv - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 4 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case () of - when () => __encoding SEL_Z_P_ZZ__ // sel_z_p_zz_ - when ('000', _, '10', _, '1xxxx', _, '000xxx', _) => - // sve_perm_extract - case (23 +: 9, 22 +: 1, 21 +: 1, 16 +: 5, 13 +: 3, 0 +: 13) of - when (_, '0', _, _, _, _) => // sve_int_perm_extract_i - __field imm8h 16 +: 5 - __field imm8l 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case () of - when () => __encoding EXT_Z_ZI_Des // ext_z_zi_des - when (_, '1', _, _, _, _) => __UNPREDICTABLE - when ('000', _, '11', _, '1xxxx', _, '000xxx', _) => // sve_int_perm_bin_long_perm_zz - __field op 22 +: 1 - __field Zm 16 +: 5 - __field opc2 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (op, opc2) of - when ('0', '000') => __encoding ZIP1_Z_ZZ_Q // zip1_z_zz_q - when ('0', '001') => __encoding ZIP2_Z_ZZ_Q // zip2_z_zz_q - when ('0', '010') => __encoding UZP1_Z_ZZ_Q // uzp1_z_zz_q - when ('0', '011') => __encoding UZP2_Z_ZZ_Q // uzp2_z_zz_q - when ('0', '10x') => __UNALLOCATED - when ('0', '110') => __encoding TRN1_Z_ZZ_Q // trn1_z_zz_q - when ('0', '111') => __encoding TRN2_Z_ZZ_Q // trn2_z_zz_q - when ('1', _) => __UNALLOCATED - when ('001', _, '0x', _, '0xxxx', _, _, _) => - // sve_cmpvec - case (24 +: 8, 22 +: 2, 21 +: 1, 15 +: 6, 14 +: 1, 0 +: 14) of - when (_, _, _, _, '0', _) => // sve_int_cmp_0 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field op 15 +: 1 - __field o2 13 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field ne 4 +: 1 - __field Pd 0 +: 4 - case (op, o2, ne) of - when ('0', '0', '0') => __encoding CMPHS_P_P_ZZ__ // cmphs_p_p_zz_ - when ('0', '0', '1') => __encoding CMPHI_P_P_ZZ__ // cmphi_p_p_zz_ - when ('0', '1', '0') => __encoding CMPEQ_P_P_ZW__ // cmpeq_p_p_zw_ - when ('0', '1', '1') => __encoding CMPNE_P_P_ZW__ // cmpne_p_p_zw_ - when ('1', '0', '0') => __encoding CMPGE_P_P_ZZ__ // cmpge_p_p_zz_ - when ('1', '0', '1') => __encoding CMPGT_P_P_ZZ__ // cmpgt_p_p_zz_ - when ('1', '1', '0') => __encoding CMPEQ_P_P_ZZ__ // cmpeq_p_p_zz_ - when ('1', '1', '1') => __encoding CMPNE_P_P_ZZ__ // cmpne_p_p_zz_ - when (_, _, _, _, '1', _) => // sve_int_cmp_1 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field U 15 +: 1 - __field lt 13 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field ne 4 +: 1 - __field Pd 0 +: 4 - case (U, lt, ne) of - when ('0', '0', '0') => __encoding CMPGE_P_P_ZW__ // cmpge_p_p_zw_ - when ('0', '0', '1') => __encoding CMPGT_P_P_ZW__ // cmpgt_p_p_zw_ - when ('0', '1', '0') => __encoding CMPLT_P_P_ZW__ // cmplt_p_p_zw_ - when ('0', '1', '1') => __encoding CMPLE_P_P_ZW__ // cmple_p_p_zw_ - when ('1', '0', '0') => __encoding CMPHS_P_P_ZW__ // cmphs_p_p_zw_ - when ('1', '0', '1') => __encoding CMPHI_P_P_ZW__ // cmphi_p_p_zw_ - when ('1', '1', '0') => __encoding CMPLO_P_P_ZW__ // cmplo_p_p_zw_ - when ('1', '1', '1') => __encoding CMPLS_P_P_ZW__ // cmpls_p_p_zw_ - when ('001', _, '0x', _, '1xxxx', _, _, _) => // sve_int_ucmp_vi - __field size 22 +: 2 - __field imm7 14 +: 7 - __field lt 13 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field ne 4 +: 1 - __field Pd 0 +: 4 - case (lt, ne) of - when ('0', '0') => __encoding CMPHS_P_P_ZI__ // cmphs_p_p_zi_ - when ('0', '1') => __encoding CMPHI_P_P_ZI__ // cmphi_p_p_zi_ - when ('1', '0') => __encoding CMPLO_P_P_ZI__ // cmplo_p_p_zi_ - when ('1', '1') => __encoding CMPLS_P_P_ZI__ // cmpls_p_p_zi_ - when ('001', _, '1x', _, '0xxxx', _, 'x0xxxx', _) => // sve_int_scmp_vi - __field size 22 +: 2 - __field imm5 16 +: 5 - __field op 15 +: 1 - __field o2 13 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field ne 4 +: 1 - __field Pd 0 +: 4 - case (op, o2, ne) of - when ('0', '0', '0') => __encoding CMPGE_P_P_ZI__ // cmpge_p_p_zi_ - when ('0', '0', '1') => __encoding CMPGT_P_P_ZI__ // cmpgt_p_p_zi_ - when ('0', '1', '0') => __encoding CMPLT_P_P_ZI__ // cmplt_p_p_zi_ - when ('0', '1', '1') => __encoding CMPLE_P_P_ZI__ // cmple_p_p_zi_ - when ('1', '0', '0') => __encoding CMPEQ_P_P_ZI__ // cmpeq_p_p_zi_ - when ('1', '0', '1') => __encoding CMPNE_P_P_ZI__ // cmpne_p_p_zi_ - when ('1', '1', _) => __UNALLOCATED - when ('001', _, '1x', _, '00xxx', _, '01xxxx', _) => // sve_int_pred_log - __field op 23 +: 1 - __field S 22 +: 1 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field o2 9 +: 1 - __field Pn 5 +: 4 - __field o3 4 +: 1 - __field Pd 0 +: 4 - case (op, S, o2, o3) of - when ('0', '0', '0', '0') => __encoding AND_P_P_PP_Z // and_p_p_pp_z - when ('0', '0', '0', '1') => __encoding BIC_P_P_PP_Z // bic_p_p_pp_z - when ('0', '0', '1', '0') => __encoding EOR_P_P_PP_Z // eor_p_p_pp_z - when ('0', '0', '1', '1') => __encoding SEL_P_P_PP__ // sel_p_p_pp_ - when ('0', '1', '0', '0') => __encoding ANDS_P_P_PP_Z // ands_p_p_pp_z - when ('0', '1', '0', '1') => __encoding BICS_P_P_PP_Z // bics_p_p_pp_z - when ('0', '1', '1', '0') => __encoding EORS_P_P_PP_Z // eors_p_p_pp_z - when ('0', '1', '1', '1') => __UNALLOCATED - when ('1', '0', '0', '0') => __encoding ORR_P_P_PP_Z // orr_p_p_pp_z - when ('1', '0', '0', '1') => __encoding ORN_P_P_PP_Z // orn_p_p_pp_z - when ('1', '0', '1', '0') => __encoding NOR_P_P_PP_Z // nor_p_p_pp_z - when ('1', '0', '1', '1') => __encoding NAND_P_P_PP_Z // nand_p_p_pp_z - when ('1', '1', '0', '0') => __encoding ORRS_P_P_PP_Z // orrs_p_p_pp_z - when ('1', '1', '0', '1') => __encoding ORNS_P_P_PP_Z // orns_p_p_pp_z - when ('1', '1', '1', '0') => __encoding NORS_P_P_PP_Z // nors_p_p_pp_z - when ('1', '1', '1', '1') => __encoding NANDS_P_P_PP_Z // nands_p_p_pp_z - when ('001', _, '1x', _, '00xxx', _, '11xxxx', _) => - // sve_pred_gen_b - case (24 +: 8, 22 +: 2, 20 +: 2, 16 +: 4, 14 +: 2, 10 +: 4, 9 +: 1, 0 +: 9) of - when (_, _, _, _, _, _, '0', _) => // sve_int_brkp - __field op 23 +: 1 - __field S 22 +: 1 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field B 4 +: 1 - __field Pd 0 +: 4 - case (op, S, B) of - when ('0', '0', '0') => __encoding BRKPA_P_P_PP__ // brkpa_p_p_pp_ - when ('0', '0', '1') => __encoding BRKPB_P_P_PP__ // brkpb_p_p_pp_ - when ('0', '1', '0') => __encoding BRKPAS_P_P_PP__ // brkpas_p_p_pp_ - when ('0', '1', '1') => __encoding BRKPBS_P_P_PP__ // brkpbs_p_p_pp_ - when ('1', _, _) => __UNALLOCATED - when (_, _, _, _, _, _, '1', _) => __UNPREDICTABLE - when ('001', _, '1x', _, '01xxx', _, '01xxxx', _) => - // sve_pred_gen_c - case (24 +: 8, 23 +: 1, 22 +: 1, 20 +: 2, 16 +: 4, 14 +: 2, 10 +: 4, 9 +: 1, 5 +: 4, 4 +: 1, 0 +: 4) of - when (_, '0', _, _, '1000', _, _, '0', _, '0', _) => // sve_int_brkn - __field S 22 +: 1 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pdm 0 +: 4 - case (S) of - when ('0') => __encoding BRKN_P_P_PP__ // brkn_p_p_pp_ - when ('1') => __encoding BRKNS_P_P_PP__ // brkns_p_p_pp_ - when (_, '0', _, _, '1000', _, _, '0', _, '1', _) => __UNPREDICTABLE - when (_, '0', _, _, 'x000', _, _, '1', _, _, _) => __UNPREDICTABLE - when (_, '0', _, _, 'x1xx', _, _, _, _, _, _) => __UNPREDICTABLE - when (_, '0', _, _, 'xx1x', _, _, _, _, _, _) => __UNPREDICTABLE - when (_, '0', _, _, 'xxx1', _, _, _, _, _, _) => __UNPREDICTABLE - when (_, '1', _, _, '0000', _, _, '1', _, _, _) => __UNPREDICTABLE - when (_, '1', _, _, !'0000', _, _, _, _, _, _) => __UNPREDICTABLE - when (_, _, _, _, '0000', _, _, '0', _, _, _) => // sve_int_break - __field B 23 +: 1 - __field S 22 +: 1 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field M 4 +: 1 - __field Pd 0 +: 4 - case (B, S, M) of - when (_, '1', '1') => __UNALLOCATED - when ('0', '0', _) => __encoding BRKA_P_P_P__ // brka_p_p_p_ - when ('0', '1', '0') => __encoding BRKAS_P_P_P_Z // brkas_p_p_p_z - when ('1', '0', _) => __encoding BRKB_P_P_P__ // brkb_p_p_p_ - when ('1', '1', '0') => __encoding BRKBS_P_P_P_Z // brkbs_p_p_p_z - when ('001', _, '1x', _, '01xxx', _, '11xxxx', _) => - // sve_pred_gen_d - case (24 +: 8, 22 +: 2, 20 +: 2, 16 +: 4, 14 +: 2, 11 +: 3, 9 +: 2, 5 +: 4, 4 +: 1, 0 +: 4) of - when (_, _, _, '0000', _, _, 'x0', _, '0', _) => // sve_int_ptest - __field op 23 +: 1 - __field S 22 +: 1 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field opc2 0 +: 4 - case (op, S, opc2) of - when ('0', '0', _) => __UNALLOCATED - when ('0', '1', '0000') => __encoding PTEST__P_P__ // ptest_p_p_ - when ('0', '1', '0001') => __UNALLOCATED - when ('0', '1', '001x') => __UNALLOCATED - when ('0', '1', '01xx') => __UNALLOCATED - when ('0', '1', '1xxx') => __UNALLOCATED - when ('1', _, _) => __UNALLOCATED - when (_, _, _, '0100', _, _, 'x0', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '0x10', _, _, 'x0', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '0xx1', _, _, 'x0', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '0xxx', _, _, 'x1', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '1000', _, '000', '00', _, '0', _) => // sve_int_pfirst - __field op 23 +: 1 - __field S 22 +: 1 - __field Pg 5 +: 4 - __field Pdn 0 +: 4 - case (op, S) of - when ('0', '0') => __UNALLOCATED - when ('0', '1') => __encoding PFIRST_P_P_P__ // pfirst_p_p_p_ - when ('1', _) => __UNALLOCATED - when (_, _, _, '1000', _, '000', !'00', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '1000', _, '100', '10', '0000', '0', _) => // sve_int_pfalse - __field op 23 +: 1 - __field S 22 +: 1 - __field Pd 0 +: 4 - case (op, S) of - when ('0', '0') => __encoding PFALSE_P__ // pfalse_p_ - when ('0', '1') => __UNALLOCATED - when ('1', _) => __UNALLOCATED - when (_, _, _, '1000', _, '100', '10', !'0000', '0', _) => __UNPREDICTABLE - when (_, _, _, '1000', _, '110', '00', _, '0', _) => // sve_int_rdffr - __field op 23 +: 1 - __field S 22 +: 1 - __field Pg 5 +: 4 - __field Pd 0 +: 4 - case (op, S) of - when ('0', '0') => __encoding RDFFR_P_P_F__ // rdffr_p_p_f_ - when ('0', '1') => __encoding RDFFRS_P_P_F__ // rdffrs_p_p_f_ - when ('1', _) => __UNALLOCATED - when (_, _, _, '1001', _, '000', '0x', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '1001', _, '000', '10', _, '0', _) => // sve_int_pnext - __field size 22 +: 2 - __field Pg 5 +: 4 - __field Pdn 0 +: 4 - case () of - when () => __encoding PNEXT_P_P_P__ // pnext_p_p_p_ - when (_, _, _, '1001', _, '000', '11', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '1001', _, '100', '10', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '1001', _, '110', '00', '0000', '0', _) => // sve_int_rdffr_2 - __field op 23 +: 1 - __field S 22 +: 1 - __field Pd 0 +: 4 - case (op, S) of - when ('0', '0') => __encoding RDFFR_P_F__ // rdffr_p_f_ - when ('0', '1') => __UNALLOCATED - when ('1', _) => __UNALLOCATED - when (_, _, _, '1001', _, '110', '00', !'0000', '0', _) => __UNPREDICTABLE - when (_, _, _, '100x', _, '010', _, _, '0', _) => __UNPREDICTABLE - when (_, _, _, '100x', _, '100', '0x', _, '0', _) => // sve_int_ptrue - __field size 22 +: 2 - __field S 16 +: 1 - __field pattern 5 +: 5 - __field Pd 0 +: 4 - case (S) of - when ('0') => __encoding PTRUE_P_S__ // ptrue_p_s_ - when ('1') => __encoding PTRUES_P_S__ // ptrues_p_s_ - when (_, _, _, '100x', _, '100', '11', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '100x', _, '110', !'00', _, '0', _) => __UNPREDICTABLE - when (_, _, _, '100x', _, 'xx1', _, _, '0', _) => __UNPREDICTABLE - when (_, _, _, '110x', _, _, _, _, '0', _) => __UNPREDICTABLE - when (_, _, _, '1x1x', _, _, _, _, '0', _) => __UNPREDICTABLE - when (_, _, _, _, _, _, _, _, '1', _) => __UNPREDICTABLE - when ('001', _, '1x', _, '1xxxx', _, '00xxxx', _) => - // sve_cmpgpr - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 14 +: 2, 13 +: 1, 10 +: 3, 4 +: 6, 0 +: 4) of - when (_, _, _, _, _, '0', _, _, _) => // sve_int_while_rr - __field size 22 +: 2 - __field Rm 16 +: 5 - __field sf 12 +: 1 - __field U 11 +: 1 - __field lt 10 +: 1 - __field Rn 5 +: 5 - __field eq 4 +: 1 - __field Pd 0 +: 4 - case (U, lt, eq) of - when (_, '0', _) => __UNALLOCATED - when ('0', '1', '0') => __encoding WHILELT_P_P_RR__ // whilelt_p_p_rr_ - when ('0', '1', '1') => __encoding WHILELE_P_P_RR__ // whilele_p_p_rr_ - when ('1', '1', '0') => __encoding WHILELO_P_P_RR__ // whilelo_p_p_rr_ - when ('1', '1', '1') => __encoding WHILELS_P_P_RR__ // whilels_p_p_rr_ - when (_, _, _, _, _, '1', '000', _, '0000') => // sve_int_cterm - __field op 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field ne 4 +: 1 - case (op, ne) of - when ('0', _) => __UNALLOCATED - when ('1', '0') => __encoding CTERMEQ_RR__ // ctermeq_rr_ - when ('1', '1') => __encoding CTERMNE_RR__ // ctermne_rr_ - when (_, _, _, _, _, '1', '000', _, !'0000') => __UNPREDICTABLE - when (_, _, _, _, _, '1', !'000', _, _) => __UNPREDICTABLE - when ('001', _, '1x', _, '1xxxx', _, '01xxxx', _) => __UNPREDICTABLE - when ('001', _, '1x', _, '1xxxx', _, '11xxxx', _) => - // sve_wideimm_unpred - case (24 +: 8, 22 +: 2, 21 +: 1, 19 +: 2, 17 +: 2, 16 +: 1, 14 +: 2, 0 +: 14) of - when (_, _, _, '00', _, _, _, _) => // sve_int_arith_imm0 - __field size 22 +: 2 - __field opc 16 +: 3 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - case (opc) of - when ('000') => __encoding ADD_Z_ZI__ // add_z_zi_ - when ('001') => __encoding SUB_Z_ZI__ // sub_z_zi_ - when ('010') => __UNALLOCATED - when ('011') => __encoding SUBR_Z_ZI__ // subr_z_zi_ - when ('100') => __encoding SQADD_Z_ZI__ // sqadd_z_zi_ - when ('101') => __encoding UQADD_Z_ZI__ // uqadd_z_zi_ - when ('110') => __encoding SQSUB_Z_ZI__ // sqsub_z_zi_ - when ('111') => __encoding UQSUB_Z_ZI__ // uqsub_z_zi_ - when (_, _, _, '01', _, _, _, _) => // sve_int_arith_imm1 - __field size 22 +: 2 - __field opc 16 +: 3 - __field o2 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - case (opc, o2) of - when ('0xx', '1') => __UNALLOCATED - when ('000', '0') => __encoding SMAX_Z_ZI__ // smax_z_zi_ - when ('001', '0') => __encoding UMAX_Z_ZI__ // umax_z_zi_ - when ('010', '0') => __encoding SMIN_Z_ZI__ // smin_z_zi_ - when ('011', '0') => __encoding UMIN_Z_ZI__ // umin_z_zi_ - when ('1xx', _) => __UNALLOCATED - when (_, _, _, '10', _, _, _, _) => // sve_int_arith_imm2 - __field size 22 +: 2 - __field opc 16 +: 3 - __field o2 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - case (opc, o2) of - when ('000', '0') => __encoding MUL_Z_ZI__ // mul_z_zi_ - when ('000', '1') => __UNALLOCATED - when ('001', _) => __UNALLOCATED - when ('01x', _) => __UNALLOCATED - when ('1xx', _) => __UNALLOCATED - when (_, _, _, '11', _, '0', _, _) => // sve_int_dup_imm - __field size 22 +: 2 - __field opc 17 +: 2 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zd 0 +: 5 - case (opc) of - when ('00') => __encoding DUP_Z_I__ // dup_z_i_ - when ('01') => __UNALLOCATED - when ('1x') => __UNALLOCATED - when (_, _, _, '11', _, '1', _, _) => // sve_int_dup_fpimm - __field size 22 +: 2 - __field opc 17 +: 2 - __field o2 13 +: 1 - __field imm8 5 +: 8 - __field Zd 0 +: 5 - case (opc, o2) of - when ('00', '0') => __encoding FDUP_Z_I__ // fdup_z_i_ - when ('00', '1') => __UNALLOCATED - when ('01', _) => __UNALLOCATED - when ('1x', _) => __UNALLOCATED - when ('001', _, '1x', _, '100xx', _, '10xxxx', _) => // sve_int_pcount_pred - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 4 - __field o2 9 +: 1 - __field Pn 5 +: 4 - __field Rd 0 +: 5 - case (opc, o2) of - when ('000', '0') => __encoding CNTP_R_P_P__ // cntp_r_p_p_ - when ('000', '1') => __UNALLOCATED - when ('001', _) => __UNALLOCATED - when ('01x', _) => __UNALLOCATED - when ('1xx', _) => __UNALLOCATED - when ('001', _, '1x', _, '101xx', _, '1000xx', _) => - // sve_pred_count_b - case (24 +: 8, 22 +: 2, 19 +: 3, 18 +: 1, 16 +: 2, 12 +: 4, 11 +: 1, 0 +: 11) of - when (_, _, _, '0', _, _, '0', _) => // sve_int_count_v_sat - __field size 22 +: 2 - __field D 17 +: 1 - __field U 16 +: 1 - __field opc 9 +: 2 - __field Pm 5 +: 4 - __field Zdn 0 +: 5 - case (D, U, opc) of - when (_, _, '01') => __UNALLOCATED - when (_, _, '1x') => __UNALLOCATED - when ('0', '0', '00') => __encoding SQINCP_Z_P_Z__ // sqincp_z_p_z_ - when ('0', '1', '00') => __encoding UQINCP_Z_P_Z__ // uqincp_z_p_z_ - when ('1', '0', '00') => __encoding SQDECP_Z_P_Z__ // sqdecp_z_p_z_ - when ('1', '1', '00') => __encoding UQDECP_Z_P_Z__ // uqdecp_z_p_z_ - when (_, _, _, '0', _, _, '1', _) => // sve_int_count_r_sat - __field size 22 +: 2 - __field D 17 +: 1 - __field U 16 +: 1 - __field sf 10 +: 1 - __field op 9 +: 1 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - case (D, U, sf, op) of - when (_, _, _, '1') => __UNALLOCATED - when ('0', '0', '0', '0') => __encoding SQINCP_R_P_R_SX // sqincp_r_p_r_sx - when ('0', '0', '1', '0') => __encoding SQINCP_R_P_R_X // sqincp_r_p_r_x - when ('0', '1', '0', '0') => __encoding UQINCP_R_P_R_UW // uqincp_r_p_r_uw - when ('0', '1', '1', '0') => __encoding UQINCP_R_P_R_X // uqincp_r_p_r_x - when ('1', '0', '0', '0') => __encoding SQDECP_R_P_R_SX // sqdecp_r_p_r_sx - when ('1', '0', '1', '0') => __encoding SQDECP_R_P_R_X // sqdecp_r_p_r_x - when ('1', '1', '0', '0') => __encoding UQDECP_R_P_R_UW // uqdecp_r_p_r_uw - when ('1', '1', '1', '0') => __encoding UQDECP_R_P_R_X // uqdecp_r_p_r_x - when (_, _, _, '1', _, _, '0', _) => // sve_int_count_v - __field size 22 +: 2 - __field op 17 +: 1 - __field D 16 +: 1 - __field opc2 9 +: 2 - __field Pm 5 +: 4 - __field Zdn 0 +: 5 - case (op, D, opc2) of - when ('0', _, '01') => __UNALLOCATED - when ('0', _, '1x') => __UNALLOCATED - when ('0', '0', '00') => __encoding INCP_Z_P_Z__ // incp_z_p_z_ - when ('0', '1', '00') => __encoding DECP_Z_P_Z__ // decp_z_p_z_ - when ('1', _, _) => __UNALLOCATED - when (_, _, _, '1', _, _, '1', _) => // sve_int_count_r - __field size 22 +: 2 - __field op 17 +: 1 - __field D 16 +: 1 - __field opc2 9 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - case (op, D, opc2) of - when ('0', _, '01') => __UNALLOCATED - when ('0', _, '1x') => __UNALLOCATED - when ('0', '0', '00') => __encoding INCP_R_P_R__ // incp_r_p_r_ - when ('0', '1', '00') => __encoding DECP_R_P_R__ // decp_r_p_r_ - when ('1', _, _) => __UNALLOCATED - when ('001', _, '1x', _, '101xx', _, '1001xx', _) => - // sve_pred_wrffr - case (24 +: 8, 22 +: 2, 19 +: 3, 18 +: 1, 16 +: 2, 12 +: 4, 9 +: 3, 5 +: 4, 0 +: 5) of - when (_, _, _, '0', '00', _, '000', _, '00000') => // sve_int_wrffr - __field opc 22 +: 2 - __field Pn 5 +: 4 - case (opc) of - when ('00') => __encoding WRFFR_F_P__ // wrffr_f_p_ - when ('01') => __UNALLOCATED - when ('1x') => __UNALLOCATED - when (_, _, _, '1', '00', _, '000', '0000', '00000') => // sve_int_setffr - __field opc 22 +: 2 - case (opc) of - when ('00') => __encoding SETFFR_F__ // setffr_f_ - when ('01') => __UNALLOCATED - when ('1x') => __UNALLOCATED - when (_, _, _, '1', '00', _, '000', '1xxx', '00000') => __UNPREDICTABLE - when (_, _, _, '1', '00', _, '000', 'x1xx', '00000') => __UNPREDICTABLE - when (_, _, _, '1', '00', _, '000', 'xx1x', '00000') => __UNPREDICTABLE - when (_, _, _, '1', '00', _, '000', 'xxx1', '00000') => __UNPREDICTABLE - when (_, _, _, _, '00', _, '000', _, !'00000') => __UNPREDICTABLE - when (_, _, _, _, '00', _, !'000', _, _) => __UNPREDICTABLE - when (_, _, _, _, !'00', _, _, _, _) => __UNPREDICTABLE - when ('001', _, '1x', _, '101xx', _, '101xxx', _) => __UNPREDICTABLE - when ('001', _, '1x', _, '11xxx', _, '10xxxx', _) => __UNPREDICTABLE - when ('010', _, '0x', _, '0xxxx', _, '0xxxxx', _) => - // sve_intx_muladd_unpred - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 15 +: 1, 14 +: 1, 11 +: 3, 10 +: 1, 0 +: 10) of - when (_, _, _, _, _, '0', '000', _, _) => // sve_intx_dot - __field size 22 +: 2 - __field Zm 16 +: 5 - __field U 10 +: 1 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (U) of - when ('0') => __encoding SDOT_Z_ZZZ__ // sdot_z_zzz_ - when ('1') => __encoding UDOT_Z_ZZZ__ // udot_z_zzz_ - when (_, _, _, _, _, '0', !'000', _, _) => __UNPREDICTABLE - when (_, _, _, _, _, '1', '0xx', _, _) => __UNPREDICTABLE - when (_, _, _, _, _, '1', '10x', _, _) => __UNPREDICTABLE - when (_, _, _, _, _, '1', '110', _, _) => __UNPREDICTABLE - when (_, _, _, _, _, '1', '111', '0', _) => // sve_intx_mixed_dot - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (size) of - when ('0x') => __UNALLOCATED - when ('10') => __encoding USDOT_Z_ZZZ_S // usdot_z_zzz_s - when ('11') => __UNALLOCATED - when (_, _, _, _, _, '1', '111', '1', _) => __UNPREDICTABLE - when ('010', _, '0x', _, '0xxxx', _, '1xxxxx', _) => __UNPREDICTABLE - when ('010', _, '0x', _, '1xxxx', _, _, _) => - // sve_intx_by_indexed_elem - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 13 +: 3, 11 +: 2, 0 +: 11) of - when (_, _, _, _, '000', '00', _) => // sve_intx_dot_by_indexed_elem - __field size 22 +: 2 - __field opc 16 +: 5 - __field U 10 +: 1 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (size, U) of - when ('0x', _) => __UNALLOCATED - when ('10', '0') => __encoding SDOT_Z_ZZZi_S // sdot_z_zzzi_s - when ('10', '1') => __encoding UDOT_Z_ZZZi_S // udot_z_zzzi_s - when ('11', '0') => __encoding SDOT_Z_ZZZi_D // sdot_z_zzzi_d - when ('11', '1') => __encoding UDOT_Z_ZZZi_D // udot_z_zzzi_d - when (_, _, _, _, '000', '01', _) => __UNPREDICTABLE - when (_, _, _, _, '000', '10', _) => __UNPREDICTABLE - when (_, _, _, _, '000', '11', _) => // sve_intx_mixed_dot_by_indexed_elem - __field size 22 +: 2 - __field opc 16 +: 5 - __field U 10 +: 1 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (size, U) of - when ('0x', _) => __UNALLOCATED - when ('10', '0') => __encoding USDOT_Z_ZZZi_S // usdot_z_zzzi_s - when ('10', '1') => __encoding SUDOT_Z_ZZZi_S // sudot_z_zzzi_s - when ('11', _) => __UNALLOCATED - when (_, _, _, _, !'000', _, _) => __UNPREDICTABLE - when ('010', _, '1x', _, '0xxxx', _, '0xxxxx', _) => __UNPREDICTABLE - when ('010', _, '1x', _, '0xxxx', _, '10xxxx', _) => - // sve_intx_constructive - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 14 +: 2, 10 +: 4, 0 +: 10) of - when (_, _, _, _, _, '00xx', _) => __UNPREDICTABLE - when (_, _, _, _, _, '010x', _) => __UNPREDICTABLE - when (_, _, _, _, _, '0110', _) => // sve_intx_mmla - __field uns 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (uns) of - when ('00') => __encoding SMMLA_Z_ZZZ__ // smmla_z_zzz_ - when ('01') => __UNALLOCATED - when ('10') => __encoding USMMLA_Z_ZZZ__ // usmmla_z_zzz_ - when ('11') => __encoding UMMLA_Z_ZZZ__ // ummla_z_zzz_ - when (_, _, _, _, _, '0111', _) => __UNPREDICTABLE - when (_, _, _, _, _, '1xxx', _) => __UNPREDICTABLE - when ('010', _, '1x', _, '0xxxx', _, '11xxxx', _) => __UNPREDICTABLE - when ('010', _, '1x', _, '1xxxx', _, _, _) => __UNPREDICTABLE - when ('011', _, '0x', _, '0xxxx', _, '0xxxxx', _) => // sve_fp_fcmla - __field size 22 +: 2 - __field Zm 16 +: 5 - __field rot 13 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case () of - when () => __encoding FCMLA_Z_P_ZZZ__ // fcmla_z_p_zzz_ - when ('011', _, '0x', _, '00x1x', _, '1xxxxx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '00000', _, '100xxx', _) => // sve_fp_fcadd - __field size 22 +: 2 - __field rot 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case () of - when () => __encoding FCADD_Z_P_ZZ__ // fcadd_z_p_zz_ - when ('011', _, '0x', _, '00000', _, '101xxx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '00000', _, '11xxxx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '00001', _, '1xxxxx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '0010x', _, '100xxx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '0010x', _, '101xxx', _) => // sve_fp_fcvt2 - __field opc 22 +: 2 - __field opc2 16 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc, opc2) of - when ('0x', _) => __UNALLOCATED - when ('10', '0x') => __UNALLOCATED - when ('10', '10') => __encoding BFCVTNT_Z_P_Z_S2BF // bfcvtnt_z_p_z_s2bf - when ('10', '11') => __UNALLOCATED - when ('11', _) => __UNALLOCATED - when ('011', _, '0x', _, '0010x', _, '11xxxx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '01xxx', _, '1xxxxx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '1xxxx', _, 'x0x01x', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '1xxxx', _, '00000x', _) => // sve_fp_fma_by_indexed_elem - __field size 22 +: 2 - __field opc 16 +: 5 - __field op 10 +: 1 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (size, op) of - when ('0x', '0') => __encoding FMLA_Z_ZZZi_H // fmla_z_zzzi_h - when ('0x', '1') => __encoding FMLS_Z_ZZZi_H // fmls_z_zzzi_h - when ('10', '0') => __encoding FMLA_Z_ZZZi_S // fmla_z_zzzi_s - when ('10', '1') => __encoding FMLS_Z_ZZZi_S // fmls_z_zzzi_s - when ('11', '0') => __encoding FMLA_Z_ZZZi_D // fmla_z_zzzi_d - when ('11', '1') => __encoding FMLS_Z_ZZZi_D // fmls_z_zzzi_d - when ('011', _, '0x', _, '1xxxx', _, '0001xx', _) => // sve_fp_fcmla_by_indexed_elem - __field size 22 +: 2 - __field opc 16 +: 5 - __field rot 10 +: 2 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (size) of - when ('0x') => __UNALLOCATED - when ('10') => __encoding FCMLA_Z_ZZZi_H // fcmla_z_zzzi_h - when ('11') => __encoding FCMLA_Z_ZZZi_S // fcmla_z_zzzi_s - when ('011', _, '0x', _, '1xxxx', _, '001000', _) => // sve_fp_fmul_by_indexed_elem - __field size 22 +: 2 - __field opc 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (size) of - when ('0x') => __encoding FMUL_Z_ZZi_H // fmul_z_zzi_h - when ('10') => __encoding FMUL_Z_ZZi_S // fmul_z_zzi_s - when ('11') => __encoding FMUL_Z_ZZi_D // fmul_z_zzi_d - when ('011', _, '0x', _, '1xxxx', _, '001001', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '1xxxx', _, '0011xx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '1xxxx', _, '01x0xx', _) => - // sve_fp_fma_long_by_indexed_elem - case (24 +: 8, 23 +: 1, 22 +: 1, 21 +: 1, 16 +: 5, 14 +: 2, 13 +: 1, 12 +: 1, 10 +: 2, 0 +: 10) of - when (_, '0', _, _, _, _, '0', _, '00', _) => // sve_fp_fdot_by_indexed_elem - __field op 22 +: 1 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (op) of - when ('0') => __UNALLOCATED - when ('1') => __encoding BFDOT_Z_ZZZi__ // bfdot_z_zzzi_ - when (_, '0', _, _, _, _, '0', _, !'00', _) => __UNPREDICTABLE - when (_, '0', _, _, _, _, '1', _, _, _) => __UNPREDICTABLE - when (_, '1', _, _, _, _, _, _, _, _) => // sve_fp_fma_long_by_indexed_elem - __field o2 22 +: 1 - __field i3h 19 +: 2 - __field Zm 16 +: 3 - __field op 13 +: 1 - __field i3l 11 +: 1 - __field T 10 +: 1 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (o2, op, T) of - when ('0', _, _) => __UNALLOCATED - when ('1', '0', '0') => __encoding BFMLALB_Z_ZZZi__ // bfmlalb_z_zzzi_ - when ('1', '0', '1') => __encoding BFMLALT_Z_ZZZi__ // bfmlalt_z_zzzi_ - when ('1', '1', _) => __UNALLOCATED - when ('011', _, '0x', _, '1xxxx', _, '01x1xx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '1xxxx', _, '10x00x', _) => - // sve_fp_fma_long - case (24 +: 8, 23 +: 1, 22 +: 1, 21 +: 1, 16 +: 5, 14 +: 2, 13 +: 1, 11 +: 2, 10 +: 1, 0 +: 10) of - when (_, '0', _, _, _, _, '0', _, '0', _) => // sve_fp_fdot - __field op 22 +: 1 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (op) of - when ('0') => __UNALLOCATED - when ('1') => __encoding BFDOT_Z_ZZZ__ // bfdot_z_zzz_ - when (_, '0', _, _, _, _, '0', _, '1', _) => __UNPREDICTABLE - when (_, '0', _, _, _, _, '1', _, _, _) => __UNPREDICTABLE - when (_, '1', _, _, _, _, _, _, _, _) => // sve_fp_fma_long - __field o2 22 +: 1 - __field Zm 16 +: 5 - __field op 13 +: 1 - __field T 10 +: 1 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (o2, op, T) of - when ('0', _, _) => __UNALLOCATED - when ('1', '0', '0') => __encoding BFMLALB_Z_ZZZ__ // bfmlalb_z_zzz_ - when ('1', '0', '1') => __encoding BFMLALT_Z_ZZZ__ // bfmlalt_z_zzz_ - when ('1', '1', _) => __UNALLOCATED - when ('011', _, '0x', _, '1xxxx', _, '10x1xx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '1xxxx', _, '110xxx', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '1xxxx', _, '111000', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '1xxxx', _, '111001', _) => // sve_fp_fmmla - __field opc 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (opc) of - when ('00') => __UNALLOCATED - when ('01') => __encoding BFMMLA_Z_ZZZ__ // bfmmla_z_zzz_ - when ('10') => __encoding FMMLA_Z_ZZZ_S // fmmla_z_zzz_s - when ('11') => __encoding FMMLA_Z_ZZZ_D // fmmla_z_zzz_d - when ('011', _, '0x', _, '1xxxx', _, '11101x', _) => __UNPREDICTABLE - when ('011', _, '0x', _, '1xxxx', _, '1111xx', _) => __UNPREDICTABLE - when ('011', _, '1x', _, '0xxxx', _, 'x1xxxx', _) => // sve_fp_3op_p_pd - __field size 22 +: 2 - __field Zm 16 +: 5 - __field op 15 +: 1 - __field o2 13 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field o3 4 +: 1 - __field Pd 0 +: 4 - case (op, o2, o3) of - when ('0', '0', '0') => __encoding FCMGE_P_P_ZZ__ // fcmge_p_p_zz_ - when ('0', '0', '1') => __encoding FCMGT_P_P_ZZ__ // fcmgt_p_p_zz_ - when ('0', '1', '0') => __encoding FCMEQ_P_P_ZZ__ // fcmeq_p_p_zz_ - when ('0', '1', '1') => __encoding FCMNE_P_P_ZZ__ // fcmne_p_p_zz_ - when ('1', '0', '0') => __encoding FCMUO_P_P_ZZ__ // fcmuo_p_p_zz_ - when ('1', '0', '1') => __encoding FACGE_P_P_ZZ__ // facge_p_p_zz_ - when ('1', '1', '0') => __UNALLOCATED - when ('1', '1', '1') => __encoding FACGT_P_P_ZZ__ // facgt_p_p_zz_ - when ('011', _, '1x', _, '0xxxx', _, '000xxx', _) => // sve_fp_3op_u_zd - __field size 22 +: 2 - __field Zm 16 +: 5 - __field opc 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('000') => __encoding FADD_Z_ZZ__ // fadd_z_zz_ - when ('001') => __encoding FSUB_Z_ZZ__ // fsub_z_zz_ - when ('010') => __encoding FMUL_Z_ZZ__ // fmul_z_zz_ - when ('011') => __encoding FTSMUL_Z_ZZ__ // ftsmul_z_zz_ - when ('10x') => __UNALLOCATED - when ('110') => __encoding FRECPS_Z_ZZ__ // frecps_z_zz_ - when ('111') => __encoding FRSQRTS_Z_ZZ__ // frsqrts_z_zz_ - when ('011', _, '1x', _, '0xxxx', _, '100xxx', _) => - // sve_fp_pred - case (24 +: 8, 22 +: 2, 21 +: 1, 19 +: 2, 16 +: 3, 13 +: 3, 10 +: 3, 6 +: 4, 0 +: 6) of - when (_, _, _, '0x', _, _, _, _, _) => // sve_fp_2op_p_zds - __field size 22 +: 2 - __field opc 16 +: 4 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (opc) of - when ('0000') => __encoding FADD_Z_P_ZZ__ // fadd_z_p_zz_ - when ('0001') => __encoding FSUB_Z_P_ZZ__ // fsub_z_p_zz_ - when ('0010') => __encoding FMUL_Z_P_ZZ__ // fmul_z_p_zz_ - when ('0011') => __encoding FSUBR_Z_P_ZZ__ // fsubr_z_p_zz_ - when ('0100') => __encoding FMAXNM_Z_P_ZZ__ // fmaxnm_z_p_zz_ - when ('0101') => __encoding FMINNM_Z_P_ZZ__ // fminnm_z_p_zz_ - when ('0110') => __encoding FMAX_Z_P_ZZ__ // fmax_z_p_zz_ - when ('0111') => __encoding FMIN_Z_P_ZZ__ // fmin_z_p_zz_ - when ('1000') => __encoding FABD_Z_P_ZZ__ // fabd_z_p_zz_ - when ('1001') => __encoding FSCALE_Z_P_ZZ__ // fscale_z_p_zz_ - when ('1010') => __encoding FMULX_Z_P_ZZ__ // fmulx_z_p_zz_ - when ('1011') => __UNALLOCATED - when ('1100') => __encoding FDIVR_Z_P_ZZ__ // fdivr_z_p_zz_ - when ('1101') => __encoding FDIV_Z_P_ZZ__ // fdiv_z_p_zz_ - when ('111x') => __UNALLOCATED - when (_, _, _, '10', _, _, '000', _, _) => // sve_fp_ftmad - __field size 22 +: 2 - __field imm3 16 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case () of - when () => __encoding FTMAD_Z_ZZI__ // ftmad_z_zzi_ - when (_, _, _, '10', _, _, !'000', _, _) => __UNPREDICTABLE - when (_, _, _, '11', _, _, _, '0000', _) => // sve_fp_2op_i_p_zds - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 3 - __field i1 5 +: 1 - __field Zdn 0 +: 5 - case (opc) of - when ('000') => __encoding FADD_Z_P_ZS__ // fadd_z_p_zs_ - when ('001') => __encoding FSUB_Z_P_ZS__ // fsub_z_p_zs_ - when ('010') => __encoding FMUL_Z_P_ZS__ // fmul_z_p_zs_ - when ('011') => __encoding FSUBR_Z_P_ZS__ // fsubr_z_p_zs_ - when ('100') => __encoding FMAXNM_Z_P_ZS__ // fmaxnm_z_p_zs_ - when ('101') => __encoding FMINNM_Z_P_ZS__ // fminnm_z_p_zs_ - when ('110') => __encoding FMAX_Z_P_ZS__ // fmax_z_p_zs_ - when ('111') => __encoding FMIN_Z_P_ZS__ // fmin_z_p_zs_ - when (_, _, _, '11', _, _, _, !'0000', _) => __UNPREDICTABLE - when ('011', _, '1x', _, '0xxxx', _, '101xxx', _) => - // sve_fp_unary - case (24 +: 8, 22 +: 2, 21 +: 1, 18 +: 3, 16 +: 2, 13 +: 3, 0 +: 13) of - when (_, _, _, '00x', _, _, _) => // sve_fp_2op_p_zd_a - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('000') => __encoding FRINTN_Z_P_Z__ // frintn_z_p_z_ - when ('001') => __encoding FRINTP_Z_P_Z__ // frintp_z_p_z_ - when ('010') => __encoding FRINTM_Z_P_Z__ // frintm_z_p_z_ - when ('011') => __encoding FRINTZ_Z_P_Z__ // frintz_z_p_z_ - when ('100') => __encoding FRINTA_Z_P_Z__ // frinta_z_p_z_ - when ('101') => __UNALLOCATED - when ('110') => __encoding FRINTX_Z_P_Z__ // frintx_z_p_z_ - when ('111') => __encoding FRINTI_Z_P_Z__ // frinti_z_p_z_ - when (_, _, _, '010', _, _, _) => // sve_fp_2op_p_zd_b_0 - __field opc 22 +: 2 - __field opc2 16 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc, opc2) of - when ('0x', _) => __UNALLOCATED - when ('10', '00') => __encoding FCVT_Z_P_Z_S2H // fcvt_z_p_z_s2h - when ('10', '01') => __encoding FCVT_Z_P_Z_H2S // fcvt_z_p_z_h2s - when ('10', '10') => __encoding BFCVT_Z_P_Z_S2BF // bfcvt_z_p_z_s2bf - when ('10', '11') => __UNALLOCATED - when ('11', '00') => __encoding FCVT_Z_P_Z_D2H // fcvt_z_p_z_d2h - when ('11', '01') => __encoding FCVT_Z_P_Z_H2D // fcvt_z_p_z_h2d - when ('11', '10') => __encoding FCVT_Z_P_Z_D2S // fcvt_z_p_z_d2s - when ('11', '11') => __encoding FCVT_Z_P_Z_S2D // fcvt_z_p_z_s2d - when (_, _, _, '011', _, _, _) => // sve_fp_2op_p_zd_b_1 - __field size 22 +: 2 - __field opc 16 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('00') => __encoding FRECPX_Z_P_Z__ // frecpx_z_p_z_ - when ('01') => __encoding FSQRT_Z_P_Z__ // fsqrt_z_p_z_ - when ('1x') => __UNALLOCATED - when (_, _, _, '10x', _, _, _) => // sve_fp_2op_p_zd_c - __field opc 22 +: 2 - __field opc2 17 +: 2 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc, opc2, U) of - when ('00', _, _) => __UNALLOCATED - when ('01', '00', _) => __UNALLOCATED - when ('01', '01', '0') => __encoding SCVTF_Z_P_Z_H2FP16 // scvtf_z_p_z_h2fp16 - when ('01', '01', '1') => __encoding UCVTF_Z_P_Z_H2FP16 // ucvtf_z_p_z_h2fp16 - when ('01', '10', '0') => __encoding SCVTF_Z_P_Z_W2FP16 // scvtf_z_p_z_w2fp16 - when ('01', '10', '1') => __encoding UCVTF_Z_P_Z_W2FP16 // ucvtf_z_p_z_w2fp16 - when ('01', '11', '0') => __encoding SCVTF_Z_P_Z_X2FP16 // scvtf_z_p_z_x2fp16 - when ('01', '11', '1') => __encoding UCVTF_Z_P_Z_X2FP16 // ucvtf_z_p_z_x2fp16 - when ('10', '0x', _) => __UNALLOCATED - when ('10', '10', '0') => __encoding SCVTF_Z_P_Z_W2S // scvtf_z_p_z_w2s - when ('10', '10', '1') => __encoding UCVTF_Z_P_Z_W2S // ucvtf_z_p_z_w2s - when ('10', '11', _) => __UNALLOCATED - when ('11', '00', '0') => __encoding SCVTF_Z_P_Z_W2D // scvtf_z_p_z_w2d - when ('11', '00', '1') => __encoding UCVTF_Z_P_Z_W2D // ucvtf_z_p_z_w2d - when ('11', '01', _) => __UNALLOCATED - when ('11', '10', '0') => __encoding SCVTF_Z_P_Z_X2S // scvtf_z_p_z_x2s - when ('11', '10', '1') => __encoding UCVTF_Z_P_Z_X2S // ucvtf_z_p_z_x2s - when ('11', '11', '0') => __encoding SCVTF_Z_P_Z_X2D // scvtf_z_p_z_x2d - when ('11', '11', '1') => __encoding UCVTF_Z_P_Z_X2D // ucvtf_z_p_z_x2d - when (_, _, _, '11x', _, _, _) => // sve_fp_2op_p_zd_d - __field opc 22 +: 2 - __field opc2 17 +: 2 - __field U 16 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc, opc2, U) of - when ('00', _, _) => __UNALLOCATED - when ('01', '00', _) => __UNALLOCATED - when ('01', '01', '0') => __encoding FCVTZS_Z_P_Z_FP162H // fcvtzs_z_p_z_fp162h - when ('01', '01', '1') => __encoding FCVTZU_Z_P_Z_FP162H // fcvtzu_z_p_z_fp162h - when ('01', '10', '0') => __encoding FCVTZS_Z_P_Z_FP162W // fcvtzs_z_p_z_fp162w - when ('01', '10', '1') => __encoding FCVTZU_Z_P_Z_FP162W // fcvtzu_z_p_z_fp162w - when ('01', '11', '0') => __encoding FCVTZS_Z_P_Z_FP162X // fcvtzs_z_p_z_fp162x - when ('01', '11', '1') => __encoding FCVTZU_Z_P_Z_FP162X // fcvtzu_z_p_z_fp162x - when ('10', '0x', _) => __UNALLOCATED - when ('10', '10', '0') => __encoding FCVTZS_Z_P_Z_S2W // fcvtzs_z_p_z_s2w - when ('10', '10', '1') => __encoding FCVTZU_Z_P_Z_S2W // fcvtzu_z_p_z_s2w - when ('10', '11', _) => __UNALLOCATED - when ('11', '00', '0') => __encoding FCVTZS_Z_P_Z_D2W // fcvtzs_z_p_z_d2w - when ('11', '00', '1') => __encoding FCVTZU_Z_P_Z_D2W // fcvtzu_z_p_z_d2w - when ('11', '01', _) => __UNALLOCATED - when ('11', '10', '0') => __encoding FCVTZS_Z_P_Z_S2X // fcvtzs_z_p_z_s2x - when ('11', '10', '1') => __encoding FCVTZU_Z_P_Z_S2X // fcvtzu_z_p_z_s2x - when ('11', '11', '0') => __encoding FCVTZS_Z_P_Z_D2X // fcvtzs_z_p_z_d2x - when ('11', '11', '1') => __encoding FCVTZU_Z_P_Z_D2X // fcvtzu_z_p_z_d2x - when ('011', _, '1x', _, '000xx', _, '001xxx', _) => // sve_fp_fast_red - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - case (opc) of - when ('000') => __encoding FADDV_V_P_Z__ // faddv_v_p_z_ - when ('001') => __UNALLOCATED - when ('01x') => __UNALLOCATED - when ('100') => __encoding FMAXNMV_V_P_Z__ // fmaxnmv_v_p_z_ - when ('101') => __encoding FMINNMV_V_P_Z__ // fminnmv_v_p_z_ - when ('110') => __encoding FMAXV_V_P_Z__ // fmaxv_v_p_z_ - when ('111') => __encoding FMINV_V_P_Z__ // fminv_v_p_z_ - when ('011', _, '1x', _, '001xx', _, '0010xx', _) => __UNPREDICTABLE - when ('011', _, '1x', _, '001xx', _, '0011xx', _) => - // sve_fp_unary_unpred - case (24 +: 8, 22 +: 2, 19 +: 3, 16 +: 3, 12 +: 4, 10 +: 2, 0 +: 10) of - when (_, _, _, _, _, '00', _) => // sve_fp_2op_u_zd - __field size 22 +: 2 - __field opc 16 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - case (opc) of - when ('0xx') => __UNALLOCATED - when ('10x') => __UNALLOCATED - when ('110') => __encoding FRECPE_Z_Z__ // frecpe_z_z_ - when ('111') => __encoding FRSQRTE_Z_Z__ // frsqrte_z_z_ - when (_, _, _, _, _, !'00', _) => __UNPREDICTABLE - when ('011', _, '1x', _, '010xx', _, '001xxx', _) => - // sve_fp_cmpzero - case (24 +: 8, 22 +: 2, 19 +: 3, 18 +: 1, 16 +: 2, 13 +: 3, 0 +: 13) of - when (_, _, _, '0', _, _, _) => // sve_fp_2op_p_pd - __field size 22 +: 2 - __field eq 17 +: 1 - __field lt 16 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field ne 4 +: 1 - __field Pd 0 +: 4 - case (eq, lt, ne) of - when ('0', '0', '0') => __encoding FCMGE_P_P_Z0__ // fcmge_p_p_z0_ - when ('0', '0', '1') => __encoding FCMGT_P_P_Z0__ // fcmgt_p_p_z0_ - when ('0', '1', '0') => __encoding FCMLT_P_P_Z0__ // fcmlt_p_p_z0_ - when ('0', '1', '1') => __encoding FCMLE_P_P_Z0__ // fcmle_p_p_z0_ - when ('1', _, '1') => __UNALLOCATED - when ('1', '0', '0') => __encoding FCMEQ_P_P_Z0__ // fcmeq_p_p_z0_ - when ('1', '1', '0') => __encoding FCMNE_P_P_Z0__ // fcmne_p_p_z0_ - when (_, _, _, '1', _, _, _) => __UNPREDICTABLE - when ('011', _, '1x', _, '011xx', _, '001xxx', _) => // sve_fp_2op_p_vd - __field size 22 +: 2 - __field opc 16 +: 3 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Vdn 0 +: 5 - case (opc) of - when ('000') => __encoding FADDA_V_P_Z__ // fadda_v_p_z_ - when ('001') => __UNALLOCATED - when ('01x') => __UNALLOCATED - when ('1xx') => __UNALLOCATED - when ('011', _, '1x', _, '1xxxx', _, _, _) => - // sve_fp_fma - case (24 +: 8, 22 +: 2, 21 +: 1, 16 +: 5, 15 +: 1, 0 +: 15) of - when (_, _, _, _, '0', _) => // sve_fp_3op_p_zds_a - __field size 22 +: 2 - __field Zm 16 +: 5 - __field opc 13 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - case (opc) of - when ('00') => __encoding FMLA_Z_P_ZZZ__ // fmla_z_p_zzz_ - when ('01') => __encoding FMLS_Z_P_ZZZ__ // fmls_z_p_zzz_ - when ('10') => __encoding FNMLA_Z_P_ZZZ__ // fnmla_z_p_zzz_ - when ('11') => __encoding FNMLS_Z_P_ZZZ__ // fnmls_z_p_zzz_ - when (_, _, _, _, '1', _) => // sve_fp_3op_p_zds_b - __field size 22 +: 2 - __field Za 16 +: 5 - __field opc 13 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - case (opc) of - when ('00') => __encoding FMAD_Z_P_ZZZ__ // fmad_z_p_zzz_ - when ('01') => __encoding FMSB_Z_P_ZZZ__ // fmsb_z_p_zzz_ - when ('10') => __encoding FNMAD_Z_P_ZZZ__ // fnmad_z_p_zzz_ - when ('11') => __encoding FNMSB_Z_P_ZZZ__ // fnmsb_z_p_zzz_ - when ('100', _, _, _, _, _, _, _) => - // sve_mem32 - case (25 +: 7, 23 +: 2, 21 +: 2, 16 +: 5, 13 +: 3, 5 +: 8, 4 +: 1, 0 +: 4) of - when (_, '00', 'x1', _, '0xx', _, '0', _) => // sve_mem_32b_prfm_sv - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field msz 13 +: 2 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - case (msz) of - when ('00') => __encoding PRFB_I_P_BZ_S_x32_scaled // prfb_i_p_bz_s_x32_scaled - when ('01') => __encoding PRFH_I_P_BZ_S_x32_scaled // prfh_i_p_bz_s_x32_scaled - when ('10') => __encoding PRFW_I_P_BZ_S_x32_scaled // prfw_i_p_bz_s_x32_scaled - when ('11') => __encoding PRFD_I_P_BZ_S_x32_scaled // prfd_i_p_bz_s_x32_scaled - when (_, '00', 'x1', _, '0xx', _, '1', _) => __UNPREDICTABLE - when (_, '01', 'x1', _, '0xx', _, _, _) => // sve_mem_32b_gld_sv_a - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field U 14 +: 1 - __field ff 13 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (U, ff) of - when ('0', '0') => __encoding LD1SH_Z_P_BZ_S_x32_scaled // ld1sh_z_p_bz_s_x32_scaled - when ('0', '1') => __encoding LDFF1SH_Z_P_BZ_S_x32_scaled // ldff1sh_z_p_bz_s_x32_scaled - when ('1', '0') => __encoding LD1H_Z_P_BZ_S_x32_scaled // ld1h_z_p_bz_s_x32_scaled - when ('1', '1') => __encoding LDFF1H_Z_P_BZ_S_x32_scaled // ldff1h_z_p_bz_s_x32_scaled - when (_, '10', 'x1', _, '0xx', _, _, _) => // sve_mem_32b_gld_sv_b - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field U 14 +: 1 - __field ff 13 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (U, ff) of - when ('0', _) => __UNALLOCATED - when ('1', '0') => __encoding LD1W_Z_P_BZ_S_x32_scaled // ld1w_z_p_bz_s_x32_scaled - when ('1', '1') => __encoding LDFF1W_Z_P_BZ_S_x32_scaled // ldff1w_z_p_bz_s_x32_scaled - when (_, '11', '0x', _, '000', _, '0', _) => // sve_mem_32b_pfill - __field imm9h 16 +: 6 - __field imm9l 10 +: 3 - __field Rn 5 +: 5 - __field Pt 0 +: 4 - case () of - when () => __encoding LDR_P_BI__ // ldr_p_bi_ - when (_, '11', '0x', _, '000', _, '1', _) => __UNPREDICTABLE - when (_, '11', '0x', _, '010', _, _, _) => // sve_mem_32b_fill - __field imm9h 16 +: 6 - __field imm9l 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case () of - when () => __encoding LDR_Z_BI__ // ldr_z_bi_ - when (_, '11', '0x', _, '0x1', _, _, _) => __UNPREDICTABLE - when (_, '11', '1x', _, '0xx', _, '0', _) => // sve_mem_prfm_si - __field imm6 16 +: 6 - __field msz 13 +: 2 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - case (msz) of - when ('00') => __encoding PRFB_I_P_BI_S // prfb_i_p_bi_s - when ('01') => __encoding PRFH_I_P_BI_S // prfh_i_p_bi_s - when ('10') => __encoding PRFW_I_P_BI_S // prfw_i_p_bi_s - when ('11') => __encoding PRFD_I_P_BI_S // prfd_i_p_bi_s - when (_, '11', '1x', _, '0xx', _, '1', _) => __UNPREDICTABLE - when (_, !'11', 'x0', _, '0xx', _, _, _) => // sve_mem_32b_gld_vs - __field opc 23 +: 2 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field U 14 +: 1 - __field ff 13 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (opc, U, ff) of - when ('00', '0', '0') => __encoding LD1SB_Z_P_BZ_S_x32_unscaled // ld1sb_z_p_bz_s_x32_unscaled - when ('00', '0', '1') => __encoding LDFF1SB_Z_P_BZ_S_x32_unscaled // ldff1sb_z_p_bz_s_x32_unscaled - when ('00', '1', '0') => __encoding LD1B_Z_P_BZ_S_x32_unscaled // ld1b_z_p_bz_s_x32_unscaled - when ('00', '1', '1') => __encoding LDFF1B_Z_P_BZ_S_x32_unscaled // ldff1b_z_p_bz_s_x32_unscaled - when ('01', '0', '0') => __encoding LD1SH_Z_P_BZ_S_x32_unscaled // ld1sh_z_p_bz_s_x32_unscaled - when ('01', '0', '1') => __encoding LDFF1SH_Z_P_BZ_S_x32_unscaled // ldff1sh_z_p_bz_s_x32_unscaled - when ('01', '1', '0') => __encoding LD1H_Z_P_BZ_S_x32_unscaled // ld1h_z_p_bz_s_x32_unscaled - when ('01', '1', '1') => __encoding LDFF1H_Z_P_BZ_S_x32_unscaled // ldff1h_z_p_bz_s_x32_unscaled - when ('10', '0', _) => __UNALLOCATED - when ('10', '1', '0') => __encoding LD1W_Z_P_BZ_S_x32_unscaled // ld1w_z_p_bz_s_x32_unscaled - when ('10', '1', '1') => __encoding LDFF1W_Z_P_BZ_S_x32_unscaled // ldff1w_z_p_bz_s_x32_unscaled - when (_, _, '00', _, '10x', _, _, _) => __UNPREDICTABLE - when (_, _, '00', _, '110', _, '0', _) => // sve_mem_prfm_ss - __field msz 23 +: 2 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - case (msz) of - when ('00') => __encoding PRFB_I_P_BR_S // prfb_i_p_br_s - when ('01') => __encoding PRFH_I_P_BR_S // prfh_i_p_br_s - when ('10') => __encoding PRFW_I_P_BR_S // prfw_i_p_br_s - when ('11') => __encoding PRFD_I_P_BR_S // prfd_i_p_br_s - when (_, _, '00', _, '111', _, '0', _) => // sve_mem_32b_prfm_vi - __field msz 23 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - case (msz) of - when ('00') => __encoding PRFB_I_P_AI_S // prfb_i_p_ai_s - when ('01') => __encoding PRFH_I_P_AI_S // prfh_i_p_ai_s - when ('10') => __encoding PRFW_I_P_AI_S // prfw_i_p_ai_s - when ('11') => __encoding PRFD_I_P_AI_S // prfd_i_p_ai_s - when (_, _, '00', _, '11x', _, '1', _) => __UNPREDICTABLE - when (_, _, '01', _, '1xx', _, _, _) => // sve_mem_32b_gld_vi - __field msz 23 +: 2 - __field imm5 16 +: 5 - __field U 14 +: 1 - __field ff 13 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - case (msz, U, ff) of - when ('00', '0', '0') => __encoding LD1SB_Z_P_AI_S // ld1sb_z_p_ai_s - when ('00', '0', '1') => __encoding LDFF1SB_Z_P_AI_S // ldff1sb_z_p_ai_s - when ('00', '1', '0') => __encoding LD1B_Z_P_AI_S // ld1b_z_p_ai_s - when ('00', '1', '1') => __encoding LDFF1B_Z_P_AI_S // ldff1b_z_p_ai_s - when ('01', '0', '0') => __encoding LD1SH_Z_P_AI_S // ld1sh_z_p_ai_s - when ('01', '0', '1') => __encoding LDFF1SH_Z_P_AI_S // ldff1sh_z_p_ai_s - when ('01', '1', '0') => __encoding LD1H_Z_P_AI_S // ld1h_z_p_ai_s - when ('01', '1', '1') => __encoding LDFF1H_Z_P_AI_S // ldff1h_z_p_ai_s - when ('10', '0', _) => __UNALLOCATED - when ('10', '1', '0') => __encoding LD1W_Z_P_AI_S // ld1w_z_p_ai_s - when ('10', '1', '1') => __encoding LDFF1W_Z_P_AI_S // ldff1w_z_p_ai_s - when ('11', _, _) => __UNALLOCATED - when (_, _, '1x', _, '1xx', _, _, _) => // sve_mem_ld_dup - __field dtypeh 23 +: 2 - __field imm6 16 +: 6 - __field dtypel 13 +: 2 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (dtypeh, dtypel) of - when ('00', '00') => __encoding LD1RB_Z_P_BI_U8 // ld1rb_z_p_bi_u8 - when ('00', '01') => __encoding LD1RB_Z_P_BI_U16 // ld1rb_z_p_bi_u16 - when ('00', '10') => __encoding LD1RB_Z_P_BI_U32 // ld1rb_z_p_bi_u32 - when ('00', '11') => __encoding LD1RB_Z_P_BI_U64 // ld1rb_z_p_bi_u64 - when ('01', '00') => __encoding LD1RSW_Z_P_BI_S64 // ld1rsw_z_p_bi_s64 - when ('01', '01') => __encoding LD1RH_Z_P_BI_U16 // ld1rh_z_p_bi_u16 - when ('01', '10') => __encoding LD1RH_Z_P_BI_U32 // ld1rh_z_p_bi_u32 - when ('01', '11') => __encoding LD1RH_Z_P_BI_U64 // ld1rh_z_p_bi_u64 - when ('10', '00') => __encoding LD1RSH_Z_P_BI_S64 // ld1rsh_z_p_bi_s64 - when ('10', '01') => __encoding LD1RSH_Z_P_BI_S32 // ld1rsh_z_p_bi_s32 - when ('10', '10') => __encoding LD1RW_Z_P_BI_U32 // ld1rw_z_p_bi_u32 - when ('10', '11') => __encoding LD1RW_Z_P_BI_U64 // ld1rw_z_p_bi_u64 - when ('11', '00') => __encoding LD1RSB_Z_P_BI_S64 // ld1rsb_z_p_bi_s64 - when ('11', '01') => __encoding LD1RSB_Z_P_BI_S32 // ld1rsb_z_p_bi_s32 - when ('11', '10') => __encoding LD1RSB_Z_P_BI_S16 // ld1rsb_z_p_bi_s16 - when ('11', '11') => __encoding LD1RD_Z_P_BI_U64 // ld1rd_z_p_bi_u64 - when ('101', _, _, _, _, _, _, _) => - // sve_memcld - case (25 +: 7, 23 +: 2, 21 +: 2, 20 +: 1, 16 +: 4, 13 +: 3, 0 +: 13) of - when (_, _, '00', '0', _, '111', _) => // sve_mem_cldnt_si - __field msz 23 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding LDNT1B_Z_P_BI_Contiguous // ldnt1b_z_p_bi_contiguous - when ('01') => __encoding LDNT1H_Z_P_BI_Contiguous // ldnt1h_z_p_bi_contiguous - when ('10') => __encoding LDNT1W_Z_P_BI_Contiguous // ldnt1w_z_p_bi_contiguous - when ('11') => __encoding LDNT1D_Z_P_BI_Contiguous // ldnt1d_z_p_bi_contiguous - when (_, _, '00', _, _, '110', _) => // sve_mem_cldnt_ss - __field msz 23 +: 2 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding LDNT1B_Z_P_BR_Contiguous // ldnt1b_z_p_br_contiguous - when ('01') => __encoding LDNT1H_Z_P_BR_Contiguous // ldnt1h_z_p_br_contiguous - when ('10') => __encoding LDNT1W_Z_P_BR_Contiguous // ldnt1w_z_p_br_contiguous - when ('11') => __encoding LDNT1D_Z_P_BR_Contiguous // ldnt1d_z_p_br_contiguous - when (_, _, !'00', '0', _, '111', _) => // sve_mem_eld_si - __field msz 23 +: 2 - __field opc 21 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz, opc) of - when ('00', '01') => __encoding LD2B_Z_P_BI_Contiguous // ld2b_z_p_bi_contiguous - when ('00', '10') => __encoding LD3B_Z_P_BI_Contiguous // ld3b_z_p_bi_contiguous - when ('00', '11') => __encoding LD4B_Z_P_BI_Contiguous // ld4b_z_p_bi_contiguous - when ('01', '01') => __encoding LD2H_Z_P_BI_Contiguous // ld2h_z_p_bi_contiguous - when ('01', '10') => __encoding LD3H_Z_P_BI_Contiguous // ld3h_z_p_bi_contiguous - when ('01', '11') => __encoding LD4H_Z_P_BI_Contiguous // ld4h_z_p_bi_contiguous - when ('10', '01') => __encoding LD2W_Z_P_BI_Contiguous // ld2w_z_p_bi_contiguous - when ('10', '10') => __encoding LD3W_Z_P_BI_Contiguous // ld3w_z_p_bi_contiguous - when ('10', '11') => __encoding LD4W_Z_P_BI_Contiguous // ld4w_z_p_bi_contiguous - when ('11', '01') => __encoding LD2D_Z_P_BI_Contiguous // ld2d_z_p_bi_contiguous - when ('11', '10') => __encoding LD3D_Z_P_BI_Contiguous // ld3d_z_p_bi_contiguous - when ('11', '11') => __encoding LD4D_Z_P_BI_Contiguous // ld4d_z_p_bi_contiguous - when (_, _, !'00', _, _, '110', _) => // sve_mem_eld_ss - __field msz 23 +: 2 - __field opc 21 +: 2 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz, opc) of - when ('00', '01') => __encoding LD2B_Z_P_BR_Contiguous // ld2b_z_p_br_contiguous - when ('00', '10') => __encoding LD3B_Z_P_BR_Contiguous // ld3b_z_p_br_contiguous - when ('00', '11') => __encoding LD4B_Z_P_BR_Contiguous // ld4b_z_p_br_contiguous - when ('01', '01') => __encoding LD2H_Z_P_BR_Contiguous // ld2h_z_p_br_contiguous - when ('01', '10') => __encoding LD3H_Z_P_BR_Contiguous // ld3h_z_p_br_contiguous - when ('01', '11') => __encoding LD4H_Z_P_BR_Contiguous // ld4h_z_p_br_contiguous - when ('10', '01') => __encoding LD2W_Z_P_BR_Contiguous // ld2w_z_p_br_contiguous - when ('10', '10') => __encoding LD3W_Z_P_BR_Contiguous // ld3w_z_p_br_contiguous - when ('10', '11') => __encoding LD4W_Z_P_BR_Contiguous // ld4w_z_p_br_contiguous - when ('11', '01') => __encoding LD2D_Z_P_BR_Contiguous // ld2d_z_p_br_contiguous - when ('11', '10') => __encoding LD3D_Z_P_BR_Contiguous // ld3d_z_p_br_contiguous - when ('11', '11') => __encoding LD4D_Z_P_BR_Contiguous // ld4d_z_p_br_contiguous - when (_, _, _, '0', _, '001', _) => // sve_mem_ldqr_si - __field msz 23 +: 2 - __field ssz 21 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz, ssz) of - when (_, '1x') => __UNALLOCATED - when ('00', '00') => __encoding LD1RQB_Z_P_BI_U8 // ld1rqb_z_p_bi_u8 - when ('00', '01') => __encoding LD1ROB_Z_P_BI_U8 // ld1rob_z_p_bi_u8 - when ('01', '00') => __encoding LD1RQH_Z_P_BI_U16 // ld1rqh_z_p_bi_u16 - when ('01', '01') => __encoding LD1ROH_Z_P_BI_U16 // ld1roh_z_p_bi_u16 - when ('10', '00') => __encoding LD1RQW_Z_P_BI_U32 // ld1rqw_z_p_bi_u32 - when ('10', '01') => __encoding LD1ROW_Z_P_BI_U32 // ld1row_z_p_bi_u32 - when ('11', '00') => __encoding LD1RQD_Z_P_BI_U64 // ld1rqd_z_p_bi_u64 - when ('11', '01') => __encoding LD1ROD_Z_P_BI_U64 // ld1rod_z_p_bi_u64 - when (_, _, _, '0', _, '101', _) => // sve_mem_cld_si - __field dtype 21 +: 4 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (dtype) of - when ('0000') => __encoding LD1B_Z_P_BI_U8 // ld1b_z_p_bi_u8 - when ('0001') => __encoding LD1B_Z_P_BI_U16 // ld1b_z_p_bi_u16 - when ('0010') => __encoding LD1B_Z_P_BI_U32 // ld1b_z_p_bi_u32 - when ('0011') => __encoding LD1B_Z_P_BI_U64 // ld1b_z_p_bi_u64 - when ('0100') => __encoding LD1SW_Z_P_BI_S64 // ld1sw_z_p_bi_s64 - when ('0101') => __encoding LD1H_Z_P_BI_U16 // ld1h_z_p_bi_u16 - when ('0110') => __encoding LD1H_Z_P_BI_U32 // ld1h_z_p_bi_u32 - when ('0111') => __encoding LD1H_Z_P_BI_U64 // ld1h_z_p_bi_u64 - when ('1000') => __encoding LD1SH_Z_P_BI_S64 // ld1sh_z_p_bi_s64 - when ('1001') => __encoding LD1SH_Z_P_BI_S32 // ld1sh_z_p_bi_s32 - when ('1010') => __encoding LD1W_Z_P_BI_U32 // ld1w_z_p_bi_u32 - when ('1011') => __encoding LD1W_Z_P_BI_U64 // ld1w_z_p_bi_u64 - when ('1100') => __encoding LD1SB_Z_P_BI_S64 // ld1sb_z_p_bi_s64 - when ('1101') => __encoding LD1SB_Z_P_BI_S32 // ld1sb_z_p_bi_s32 - when ('1110') => __encoding LD1SB_Z_P_BI_S16 // ld1sb_z_p_bi_s16 - when ('1111') => __encoding LD1D_Z_P_BI_U64 // ld1d_z_p_bi_u64 - when (_, _, _, '1', _, '001', _) => __UNPREDICTABLE - when (_, _, _, '1', _, '101', _) => // sve_mem_cldnf_si - __field dtype 21 +: 4 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (dtype) of - when ('0000') => __encoding LDNF1B_Z_P_BI_U8 // ldnf1b_z_p_bi_u8 - when ('0001') => __encoding LDNF1B_Z_P_BI_U16 // ldnf1b_z_p_bi_u16 - when ('0010') => __encoding LDNF1B_Z_P_BI_U32 // ldnf1b_z_p_bi_u32 - when ('0011') => __encoding LDNF1B_Z_P_BI_U64 // ldnf1b_z_p_bi_u64 - when ('0100') => __encoding LDNF1SW_Z_P_BI_S64 // ldnf1sw_z_p_bi_s64 - when ('0101') => __encoding LDNF1H_Z_P_BI_U16 // ldnf1h_z_p_bi_u16 - when ('0110') => __encoding LDNF1H_Z_P_BI_U32 // ldnf1h_z_p_bi_u32 - when ('0111') => __encoding LDNF1H_Z_P_BI_U64 // ldnf1h_z_p_bi_u64 - when ('1000') => __encoding LDNF1SH_Z_P_BI_S64 // ldnf1sh_z_p_bi_s64 - when ('1001') => __encoding LDNF1SH_Z_P_BI_S32 // ldnf1sh_z_p_bi_s32 - when ('1010') => __encoding LDNF1W_Z_P_BI_U32 // ldnf1w_z_p_bi_u32 - when ('1011') => __encoding LDNF1W_Z_P_BI_U64 // ldnf1w_z_p_bi_u64 - when ('1100') => __encoding LDNF1SB_Z_P_BI_S64 // ldnf1sb_z_p_bi_s64 - when ('1101') => __encoding LDNF1SB_Z_P_BI_S32 // ldnf1sb_z_p_bi_s32 - when ('1110') => __encoding LDNF1SB_Z_P_BI_S16 // ldnf1sb_z_p_bi_s16 - when ('1111') => __encoding LDNF1D_Z_P_BI_U64 // ldnf1d_z_p_bi_u64 - when (_, _, _, '1', _, '111', _) => __UNPREDICTABLE - when (_, _, _, _, _, '000', _) => // sve_mem_ldqr_ss - __field msz 23 +: 2 - __field ssz 21 +: 2 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz, ssz) of - when (_, '1x') => __UNALLOCATED - when ('00', '00') => __encoding LD1RQB_Z_P_BR_Contiguous // ld1rqb_z_p_br_contiguous - when ('00', '01') => __encoding LD1ROB_Z_P_BR_Contiguous // ld1rob_z_p_br_contiguous - when ('01', '00') => __encoding LD1RQH_Z_P_BR_Contiguous // ld1rqh_z_p_br_contiguous - when ('01', '01') => __encoding LD1ROH_Z_P_BR_Contiguous // ld1roh_z_p_br_contiguous - when ('10', '00') => __encoding LD1RQW_Z_P_BR_Contiguous // ld1rqw_z_p_br_contiguous - when ('10', '01') => __encoding LD1ROW_Z_P_BR_Contiguous // ld1row_z_p_br_contiguous - when ('11', '00') => __encoding LD1RQD_Z_P_BR_Contiguous // ld1rqd_z_p_br_contiguous - when ('11', '01') => __encoding LD1ROD_Z_P_BR_Contiguous // ld1rod_z_p_br_contiguous - when (_, _, _, _, _, '010', _) => // sve_mem_cld_ss - __field dtype 21 +: 4 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (dtype) of - when ('0000') => __encoding LD1B_Z_P_BR_U8 // ld1b_z_p_br_u8 - when ('0001') => __encoding LD1B_Z_P_BR_U16 // ld1b_z_p_br_u16 - when ('0010') => __encoding LD1B_Z_P_BR_U32 // ld1b_z_p_br_u32 - when ('0011') => __encoding LD1B_Z_P_BR_U64 // ld1b_z_p_br_u64 - when ('0100') => __encoding LD1SW_Z_P_BR_S64 // ld1sw_z_p_br_s64 - when ('0101') => __encoding LD1H_Z_P_BR_U16 // ld1h_z_p_br_u16 - when ('0110') => __encoding LD1H_Z_P_BR_U32 // ld1h_z_p_br_u32 - when ('0111') => __encoding LD1H_Z_P_BR_U64 // ld1h_z_p_br_u64 - when ('1000') => __encoding LD1SH_Z_P_BR_S64 // ld1sh_z_p_br_s64 - when ('1001') => __encoding LD1SH_Z_P_BR_S32 // ld1sh_z_p_br_s32 - when ('1010') => __encoding LD1W_Z_P_BR_U32 // ld1w_z_p_br_u32 - when ('1011') => __encoding LD1W_Z_P_BR_U64 // ld1w_z_p_br_u64 - when ('1100') => __encoding LD1SB_Z_P_BR_S64 // ld1sb_z_p_br_s64 - when ('1101') => __encoding LD1SB_Z_P_BR_S32 // ld1sb_z_p_br_s32 - when ('1110') => __encoding LD1SB_Z_P_BR_S16 // ld1sb_z_p_br_s16 - when ('1111') => __encoding LD1D_Z_P_BR_U64 // ld1d_z_p_br_u64 - when (_, _, _, _, _, '011', _) => // sve_mem_cldff_ss - __field dtype 21 +: 4 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (dtype) of - when ('0000') => __encoding LDFF1B_Z_P_BR_U8 // ldff1b_z_p_br_u8 - when ('0001') => __encoding LDFF1B_Z_P_BR_U16 // ldff1b_z_p_br_u16 - when ('0010') => __encoding LDFF1B_Z_P_BR_U32 // ldff1b_z_p_br_u32 - when ('0011') => __encoding LDFF1B_Z_P_BR_U64 // ldff1b_z_p_br_u64 - when ('0100') => __encoding LDFF1SW_Z_P_BR_S64 // ldff1sw_z_p_br_s64 - when ('0101') => __encoding LDFF1H_Z_P_BR_U16 // ldff1h_z_p_br_u16 - when ('0110') => __encoding LDFF1H_Z_P_BR_U32 // ldff1h_z_p_br_u32 - when ('0111') => __encoding LDFF1H_Z_P_BR_U64 // ldff1h_z_p_br_u64 - when ('1000') => __encoding LDFF1SH_Z_P_BR_S64 // ldff1sh_z_p_br_s64 - when ('1001') => __encoding LDFF1SH_Z_P_BR_S32 // ldff1sh_z_p_br_s32 - when ('1010') => __encoding LDFF1W_Z_P_BR_U32 // ldff1w_z_p_br_u32 - when ('1011') => __encoding LDFF1W_Z_P_BR_U64 // ldff1w_z_p_br_u64 - when ('1100') => __encoding LDFF1SB_Z_P_BR_S64 // ldff1sb_z_p_br_s64 - when ('1101') => __encoding LDFF1SB_Z_P_BR_S32 // ldff1sb_z_p_br_s32 - when ('1110') => __encoding LDFF1SB_Z_P_BR_S16 // ldff1sb_z_p_br_s16 - when ('1111') => __encoding LDFF1D_Z_P_BR_U64 // ldff1d_z_p_br_u64 - when (_, _, _, _, _, '100', _) => __UNPREDICTABLE - when ('110', _, _, _, _, _, _, _) => - // sve_mem64 - case (25 +: 7, 23 +: 2, 21 +: 2, 16 +: 5, 13 +: 3, 5 +: 8, 4 +: 1, 0 +: 4) of - when (_, '00', '01', _, '0xx', _, '1', _) => __UNPREDICTABLE - when (_, '00', '11', _, '1xx', _, '0', _) => // sve_mem_64b_prfm_sv2 - __field Zm 16 +: 5 - __field msz 13 +: 2 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - case (msz) of - when ('00') => __encoding PRFB_I_P_BZ_D_64_scaled // prfb_i_p_bz_d_64_scaled - when ('01') => __encoding PRFH_I_P_BZ_D_64_scaled // prfh_i_p_bz_d_64_scaled - when ('10') => __encoding PRFW_I_P_BZ_D_64_scaled // prfw_i_p_bz_d_64_scaled - when ('11') => __encoding PRFD_I_P_BZ_D_64_scaled // prfd_i_p_bz_d_64_scaled - when (_, '00', '11', _, _, _, '1', _) => __UNPREDICTABLE - when (_, '00', 'x1', _, '0xx', _, '0', _) => // sve_mem_64b_prfm_sv - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field msz 13 +: 2 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - case (msz) of - when ('00') => __encoding PRFB_I_P_BZ_D_x32_scaled // prfb_i_p_bz_d_x32_scaled - when ('01') => __encoding PRFH_I_P_BZ_D_x32_scaled // prfh_i_p_bz_d_x32_scaled - when ('10') => __encoding PRFW_I_P_BZ_D_x32_scaled // prfw_i_p_bz_d_x32_scaled - when ('11') => __encoding PRFD_I_P_BZ_D_x32_scaled // prfd_i_p_bz_d_x32_scaled - when (_, !'00', '11', _, '1xx', _, _, _) => // sve_mem_64b_gld_sv2 - __field opc 23 +: 2 - __field Zm 16 +: 5 - __field U 14 +: 1 - __field ff 13 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (opc, U, ff) of - when ('01', '0', '0') => __encoding LD1SH_Z_P_BZ_D_64_scaled // ld1sh_z_p_bz_d_64_scaled - when ('01', '0', '1') => __encoding LDFF1SH_Z_P_BZ_D_64_scaled // ldff1sh_z_p_bz_d_64_scaled - when ('01', '1', '0') => __encoding LD1H_Z_P_BZ_D_64_scaled // ld1h_z_p_bz_d_64_scaled - when ('01', '1', '1') => __encoding LDFF1H_Z_P_BZ_D_64_scaled // ldff1h_z_p_bz_d_64_scaled - when ('10', '0', '0') => __encoding LD1SW_Z_P_BZ_D_64_scaled // ld1sw_z_p_bz_d_64_scaled - when ('10', '0', '1') => __encoding LDFF1SW_Z_P_BZ_D_64_scaled // ldff1sw_z_p_bz_d_64_scaled - when ('10', '1', '0') => __encoding LD1W_Z_P_BZ_D_64_scaled // ld1w_z_p_bz_d_64_scaled - when ('10', '1', '1') => __encoding LDFF1W_Z_P_BZ_D_64_scaled // ldff1w_z_p_bz_d_64_scaled - when ('11', '0', _) => __UNALLOCATED - when ('11', '1', '0') => __encoding LD1D_Z_P_BZ_D_64_scaled // ld1d_z_p_bz_d_64_scaled - when ('11', '1', '1') => __encoding LDFF1D_Z_P_BZ_D_64_scaled // ldff1d_z_p_bz_d_64_scaled - when (_, !'00', 'x1', _, '0xx', _, _, _) => // sve_mem_64b_gld_sv - __field opc 23 +: 2 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field U 14 +: 1 - __field ff 13 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (opc, U, ff) of - when ('01', '0', '0') => __encoding LD1SH_Z_P_BZ_D_x32_scaled // ld1sh_z_p_bz_d_x32_scaled - when ('01', '0', '1') => __encoding LDFF1SH_Z_P_BZ_D_x32_scaled // ldff1sh_z_p_bz_d_x32_scaled - when ('01', '1', '0') => __encoding LD1H_Z_P_BZ_D_x32_scaled // ld1h_z_p_bz_d_x32_scaled - when ('01', '1', '1') => __encoding LDFF1H_Z_P_BZ_D_x32_scaled // ldff1h_z_p_bz_d_x32_scaled - when ('10', '0', '0') => __encoding LD1SW_Z_P_BZ_D_x32_scaled // ld1sw_z_p_bz_d_x32_scaled - when ('10', '0', '1') => __encoding LDFF1SW_Z_P_BZ_D_x32_scaled // ldff1sw_z_p_bz_d_x32_scaled - when ('10', '1', '0') => __encoding LD1W_Z_P_BZ_D_x32_scaled // ld1w_z_p_bz_d_x32_scaled - when ('10', '1', '1') => __encoding LDFF1W_Z_P_BZ_D_x32_scaled // ldff1w_z_p_bz_d_x32_scaled - when ('11', '0', _) => __UNALLOCATED - when ('11', '1', '0') => __encoding LD1D_Z_P_BZ_D_x32_scaled // ld1d_z_p_bz_d_x32_scaled - when ('11', '1', '1') => __encoding LDFF1D_Z_P_BZ_D_x32_scaled // ldff1d_z_p_bz_d_x32_scaled - when (_, _, '00', _, '10x', _, _, _) => __UNPREDICTABLE - when (_, _, '00', _, '110', _, _, _) => __UNPREDICTABLE - when (_, _, '00', _, '111', _, '0', _) => // sve_mem_64b_prfm_vi - __field msz 23 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - case (msz) of - when ('00') => __encoding PRFB_I_P_AI_D // prfb_i_p_ai_d - when ('01') => __encoding PRFH_I_P_AI_D // prfh_i_p_ai_d - when ('10') => __encoding PRFW_I_P_AI_D // prfw_i_p_ai_d - when ('11') => __encoding PRFD_I_P_AI_D // prfd_i_p_ai_d - when (_, _, '00', _, '111', _, '1', _) => __UNPREDICTABLE - when (_, _, '01', _, '1xx', _, _, _) => // sve_mem_64b_gld_vi - __field msz 23 +: 2 - __field imm5 16 +: 5 - __field U 14 +: 1 - __field ff 13 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - case (msz, U, ff) of - when ('00', '0', '0') => __encoding LD1SB_Z_P_AI_D // ld1sb_z_p_ai_d - when ('00', '0', '1') => __encoding LDFF1SB_Z_P_AI_D // ldff1sb_z_p_ai_d - when ('00', '1', '0') => __encoding LD1B_Z_P_AI_D // ld1b_z_p_ai_d - when ('00', '1', '1') => __encoding LDFF1B_Z_P_AI_D // ldff1b_z_p_ai_d - when ('01', '0', '0') => __encoding LD1SH_Z_P_AI_D // ld1sh_z_p_ai_d - when ('01', '0', '1') => __encoding LDFF1SH_Z_P_AI_D // ldff1sh_z_p_ai_d - when ('01', '1', '0') => __encoding LD1H_Z_P_AI_D // ld1h_z_p_ai_d - when ('01', '1', '1') => __encoding LDFF1H_Z_P_AI_D // ldff1h_z_p_ai_d - when ('10', '0', '0') => __encoding LD1SW_Z_P_AI_D // ld1sw_z_p_ai_d - when ('10', '0', '1') => __encoding LDFF1SW_Z_P_AI_D // ldff1sw_z_p_ai_d - when ('10', '1', '0') => __encoding LD1W_Z_P_AI_D // ld1w_z_p_ai_d - when ('10', '1', '1') => __encoding LDFF1W_Z_P_AI_D // ldff1w_z_p_ai_d - when ('11', '0', _) => __UNALLOCATED - when ('11', '1', '0') => __encoding LD1D_Z_P_AI_D // ld1d_z_p_ai_d - when ('11', '1', '1') => __encoding LDFF1D_Z_P_AI_D // ldff1d_z_p_ai_d - when (_, _, '10', _, '1xx', _, _, _) => // sve_mem_64b_gld_vs2 - __field msz 23 +: 2 - __field Zm 16 +: 5 - __field U 14 +: 1 - __field ff 13 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz, U, ff) of - when ('00', '0', '0') => __encoding LD1SB_Z_P_BZ_D_64_unscaled // ld1sb_z_p_bz_d_64_unscaled - when ('00', '0', '1') => __encoding LDFF1SB_Z_P_BZ_D_64_unscaled // ldff1sb_z_p_bz_d_64_unscaled - when ('00', '1', '0') => __encoding LD1B_Z_P_BZ_D_64_unscaled // ld1b_z_p_bz_d_64_unscaled - when ('00', '1', '1') => __encoding LDFF1B_Z_P_BZ_D_64_unscaled // ldff1b_z_p_bz_d_64_unscaled - when ('01', '0', '0') => __encoding LD1SH_Z_P_BZ_D_64_unscaled // ld1sh_z_p_bz_d_64_unscaled - when ('01', '0', '1') => __encoding LDFF1SH_Z_P_BZ_D_64_unscaled // ldff1sh_z_p_bz_d_64_unscaled - when ('01', '1', '0') => __encoding LD1H_Z_P_BZ_D_64_unscaled // ld1h_z_p_bz_d_64_unscaled - when ('01', '1', '1') => __encoding LDFF1H_Z_P_BZ_D_64_unscaled // ldff1h_z_p_bz_d_64_unscaled - when ('10', '0', '0') => __encoding LD1SW_Z_P_BZ_D_64_unscaled // ld1sw_z_p_bz_d_64_unscaled - when ('10', '0', '1') => __encoding LDFF1SW_Z_P_BZ_D_64_unscaled // ldff1sw_z_p_bz_d_64_unscaled - when ('10', '1', '0') => __encoding LD1W_Z_P_BZ_D_64_unscaled // ld1w_z_p_bz_d_64_unscaled - when ('10', '1', '1') => __encoding LDFF1W_Z_P_BZ_D_64_unscaled // ldff1w_z_p_bz_d_64_unscaled - when ('11', '0', _) => __UNALLOCATED - when ('11', '1', '0') => __encoding LD1D_Z_P_BZ_D_64_unscaled // ld1d_z_p_bz_d_64_unscaled - when ('11', '1', '1') => __encoding LDFF1D_Z_P_BZ_D_64_unscaled // ldff1d_z_p_bz_d_64_unscaled - when (_, _, 'x0', _, '0xx', _, _, _) => // sve_mem_64b_gld_vs - __field msz 23 +: 2 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field U 14 +: 1 - __field ff 13 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz, U, ff) of - when ('00', '0', '0') => __encoding LD1SB_Z_P_BZ_D_x32_unscaled // ld1sb_z_p_bz_d_x32_unscaled - when ('00', '0', '1') => __encoding LDFF1SB_Z_P_BZ_D_x32_unscaled // ldff1sb_z_p_bz_d_x32_unscaled - when ('00', '1', '0') => __encoding LD1B_Z_P_BZ_D_x32_unscaled // ld1b_z_p_bz_d_x32_unscaled - when ('00', '1', '1') => __encoding LDFF1B_Z_P_BZ_D_x32_unscaled // ldff1b_z_p_bz_d_x32_unscaled - when ('01', '0', '0') => __encoding LD1SH_Z_P_BZ_D_x32_unscaled // ld1sh_z_p_bz_d_x32_unscaled - when ('01', '0', '1') => __encoding LDFF1SH_Z_P_BZ_D_x32_unscaled // ldff1sh_z_p_bz_d_x32_unscaled - when ('01', '1', '0') => __encoding LD1H_Z_P_BZ_D_x32_unscaled // ld1h_z_p_bz_d_x32_unscaled - when ('01', '1', '1') => __encoding LDFF1H_Z_P_BZ_D_x32_unscaled // ldff1h_z_p_bz_d_x32_unscaled - when ('10', '0', '0') => __encoding LD1SW_Z_P_BZ_D_x32_unscaled // ld1sw_z_p_bz_d_x32_unscaled - when ('10', '0', '1') => __encoding LDFF1SW_Z_P_BZ_D_x32_unscaled // ldff1sw_z_p_bz_d_x32_unscaled - when ('10', '1', '0') => __encoding LD1W_Z_P_BZ_D_x32_unscaled // ld1w_z_p_bz_d_x32_unscaled - when ('10', '1', '1') => __encoding LDFF1W_Z_P_BZ_D_x32_unscaled // ldff1w_z_p_bz_d_x32_unscaled - when ('11', '0', _) => __UNALLOCATED - when ('11', '1', '0') => __encoding LD1D_Z_P_BZ_D_x32_unscaled // ld1d_z_p_bz_d_x32_unscaled - when ('11', '1', '1') => __encoding LDFF1D_Z_P_BZ_D_x32_unscaled // ldff1d_z_p_bz_d_x32_unscaled - when ('111', _, _, _, _, _, '0x0xxx', _) => - // sve_memst_cs - case (25 +: 7, 22 +: 3, 16 +: 6, 15 +: 1, 14 +: 1, 13 +: 1, 5 +: 8, 4 +: 1, 0 +: 4) of - when (_, '0xx', _, _, '0', _, _, _, _) => __UNPREDICTABLE - when (_, '10x', _, _, '0', _, _, _, _) => __UNPREDICTABLE - when (_, '110', _, _, '0', _, _, '0', _) => // sve_mem_pspill - __field imm9h 16 +: 6 - __field imm9l 10 +: 3 - __field Rn 5 +: 5 - __field Pt 0 +: 4 - case () of - when () => __encoding STR_P_BI__ // str_p_bi_ - when (_, '110', _, _, '0', _, _, '1', _) => __UNPREDICTABLE - when (_, '110', _, _, '1', _, _, _, _) => // sve_mem_spill - __field imm9h 16 +: 6 - __field imm9l 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case () of - when () => __encoding STR_Z_BI__ // str_z_bi_ - when (_, '111', _, _, '0', _, _, _, _) => __UNPREDICTABLE - when (_, !'110', _, _, '1', _, _, _, _) => // sve_mem_cst_ss - __field opc 22 +: 3 - __field o2 21 +: 1 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (opc, o2) of - when ('00x', _) => __encoding ST1B_Z_P_BR__ // st1b_z_p_br_ - when ('01x', _) => __encoding ST1H_Z_P_BR__ // st1h_z_p_br_ - when ('10x', _) => __encoding ST1W_Z_P_BR__ // st1w_z_p_br_ - when ('111', '0') => __UNALLOCATED - when ('111', '1') => __encoding ST1D_Z_P_BR__ // st1d_z_p_br_ - when ('111', _, _, _, _, _, '0x1xxx', _) => - // sve_memst_nt - case (25 +: 7, 23 +: 2, 21 +: 2, 16 +: 5, 15 +: 1, 14 +: 1, 13 +: 1, 0 +: 13) of - when (_, _, '00', _, _, '1', _, _) => // sve_mem_cstnt_ss - __field msz 23 +: 2 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding STNT1B_Z_P_BR_Contiguous // stnt1b_z_p_br_contiguous - when ('01') => __encoding STNT1H_Z_P_BR_Contiguous // stnt1h_z_p_br_contiguous - when ('10') => __encoding STNT1W_Z_P_BR_Contiguous // stnt1w_z_p_br_contiguous - when ('11') => __encoding STNT1D_Z_P_BR_Contiguous // stnt1d_z_p_br_contiguous - when (_, _, !'00', _, _, '1', _, _) => // sve_mem_est_ss - __field msz 23 +: 2 - __field opc 21 +: 2 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz, opc) of - when ('00', '01') => __encoding ST2B_Z_P_BR_Contiguous // st2b_z_p_br_contiguous - when ('00', '10') => __encoding ST3B_Z_P_BR_Contiguous // st3b_z_p_br_contiguous - when ('00', '11') => __encoding ST4B_Z_P_BR_Contiguous // st4b_z_p_br_contiguous - when ('01', '01') => __encoding ST2H_Z_P_BR_Contiguous // st2h_z_p_br_contiguous - when ('01', '10') => __encoding ST3H_Z_P_BR_Contiguous // st3h_z_p_br_contiguous - when ('01', '11') => __encoding ST4H_Z_P_BR_Contiguous // st4h_z_p_br_contiguous - when ('10', '01') => __encoding ST2W_Z_P_BR_Contiguous // st2w_z_p_br_contiguous - when ('10', '10') => __encoding ST3W_Z_P_BR_Contiguous // st3w_z_p_br_contiguous - when ('10', '11') => __encoding ST4W_Z_P_BR_Contiguous // st4w_z_p_br_contiguous - when ('11', '01') => __encoding ST2D_Z_P_BR_Contiguous // st2d_z_p_br_contiguous - when ('11', '10') => __encoding ST3D_Z_P_BR_Contiguous // st3d_z_p_br_contiguous - when ('11', '11') => __encoding ST4D_Z_P_BR_Contiguous // st4d_z_p_br_contiguous - when (_, _, _, _, _, '0', _, _) => __UNPREDICTABLE - when ('111', _, _, _, _, _, '1x0xxx', _) => - // sve_memst_ss - case (25 +: 7, 23 +: 2, 21 +: 2, 16 +: 5, 15 +: 1, 14 +: 1, 13 +: 1, 0 +: 13) of - when (_, _, '00', _, _, _, _, _) => // sve_mem_sst_vs_a - __field msz 23 +: 2 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding ST1B_Z_P_BZ_D_x32_unscaled // st1b_z_p_bz_d_x32_unscaled - when ('01') => __encoding ST1H_Z_P_BZ_D_x32_unscaled // st1h_z_p_bz_d_x32_unscaled - when ('10') => __encoding ST1W_Z_P_BZ_D_x32_unscaled // st1w_z_p_bz_d_x32_unscaled - when ('11') => __encoding ST1D_Z_P_BZ_D_x32_unscaled // st1d_z_p_bz_d_x32_unscaled - when (_, _, '01', _, _, _, _, _) => // sve_mem_sst_sv_a - __field msz 23 +: 2 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __UNALLOCATED - when ('01') => __encoding ST1H_Z_P_BZ_D_x32_scaled // st1h_z_p_bz_d_x32_scaled - when ('10') => __encoding ST1W_Z_P_BZ_D_x32_scaled // st1w_z_p_bz_d_x32_scaled - when ('11') => __encoding ST1D_Z_P_BZ_D_x32_scaled // st1d_z_p_bz_d_x32_scaled - when (_, _, '10', _, _, _, _, _) => // sve_mem_sst_vs_b - __field msz 23 +: 2 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding ST1B_Z_P_BZ_S_x32_unscaled // st1b_z_p_bz_s_x32_unscaled - when ('01') => __encoding ST1H_Z_P_BZ_S_x32_unscaled // st1h_z_p_bz_s_x32_unscaled - when ('10') => __encoding ST1W_Z_P_BZ_S_x32_unscaled // st1w_z_p_bz_s_x32_unscaled - when ('11') => __UNALLOCATED - when (_, _, '11', _, _, _, _, _) => // sve_mem_sst_sv_b - __field msz 23 +: 2 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __UNALLOCATED - when ('01') => __encoding ST1H_Z_P_BZ_S_x32_scaled // st1h_z_p_bz_s_x32_scaled - when ('10') => __encoding ST1W_Z_P_BZ_S_x32_scaled // st1w_z_p_bz_s_x32_scaled - when ('11') => __UNALLOCATED - when ('111', _, _, _, _, _, '101xxx', _) => - // sve_memst_ss2 - case (25 +: 7, 23 +: 2, 21 +: 2, 16 +: 5, 13 +: 3, 0 +: 13) of - when (_, _, '00', _, _, _) => // sve_mem_sst_vs2 - __field msz 23 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding ST1B_Z_P_BZ_D_64_unscaled // st1b_z_p_bz_d_64_unscaled - when ('01') => __encoding ST1H_Z_P_BZ_D_64_unscaled // st1h_z_p_bz_d_64_unscaled - when ('10') => __encoding ST1W_Z_P_BZ_D_64_unscaled // st1w_z_p_bz_d_64_unscaled - when ('11') => __encoding ST1D_Z_P_BZ_D_64_unscaled // st1d_z_p_bz_d_64_unscaled - when (_, _, '01', _, _, _) => // sve_mem_sst_sv2 - __field msz 23 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __UNALLOCATED - when ('01') => __encoding ST1H_Z_P_BZ_D_64_scaled // st1h_z_p_bz_d_64_scaled - when ('10') => __encoding ST1W_Z_P_BZ_D_64_scaled // st1w_z_p_bz_d_64_scaled - when ('11') => __encoding ST1D_Z_P_BZ_D_64_scaled // st1d_z_p_bz_d_64_scaled - when (_, _, '10', _, _, _) => // sve_mem_sst_vi_a - __field msz 23 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding ST1B_Z_P_AI_D // st1b_z_p_ai_d - when ('01') => __encoding ST1H_Z_P_AI_D // st1h_z_p_ai_d - when ('10') => __encoding ST1W_Z_P_AI_D // st1w_z_p_ai_d - when ('11') => __encoding ST1D_Z_P_AI_D // st1d_z_p_ai_d - when (_, _, '11', _, _, _) => // sve_mem_sst_vi_b - __field msz 23 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding ST1B_Z_P_AI_S // st1b_z_p_ai_s - when ('01') => __encoding ST1H_Z_P_AI_S // st1h_z_p_ai_s - when ('10') => __encoding ST1W_Z_P_AI_S // st1w_z_p_ai_s - when ('11') => __UNALLOCATED - when ('111', _, _, _, _, _, '111xxx', _) => - // sve_memst_si - case (25 +: 7, 23 +: 2, 21 +: 2, 20 +: 1, 16 +: 4, 13 +: 3, 0 +: 13) of - when (_, _, '00', '1', _, _, _) => // sve_mem_cstnt_si - __field msz 23 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding STNT1B_Z_P_BI_Contiguous // stnt1b_z_p_bi_contiguous - when ('01') => __encoding STNT1H_Z_P_BI_Contiguous // stnt1h_z_p_bi_contiguous - when ('10') => __encoding STNT1W_Z_P_BI_Contiguous // stnt1w_z_p_bi_contiguous - when ('11') => __encoding STNT1D_Z_P_BI_Contiguous // stnt1d_z_p_bi_contiguous - when (_, _, !'00', '1', _, _, _) => // sve_mem_est_si - __field msz 23 +: 2 - __field opc 21 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz, opc) of - when ('00', '01') => __encoding ST2B_Z_P_BI_Contiguous // st2b_z_p_bi_contiguous - when ('00', '10') => __encoding ST3B_Z_P_BI_Contiguous // st3b_z_p_bi_contiguous - when ('00', '11') => __encoding ST4B_Z_P_BI_Contiguous // st4b_z_p_bi_contiguous - when ('01', '01') => __encoding ST2H_Z_P_BI_Contiguous // st2h_z_p_bi_contiguous - when ('01', '10') => __encoding ST3H_Z_P_BI_Contiguous // st3h_z_p_bi_contiguous - when ('01', '11') => __encoding ST4H_Z_P_BI_Contiguous // st4h_z_p_bi_contiguous - when ('10', '01') => __encoding ST2W_Z_P_BI_Contiguous // st2w_z_p_bi_contiguous - when ('10', '10') => __encoding ST3W_Z_P_BI_Contiguous // st3w_z_p_bi_contiguous - when ('10', '11') => __encoding ST4W_Z_P_BI_Contiguous // st4w_z_p_bi_contiguous - when ('11', '01') => __encoding ST2D_Z_P_BI_Contiguous // st2d_z_p_bi_contiguous - when ('11', '10') => __encoding ST3D_Z_P_BI_Contiguous // st3d_z_p_bi_contiguous - when ('11', '11') => __encoding ST4D_Z_P_BI_Contiguous // st4d_z_p_bi_contiguous - when (_, _, _, '0', _, _, _) => // sve_mem_cst_si - __field msz 23 +: 2 - __field size 21 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - case (msz) of - when ('00') => __encoding ST1B_Z_P_BI__ // st1b_z_p_bi_ - when ('01') => __encoding ST1H_Z_P_BI__ // st1h_z_p_bi_ - when ('10') => __encoding ST1W_Z_P_BI__ // st1w_z_p_bi_ - when ('11') => __encoding ST1D_Z_P_BI__ // st1d_z_p_bi_ - when (_, '0011x', _) => __UNPREDICTABLE - when (_, '100xx', _) => - // dpimm - case (29 +: 3, 26 +: 3, 23 +: 3, 0 +: 23) of - when (_, _, '00x', _) => // pcreladdr - __field op 31 +: 1 - __field immlo 29 +: 2 - __field immhi 5 +: 19 - __field Rd 0 +: 5 - case (op) of - when ('0') => __encoding aarch64_integer_arithmetic_address_pc_rel // ADR_only_pcreladdr - when ('1') => __encoding aarch64_integer_arithmetic_address_pc_rel // ADRP_only_pcreladdr - when (_, _, '010', _) => // addsub_imm - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field sh 22 +: 1 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, op, S) of - when ('0', '0', '0') => __encoding aarch64_integer_arithmetic_add_sub_immediate // ADD_32_addsub_imm - when ('0', '0', '1') => __encoding aarch64_integer_arithmetic_add_sub_immediate // ADDS_32S_addsub_imm - when ('0', '1', '0') => __encoding aarch64_integer_arithmetic_add_sub_immediate // SUB_32_addsub_imm - when ('0', '1', '1') => __encoding aarch64_integer_arithmetic_add_sub_immediate // SUBS_32S_addsub_imm - when ('1', '0', '0') => __encoding aarch64_integer_arithmetic_add_sub_immediate // ADD_64_addsub_imm - when ('1', '0', '1') => __encoding aarch64_integer_arithmetic_add_sub_immediate // ADDS_64S_addsub_imm - when ('1', '1', '0') => __encoding aarch64_integer_arithmetic_add_sub_immediate // SUB_64_addsub_imm - when ('1', '1', '1') => __encoding aarch64_integer_arithmetic_add_sub_immediate // SUBS_64S_addsub_imm - when (_, _, '011', _) => // addsub_immtags - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field o2 22 +: 1 - __field uimm6 16 +: 6 - __field op3 14 +: 2 - __field uimm4 10 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, op, S, o2) of - when (_, _, _, '1') => __UNALLOCATED - when ('0', _, _, '0') => __UNALLOCATED - when ('1', _, '1', '0') => __UNALLOCATED - when ('1', '0', '0', '0') => __encoding aarch64_integer_tags_mcaddtag // ADDG_64_addsub_immtags - when ('1', '1', '0', '0') => __encoding aarch64_integer_tags_mcsubtag // SUBG_64_addsub_immtags - when (_, _, '100', _) => // log_imm - __field sf 31 +: 1 - __field opc 29 +: 2 - __field N 22 +: 1 - __field immr 16 +: 6 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, opc, N) of - when ('0', _, '1') => __UNALLOCATED - when ('0', '00', '0') => __encoding aarch64_integer_logical_immediate // AND_32_log_imm - when ('0', '01', '0') => __encoding aarch64_integer_logical_immediate // ORR_32_log_imm - when ('0', '10', '0') => __encoding aarch64_integer_logical_immediate // EOR_32_log_imm - when ('0', '11', '0') => __encoding aarch64_integer_logical_immediate // ANDS_32S_log_imm - when ('1', '00', _) => __encoding aarch64_integer_logical_immediate // AND_64_log_imm - when ('1', '01', _) => __encoding aarch64_integer_logical_immediate // ORR_64_log_imm - when ('1', '10', _) => __encoding aarch64_integer_logical_immediate // EOR_64_log_imm - when ('1', '11', _) => __encoding aarch64_integer_logical_immediate // ANDS_64S_log_imm - when (_, _, '101', _) => // movewide - __field sf 31 +: 1 - __field opc 29 +: 2 - __field hw 21 +: 2 - __field imm16 5 +: 16 - __field Rd 0 +: 5 - case (sf, opc, hw) of - when (_, '01', _) => __UNALLOCATED - when ('0', _, '1x') => __UNALLOCATED - when ('0', '00', '0x') => __encoding aarch64_integer_ins_ext_insert_movewide // MOVN_32_movewide - when ('0', '10', '0x') => __encoding aarch64_integer_ins_ext_insert_movewide // MOVZ_32_movewide - when ('0', '11', '0x') => __encoding aarch64_integer_ins_ext_insert_movewide // MOVK_32_movewide - when ('1', '00', _) => __encoding aarch64_integer_ins_ext_insert_movewide // MOVN_64_movewide - when ('1', '10', _) => __encoding aarch64_integer_ins_ext_insert_movewide // MOVZ_64_movewide - when ('1', '11', _) => __encoding aarch64_integer_ins_ext_insert_movewide // MOVK_64_movewide - when (_, _, '110', _) => // bitfield - __field sf 31 +: 1 - __field opc 29 +: 2 - __field N 22 +: 1 - __field immr 16 +: 6 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, opc, N) of - when (_, '11', _) => __UNALLOCATED - when ('0', _, '1') => __UNALLOCATED - when ('0', '00', '0') => __encoding aarch64_integer_bitfield // SBFM_32M_bitfield - when ('0', '01', '0') => __encoding aarch64_integer_bitfield // BFM_32M_bitfield - when ('0', '10', '0') => __encoding aarch64_integer_bitfield // UBFM_32M_bitfield - when ('1', _, '0') => __UNALLOCATED - when ('1', '00', '1') => __encoding aarch64_integer_bitfield // SBFM_64M_bitfield - when ('1', '01', '1') => __encoding aarch64_integer_bitfield // BFM_64M_bitfield - when ('1', '10', '1') => __encoding aarch64_integer_bitfield // UBFM_64M_bitfield - when (_, _, '111', _) => // extract - __field sf 31 +: 1 - __field op21 29 +: 2 - __field N 22 +: 1 - __field o0 21 +: 1 - __field Rm 16 +: 5 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, op21, N, o0, imms) of - when (_, 'x1', _, _, _) => __UNALLOCATED - when (_, '00', _, '1', _) => __UNALLOCATED - when (_, '1x', _, _, _) => __UNALLOCATED - when ('0', _, _, _, '1xxxxx') => __UNALLOCATED - when ('0', _, '1', _, _) => __UNALLOCATED - when ('0', '00', '0', '0', '0xxxxx') => __encoding aarch64_integer_ins_ext_extract_immediate // EXTR_32_extract - when ('1', _, '0', _, _) => __UNALLOCATED - when ('1', '00', '1', '0', _) => __encoding aarch64_integer_ins_ext_extract_immediate // EXTR_64_extract - when (_, '101xx', _) => - // control - case (29 +: 3, 26 +: 3, 12 +: 14, 5 +: 7, 0 +: 5) of - when ('010', _, '0xxxxxxxxxxxxx', _, _) => // condbranch - __field o1 24 +: 1 - __field imm19 5 +: 19 - __field o0 4 +: 1 - __field cond 0 +: 4 - case (o1, o0) of - when ('0', '0') => __encoding aarch64_branch_conditional_cond // B_only_condbranch - when ('0', '1') => __UNALLOCATED - when ('1', _) => __UNALLOCATED - when ('110', _, '00xxxxxxxxxxxx', _, _) => // exception - __field opc 21 +: 3 - __field imm16 5 +: 16 - __field op2 2 +: 3 - __field LL 0 +: 2 - case (opc, op2, LL) of - when (_, '001', _) => __UNALLOCATED - when (_, '01x', _) => __UNALLOCATED - when (_, '1xx', _) => __UNALLOCATED - when ('000', '000', '00') => __UNALLOCATED - when ('000', '000', '01') => __encoding aarch64_system_exceptions_runtime_svc // SVC_EX_exception - when ('000', '000', '10') => __encoding aarch64_system_exceptions_runtime_hvc // HVC_EX_exception - when ('000', '000', '11') => __encoding aarch64_system_exceptions_runtime_smc // SMC_EX_exception - when ('001', '000', 'x1') => __UNALLOCATED - when ('001', '000', '00') => __encoding aarch64_system_exceptions_debug_breakpoint // BRK_EX_exception - when ('001', '000', '1x') => __UNALLOCATED - when ('010', '000', 'x1') => __UNALLOCATED - when ('010', '000', '00') => __encoding aarch64_system_exceptions_debug_halt // HLT_EX_exception - when ('010', '000', '1x') => __UNALLOCATED - when ('011', '000', '01') => __UNALLOCATED - when ('011', '000', '1x') => __UNALLOCATED - when ('100', '000', _) => __UNALLOCATED - when ('101', '000', '00') => __UNALLOCATED - when ('101', '000', '01') => __encoding aarch64_system_exceptions_debug_exception // DCPS1_DC_exception - when ('101', '000', '10') => __encoding aarch64_system_exceptions_debug_exception // DCPS2_DC_exception - when ('101', '000', '11') => __encoding aarch64_system_exceptions_debug_exception // DCPS3_DC_exception - when ('110', '000', _) => __UNALLOCATED - when ('111', '000', _) => __UNALLOCATED - when ('110', _, '01000000110010', _, '11111') => // hints - __field CRm 8 +: 4 - __field op2 5 +: 3 - case (CRm, op2) of - when (_, _) => __encoding aarch64_system_hints // HINT_HM_hints - when ('0000', '000') => __encoding aarch64_system_hints // NOP_HI_hints - when ('0000', '001') => __encoding aarch64_system_hints // YIELD_HI_hints - when ('0000', '010') => __encoding aarch64_system_hints // WFE_HI_hints - when ('0000', '011') => __encoding aarch64_system_hints // WFI_HI_hints - when ('0000', '100') => __encoding aarch64_system_hints // SEV_HI_hints - when ('0000', '101') => __encoding aarch64_system_hints // SEVL_HI_hints - when ('0000', '110') => __encoding aarch64_system_hints // DGH_HI_hints - when ('0000', '111') => __encoding aarch64_integer_pac_strip_hint // XPACLRI_HI_hints - when ('0001', '000') => __encoding aarch64_integer_pac_pacia_hint // PACIA1716_HI_hints - when ('0001', '010') => __encoding aarch64_integer_pac_pacib_hint // PACIB1716_HI_hints - when ('0001', '100') => __encoding aarch64_integer_pac_autia_hint // AUTIA1716_HI_hints - when ('0001', '110') => __encoding aarch64_integer_pac_autib_hint // AUTIB1716_HI_hints - when ('0010', '000') => __encoding aarch64_system_hints // ESB_HI_hints - when ('0010', '001') => __encoding aarch64_system_hints // PSB_HC_hints - when ('0010', '010') => __encoding aarch64_system_hints // TSB_HC_hints - when ('0010', '100') => __encoding aarch64_system_hints // CSDB_HI_hints - when ('0011', '000') => __encoding aarch64_integer_pac_pacia_hint // PACIAZ_HI_hints - when ('0011', '001') => __encoding aarch64_integer_pac_pacia_hint // PACIASP_HI_hints - when ('0011', '010') => __encoding aarch64_integer_pac_pacib_hint // PACIBZ_HI_hints - when ('0011', '011') => __encoding aarch64_integer_pac_pacib_hint // PACIBSP_HI_hints - when ('0011', '100') => __encoding aarch64_integer_pac_autia_hint // AUTIAZ_HI_hints - when ('0011', '101') => __encoding aarch64_integer_pac_autia_hint // AUTIASP_HI_hints - when ('0011', '110') => __encoding aarch64_integer_pac_autib_hint // AUTIBZ_HI_hints - when ('0011', '111') => __encoding aarch64_integer_pac_autib_hint // AUTIBSP_HI_hints - when ('0100', 'xx0') => __encoding aarch64_system_hints // BTI_HB_hints - when ('110', _, '01000000110011', _, _) => // barriers - __field CRm 8 +: 4 - __field op2 5 +: 3 - __field Rt 0 +: 5 - case (CRm, op2, Rt) of - when (_, '000', _) => __UNALLOCATED - when (_, '001', _) => __UNALLOCATED - when (_, '010', '11111') => __encoding aarch64_system_monitors // CLREX_BN_barriers - when (_, '101', '11111') => __encoding aarch64_system_barriers_dmb // DMB_BO_barriers - when (_, '110', '11111') => __encoding aarch64_system_barriers_isb // ISB_BI_barriers - when (_, '111', !'11111') => __UNALLOCATED - when (_, '111', '11111') => __encoding aarch64_system_barriers_sb // SB_only_barriers - when (!'0x00', '100', '11111') => __encoding aarch64_system_barriers_dsb // DSB_BO_barriers - when ('0000', '100', '11111') => __encoding aarch64_system_barriers_ssbb // SSBB_only_barriers - when ('0001', '011', _) => __UNALLOCATED - when ('001x', '011', _) => __UNALLOCATED - when ('01xx', '011', _) => __UNALLOCATED - when ('0100', '100', '11111') => __encoding aarch64_system_barriers_pssbb // PSSBB_only_barriers - when ('1xxx', '011', _) => __UNALLOCATED - when ('110', _, '0100000xxx0100', _, _) => // pstate - __field op1 16 +: 3 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __field Rt 0 +: 5 - case (op1, op2, Rt) of - when (_, _, !'11111') => __UNALLOCATED - when (_, _, '11111') => __encoding aarch64_system_register_cpsr // MSR_SI_pstate - when ('000', '000', '11111') => __encoding aarch64_integer_flags_cfinv // CFINV_M_pstate - when ('000', '001', '11111') => __encoding aarch64_integer_flags_xaflag // XAFLAG_M_pstate - when ('000', '010', '11111') => __encoding aarch64_integer_flags_axflag // AXFLAG_M_pstate - when ('110', _, '0100x01xxxxxxx', _, _) => // systeminstrs - __field L 21 +: 1 - __field op1 16 +: 3 - __field CRn 12 +: 4 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __field Rt 0 +: 5 - case (L) of - when ('0') => __encoding aarch64_system_sysops // SYS_CR_systeminstrs - when ('1') => __encoding aarch64_system_sysops // SYSL_RC_systeminstrs - when ('110', _, '0100x1xxxxxxxx', _, _) => // systemmove - __field L 21 +: 1 - __field o0 19 +: 1 - __field op1 16 +: 3 - __field CRn 12 +: 4 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __field Rt 0 +: 5 - case (L) of - when ('0') => __encoding aarch64_system_register_system // MSR_SR_systemmove - when ('1') => __encoding aarch64_system_register_system // MRS_RS_systemmove - when ('110', _, '1xxxxxxxxxxxxx', _, _) => // branch_reg - __field opc 21 +: 4 - __field op2 16 +: 5 - __field op3 10 +: 6 - __field Rn 5 +: 5 - __field op4 0 +: 5 - case (opc, op2, op3, Rn, op4) of - when (_, !'11111', _, _, _) => __UNALLOCATED - when ('0000', '11111', '000000', _, !'00000') => __UNALLOCATED - when ('0000', '11111', '000000', _, '00000') => __encoding aarch64_branch_unconditional_register // BR_64_branch_reg - when ('0000', '11111', '000001', _, _) => __UNALLOCATED - when ('0000', '11111', '000010', _, !'11111') => __UNALLOCATED - when ('0000', '11111', '000010', _, '11111') => __encoding aarch64_branch_unconditional_register // BRAAZ_64_branch_reg - when ('0000', '11111', '000011', _, !'11111') => __UNALLOCATED - when ('0000', '11111', '000011', _, '11111') => __encoding aarch64_branch_unconditional_register // BRABZ_64_branch_reg - when ('0000', '11111', '0001xx', _, _) => __UNALLOCATED - when ('0000', '11111', '001xxx', _, _) => __UNALLOCATED - when ('0000', '11111', '01xxxx', _, _) => __UNALLOCATED - when ('0000', '11111', '1xxxxx', _, _) => __UNALLOCATED - when ('0001', '11111', '000000', _, !'00000') => __UNALLOCATED - when ('0001', '11111', '000000', _, '00000') => __encoding aarch64_branch_unconditional_register // BLR_64_branch_reg - when ('0001', '11111', '000001', _, _) => __UNALLOCATED - when ('0001', '11111', '000010', _, !'11111') => __UNALLOCATED - when ('0001', '11111', '000010', _, '11111') => __encoding aarch64_branch_unconditional_register // BLRAAZ_64_branch_reg - when ('0001', '11111', '000011', _, !'11111') => __UNALLOCATED - when ('0001', '11111', '000011', _, '11111') => __encoding aarch64_branch_unconditional_register // BLRABZ_64_branch_reg - when ('0001', '11111', '0001xx', _, _) => __UNALLOCATED - when ('0001', '11111', '001xxx', _, _) => __UNALLOCATED - when ('0001', '11111', '01xxxx', _, _) => __UNALLOCATED - when ('0001', '11111', '1xxxxx', _, _) => __UNALLOCATED - when ('0010', '11111', '000000', _, !'00000') => __UNALLOCATED - when ('0010', '11111', '000000', _, '00000') => __encoding aarch64_branch_unconditional_register // RET_64R_branch_reg - when ('0010', '11111', '000001', _, _) => __UNALLOCATED - when ('0010', '11111', '000010', !'11111', !'11111') => __UNALLOCATED - when ('0010', '11111', '000010', '11111', '11111') => __encoding aarch64_branch_unconditional_register // RETAA_64E_branch_reg - when ('0010', '11111', '000011', !'11111', !'11111') => __UNALLOCATED - when ('0010', '11111', '000011', '11111', '11111') => __encoding aarch64_branch_unconditional_register // RETAB_64E_branch_reg - when ('0010', '11111', '0001xx', _, _) => __UNALLOCATED - when ('0010', '11111', '001xxx', _, _) => __UNALLOCATED - when ('0010', '11111', '01xxxx', _, _) => __UNALLOCATED - when ('0010', '11111', '1xxxxx', _, _) => __UNALLOCATED - when ('0011', '11111', _, _, _) => __UNALLOCATED - when ('0100', '11111', '000000', !'11111', !'00000') => __UNALLOCATED - when ('0100', '11111', '000000', !'11111', '00000') => __UNALLOCATED - when ('0100', '11111', '000000', '11111', !'00000') => __UNALLOCATED - when ('0100', '11111', '000000', '11111', '00000') => __encoding aarch64_branch_unconditional_eret // ERET_64E_branch_reg - when ('0100', '11111', '000001', _, _) => __UNALLOCATED - when ('0100', '11111', '000010', !'11111', !'11111') => __UNALLOCATED - when ('0100', '11111', '000010', !'11111', '11111') => __UNALLOCATED - when ('0100', '11111', '000010', '11111', !'11111') => __UNALLOCATED - when ('0100', '11111', '000010', '11111', '11111') => __encoding aarch64_branch_unconditional_eret // ERETAA_64E_branch_reg - when ('0100', '11111', '000011', !'11111', !'11111') => __UNALLOCATED - when ('0100', '11111', '000011', !'11111', '11111') => __UNALLOCATED - when ('0100', '11111', '000011', '11111', !'11111') => __UNALLOCATED - when ('0100', '11111', '000011', '11111', '11111') => __encoding aarch64_branch_unconditional_eret // ERETAB_64E_branch_reg - when ('0100', '11111', '0001xx', _, _) => __UNALLOCATED - when ('0100', '11111', '001xxx', _, _) => __UNALLOCATED - when ('0100', '11111', '01xxxx', _, _) => __UNALLOCATED - when ('0100', '11111', '1xxxxx', _, _) => __UNALLOCATED - when ('0101', '11111', !'000000', _, _) => __UNALLOCATED - when ('0101', '11111', '000000', !'11111', !'00000') => __UNALLOCATED - when ('0101', '11111', '000000', !'11111', '00000') => __UNALLOCATED - when ('0101', '11111', '000000', '11111', !'00000') => __UNALLOCATED - when ('0101', '11111', '000000', '11111', '00000') => __encoding aarch64_branch_unconditional_dret // DRPS_64E_branch_reg - when ('011x', '11111', _, _, _) => __UNALLOCATED - when ('1000', '11111', '00000x', _, _) => __UNALLOCATED - when ('1000', '11111', '000010', _, _) => __encoding aarch64_branch_unconditional_register // BRAA_64P_branch_reg - when ('1000', '11111', '000011', _, _) => __encoding aarch64_branch_unconditional_register // BRAB_64P_branch_reg - when ('1000', '11111', '0001xx', _, _) => __UNALLOCATED - when ('1000', '11111', '001xxx', _, _) => __UNALLOCATED - when ('1000', '11111', '01xxxx', _, _) => __UNALLOCATED - when ('1000', '11111', '1xxxxx', _, _) => __UNALLOCATED - when ('1001', '11111', '00000x', _, _) => __UNALLOCATED - when ('1001', '11111', '000010', _, _) => __encoding aarch64_branch_unconditional_register // BLRAA_64P_branch_reg - when ('1001', '11111', '000011', _, _) => __encoding aarch64_branch_unconditional_register // BLRAB_64P_branch_reg - when ('1001', '11111', '0001xx', _, _) => __UNALLOCATED - when ('1001', '11111', '001xxx', _, _) => __UNALLOCATED - when ('1001', '11111', '01xxxx', _, _) => __UNALLOCATED - when ('1001', '11111', '1xxxxx', _, _) => __UNALLOCATED - when ('101x', '11111', _, _, _) => __UNALLOCATED - when ('11xx', '11111', _, _, _) => __UNALLOCATED - when ('x00', _, _, _, _) => // branch_imm - __field op 31 +: 1 - __field imm26 0 +: 26 - case (op) of - when ('0') => __encoding aarch64_branch_unconditional_immediate // B_only_branch_imm - when ('1') => __encoding aarch64_branch_unconditional_immediate // BL_only_branch_imm - when ('x01', _, '0xxxxxxxxxxxxx', _, _) => // compbranch - __field sf 31 +: 1 - __field op 24 +: 1 - __field imm19 5 +: 19 - __field Rt 0 +: 5 - case (sf, op) of - when ('0', '0') => __encoding aarch64_branch_conditional_compare // CBZ_32_compbranch - when ('0', '1') => __encoding aarch64_branch_conditional_compare // CBNZ_32_compbranch - when ('1', '0') => __encoding aarch64_branch_conditional_compare // CBZ_64_compbranch - when ('1', '1') => __encoding aarch64_branch_conditional_compare // CBNZ_64_compbranch - when ('x01', _, '1xxxxxxxxxxxxx', _, _) => // testbranch - __field b5 31 +: 1 - __field op 24 +: 1 - __field b40 19 +: 5 - __field imm14 5 +: 14 - __field Rt 0 +: 5 - case (op) of - when ('0') => __encoding aarch64_branch_conditional_test // TBZ_only_testbranch - when ('1') => __encoding aarch64_branch_conditional_test // TBNZ_only_testbranch - when (_, 'x1x0x', _) => - // ldst - case (28 +: 4, 27 +: 1, 26 +: 1, 25 +: 1, 23 +: 2, 22 +: 1, 16 +: 6, 12 +: 4, 10 +: 2, 0 +: 10) of - when ('0x00', _, '1', _, '00', _, '000000', _, _, _) => // asisdlse - __field Q 30 +: 1 - __field L 22 +: 1 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (L, opcode) of - when ('0', '0000') => __encoding aarch64_memory_vector_multiple_no_wb // ST4_asisdlse_R4 - when ('0', '0001') => __UNALLOCATED - when ('0', '0010') => __encoding aarch64_memory_vector_multiple_no_wb // ST1_asisdlse_R4_4v - when ('0', '0011') => __UNALLOCATED - when ('0', '0100') => __encoding aarch64_memory_vector_multiple_no_wb // ST3_asisdlse_R3 - when ('0', '0101') => __UNALLOCATED - when ('0', '0110') => __encoding aarch64_memory_vector_multiple_no_wb // ST1_asisdlse_R3_3v - when ('0', '0111') => __encoding aarch64_memory_vector_multiple_no_wb // ST1_asisdlse_R1_1v - when ('0', '1000') => __encoding aarch64_memory_vector_multiple_no_wb // ST2_asisdlse_R2 - when ('0', '1001') => __UNALLOCATED - when ('0', '1010') => __encoding aarch64_memory_vector_multiple_no_wb // ST1_asisdlse_R2_2v - when ('0', '1011') => __UNALLOCATED - when ('0', '11xx') => __UNALLOCATED - when ('1', '0000') => __encoding aarch64_memory_vector_multiple_no_wb // LD4_asisdlse_R4 - when ('1', '0001') => __UNALLOCATED - when ('1', '0010') => __encoding aarch64_memory_vector_multiple_no_wb // LD1_asisdlse_R4_4v - when ('1', '0011') => __UNALLOCATED - when ('1', '0100') => __encoding aarch64_memory_vector_multiple_no_wb // LD3_asisdlse_R3 - when ('1', '0101') => __UNALLOCATED - when ('1', '0110') => __encoding aarch64_memory_vector_multiple_no_wb // LD1_asisdlse_R3_3v - when ('1', '0111') => __encoding aarch64_memory_vector_multiple_no_wb // LD1_asisdlse_R1_1v - when ('1', '1000') => __encoding aarch64_memory_vector_multiple_no_wb // LD2_asisdlse_R2 - when ('1', '1001') => __UNALLOCATED - when ('1', '1010') => __encoding aarch64_memory_vector_multiple_no_wb // LD1_asisdlse_R2_2v - when ('1', '1011') => __UNALLOCATED - when ('1', '11xx') => __UNALLOCATED - when ('0x00', _, '1', _, '01', _, '0xxxxx', _, _, _) => // asisdlsep - __field Q 30 +: 1 - __field L 22 +: 1 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (L, Rm, opcode) of - when ('0', _, '0001') => __UNALLOCATED - when ('0', _, '0011') => __UNALLOCATED - when ('0', _, '0101') => __UNALLOCATED - when ('0', _, '1001') => __UNALLOCATED - when ('0', _, '1011') => __UNALLOCATED - when ('0', _, '11xx') => __UNALLOCATED - when ('0', !'11111', '0000') => __encoding aarch64_memory_vector_multiple_post_inc // ST4_asisdlsep_R4_r - when ('0', !'11111', '0010') => __encoding aarch64_memory_vector_multiple_post_inc // ST1_asisdlsep_R4_r4 - when ('0', !'11111', '0100') => __encoding aarch64_memory_vector_multiple_post_inc // ST3_asisdlsep_R3_r - when ('0', !'11111', '0110') => __encoding aarch64_memory_vector_multiple_post_inc // ST1_asisdlsep_R3_r3 - when ('0', !'11111', '0111') => __encoding aarch64_memory_vector_multiple_post_inc // ST1_asisdlsep_R1_r1 - when ('0', !'11111', '1000') => __encoding aarch64_memory_vector_multiple_post_inc // ST2_asisdlsep_R2_r - when ('0', !'11111', '1010') => __encoding aarch64_memory_vector_multiple_post_inc // ST1_asisdlsep_R2_r2 - when ('0', '11111', '0000') => __encoding aarch64_memory_vector_multiple_post_inc // ST4_asisdlsep_I4_i - when ('0', '11111', '0010') => __encoding aarch64_memory_vector_multiple_post_inc // ST1_asisdlsep_I4_i4 - when ('0', '11111', '0100') => __encoding aarch64_memory_vector_multiple_post_inc // ST3_asisdlsep_I3_i - when ('0', '11111', '0110') => __encoding aarch64_memory_vector_multiple_post_inc // ST1_asisdlsep_I3_i3 - when ('0', '11111', '0111') => __encoding aarch64_memory_vector_multiple_post_inc // ST1_asisdlsep_I1_i1 - when ('0', '11111', '1000') => __encoding aarch64_memory_vector_multiple_post_inc // ST2_asisdlsep_I2_i - when ('0', '11111', '1010') => __encoding aarch64_memory_vector_multiple_post_inc // ST1_asisdlsep_I2_i2 - when ('1', _, '0001') => __UNALLOCATED - when ('1', _, '0011') => __UNALLOCATED - when ('1', _, '0101') => __UNALLOCATED - when ('1', _, '1001') => __UNALLOCATED - when ('1', _, '1011') => __UNALLOCATED - when ('1', _, '11xx') => __UNALLOCATED - when ('1', !'11111', '0000') => __encoding aarch64_memory_vector_multiple_post_inc // LD4_asisdlsep_R4_r - when ('1', !'11111', '0010') => __encoding aarch64_memory_vector_multiple_post_inc // LD1_asisdlsep_R4_r4 - when ('1', !'11111', '0100') => __encoding aarch64_memory_vector_multiple_post_inc // LD3_asisdlsep_R3_r - when ('1', !'11111', '0110') => __encoding aarch64_memory_vector_multiple_post_inc // LD1_asisdlsep_R3_r3 - when ('1', !'11111', '0111') => __encoding aarch64_memory_vector_multiple_post_inc // LD1_asisdlsep_R1_r1 - when ('1', !'11111', '1000') => __encoding aarch64_memory_vector_multiple_post_inc // LD2_asisdlsep_R2_r - when ('1', !'11111', '1010') => __encoding aarch64_memory_vector_multiple_post_inc // LD1_asisdlsep_R2_r2 - when ('1', '11111', '0000') => __encoding aarch64_memory_vector_multiple_post_inc // LD4_asisdlsep_I4_i - when ('1', '11111', '0010') => __encoding aarch64_memory_vector_multiple_post_inc // LD1_asisdlsep_I4_i4 - when ('1', '11111', '0100') => __encoding aarch64_memory_vector_multiple_post_inc // LD3_asisdlsep_I3_i - when ('1', '11111', '0110') => __encoding aarch64_memory_vector_multiple_post_inc // LD1_asisdlsep_I3_i3 - when ('1', '11111', '0111') => __encoding aarch64_memory_vector_multiple_post_inc // LD1_asisdlsep_I1_i1 - when ('1', '11111', '1000') => __encoding aarch64_memory_vector_multiple_post_inc // LD2_asisdlsep_I2_i - when ('1', '11111', '1010') => __encoding aarch64_memory_vector_multiple_post_inc // LD1_asisdlsep_I2_i2 - when ('0x00', _, '1', _, '0x', _, '1xxxxx', _, _, _) => __UNPREDICTABLE - when ('0x00', _, '1', _, '10', _, 'x00000', _, _, _) => // asisdlso - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (L, R, opcode, S, size) of - when ('0', _, '11x', _, _) => __UNALLOCATED - when ('0', '0', '000', _, _) => __encoding aarch64_memory_vector_single_no_wb // ST1_asisdlso_B1_1b - when ('0', '0', '001', _, _) => __encoding aarch64_memory_vector_single_no_wb // ST3_asisdlso_B3_3b - when ('0', '0', '010', _, 'x0') => __encoding aarch64_memory_vector_single_no_wb // ST1_asisdlso_H1_1h - when ('0', '0', '010', _, 'x1') => __UNALLOCATED - when ('0', '0', '011', _, 'x0') => __encoding aarch64_memory_vector_single_no_wb // ST3_asisdlso_H3_3h - when ('0', '0', '011', _, 'x1') => __UNALLOCATED - when ('0', '0', '100', _, '00') => __encoding aarch64_memory_vector_single_no_wb // ST1_asisdlso_S1_1s - when ('0', '0', '100', _, '1x') => __UNALLOCATED - when ('0', '0', '100', '0', '01') => __encoding aarch64_memory_vector_single_no_wb // ST1_asisdlso_D1_1d - when ('0', '0', '100', '1', '01') => __UNALLOCATED - when ('0', '0', '101', _, '00') => __encoding aarch64_memory_vector_single_no_wb // ST3_asisdlso_S3_3s - when ('0', '0', '101', _, '10') => __UNALLOCATED - when ('0', '0', '101', '0', '01') => __encoding aarch64_memory_vector_single_no_wb // ST3_asisdlso_D3_3d - when ('0', '0', '101', '0', '11') => __UNALLOCATED - when ('0', '0', '101', '1', 'x1') => __UNALLOCATED - when ('0', '1', '000', _, _) => __encoding aarch64_memory_vector_single_no_wb // ST2_asisdlso_B2_2b - when ('0', '1', '001', _, _) => __encoding aarch64_memory_vector_single_no_wb // ST4_asisdlso_B4_4b - when ('0', '1', '010', _, 'x0') => __encoding aarch64_memory_vector_single_no_wb // ST2_asisdlso_H2_2h - when ('0', '1', '010', _, 'x1') => __UNALLOCATED - when ('0', '1', '011', _, 'x0') => __encoding aarch64_memory_vector_single_no_wb // ST4_asisdlso_H4_4h - when ('0', '1', '011', _, 'x1') => __UNALLOCATED - when ('0', '1', '100', _, '00') => __encoding aarch64_memory_vector_single_no_wb // ST2_asisdlso_S2_2s - when ('0', '1', '100', _, '10') => __UNALLOCATED - when ('0', '1', '100', '0', '01') => __encoding aarch64_memory_vector_single_no_wb // ST2_asisdlso_D2_2d - when ('0', '1', '100', '0', '11') => __UNALLOCATED - when ('0', '1', '100', '1', 'x1') => __UNALLOCATED - when ('0', '1', '101', _, '00') => __encoding aarch64_memory_vector_single_no_wb // ST4_asisdlso_S4_4s - when ('0', '1', '101', _, '10') => __UNALLOCATED - when ('0', '1', '101', '0', '01') => __encoding aarch64_memory_vector_single_no_wb // ST4_asisdlso_D4_4d - when ('0', '1', '101', '0', '11') => __UNALLOCATED - when ('0', '1', '101', '1', 'x1') => __UNALLOCATED - when ('1', '0', '000', _, _) => __encoding aarch64_memory_vector_single_no_wb // LD1_asisdlso_B1_1b - when ('1', '0', '001', _, _) => __encoding aarch64_memory_vector_single_no_wb // LD3_asisdlso_B3_3b - when ('1', '0', '010', _, 'x0') => __encoding aarch64_memory_vector_single_no_wb // LD1_asisdlso_H1_1h - when ('1', '0', '010', _, 'x1') => __UNALLOCATED - when ('1', '0', '011', _, 'x0') => __encoding aarch64_memory_vector_single_no_wb // LD3_asisdlso_H3_3h - when ('1', '0', '011', _, 'x1') => __UNALLOCATED - when ('1', '0', '100', _, '00') => __encoding aarch64_memory_vector_single_no_wb // LD1_asisdlso_S1_1s - when ('1', '0', '100', _, '1x') => __UNALLOCATED - when ('1', '0', '100', '0', '01') => __encoding aarch64_memory_vector_single_no_wb // LD1_asisdlso_D1_1d - when ('1', '0', '100', '1', '01') => __UNALLOCATED - when ('1', '0', '101', _, '00') => __encoding aarch64_memory_vector_single_no_wb // LD3_asisdlso_S3_3s - when ('1', '0', '101', _, '10') => __UNALLOCATED - when ('1', '0', '101', '0', '01') => __encoding aarch64_memory_vector_single_no_wb // LD3_asisdlso_D3_3d - when ('1', '0', '101', '0', '11') => __UNALLOCATED - when ('1', '0', '101', '1', 'x1') => __UNALLOCATED - when ('1', '0', '110', '0', _) => __encoding aarch64_memory_vector_single_no_wb // LD1R_asisdlso_R1 - when ('1', '0', '110', '1', _) => __UNALLOCATED - when ('1', '0', '111', '0', _) => __encoding aarch64_memory_vector_single_no_wb // LD3R_asisdlso_R3 - when ('1', '0', '111', '1', _) => __UNALLOCATED - when ('1', '1', '000', _, _) => __encoding aarch64_memory_vector_single_no_wb // LD2_asisdlso_B2_2b - when ('1', '1', '001', _, _) => __encoding aarch64_memory_vector_single_no_wb // LD4_asisdlso_B4_4b - when ('1', '1', '010', _, 'x0') => __encoding aarch64_memory_vector_single_no_wb // LD2_asisdlso_H2_2h - when ('1', '1', '010', _, 'x1') => __UNALLOCATED - when ('1', '1', '011', _, 'x0') => __encoding aarch64_memory_vector_single_no_wb // LD4_asisdlso_H4_4h - when ('1', '1', '011', _, 'x1') => __UNALLOCATED - when ('1', '1', '100', _, '00') => __encoding aarch64_memory_vector_single_no_wb // LD2_asisdlso_S2_2s - when ('1', '1', '100', _, '10') => __UNALLOCATED - when ('1', '1', '100', '0', '01') => __encoding aarch64_memory_vector_single_no_wb // LD2_asisdlso_D2_2d - when ('1', '1', '100', '0', '11') => __UNALLOCATED - when ('1', '1', '100', '1', 'x1') => __UNALLOCATED - when ('1', '1', '101', _, '00') => __encoding aarch64_memory_vector_single_no_wb // LD4_asisdlso_S4_4s - when ('1', '1', '101', _, '10') => __UNALLOCATED - when ('1', '1', '101', '0', '01') => __encoding aarch64_memory_vector_single_no_wb // LD4_asisdlso_D4_4d - when ('1', '1', '101', '0', '11') => __UNALLOCATED - when ('1', '1', '101', '1', 'x1') => __UNALLOCATED - when ('1', '1', '110', '0', _) => __encoding aarch64_memory_vector_single_no_wb // LD2R_asisdlso_R2 - when ('1', '1', '110', '1', _) => __UNALLOCATED - when ('1', '1', '111', '0', _) => __encoding aarch64_memory_vector_single_no_wb // LD4R_asisdlso_R4 - when ('1', '1', '111', '1', _) => __UNALLOCATED - when ('0x00', _, '1', _, '11', _, _, _, _, _) => // asisdlsop - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (L, R, Rm, opcode, S, size) of - when ('0', _, _, '11x', _, _) => __UNALLOCATED - when ('0', '0', _, '010', _, 'x1') => __UNALLOCATED - when ('0', '0', _, '011', _, 'x1') => __UNALLOCATED - when ('0', '0', _, '100', _, '1x') => __UNALLOCATED - when ('0', '0', _, '100', '1', '01') => __UNALLOCATED - when ('0', '0', _, '101', _, '10') => __UNALLOCATED - when ('0', '0', _, '101', '0', '11') => __UNALLOCATED - when ('0', '0', _, '101', '1', 'x1') => __UNALLOCATED - when ('0', '0', !'11111', '000', _, _) => __encoding aarch64_memory_vector_single_post_inc // ST1_asisdlsop_BX1_r1b - when ('0', '0', !'11111', '001', _, _) => __encoding aarch64_memory_vector_single_post_inc // ST3_asisdlsop_BX3_r3b - when ('0', '0', !'11111', '010', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // ST1_asisdlsop_HX1_r1h - when ('0', '0', !'11111', '011', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // ST3_asisdlsop_HX3_r3h - when ('0', '0', !'11111', '100', _, '00') => __encoding aarch64_memory_vector_single_post_inc // ST1_asisdlsop_SX1_r1s - when ('0', '0', !'11111', '100', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // ST1_asisdlsop_DX1_r1d - when ('0', '0', !'11111', '101', _, '00') => __encoding aarch64_memory_vector_single_post_inc // ST3_asisdlsop_SX3_r3s - when ('0', '0', !'11111', '101', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // ST3_asisdlsop_DX3_r3d - when ('0', '0', '11111', '000', _, _) => __encoding aarch64_memory_vector_single_post_inc // ST1_asisdlsop_B1_i1b - when ('0', '0', '11111', '001', _, _) => __encoding aarch64_memory_vector_single_post_inc // ST3_asisdlsop_B3_i3b - when ('0', '0', '11111', '010', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // ST1_asisdlsop_H1_i1h - when ('0', '0', '11111', '011', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // ST3_asisdlsop_H3_i3h - when ('0', '0', '11111', '100', _, '00') => __encoding aarch64_memory_vector_single_post_inc // ST1_asisdlsop_S1_i1s - when ('0', '0', '11111', '100', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // ST1_asisdlsop_D1_i1d - when ('0', '0', '11111', '101', _, '00') => __encoding aarch64_memory_vector_single_post_inc // ST3_asisdlsop_S3_i3s - when ('0', '0', '11111', '101', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // ST3_asisdlsop_D3_i3d - when ('0', '1', _, '010', _, 'x1') => __UNALLOCATED - when ('0', '1', _, '011', _, 'x1') => __UNALLOCATED - when ('0', '1', _, '100', _, '10') => __UNALLOCATED - when ('0', '1', _, '100', '0', '11') => __UNALLOCATED - when ('0', '1', _, '100', '1', 'x1') => __UNALLOCATED - when ('0', '1', _, '101', _, '10') => __UNALLOCATED - when ('0', '1', _, '101', '0', '11') => __UNALLOCATED - when ('0', '1', _, '101', '1', 'x1') => __UNALLOCATED - when ('0', '1', !'11111', '000', _, _) => __encoding aarch64_memory_vector_single_post_inc // ST2_asisdlsop_BX2_r2b - when ('0', '1', !'11111', '001', _, _) => __encoding aarch64_memory_vector_single_post_inc // ST4_asisdlsop_BX4_r4b - when ('0', '1', !'11111', '010', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // ST2_asisdlsop_HX2_r2h - when ('0', '1', !'11111', '011', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // ST4_asisdlsop_HX4_r4h - when ('0', '1', !'11111', '100', _, '00') => __encoding aarch64_memory_vector_single_post_inc // ST2_asisdlsop_SX2_r2s - when ('0', '1', !'11111', '100', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // ST2_asisdlsop_DX2_r2d - when ('0', '1', !'11111', '101', _, '00') => __encoding aarch64_memory_vector_single_post_inc // ST4_asisdlsop_SX4_r4s - when ('0', '1', !'11111', '101', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // ST4_asisdlsop_DX4_r4d - when ('0', '1', '11111', '000', _, _) => __encoding aarch64_memory_vector_single_post_inc // ST2_asisdlsop_B2_i2b - when ('0', '1', '11111', '001', _, _) => __encoding aarch64_memory_vector_single_post_inc // ST4_asisdlsop_B4_i4b - when ('0', '1', '11111', '010', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // ST2_asisdlsop_H2_i2h - when ('0', '1', '11111', '011', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // ST4_asisdlsop_H4_i4h - when ('0', '1', '11111', '100', _, '00') => __encoding aarch64_memory_vector_single_post_inc // ST2_asisdlsop_S2_i2s - when ('0', '1', '11111', '100', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // ST2_asisdlsop_D2_i2d - when ('0', '1', '11111', '101', _, '00') => __encoding aarch64_memory_vector_single_post_inc // ST4_asisdlsop_S4_i4s - when ('0', '1', '11111', '101', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // ST4_asisdlsop_D4_i4d - when ('1', '0', _, '010', _, 'x1') => __UNALLOCATED - when ('1', '0', _, '011', _, 'x1') => __UNALLOCATED - when ('1', '0', _, '100', _, '1x') => __UNALLOCATED - when ('1', '0', _, '100', '1', '01') => __UNALLOCATED - when ('1', '0', _, '101', _, '10') => __UNALLOCATED - when ('1', '0', _, '101', '0', '11') => __UNALLOCATED - when ('1', '0', _, '101', '1', 'x1') => __UNALLOCATED - when ('1', '0', _, '110', '1', _) => __UNALLOCATED - when ('1', '0', _, '111', '1', _) => __UNALLOCATED - when ('1', '0', !'11111', '000', _, _) => __encoding aarch64_memory_vector_single_post_inc // LD1_asisdlsop_BX1_r1b - when ('1', '0', !'11111', '001', _, _) => __encoding aarch64_memory_vector_single_post_inc // LD3_asisdlsop_BX3_r3b - when ('1', '0', !'11111', '010', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // LD1_asisdlsop_HX1_r1h - when ('1', '0', !'11111', '011', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // LD3_asisdlsop_HX3_r3h - when ('1', '0', !'11111', '100', _, '00') => __encoding aarch64_memory_vector_single_post_inc // LD1_asisdlsop_SX1_r1s - when ('1', '0', !'11111', '100', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // LD1_asisdlsop_DX1_r1d - when ('1', '0', !'11111', '101', _, '00') => __encoding aarch64_memory_vector_single_post_inc // LD3_asisdlsop_SX3_r3s - when ('1', '0', !'11111', '101', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // LD3_asisdlsop_DX3_r3d - when ('1', '0', !'11111', '110', '0', _) => __encoding aarch64_memory_vector_single_post_inc // LD1R_asisdlsop_RX1_r - when ('1', '0', !'11111', '111', '0', _) => __encoding aarch64_memory_vector_single_post_inc // LD3R_asisdlsop_RX3_r - when ('1', '0', '11111', '000', _, _) => __encoding aarch64_memory_vector_single_post_inc // LD1_asisdlsop_B1_i1b - when ('1', '0', '11111', '001', _, _) => __encoding aarch64_memory_vector_single_post_inc // LD3_asisdlsop_B3_i3b - when ('1', '0', '11111', '010', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // LD1_asisdlsop_H1_i1h - when ('1', '0', '11111', '011', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // LD3_asisdlsop_H3_i3h - when ('1', '0', '11111', '100', _, '00') => __encoding aarch64_memory_vector_single_post_inc // LD1_asisdlsop_S1_i1s - when ('1', '0', '11111', '100', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // LD1_asisdlsop_D1_i1d - when ('1', '0', '11111', '101', _, '00') => __encoding aarch64_memory_vector_single_post_inc // LD3_asisdlsop_S3_i3s - when ('1', '0', '11111', '101', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // LD3_asisdlsop_D3_i3d - when ('1', '0', '11111', '110', '0', _) => __encoding aarch64_memory_vector_single_post_inc // LD1R_asisdlsop_R1_i - when ('1', '0', '11111', '111', '0', _) => __encoding aarch64_memory_vector_single_post_inc // LD3R_asisdlsop_R3_i - when ('1', '1', _, '010', _, 'x1') => __UNALLOCATED - when ('1', '1', _, '011', _, 'x1') => __UNALLOCATED - when ('1', '1', _, '100', _, '10') => __UNALLOCATED - when ('1', '1', _, '100', '0', '11') => __UNALLOCATED - when ('1', '1', _, '100', '1', 'x1') => __UNALLOCATED - when ('1', '1', _, '101', _, '10') => __UNALLOCATED - when ('1', '1', _, '101', '0', '11') => __UNALLOCATED - when ('1', '1', _, '101', '1', 'x1') => __UNALLOCATED - when ('1', '1', _, '110', '1', _) => __UNALLOCATED - when ('1', '1', _, '111', '1', _) => __UNALLOCATED - when ('1', '1', !'11111', '000', _, _) => __encoding aarch64_memory_vector_single_post_inc // LD2_asisdlsop_BX2_r2b - when ('1', '1', !'11111', '001', _, _) => __encoding aarch64_memory_vector_single_post_inc // LD4_asisdlsop_BX4_r4b - when ('1', '1', !'11111', '010', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // LD2_asisdlsop_HX2_r2h - when ('1', '1', !'11111', '011', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // LD4_asisdlsop_HX4_r4h - when ('1', '1', !'11111', '100', _, '00') => __encoding aarch64_memory_vector_single_post_inc // LD2_asisdlsop_SX2_r2s - when ('1', '1', !'11111', '100', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // LD2_asisdlsop_DX2_r2d - when ('1', '1', !'11111', '101', _, '00') => __encoding aarch64_memory_vector_single_post_inc // LD4_asisdlsop_SX4_r4s - when ('1', '1', !'11111', '101', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // LD4_asisdlsop_DX4_r4d - when ('1', '1', !'11111', '110', '0', _) => __encoding aarch64_memory_vector_single_post_inc // LD2R_asisdlsop_RX2_r - when ('1', '1', !'11111', '111', '0', _) => __encoding aarch64_memory_vector_single_post_inc // LD4R_asisdlsop_RX4_r - when ('1', '1', '11111', '000', _, _) => __encoding aarch64_memory_vector_single_post_inc // LD2_asisdlsop_B2_i2b - when ('1', '1', '11111', '001', _, _) => __encoding aarch64_memory_vector_single_post_inc // LD4_asisdlsop_B4_i4b - when ('1', '1', '11111', '010', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // LD2_asisdlsop_H2_i2h - when ('1', '1', '11111', '011', _, 'x0') => __encoding aarch64_memory_vector_single_post_inc // LD4_asisdlsop_H4_i4h - when ('1', '1', '11111', '100', _, '00') => __encoding aarch64_memory_vector_single_post_inc // LD2_asisdlsop_S2_i2s - when ('1', '1', '11111', '100', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // LD2_asisdlsop_D2_i2d - when ('1', '1', '11111', '101', _, '00') => __encoding aarch64_memory_vector_single_post_inc // LD4_asisdlsop_S4_i4s - when ('1', '1', '11111', '101', '0', '01') => __encoding aarch64_memory_vector_single_post_inc // LD4_asisdlsop_D4_i4d - when ('1', '1', '11111', '110', '0', _) => __encoding aarch64_memory_vector_single_post_inc // LD2R_asisdlsop_R2_i - when ('1', '1', '11111', '111', '0', _) => __encoding aarch64_memory_vector_single_post_inc // LD4R_asisdlsop_R4_i - when ('0x00', _, '1', _, 'x0', _, 'x1xxxx', _, _, _) => __UNPREDICTABLE - when ('0x00', _, '1', _, 'x0', _, 'xx1xxx', _, _, _) => __UNPREDICTABLE - when ('0x00', _, '1', _, 'x0', _, 'xxx1xx', _, _, _) => __UNPREDICTABLE - when ('0x00', _, '1', _, 'x0', _, 'xxxx1x', _, _, _) => __UNPREDICTABLE - when ('0x00', _, '1', _, 'x0', _, 'xxxxx1', _, _, _) => __UNPREDICTABLE - when ('1101', _, '0', _, '1x', _, '1xxxxx', _, _, _) => // ldsttags - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field op2 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (opc, imm9, op2) of - when ('00', _, '01') => __encoding aarch64_integer_tags_mcsettagpost // STG_64Spost_ldsttags - when ('00', _, '10') => __encoding aarch64_integer_tags_mcsettag // STG_64Soffset_ldsttags - when ('00', _, '11') => __encoding aarch64_integer_tags_mcsettagpre // STG_64Spre_ldsttags - when ('00', '000000000', '00') => __encoding aarch64_integer_tags_mcsettagandzeroarray // STZGM_64bulk_ldsttags - when ('01', _, '00') => __encoding aarch64_integer_tags_mcgettag // LDG_64Loffset_ldsttags - when ('01', _, '01') => __encoding aarch64_integer_tags_mcsettagandzerodatapost // STZG_64Spost_ldsttags - when ('01', _, '10') => __encoding aarch64_integer_tags_mcsettagandzerodata // STZG_64Soffset_ldsttags - when ('01', _, '11') => __encoding aarch64_integer_tags_mcsettagandzerodatapre // STZG_64Spre_ldsttags - when ('10', _, '01') => __encoding aarch64_integer_tags_mcsettagpairpost // ST2G_64Spost_ldsttags - when ('10', _, '10') => __encoding aarch64_integer_tags_mcsettagpair // ST2G_64Soffset_ldsttags - when ('10', _, '11') => __encoding aarch64_integer_tags_mcsettagpairpre // ST2G_64Spre_ldsttags - when ('10', !'000000000', '00') => __UNALLOCATED - when ('10', '000000000', '00') => __encoding aarch64_integer_tags_mcsettagarray // STGM_64bulk_ldsttags - when ('11', _, '01') => __encoding aarch64_integer_tags_mcsettagpairandzerodatapost // STZ2G_64Spost_ldsttags - when ('11', _, '10') => __encoding aarch64_integer_tags_mcsettagpairandzerodata // STZ2G_64Soffset_ldsttags - when ('11', _, '11') => __encoding aarch64_integer_tags_mcsettagpairandzerodatapre // STZ2G_64Spre_ldsttags - when ('11', !'000000000', '00') => __UNALLOCATED - when ('11', '000000000', '00') => __encoding aarch64_integer_tags_mcgettagarray // LDGM_64bulk_ldsttags - when ('1x00', _, '1', _, _, _, _, _, _, _) => __UNPREDICTABLE - when ('xx00', _, '0', _, '0x', _, _, _, _, _) => // ldstexcl - __field size 30 +: 2 - __field o2 23 +: 1 - __field L 22 +: 1 - __field o1 21 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, o2, L, o1, o0, Rt2) of - when (_, '1', _, '1', _, !'11111') => __UNALLOCATED - when ('0x', '0', _, '1', _, !'11111') => __UNALLOCATED - when ('00', '0', '0', '0', '0', _) => __encoding aarch64_memory_exclusive_single // STXRB_SR32_ldstexcl - when ('00', '0', '0', '0', '1', _) => __encoding aarch64_memory_exclusive_single // STLXRB_SR32_ldstexcl - when ('00', '0', '0', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_pair // CASP_CP32_ldstexcl - when ('00', '0', '0', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_pair // CASPL_CP32_ldstexcl - when ('00', '0', '1', '0', '0', _) => __encoding aarch64_memory_exclusive_single // LDXRB_LR32_ldstexcl - when ('00', '0', '1', '0', '1', _) => __encoding aarch64_memory_exclusive_single // LDAXRB_LR32_ldstexcl - when ('00', '0', '1', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_pair // CASPA_CP32_ldstexcl - when ('00', '0', '1', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_pair // CASPAL_CP32_ldstexcl - when ('00', '1', '0', '0', '0', _) => __encoding aarch64_memory_ordered // STLLRB_SL32_ldstexcl - when ('00', '1', '0', '0', '1', _) => __encoding aarch64_memory_ordered // STLRB_SL32_ldstexcl - when ('00', '1', '0', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASB_C32_ldstexcl - when ('00', '1', '0', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASLB_C32_ldstexcl - when ('00', '1', '1', '0', '0', _) => __encoding aarch64_memory_ordered // LDLARB_LR32_ldstexcl - when ('00', '1', '1', '0', '1', _) => __encoding aarch64_memory_ordered // LDARB_LR32_ldstexcl - when ('00', '1', '1', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASAB_C32_ldstexcl - when ('00', '1', '1', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASALB_C32_ldstexcl - when ('01', '0', '0', '0', '0', _) => __encoding aarch64_memory_exclusive_single // STXRH_SR32_ldstexcl - when ('01', '0', '0', '0', '1', _) => __encoding aarch64_memory_exclusive_single // STLXRH_SR32_ldstexcl - when ('01', '0', '0', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_pair // CASP_CP64_ldstexcl - when ('01', '0', '0', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_pair // CASPL_CP64_ldstexcl - when ('01', '0', '1', '0', '0', _) => __encoding aarch64_memory_exclusive_single // LDXRH_LR32_ldstexcl - when ('01', '0', '1', '0', '1', _) => __encoding aarch64_memory_exclusive_single // LDAXRH_LR32_ldstexcl - when ('01', '0', '1', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_pair // CASPA_CP64_ldstexcl - when ('01', '0', '1', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_pair // CASPAL_CP64_ldstexcl - when ('01', '1', '0', '0', '0', _) => __encoding aarch64_memory_ordered // STLLRH_SL32_ldstexcl - when ('01', '1', '0', '0', '1', _) => __encoding aarch64_memory_ordered // STLRH_SL32_ldstexcl - when ('01', '1', '0', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASH_C32_ldstexcl - when ('01', '1', '0', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASLH_C32_ldstexcl - when ('01', '1', '1', '0', '0', _) => __encoding aarch64_memory_ordered // LDLARH_LR32_ldstexcl - when ('01', '1', '1', '0', '1', _) => __encoding aarch64_memory_ordered // LDARH_LR32_ldstexcl - when ('01', '1', '1', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASAH_C32_ldstexcl - when ('01', '1', '1', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASALH_C32_ldstexcl - when ('10', '0', '0', '0', '0', _) => __encoding aarch64_memory_exclusive_single // STXR_SR32_ldstexcl - when ('10', '0', '0', '0', '1', _) => __encoding aarch64_memory_exclusive_single // STLXR_SR32_ldstexcl - when ('10', '0', '0', '1', '0', _) => __encoding aarch64_memory_exclusive_pair // STXP_SP32_ldstexcl - when ('10', '0', '0', '1', '1', _) => __encoding aarch64_memory_exclusive_pair // STLXP_SP32_ldstexcl - when ('10', '0', '1', '0', '0', _) => __encoding aarch64_memory_exclusive_single // LDXR_LR32_ldstexcl - when ('10', '0', '1', '0', '1', _) => __encoding aarch64_memory_exclusive_single // LDAXR_LR32_ldstexcl - when ('10', '0', '1', '1', '0', _) => __encoding aarch64_memory_exclusive_pair // LDXP_LP32_ldstexcl - when ('10', '0', '1', '1', '1', _) => __encoding aarch64_memory_exclusive_pair // LDAXP_LP32_ldstexcl - when ('10', '1', '0', '0', '0', _) => __encoding aarch64_memory_ordered // STLLR_SL32_ldstexcl - when ('10', '1', '0', '0', '1', _) => __encoding aarch64_memory_ordered // STLR_SL32_ldstexcl - when ('10', '1', '0', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_single // CAS_C32_ldstexcl - when ('10', '1', '0', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASL_C32_ldstexcl - when ('10', '1', '1', '0', '0', _) => __encoding aarch64_memory_ordered // LDLAR_LR32_ldstexcl - when ('10', '1', '1', '0', '1', _) => __encoding aarch64_memory_ordered // LDAR_LR32_ldstexcl - when ('10', '1', '1', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASA_C32_ldstexcl - when ('10', '1', '1', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASAL_C32_ldstexcl - when ('11', '0', '0', '0', '0', _) => __encoding aarch64_memory_exclusive_single // STXR_SR64_ldstexcl - when ('11', '0', '0', '0', '1', _) => __encoding aarch64_memory_exclusive_single // STLXR_SR64_ldstexcl - when ('11', '0', '0', '1', '0', _) => __encoding aarch64_memory_exclusive_pair // STXP_SP64_ldstexcl - when ('11', '0', '0', '1', '1', _) => __encoding aarch64_memory_exclusive_pair // STLXP_SP64_ldstexcl - when ('11', '0', '1', '0', '0', _) => __encoding aarch64_memory_exclusive_single // LDXR_LR64_ldstexcl - when ('11', '0', '1', '0', '1', _) => __encoding aarch64_memory_exclusive_single // LDAXR_LR64_ldstexcl - when ('11', '0', '1', '1', '0', _) => __encoding aarch64_memory_exclusive_pair // LDXP_LP64_ldstexcl - when ('11', '0', '1', '1', '1', _) => __encoding aarch64_memory_exclusive_pair // LDAXP_LP64_ldstexcl - when ('11', '1', '0', '0', '0', _) => __encoding aarch64_memory_ordered // STLLR_SL64_ldstexcl - when ('11', '1', '0', '0', '1', _) => __encoding aarch64_memory_ordered // STLR_SL64_ldstexcl - when ('11', '1', '0', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_single // CAS_C64_ldstexcl - when ('11', '1', '0', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASL_C64_ldstexcl - when ('11', '1', '1', '0', '0', _) => __encoding aarch64_memory_ordered // LDLAR_LR64_ldstexcl - when ('11', '1', '1', '0', '1', _) => __encoding aarch64_memory_ordered // LDAR_LR64_ldstexcl - when ('11', '1', '1', '1', '0', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASA_C64_ldstexcl - when ('11', '1', '1', '1', '1', '11111') => __encoding aarch64_memory_atomicops_cas_single // CASAL_C64_ldstexcl - when ('xx01', _, '0', _, '1x', _, '0xxxxx', _, '00', _) => // ldapstl_unscaled - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, opc) of - when ('00', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // STLURB_32_ldapstl_unscaled - when ('00', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // LDAPURB_32_ldapstl_unscaled - when ('00', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // LDAPURSB_64_ldapstl_unscaled - when ('00', '11') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // LDAPURSB_32_ldapstl_unscaled - when ('01', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // STLURH_32_ldapstl_unscaled - when ('01', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // LDAPURH_32_ldapstl_unscaled - when ('01', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // LDAPURSH_64_ldapstl_unscaled - when ('01', '11') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // LDAPURSH_32_ldapstl_unscaled - when ('10', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // STLUR_32_ldapstl_unscaled - when ('10', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // LDAPUR_32_ldapstl_unscaled - when ('10', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // LDAPURSW_64_ldapstl_unscaled - when ('10', '11') => __UNALLOCATED - when ('11', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // STLUR_64_ldapstl_unscaled - when ('11', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl // LDAPUR_64_ldapstl_unscaled - when ('11', '10') => __UNALLOCATED - when ('11', '11') => __UNALLOCATED - when ('xx01', _, _, _, '0x', _, _, _, _, _) => // loadlit - __field opc 30 +: 2 - __field V 26 +: 1 - __field imm19 5 +: 19 - __field Rt 0 +: 5 - case (opc, V) of - when ('00', '0') => __encoding aarch64_memory_literal_general // LDR_32_loadlit - when ('00', '1') => __encoding aarch64_memory_literal_simdfp // LDR_S_loadlit - when ('01', '0') => __encoding aarch64_memory_literal_general // LDR_64_loadlit - when ('01', '1') => __encoding aarch64_memory_literal_simdfp // LDR_D_loadlit - when ('10', '0') => __encoding aarch64_memory_literal_general // LDRSW_64_loadlit - when ('10', '1') => __encoding aarch64_memory_literal_simdfp // LDR_Q_loadlit - when ('11', '0') => __encoding aarch64_memory_literal_general // PRFM_P_loadlit - when ('11', '1') => __UNALLOCATED - when ('xx10', _, _, _, '00', _, _, _, _, _) => // ldstnapair_offs - __field opc 30 +: 2 - __field V 26 +: 1 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (opc, V, L) of - when ('00', '0', '0') => __encoding aarch64_memory_pair_general_no_alloc // STNP_32_ldstnapair_offs - when ('00', '0', '1') => __encoding aarch64_memory_pair_general_no_alloc // LDNP_32_ldstnapair_offs - when ('00', '1', '0') => __encoding aarch64_memory_pair_simdfp_no_alloc // STNP_S_ldstnapair_offs - when ('00', '1', '1') => __encoding aarch64_memory_pair_simdfp_no_alloc // LDNP_S_ldstnapair_offs - when ('01', '0', _) => __UNALLOCATED - when ('01', '1', '0') => __encoding aarch64_memory_pair_simdfp_no_alloc // STNP_D_ldstnapair_offs - when ('01', '1', '1') => __encoding aarch64_memory_pair_simdfp_no_alloc // LDNP_D_ldstnapair_offs - when ('10', '0', '0') => __encoding aarch64_memory_pair_general_no_alloc // STNP_64_ldstnapair_offs - when ('10', '0', '1') => __encoding aarch64_memory_pair_general_no_alloc // LDNP_64_ldstnapair_offs - when ('10', '1', '0') => __encoding aarch64_memory_pair_simdfp_no_alloc // STNP_Q_ldstnapair_offs - when ('10', '1', '1') => __encoding aarch64_memory_pair_simdfp_no_alloc // LDNP_Q_ldstnapair_offs - when ('11', _, _) => __UNALLOCATED - when ('xx10', _, _, _, '01', _, _, _, _, _) => // ldstpair_post - __field opc 30 +: 2 - __field V 26 +: 1 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (opc, V, L) of - when ('00', '0', '0') => __encoding aarch64_memory_pair_general_post_idx // STP_32_ldstpair_post - when ('00', '0', '1') => __encoding aarch64_memory_pair_general_post_idx // LDP_32_ldstpair_post - when ('00', '1', '0') => __encoding aarch64_memory_pair_simdfp_post_idx // STP_S_ldstpair_post - when ('00', '1', '1') => __encoding aarch64_memory_pair_simdfp_post_idx // LDP_S_ldstpair_post - when ('01', '0', '0') => __encoding aarch64_integer_tags_mcsettaganddatapairpost // STGP_64_ldstpair_post - when ('01', '0', '1') => __encoding aarch64_memory_pair_general_post_idx // LDPSW_64_ldstpair_post - when ('01', '1', '0') => __encoding aarch64_memory_pair_simdfp_post_idx // STP_D_ldstpair_post - when ('01', '1', '1') => __encoding aarch64_memory_pair_simdfp_post_idx // LDP_D_ldstpair_post - when ('10', '0', '0') => __encoding aarch64_memory_pair_general_post_idx // STP_64_ldstpair_post - when ('10', '0', '1') => __encoding aarch64_memory_pair_general_post_idx // LDP_64_ldstpair_post - when ('10', '1', '0') => __encoding aarch64_memory_pair_simdfp_post_idx // STP_Q_ldstpair_post - when ('10', '1', '1') => __encoding aarch64_memory_pair_simdfp_post_idx // LDP_Q_ldstpair_post - when ('11', _, _) => __UNALLOCATED - when ('xx10', _, _, _, '10', _, _, _, _, _) => // ldstpair_off - __field opc 30 +: 2 - __field V 26 +: 1 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (opc, V, L) of - when ('00', '0', '0') => __encoding aarch64_memory_pair_general_offset // STP_32_ldstpair_off - when ('00', '0', '1') => __encoding aarch64_memory_pair_general_offset // LDP_32_ldstpair_off - when ('00', '1', '0') => __encoding aarch64_memory_pair_simdfp_offset // STP_S_ldstpair_off - when ('00', '1', '1') => __encoding aarch64_memory_pair_simdfp_offset // LDP_S_ldstpair_off - when ('01', '0', '0') => __encoding aarch64_integer_tags_mcsettaganddatapair // STGP_64_ldstpair_off - when ('01', '0', '1') => __encoding aarch64_memory_pair_general_offset // LDPSW_64_ldstpair_off - when ('01', '1', '0') => __encoding aarch64_memory_pair_simdfp_offset // STP_D_ldstpair_off - when ('01', '1', '1') => __encoding aarch64_memory_pair_simdfp_offset // LDP_D_ldstpair_off - when ('10', '0', '0') => __encoding aarch64_memory_pair_general_offset // STP_64_ldstpair_off - when ('10', '0', '1') => __encoding aarch64_memory_pair_general_offset // LDP_64_ldstpair_off - when ('10', '1', '0') => __encoding aarch64_memory_pair_simdfp_offset // STP_Q_ldstpair_off - when ('10', '1', '1') => __encoding aarch64_memory_pair_simdfp_offset // LDP_Q_ldstpair_off - when ('11', _, _) => __UNALLOCATED - when ('xx10', _, _, _, '11', _, _, _, _, _) => // ldstpair_pre - __field opc 30 +: 2 - __field V 26 +: 1 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (opc, V, L) of - when ('00', '0', '0') => __encoding aarch64_memory_pair_general_pre_idx // STP_32_ldstpair_pre - when ('00', '0', '1') => __encoding aarch64_memory_pair_general_pre_idx // LDP_32_ldstpair_pre - when ('00', '1', '0') => __encoding aarch64_memory_pair_simdfp_pre_idx // STP_S_ldstpair_pre - when ('00', '1', '1') => __encoding aarch64_memory_pair_simdfp_pre_idx // LDP_S_ldstpair_pre - when ('01', '0', '0') => __encoding aarch64_integer_tags_mcsettaganddatapairpre // STGP_64_ldstpair_pre - when ('01', '0', '1') => __encoding aarch64_memory_pair_general_pre_idx // LDPSW_64_ldstpair_pre - when ('01', '1', '0') => __encoding aarch64_memory_pair_simdfp_pre_idx // STP_D_ldstpair_pre - when ('01', '1', '1') => __encoding aarch64_memory_pair_simdfp_pre_idx // LDP_D_ldstpair_pre - when ('10', '0', '0') => __encoding aarch64_memory_pair_general_pre_idx // STP_64_ldstpair_pre - when ('10', '0', '1') => __encoding aarch64_memory_pair_general_pre_idx // LDP_64_ldstpair_pre - when ('10', '1', '0') => __encoding aarch64_memory_pair_simdfp_pre_idx // STP_Q_ldstpair_pre - when ('10', '1', '1') => __encoding aarch64_memory_pair_simdfp_pre_idx // LDP_Q_ldstpair_pre - when ('11', _, _) => __UNALLOCATED - when ('xx11', _, _, _, '0x', _, '0xxxxx', _, '00', _) => // ldst_unscaled - __field size 30 +: 2 - __field V 26 +: 1 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, V, opc) of - when ('x1', '1', '1x') => __UNALLOCATED - when ('00', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // STURB_32_ldst_unscaled - when ('00', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // LDURB_32_ldst_unscaled - when ('00', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // LDURSB_64_ldst_unscaled - when ('00', '0', '11') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // LDURSB_32_ldst_unscaled - when ('00', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // STUR_B_ldst_unscaled - when ('00', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // LDUR_B_ldst_unscaled - when ('00', '1', '10') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // STUR_Q_ldst_unscaled - when ('00', '1', '11') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // LDUR_Q_ldst_unscaled - when ('01', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // STURH_32_ldst_unscaled - when ('01', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // LDURH_32_ldst_unscaled - when ('01', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // LDURSH_64_ldst_unscaled - when ('01', '0', '11') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // LDURSH_32_ldst_unscaled - when ('01', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // STUR_H_ldst_unscaled - when ('01', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // LDUR_H_ldst_unscaled - when ('1x', '0', '11') => __UNALLOCATED - when ('1x', '1', '1x') => __UNALLOCATED - when ('10', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // STUR_32_ldst_unscaled - when ('10', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // LDUR_32_ldst_unscaled - when ('10', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // LDURSW_64_ldst_unscaled - when ('10', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // STUR_S_ldst_unscaled - when ('10', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // LDUR_S_ldst_unscaled - when ('11', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // STUR_64_ldst_unscaled - when ('11', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // LDUR_64_ldst_unscaled - when ('11', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_normal // PRFUM_P_ldst_unscaled - when ('11', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // STUR_D_ldst_unscaled - when ('11', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal // LDUR_D_ldst_unscaled - when ('xx11', _, _, _, '0x', _, '0xxxxx', _, '01', _) => // ldst_immpost - __field size 30 +: 2 - __field V 26 +: 1 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, V, opc) of - when ('x1', '1', '1x') => __UNALLOCATED - when ('00', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // STRB_32_ldst_immpost - when ('00', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // LDRB_32_ldst_immpost - when ('00', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // LDRSB_64_ldst_immpost - when ('00', '0', '11') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // LDRSB_32_ldst_immpost - when ('00', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // STR_B_ldst_immpost - when ('00', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // LDR_B_ldst_immpost - when ('00', '1', '10') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // STR_Q_ldst_immpost - when ('00', '1', '11') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // LDR_Q_ldst_immpost - when ('01', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // STRH_32_ldst_immpost - when ('01', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // LDRH_32_ldst_immpost - when ('01', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // LDRSH_64_ldst_immpost - when ('01', '0', '11') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // LDRSH_32_ldst_immpost - when ('01', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // STR_H_ldst_immpost - when ('01', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // LDR_H_ldst_immpost - when ('1x', '0', '11') => __UNALLOCATED - when ('1x', '1', '1x') => __UNALLOCATED - when ('10', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // STR_32_ldst_immpost - when ('10', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // LDR_32_ldst_immpost - when ('10', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // LDRSW_64_ldst_immpost - when ('10', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // STR_S_ldst_immpost - when ('10', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // LDR_S_ldst_immpost - when ('11', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // STR_64_ldst_immpost - when ('11', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_post_idx // LDR_64_ldst_immpost - when ('11', '0', '10') => __UNALLOCATED - when ('11', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // STR_D_ldst_immpost - when ('11', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx // LDR_D_ldst_immpost - when ('xx11', _, _, _, '0x', _, '0xxxxx', _, '10', _) => // ldst_unpriv - __field size 30 +: 2 - __field V 26 +: 1 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, V, opc) of - when (_, '1', _) => __UNALLOCATED - when ('00', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // STTRB_32_ldst_unpriv - when ('00', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // LDTRB_32_ldst_unpriv - when ('00', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // LDTRSB_64_ldst_unpriv - when ('00', '0', '11') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // LDTRSB_32_ldst_unpriv - when ('01', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // STTRH_32_ldst_unpriv - when ('01', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // LDTRH_32_ldst_unpriv - when ('01', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // LDTRSH_64_ldst_unpriv - when ('01', '0', '11') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // LDTRSH_32_ldst_unpriv - when ('1x', '0', '11') => __UNALLOCATED - when ('10', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // STTR_32_ldst_unpriv - when ('10', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // LDTR_32_ldst_unpriv - when ('10', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // LDTRSW_64_ldst_unpriv - when ('11', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // STTR_64_ldst_unpriv - when ('11', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv // LDTR_64_ldst_unpriv - when ('11', '0', '10') => __UNALLOCATED - when ('xx11', _, _, _, '0x', _, '0xxxxx', _, '11', _) => // ldst_immpre - __field size 30 +: 2 - __field V 26 +: 1 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, V, opc) of - when ('x1', '1', '1x') => __UNALLOCATED - when ('00', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // STRB_32_ldst_immpre - when ('00', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // LDRB_32_ldst_immpre - when ('00', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // LDRSB_64_ldst_immpre - when ('00', '0', '11') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // LDRSB_32_ldst_immpre - when ('00', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // STR_B_ldst_immpre - when ('00', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // LDR_B_ldst_immpre - when ('00', '1', '10') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // STR_Q_ldst_immpre - when ('00', '1', '11') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // LDR_Q_ldst_immpre - when ('01', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // STRH_32_ldst_immpre - when ('01', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // LDRH_32_ldst_immpre - when ('01', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // LDRSH_64_ldst_immpre - when ('01', '0', '11') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // LDRSH_32_ldst_immpre - when ('01', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // STR_H_ldst_immpre - when ('01', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // LDR_H_ldst_immpre - when ('1x', '0', '11') => __UNALLOCATED - when ('1x', '1', '1x') => __UNALLOCATED - when ('10', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // STR_32_ldst_immpre - when ('10', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // LDR_32_ldst_immpre - when ('10', '0', '10') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // LDRSW_64_ldst_immpre - when ('10', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // STR_S_ldst_immpre - when ('10', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // LDR_S_ldst_immpre - when ('11', '0', '00') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // STR_64_ldst_immpre - when ('11', '0', '01') => __encoding aarch64_memory_single_general_immediate_signed_pre_idx // LDR_64_ldst_immpre - when ('11', '0', '10') => __UNALLOCATED - when ('11', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // STR_D_ldst_immpre - when ('11', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx // LDR_D_ldst_immpre - when ('xx11', _, _, _, '0x', _, '1xxxxx', _, '00', _) => // memop - __field size 30 +: 2 - __field V 26 +: 1 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field o3 15 +: 1 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, V, A, R, o3, opc) of - when (_, '0', _, _, '1', '001') => __UNALLOCATED - when (_, '0', _, _, '1', '01x') => __UNALLOCATED - when (_, '0', _, _, '1', '101') => __UNALLOCATED - when (_, '0', _, _, '1', '11x') => __UNALLOCATED - when (_, '0', '0', _, '1', '100') => __UNALLOCATED - when (_, '0', '1', '1', '1', '100') => __UNALLOCATED - when (_, '1', _, _, _, _) => __UNALLOCATED - when ('00', '0', '0', '0', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDB_32_memop - when ('00', '0', '0', '0', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRB_32_memop - when ('00', '0', '0', '0', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORB_32_memop - when ('00', '0', '0', '0', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETB_32_memop - when ('00', '0', '0', '0', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXB_32_memop - when ('00', '0', '0', '0', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINB_32_memop - when ('00', '0', '0', '0', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXB_32_memop - when ('00', '0', '0', '0', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINB_32_memop - when ('00', '0', '0', '0', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPB_32_memop - when ('00', '0', '0', '1', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDLB_32_memop - when ('00', '0', '0', '1', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRLB_32_memop - when ('00', '0', '0', '1', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORLB_32_memop - when ('00', '0', '0', '1', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETLB_32_memop - when ('00', '0', '0', '1', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXLB_32_memop - when ('00', '0', '0', '1', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINLB_32_memop - when ('00', '0', '0', '1', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXLB_32_memop - when ('00', '0', '0', '1', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINLB_32_memop - when ('00', '0', '0', '1', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPLB_32_memop - when ('00', '0', '1', '0', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDAB_32_memop - when ('00', '0', '1', '0', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRAB_32_memop - when ('00', '0', '1', '0', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORAB_32_memop - when ('00', '0', '1', '0', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETAB_32_memop - when ('00', '0', '1', '0', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXAB_32_memop - when ('00', '0', '1', '0', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINAB_32_memop - when ('00', '0', '1', '0', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXAB_32_memop - when ('00', '0', '1', '0', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINAB_32_memop - when ('00', '0', '1', '0', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPAB_32_memop - when ('00', '0', '1', '0', '1', '100') => __encoding aarch64_memory_ordered_rcpc // LDAPRB_32L_memop - when ('00', '0', '1', '1', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDALB_32_memop - when ('00', '0', '1', '1', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRALB_32_memop - when ('00', '0', '1', '1', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORALB_32_memop - when ('00', '0', '1', '1', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETALB_32_memop - when ('00', '0', '1', '1', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXALB_32_memop - when ('00', '0', '1', '1', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINALB_32_memop - when ('00', '0', '1', '1', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXALB_32_memop - when ('00', '0', '1', '1', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINALB_32_memop - when ('00', '0', '1', '1', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPALB_32_memop - when ('01', '0', '0', '0', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDH_32_memop - when ('01', '0', '0', '0', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRH_32_memop - when ('01', '0', '0', '0', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORH_32_memop - when ('01', '0', '0', '0', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETH_32_memop - when ('01', '0', '0', '0', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXH_32_memop - when ('01', '0', '0', '0', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINH_32_memop - when ('01', '0', '0', '0', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXH_32_memop - when ('01', '0', '0', '0', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINH_32_memop - when ('01', '0', '0', '0', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPH_32_memop - when ('01', '0', '0', '1', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDLH_32_memop - when ('01', '0', '0', '1', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRLH_32_memop - when ('01', '0', '0', '1', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORLH_32_memop - when ('01', '0', '0', '1', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETLH_32_memop - when ('01', '0', '0', '1', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXLH_32_memop - when ('01', '0', '0', '1', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINLH_32_memop - when ('01', '0', '0', '1', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXLH_32_memop - when ('01', '0', '0', '1', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINLH_32_memop - when ('01', '0', '0', '1', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPLH_32_memop - when ('01', '0', '1', '0', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDAH_32_memop - when ('01', '0', '1', '0', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRAH_32_memop - when ('01', '0', '1', '0', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORAH_32_memop - when ('01', '0', '1', '0', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETAH_32_memop - when ('01', '0', '1', '0', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXAH_32_memop - when ('01', '0', '1', '0', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINAH_32_memop - when ('01', '0', '1', '0', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXAH_32_memop - when ('01', '0', '1', '0', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINAH_32_memop - when ('01', '0', '1', '0', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPAH_32_memop - when ('01', '0', '1', '0', '1', '100') => __encoding aarch64_memory_ordered_rcpc // LDAPRH_32L_memop - when ('01', '0', '1', '1', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDALH_32_memop - when ('01', '0', '1', '1', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRALH_32_memop - when ('01', '0', '1', '1', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORALH_32_memop - when ('01', '0', '1', '1', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETALH_32_memop - when ('01', '0', '1', '1', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXALH_32_memop - when ('01', '0', '1', '1', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINALH_32_memop - when ('01', '0', '1', '1', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXALH_32_memop - when ('01', '0', '1', '1', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINALH_32_memop - when ('01', '0', '1', '1', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPALH_32_memop - when ('10', '0', '0', '0', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADD_32_memop - when ('10', '0', '0', '0', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLR_32_memop - when ('10', '0', '0', '0', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEOR_32_memop - when ('10', '0', '0', '0', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSET_32_memop - when ('10', '0', '0', '0', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAX_32_memop - when ('10', '0', '0', '0', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMIN_32_memop - when ('10', '0', '0', '0', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAX_32_memop - when ('10', '0', '0', '0', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMIN_32_memop - when ('10', '0', '0', '0', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWP_32_memop - when ('10', '0', '0', '1', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDL_32_memop - when ('10', '0', '0', '1', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRL_32_memop - when ('10', '0', '0', '1', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORL_32_memop - when ('10', '0', '0', '1', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETL_32_memop - when ('10', '0', '0', '1', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXL_32_memop - when ('10', '0', '0', '1', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINL_32_memop - when ('10', '0', '0', '1', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXL_32_memop - when ('10', '0', '0', '1', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINL_32_memop - when ('10', '0', '0', '1', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPL_32_memop - when ('10', '0', '1', '0', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDA_32_memop - when ('10', '0', '1', '0', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRA_32_memop - when ('10', '0', '1', '0', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORA_32_memop - when ('10', '0', '1', '0', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETA_32_memop - when ('10', '0', '1', '0', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXA_32_memop - when ('10', '0', '1', '0', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINA_32_memop - when ('10', '0', '1', '0', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXA_32_memop - when ('10', '0', '1', '0', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINA_32_memop - when ('10', '0', '1', '0', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPA_32_memop - when ('10', '0', '1', '0', '1', '100') => __encoding aarch64_memory_ordered_rcpc // LDAPR_32L_memop - when ('10', '0', '1', '1', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDAL_32_memop - when ('10', '0', '1', '1', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRAL_32_memop - when ('10', '0', '1', '1', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORAL_32_memop - when ('10', '0', '1', '1', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETAL_32_memop - when ('10', '0', '1', '1', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXAL_32_memop - when ('10', '0', '1', '1', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINAL_32_memop - when ('10', '0', '1', '1', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXAL_32_memop - when ('10', '0', '1', '1', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINAL_32_memop - when ('10', '0', '1', '1', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPAL_32_memop - when ('11', '0', '0', '0', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADD_64_memop - when ('11', '0', '0', '0', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLR_64_memop - when ('11', '0', '0', '0', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEOR_64_memop - when ('11', '0', '0', '0', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSET_64_memop - when ('11', '0', '0', '0', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAX_64_memop - when ('11', '0', '0', '0', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMIN_64_memop - when ('11', '0', '0', '0', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAX_64_memop - when ('11', '0', '0', '0', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMIN_64_memop - when ('11', '0', '0', '0', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWP_64_memop - when ('11', '0', '0', '1', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDL_64_memop - when ('11', '0', '0', '1', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRL_64_memop - when ('11', '0', '0', '1', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORL_64_memop - when ('11', '0', '0', '1', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETL_64_memop - when ('11', '0', '0', '1', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXL_64_memop - when ('11', '0', '0', '1', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINL_64_memop - when ('11', '0', '0', '1', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXL_64_memop - when ('11', '0', '0', '1', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINL_64_memop - when ('11', '0', '0', '1', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPL_64_memop - when ('11', '0', '1', '0', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDA_64_memop - when ('11', '0', '1', '0', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRA_64_memop - when ('11', '0', '1', '0', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORA_64_memop - when ('11', '0', '1', '0', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETA_64_memop - when ('11', '0', '1', '0', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXA_64_memop - when ('11', '0', '1', '0', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINA_64_memop - when ('11', '0', '1', '0', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXA_64_memop - when ('11', '0', '1', '0', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINA_64_memop - when ('11', '0', '1', '0', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPA_64_memop - when ('11', '0', '1', '0', '1', '100') => __encoding aarch64_memory_ordered_rcpc // LDAPR_64L_memop - when ('11', '0', '1', '1', '0', '000') => __encoding aarch64_memory_atomicops_ld // LDADDAL_64_memop - when ('11', '0', '1', '1', '0', '001') => __encoding aarch64_memory_atomicops_ld // LDCLRAL_64_memop - when ('11', '0', '1', '1', '0', '010') => __encoding aarch64_memory_atomicops_ld // LDEORAL_64_memop - when ('11', '0', '1', '1', '0', '011') => __encoding aarch64_memory_atomicops_ld // LDSETAL_64_memop - when ('11', '0', '1', '1', '0', '100') => __encoding aarch64_memory_atomicops_ld // LDSMAXAL_64_memop - when ('11', '0', '1', '1', '0', '101') => __encoding aarch64_memory_atomicops_ld // LDSMINAL_64_memop - when ('11', '0', '1', '1', '0', '110') => __encoding aarch64_memory_atomicops_ld // LDUMAXAL_64_memop - when ('11', '0', '1', '1', '0', '111') => __encoding aarch64_memory_atomicops_ld // LDUMINAL_64_memop - when ('11', '0', '1', '1', '1', '000') => __encoding aarch64_memory_atomicops_swp // SWPAL_64_memop - when ('xx11', _, _, _, '0x', _, '1xxxxx', _, '10', _) => // ldst_regoff - __field size 30 +: 2 - __field V 26 +: 1 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, V, opc, option) of - when (_, _, _, 'x0x') => __UNALLOCATED - when ('x1', '1', '1x', _) => __UNALLOCATED - when ('00', '0', '00', !'011') => __encoding aarch64_memory_single_general_register // STRB_32B_ldst_regoff - when ('00', '0', '00', '011') => __encoding aarch64_memory_single_general_register // STRB_32BL_ldst_regoff - when ('00', '0', '01', !'011') => __encoding aarch64_memory_single_general_register // LDRB_32B_ldst_regoff - when ('00', '0', '01', '011') => __encoding aarch64_memory_single_general_register // LDRB_32BL_ldst_regoff - when ('00', '0', '10', !'011') => __encoding aarch64_memory_single_general_register // LDRSB_64B_ldst_regoff - when ('00', '0', '10', '011') => __encoding aarch64_memory_single_general_register // LDRSB_64BL_ldst_regoff - when ('00', '0', '11', !'011') => __encoding aarch64_memory_single_general_register // LDRSB_32B_ldst_regoff - when ('00', '0', '11', '011') => __encoding aarch64_memory_single_general_register // LDRSB_32BL_ldst_regoff - when ('00', '1', '00', !'011') => __encoding aarch64_memory_single_simdfp_register // STR_B_ldst_regoff - when ('00', '1', '00', '011') => __encoding aarch64_memory_single_simdfp_register // STR_BL_ldst_regoff - when ('00', '1', '01', !'011') => __encoding aarch64_memory_single_simdfp_register // LDR_B_ldst_regoff - when ('00', '1', '01', '011') => __encoding aarch64_memory_single_simdfp_register // LDR_BL_ldst_regoff - when ('00', '1', '10', _) => __encoding aarch64_memory_single_simdfp_register // STR_Q_ldst_regoff - when ('00', '1', '11', _) => __encoding aarch64_memory_single_simdfp_register // LDR_Q_ldst_regoff - when ('01', '0', '00', _) => __encoding aarch64_memory_single_general_register // STRH_32_ldst_regoff - when ('01', '0', '01', _) => __encoding aarch64_memory_single_general_register // LDRH_32_ldst_regoff - when ('01', '0', '10', _) => __encoding aarch64_memory_single_general_register // LDRSH_64_ldst_regoff - when ('01', '0', '11', _) => __encoding aarch64_memory_single_general_register // LDRSH_32_ldst_regoff - when ('01', '1', '00', _) => __encoding aarch64_memory_single_simdfp_register // STR_H_ldst_regoff - when ('01', '1', '01', _) => __encoding aarch64_memory_single_simdfp_register // LDR_H_ldst_regoff - when ('1x', '0', '11', _) => __UNALLOCATED - when ('1x', '1', '1x', _) => __UNALLOCATED - when ('10', '0', '00', _) => __encoding aarch64_memory_single_general_register // STR_32_ldst_regoff - when ('10', '0', '01', _) => __encoding aarch64_memory_single_general_register // LDR_32_ldst_regoff - when ('10', '0', '10', _) => __encoding aarch64_memory_single_general_register // LDRSW_64_ldst_regoff - when ('10', '1', '00', _) => __encoding aarch64_memory_single_simdfp_register // STR_S_ldst_regoff - when ('10', '1', '01', _) => __encoding aarch64_memory_single_simdfp_register // LDR_S_ldst_regoff - when ('11', '0', '00', _) => __encoding aarch64_memory_single_general_register // STR_64_ldst_regoff - when ('11', '0', '01', _) => __encoding aarch64_memory_single_general_register // LDR_64_ldst_regoff - when ('11', '0', '10', _) => __encoding aarch64_memory_single_general_register // PRFM_P_ldst_regoff - when ('11', '1', '00', _) => __encoding aarch64_memory_single_simdfp_register // STR_D_ldst_regoff - when ('11', '1', '01', _) => __encoding aarch64_memory_single_simdfp_register // LDR_D_ldst_regoff - when ('xx11', _, _, _, '0x', _, '1xxxxx', _, 'x1', _) => // ldst_pac - __field size 30 +: 2 - __field V 26 +: 1 - __field M 23 +: 1 - __field S 22 +: 1 - __field imm9 12 +: 9 - __field W 11 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, V, M, W) of - when (!'11', _, _, _) => __UNALLOCATED - when ('11', '0', '0', '0') => __encoding aarch64_memory_single_general_immediate_signed_pac // LDRAA_64_ldst_pac - when ('11', '0', '0', '1') => __encoding aarch64_memory_single_general_immediate_signed_pac // LDRAA_64W_ldst_pac - when ('11', '0', '1', '0') => __encoding aarch64_memory_single_general_immediate_signed_pac // LDRAB_64_ldst_pac - when ('11', '0', '1', '1') => __encoding aarch64_memory_single_general_immediate_signed_pac // LDRAB_64W_ldst_pac - when ('11', '1', _, _) => __UNALLOCATED - when ('xx11', _, _, _, '1x', _, _, _, _, _) => // ldst_pos - __field size 30 +: 2 - __field V 26 +: 1 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - case (size, V, opc) of - when ('x1', '1', '1x') => __UNALLOCATED - when ('00', '0', '00') => __encoding aarch64_memory_single_general_immediate_unsigned // STRB_32_ldst_pos - when ('00', '0', '01') => __encoding aarch64_memory_single_general_immediate_unsigned // LDRB_32_ldst_pos - when ('00', '0', '10') => __encoding aarch64_memory_single_general_immediate_unsigned // LDRSB_64_ldst_pos - when ('00', '0', '11') => __encoding aarch64_memory_single_general_immediate_unsigned // LDRSB_32_ldst_pos - when ('00', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // STR_B_ldst_pos - when ('00', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // LDR_B_ldst_pos - when ('00', '1', '10') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // STR_Q_ldst_pos - when ('00', '1', '11') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // LDR_Q_ldst_pos - when ('01', '0', '00') => __encoding aarch64_memory_single_general_immediate_unsigned // STRH_32_ldst_pos - when ('01', '0', '01') => __encoding aarch64_memory_single_general_immediate_unsigned // LDRH_32_ldst_pos - when ('01', '0', '10') => __encoding aarch64_memory_single_general_immediate_unsigned // LDRSH_64_ldst_pos - when ('01', '0', '11') => __encoding aarch64_memory_single_general_immediate_unsigned // LDRSH_32_ldst_pos - when ('01', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // STR_H_ldst_pos - when ('01', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // LDR_H_ldst_pos - when ('1x', '0', '11') => __UNALLOCATED - when ('1x', '1', '1x') => __UNALLOCATED - when ('10', '0', '00') => __encoding aarch64_memory_single_general_immediate_unsigned // STR_32_ldst_pos - when ('10', '0', '01') => __encoding aarch64_memory_single_general_immediate_unsigned // LDR_32_ldst_pos - when ('10', '0', '10') => __encoding aarch64_memory_single_general_immediate_unsigned // LDRSW_64_ldst_pos - when ('10', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // STR_S_ldst_pos - when ('10', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // LDR_S_ldst_pos - when ('11', '0', '00') => __encoding aarch64_memory_single_general_immediate_unsigned // STR_64_ldst_pos - when ('11', '0', '01') => __encoding aarch64_memory_single_general_immediate_unsigned // LDR_64_ldst_pos - when ('11', '0', '10') => __encoding aarch64_memory_single_general_immediate_unsigned // PRFM_P_ldst_pos - when ('11', '1', '00') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // STR_D_ldst_pos - when ('11', '1', '01') => __encoding aarch64_memory_single_simdfp_immediate_unsigned // LDR_D_ldst_pos - when (_, 'x101x', _) => - // dpreg - case (31 +: 1, 30 +: 1, 29 +: 1, 28 +: 1, 25 +: 3, 21 +: 4, 16 +: 5, 10 +: 6, 0 +: 10) of - when (_, '0', _, '1', _, '0110', _, _, _) => // dp_2src - __field sf 31 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field opcode 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, S, opcode) of - when (_, _, '000001') => __UNALLOCATED - when (_, _, '011xxx') => __UNALLOCATED - when (_, _, '1xxxxx') => __UNALLOCATED - when (_, '0', '00011x') => __UNALLOCATED - when (_, '0', '001101') => __UNALLOCATED - when (_, '0', '00111x') => __UNALLOCATED - when (_, '1', '00001x') => __UNALLOCATED - when (_, '1', '0001xx') => __UNALLOCATED - when (_, '1', '001xxx') => __UNALLOCATED - when (_, '1', '01xxxx') => __UNALLOCATED - when ('0', _, '000000') => __UNALLOCATED - when ('0', '0', '000010') => __encoding aarch64_integer_arithmetic_div // UDIV_32_dp_2src - when ('0', '0', '000011') => __encoding aarch64_integer_arithmetic_div // SDIV_32_dp_2src - when ('0', '0', '00010x') => __UNALLOCATED - when ('0', '0', '001000') => __encoding aarch64_integer_shift_variable // LSLV_32_dp_2src - when ('0', '0', '001001') => __encoding aarch64_integer_shift_variable // LSRV_32_dp_2src - when ('0', '0', '001010') => __encoding aarch64_integer_shift_variable // ASRV_32_dp_2src - when ('0', '0', '001011') => __encoding aarch64_integer_shift_variable // RORV_32_dp_2src - when ('0', '0', '001100') => __UNALLOCATED - when ('0', '0', '010x11') => __UNALLOCATED - when ('0', '0', '010000') => __encoding aarch64_integer_crc // CRC32B_32C_dp_2src - when ('0', '0', '010001') => __encoding aarch64_integer_crc // CRC32H_32C_dp_2src - when ('0', '0', '010010') => __encoding aarch64_integer_crc // CRC32W_32C_dp_2src - when ('0', '0', '010100') => __encoding aarch64_integer_crc // CRC32CB_32C_dp_2src - when ('0', '0', '010101') => __encoding aarch64_integer_crc // CRC32CH_32C_dp_2src - when ('0', '0', '010110') => __encoding aarch64_integer_crc // CRC32CW_32C_dp_2src - when ('1', '0', '000000') => __encoding aarch64_integer_arithmetic_pointer_mcsubtracttaggedaddress // SUBP_64S_dp_2src - when ('1', '0', '000010') => __encoding aarch64_integer_arithmetic_div // UDIV_64_dp_2src - when ('1', '0', '000011') => __encoding aarch64_integer_arithmetic_div // SDIV_64_dp_2src - when ('1', '0', '000100') => __encoding aarch64_integer_tags_mcinsertrandomtag // IRG_64I_dp_2src - when ('1', '0', '000101') => __encoding aarch64_integer_tags_mcinserttagmask // GMI_64G_dp_2src - when ('1', '0', '001000') => __encoding aarch64_integer_shift_variable // LSLV_64_dp_2src - when ('1', '0', '001001') => __encoding aarch64_integer_shift_variable // LSRV_64_dp_2src - when ('1', '0', '001010') => __encoding aarch64_integer_shift_variable // ASRV_64_dp_2src - when ('1', '0', '001011') => __encoding aarch64_integer_shift_variable // RORV_64_dp_2src - when ('1', '0', '001100') => __encoding aarch64_integer_pac_pacga_dp_2src // PACGA_64P_dp_2src - when ('1', '0', '010xx0') => __UNALLOCATED - when ('1', '0', '010x0x') => __UNALLOCATED - when ('1', '0', '010011') => __encoding aarch64_integer_crc // CRC32X_64C_dp_2src - when ('1', '0', '010111') => __encoding aarch64_integer_crc // CRC32CX_64C_dp_2src - when ('1', '1', '000000') => __encoding aarch64_integer_arithmetic_pointer_mcsubtracttaggedaddresssetflags // SUBPS_64S_dp_2src - when (_, '1', _, '1', _, '0110', _, _, _) => // dp_1src - __field sf 31 +: 1 - __field S 29 +: 1 - __field opcode2 16 +: 5 - __field opcode 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, S, opcode2, opcode, Rn) of - when (_, _, _, '1xxxxx', _) => __UNALLOCATED - when (_, _, 'xxx1x', _, _) => __UNALLOCATED - when (_, _, 'xx1xx', _, _) => __UNALLOCATED - when (_, _, 'x1xxx', _, _) => __UNALLOCATED - when (_, _, '1xxxx', _, _) => __UNALLOCATED - when (_, '0', '00000', '00011x', _) => __UNALLOCATED - when (_, '0', '00000', '001xxx', _) => __UNALLOCATED - when (_, '0', '00000', '01xxxx', _) => __UNALLOCATED - when (_, '1', _, _, _) => __UNALLOCATED - when ('0', _, '00001', _, _) => __UNALLOCATED - when ('0', '0', '00000', '000000', _) => __encoding aarch64_integer_arithmetic_rbit // RBIT_32_dp_1src - when ('0', '0', '00000', '000001', _) => __encoding aarch64_integer_arithmetic_rev // REV16_32_dp_1src - when ('0', '0', '00000', '000010', _) => __encoding aarch64_integer_arithmetic_rev // REV_32_dp_1src - when ('0', '0', '00000', '000011', _) => __UNALLOCATED - when ('0', '0', '00000', '000100', _) => __encoding aarch64_integer_arithmetic_cnt // CLZ_32_dp_1src - when ('0', '0', '00000', '000101', _) => __encoding aarch64_integer_arithmetic_cnt // CLS_32_dp_1src - when ('1', '0', '00000', '000000', _) => __encoding aarch64_integer_arithmetic_rbit // RBIT_64_dp_1src - when ('1', '0', '00000', '000001', _) => __encoding aarch64_integer_arithmetic_rev // REV16_64_dp_1src - when ('1', '0', '00000', '000010', _) => __encoding aarch64_integer_arithmetic_rev // REV32_64_dp_1src - when ('1', '0', '00000', '000011', _) => __encoding aarch64_integer_arithmetic_rev // REV_64_dp_1src - when ('1', '0', '00000', '000100', _) => __encoding aarch64_integer_arithmetic_cnt // CLZ_64_dp_1src - when ('1', '0', '00000', '000101', _) => __encoding aarch64_integer_arithmetic_cnt // CLS_64_dp_1src - when ('1', '0', '00001', '000000', _) => __encoding aarch64_integer_pac_pacia_dp_1src // PACIA_64P_dp_1src - when ('1', '0', '00001', '000001', _) => __encoding aarch64_integer_pac_pacib_dp_1src // PACIB_64P_dp_1src - when ('1', '0', '00001', '000010', _) => __encoding aarch64_integer_pac_pacda_dp_1src // PACDA_64P_dp_1src - when ('1', '0', '00001', '000011', _) => __encoding aarch64_integer_pac_pacdb_dp_1src // PACDB_64P_dp_1src - when ('1', '0', '00001', '000100', _) => __encoding aarch64_integer_pac_autia_dp_1src // AUTIA_64P_dp_1src - when ('1', '0', '00001', '000101', _) => __encoding aarch64_integer_pac_autib_dp_1src // AUTIB_64P_dp_1src - when ('1', '0', '00001', '000110', _) => __encoding aarch64_integer_pac_autda_dp_1src // AUTDA_64P_dp_1src - when ('1', '0', '00001', '000111', _) => __encoding aarch64_integer_pac_autdb_dp_1src // AUTDB_64P_dp_1src - when ('1', '0', '00001', '001000', '11111') => __encoding aarch64_integer_pac_pacia_dp_1src // PACIZA_64Z_dp_1src - when ('1', '0', '00001', '001001', '11111') => __encoding aarch64_integer_pac_pacib_dp_1src // PACIZB_64Z_dp_1src - when ('1', '0', '00001', '001010', '11111') => __encoding aarch64_integer_pac_pacda_dp_1src // PACDZA_64Z_dp_1src - when ('1', '0', '00001', '001011', '11111') => __encoding aarch64_integer_pac_pacdb_dp_1src // PACDZB_64Z_dp_1src - when ('1', '0', '00001', '001100', '11111') => __encoding aarch64_integer_pac_autia_dp_1src // AUTIZA_64Z_dp_1src - when ('1', '0', '00001', '001101', '11111') => __encoding aarch64_integer_pac_autib_dp_1src // AUTIZB_64Z_dp_1src - when ('1', '0', '00001', '001110', '11111') => __encoding aarch64_integer_pac_autda_dp_1src // AUTDZA_64Z_dp_1src - when ('1', '0', '00001', '001111', '11111') => __encoding aarch64_integer_pac_autdb_dp_1src // AUTDZB_64Z_dp_1src - when ('1', '0', '00001', '010000', '11111') => __encoding aarch64_integer_pac_strip_dp_1src // XPACI_64Z_dp_1src - when ('1', '0', '00001', '010001', '11111') => __encoding aarch64_integer_pac_strip_dp_1src // XPACD_64Z_dp_1src - when ('1', '0', '00001', '01001x', _) => __UNALLOCATED - when ('1', '0', '00001', '0101xx', _) => __UNALLOCATED - when ('1', '0', '00001', '011xxx', _) => __UNALLOCATED - when (_, _, _, '0', _, '0xxx', _, _, _) => // log_shift - __field sf 31 +: 1 - __field opc 29 +: 2 - __field shift 22 +: 2 - __field N 21 +: 1 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, opc, N, imm6) of - when ('0', _, _, '1xxxxx') => __UNALLOCATED - when ('0', '00', '0', _) => __encoding aarch64_integer_logical_shiftedreg // AND_32_log_shift - when ('0', '00', '1', _) => __encoding aarch64_integer_logical_shiftedreg // BIC_32_log_shift - when ('0', '01', '0', _) => __encoding aarch64_integer_logical_shiftedreg // ORR_32_log_shift - when ('0', '01', '1', _) => __encoding aarch64_integer_logical_shiftedreg // ORN_32_log_shift - when ('0', '10', '0', _) => __encoding aarch64_integer_logical_shiftedreg // EOR_32_log_shift - when ('0', '10', '1', _) => __encoding aarch64_integer_logical_shiftedreg // EON_32_log_shift - when ('0', '11', '0', _) => __encoding aarch64_integer_logical_shiftedreg // ANDS_32_log_shift - when ('0', '11', '1', _) => __encoding aarch64_integer_logical_shiftedreg // BICS_32_log_shift - when ('1', '00', '0', _) => __encoding aarch64_integer_logical_shiftedreg // AND_64_log_shift - when ('1', '00', '1', _) => __encoding aarch64_integer_logical_shiftedreg // BIC_64_log_shift - when ('1', '01', '0', _) => __encoding aarch64_integer_logical_shiftedreg // ORR_64_log_shift - when ('1', '01', '1', _) => __encoding aarch64_integer_logical_shiftedreg // ORN_64_log_shift - when ('1', '10', '0', _) => __encoding aarch64_integer_logical_shiftedreg // EOR_64_log_shift - when ('1', '10', '1', _) => __encoding aarch64_integer_logical_shiftedreg // EON_64_log_shift - when ('1', '11', '0', _) => __encoding aarch64_integer_logical_shiftedreg // ANDS_64_log_shift - when ('1', '11', '1', _) => __encoding aarch64_integer_logical_shiftedreg // BICS_64_log_shift - when (_, _, _, '0', _, '1xx0', _, _, _) => // addsub_shift - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field shift 22 +: 2 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, op, S, shift, imm6) of - when (_, _, _, '11', _) => __UNALLOCATED - when ('0', _, _, _, '1xxxxx') => __UNALLOCATED - when ('0', '0', '0', _, _) => __encoding aarch64_integer_arithmetic_add_sub_shiftedreg // ADD_32_addsub_shift - when ('0', '0', '1', _, _) => __encoding aarch64_integer_arithmetic_add_sub_shiftedreg // ADDS_32_addsub_shift - when ('0', '1', '0', _, _) => __encoding aarch64_integer_arithmetic_add_sub_shiftedreg // SUB_32_addsub_shift - when ('0', '1', '1', _, _) => __encoding aarch64_integer_arithmetic_add_sub_shiftedreg // SUBS_32_addsub_shift - when ('1', '0', '0', _, _) => __encoding aarch64_integer_arithmetic_add_sub_shiftedreg // ADD_64_addsub_shift - when ('1', '0', '1', _, _) => __encoding aarch64_integer_arithmetic_add_sub_shiftedreg // ADDS_64_addsub_shift - when ('1', '1', '0', _, _) => __encoding aarch64_integer_arithmetic_add_sub_shiftedreg // SUB_64_addsub_shift - when ('1', '1', '1', _, _) => __encoding aarch64_integer_arithmetic_add_sub_shiftedreg // SUBS_64_addsub_shift - when (_, _, _, '0', _, '1xx1', _, _, _) => // addsub_ext - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field opt 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field imm3 10 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, op, S, opt, imm3) of - when (_, _, _, _, '1x1') => __UNALLOCATED - when (_, _, _, _, '11x') => __UNALLOCATED - when (_, _, _, 'x1', _) => __UNALLOCATED - when (_, _, _, '1x', _) => __UNALLOCATED - when ('0', '0', '0', '00', _) => __encoding aarch64_integer_arithmetic_add_sub_extendedreg // ADD_32_addsub_ext - when ('0', '0', '1', '00', _) => __encoding aarch64_integer_arithmetic_add_sub_extendedreg // ADDS_32S_addsub_ext - when ('0', '1', '0', '00', _) => __encoding aarch64_integer_arithmetic_add_sub_extendedreg // SUB_32_addsub_ext - when ('0', '1', '1', '00', _) => __encoding aarch64_integer_arithmetic_add_sub_extendedreg // SUBS_32S_addsub_ext - when ('1', '0', '0', '00', _) => __encoding aarch64_integer_arithmetic_add_sub_extendedreg // ADD_64_addsub_ext - when ('1', '0', '1', '00', _) => __encoding aarch64_integer_arithmetic_add_sub_extendedreg // ADDS_64S_addsub_ext - when ('1', '1', '0', '00', _) => __encoding aarch64_integer_arithmetic_add_sub_extendedreg // SUB_64_addsub_ext - when ('1', '1', '1', '00', _) => __encoding aarch64_integer_arithmetic_add_sub_extendedreg // SUBS_64S_addsub_ext - when (_, _, _, '1', _, '0000', _, '000000', _) => // addsub_carry - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, op, S) of - when ('0', '0', '0') => __encoding aarch64_integer_arithmetic_add_sub_carry // ADC_32_addsub_carry - when ('0', '0', '1') => __encoding aarch64_integer_arithmetic_add_sub_carry // ADCS_32_addsub_carry - when ('0', '1', '0') => __encoding aarch64_integer_arithmetic_add_sub_carry // SBC_32_addsub_carry - when ('0', '1', '1') => __encoding aarch64_integer_arithmetic_add_sub_carry // SBCS_32_addsub_carry - when ('1', '0', '0') => __encoding aarch64_integer_arithmetic_add_sub_carry // ADC_64_addsub_carry - when ('1', '0', '1') => __encoding aarch64_integer_arithmetic_add_sub_carry // ADCS_64_addsub_carry - when ('1', '1', '0') => __encoding aarch64_integer_arithmetic_add_sub_carry // SBC_64_addsub_carry - when ('1', '1', '1') => __encoding aarch64_integer_arithmetic_add_sub_carry // SBCS_64_addsub_carry - when (_, _, _, '1', _, '0000', _, 'x00001', _) => // rmif - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field imm6 15 +: 6 - __field Rn 5 +: 5 - __field o2 4 +: 1 - __field mask 0 +: 4 - case (sf, op, S, o2) of - when ('0', _, _, _) => __UNALLOCATED - when ('1', '0', '0', _) => __UNALLOCATED - when ('1', '0', '1', '0') => __encoding aarch64_integer_flags_rmif // RMIF_only_rmif - when ('1', '0', '1', '1') => __UNALLOCATED - when ('1', '1', _, _) => __UNALLOCATED - when (_, _, _, '1', _, '0000', _, 'xx0010', _) => // setf - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field opcode2 15 +: 6 - __field sz 14 +: 1 - __field Rn 5 +: 5 - __field o3 4 +: 1 - __field mask 0 +: 4 - case (sf, op, S, opcode2, sz, o3, mask) of - when ('0', '0', '0', _, _, _, _) => __UNALLOCATED - when ('0', '0', '1', !'000000', _, _, _) => __UNALLOCATED - when ('0', '0', '1', '000000', _, '0', !'1101') => __UNALLOCATED - when ('0', '0', '1', '000000', _, '1', _) => __UNALLOCATED - when ('0', '0', '1', '000000', '0', '0', '1101') => __encoding aarch64_integer_flags_setf // SETF8_only_setf - when ('0', '0', '1', '000000', '1', '0', '1101') => __encoding aarch64_integer_flags_setf // SETF16_only_setf - when ('0', '1', _, _, _, _, _) => __UNALLOCATED - when ('1', _, _, _, _, _, _) => __UNALLOCATED - when (_, _, _, '1', _, '0010', _, 'xxxx0x', _) => // condcmp_reg - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field o2 10 +: 1 - __field Rn 5 +: 5 - __field o3 4 +: 1 - __field nzcv 0 +: 4 - case (sf, op, S, o2, o3) of - when (_, _, _, _, '1') => __UNALLOCATED - when (_, _, _, '1', _) => __UNALLOCATED - when (_, _, '0', _, _) => __UNALLOCATED - when ('0', '0', '1', '0', '0') => __encoding aarch64_integer_conditional_compare_register // CCMN_32_condcmp_reg - when ('0', '1', '1', '0', '0') => __encoding aarch64_integer_conditional_compare_register // CCMP_32_condcmp_reg - when ('1', '0', '1', '0', '0') => __encoding aarch64_integer_conditional_compare_register // CCMN_64_condcmp_reg - when ('1', '1', '1', '0', '0') => __encoding aarch64_integer_conditional_compare_register // CCMP_64_condcmp_reg - when (_, _, _, '1', _, '0010', _, 'xxxx1x', _) => // condcmp_imm - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field imm5 16 +: 5 - __field cond 12 +: 4 - __field o2 10 +: 1 - __field Rn 5 +: 5 - __field o3 4 +: 1 - __field nzcv 0 +: 4 - case (sf, op, S, o2, o3) of - when (_, _, _, _, '1') => __UNALLOCATED - when (_, _, _, '1', _) => __UNALLOCATED - when (_, _, '0', _, _) => __UNALLOCATED - when ('0', '0', '1', '0', '0') => __encoding aarch64_integer_conditional_compare_immediate // CCMN_32_condcmp_imm - when ('0', '1', '1', '0', '0') => __encoding aarch64_integer_conditional_compare_immediate // CCMP_32_condcmp_imm - when ('1', '0', '1', '0', '0') => __encoding aarch64_integer_conditional_compare_immediate // CCMN_64_condcmp_imm - when ('1', '1', '1', '0', '0') => __encoding aarch64_integer_conditional_compare_immediate // CCMP_64_condcmp_imm - when (_, _, _, '1', _, '0100', _, _, _) => // condsel - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field op2 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, op, S, op2) of - when (_, _, _, '1x') => __UNALLOCATED - when (_, _, '1', _) => __UNALLOCATED - when ('0', '0', '0', '00') => __encoding aarch64_integer_conditional_select // CSEL_32_condsel - when ('0', '0', '0', '01') => __encoding aarch64_integer_conditional_select // CSINC_32_condsel - when ('0', '1', '0', '00') => __encoding aarch64_integer_conditional_select // CSINV_32_condsel - when ('0', '1', '0', '01') => __encoding aarch64_integer_conditional_select // CSNEG_32_condsel - when ('1', '0', '0', '00') => __encoding aarch64_integer_conditional_select // CSEL_64_condsel - when ('1', '0', '0', '01') => __encoding aarch64_integer_conditional_select // CSINC_64_condsel - when ('1', '1', '0', '00') => __encoding aarch64_integer_conditional_select // CSINV_64_condsel - when ('1', '1', '0', '01') => __encoding aarch64_integer_conditional_select // CSNEG_64_condsel - when (_, _, _, '1', _, '1xxx', _, _, _) => // dp_3src - __field sf 31 +: 1 - __field op54 29 +: 2 - __field op31 21 +: 3 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, op54, op31, o0) of - when (_, '00', '010', '1') => __UNALLOCATED - when (_, '00', '011', _) => __UNALLOCATED - when (_, '00', '100', _) => __UNALLOCATED - when (_, '00', '110', '1') => __UNALLOCATED - when (_, '00', '111', _) => __UNALLOCATED - when (_, '01', _, _) => __UNALLOCATED - when (_, '1x', _, _) => __UNALLOCATED - when ('0', '00', '000', '0') => __encoding aarch64_integer_arithmetic_mul_uniform_add_sub // MADD_32A_dp_3src - when ('0', '00', '000', '1') => __encoding aarch64_integer_arithmetic_mul_uniform_add_sub // MSUB_32A_dp_3src - when ('0', '00', '001', '0') => __UNALLOCATED - when ('0', '00', '001', '1') => __UNALLOCATED - when ('0', '00', '010', '0') => __UNALLOCATED - when ('0', '00', '101', '0') => __UNALLOCATED - when ('0', '00', '101', '1') => __UNALLOCATED - when ('0', '00', '110', '0') => __UNALLOCATED - when ('1', '00', '000', '0') => __encoding aarch64_integer_arithmetic_mul_uniform_add_sub // MADD_64A_dp_3src - when ('1', '00', '000', '1') => __encoding aarch64_integer_arithmetic_mul_uniform_add_sub // MSUB_64A_dp_3src - when ('1', '00', '001', '0') => __encoding aarch64_integer_arithmetic_mul_widening_32_64 // SMADDL_64WA_dp_3src - when ('1', '00', '001', '1') => __encoding aarch64_integer_arithmetic_mul_widening_32_64 // SMSUBL_64WA_dp_3src - when ('1', '00', '010', '0') => __encoding aarch64_integer_arithmetic_mul_widening_64_128hi // SMULH_64_dp_3src - when ('1', '00', '101', '0') => __encoding aarch64_integer_arithmetic_mul_widening_32_64 // UMADDL_64WA_dp_3src - when ('1', '00', '101', '1') => __encoding aarch64_integer_arithmetic_mul_widening_32_64 // UMSUBL_64WA_dp_3src - when ('1', '00', '110', '0') => __encoding aarch64_integer_arithmetic_mul_widening_64_128hi // UMULH_64_dp_3src - when (_, 'x111x', _) => - // simd-dp - case (28 +: 4, 25 +: 3, 23 +: 2, 19 +: 4, 10 +: 9, 0 +: 10) of - when ('0000', _, '0x', 'x101', '00xxxxx10', _) => __UNPREDICTABLE - when ('0010', _, '0x', 'x101', '00xxxxx10', _) => __UNPREDICTABLE - when ('0100', _, '0x', 'x101', '00xxxxx10', _) => // cryptoaes - __field size 22 +: 2 - __field opcode 12 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (size, opcode) of - when (_, 'x1xxx') => __UNALLOCATED - when (_, '000xx') => __UNALLOCATED - when (_, '1xxxx') => __UNALLOCATED - when ('x1', _) => __UNALLOCATED - when ('00', '00100') => __encoding aarch64_vector_crypto_aes_round // AESE_B_cryptoaes - when ('00', '00101') => __encoding aarch64_vector_crypto_aes_round // AESD_B_cryptoaes - when ('00', '00110') => __encoding aarch64_vector_crypto_aes_mix // AESMC_B_cryptoaes - when ('00', '00111') => __encoding aarch64_vector_crypto_aes_mix // AESIMC_B_cryptoaes - when ('1x', _) => __UNALLOCATED - when ('0101', _, '0x', 'x0xx', 'xxx0xxx00', _) => // cryptosha3 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field opcode 12 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (size, opcode) of - when (_, '111') => __UNALLOCATED - when ('x1', _) => __UNALLOCATED - when ('00', '000') => __encoding aarch64_vector_crypto_sha3op_sha1_hash_choose // SHA1C_QSV_cryptosha3 - when ('00', '001') => __encoding aarch64_vector_crypto_sha3op_sha1_hash_parity // SHA1P_QSV_cryptosha3 - when ('00', '010') => __encoding aarch64_vector_crypto_sha3op_sha1_hash_majority // SHA1M_QSV_cryptosha3 - when ('00', '011') => __encoding aarch64_vector_crypto_sha3op_sha1_sched0 // SHA1SU0_VVV_cryptosha3 - when ('00', '100') => __encoding aarch64_vector_crypto_sha3op_sha256_hash // SHA256H_QQV_cryptosha3 - when ('00', '101') => __encoding aarch64_vector_crypto_sha3op_sha256_hash // SHA256H2_QQV_cryptosha3 - when ('00', '110') => __encoding aarch64_vector_crypto_sha3op_sha256_sched1 // SHA256SU1_VVV_cryptosha3 - when ('1x', _) => __UNALLOCATED - when ('0101', _, '0x', 'x0xx', 'xxx0xxx10', _) => __UNPREDICTABLE - when ('0101', _, '0x', 'x101', '00xxxxx10', _) => // cryptosha2 - __field size 22 +: 2 - __field opcode 12 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (size, opcode) of - when (_, 'xx1xx') => __UNALLOCATED - when (_, 'x1xxx') => __UNALLOCATED - when (_, '1xxxx') => __UNALLOCATED - when ('x1', _) => __UNALLOCATED - when ('00', '00000') => __encoding aarch64_vector_crypto_sha2op_sha1_hash // SHA1H_SS_cryptosha2 - when ('00', '00001') => __encoding aarch64_vector_crypto_sha2op_sha1_sched1 // SHA1SU1_VV_cryptosha2 - when ('00', '00010') => __encoding aarch64_vector_crypto_sha2op_sha256_sched0 // SHA256SU0_VV_cryptosha2 - when ('00', '00011') => __UNALLOCATED - when ('1x', _) => __UNALLOCATED - when ('0110', _, '0x', 'x101', '00xxxxx10', _) => __UNPREDICTABLE - when ('0111', _, '0x', 'x0xx', 'xxx0xxxx0', _) => __UNPREDICTABLE - when ('0111', _, '0x', 'x101', '00xxxxx10', _) => __UNPREDICTABLE - when ('01x1', _, '00', '00xx', 'xxx0xxxx1', _) => // asisdone - __field op 29 +: 1 - __field imm5 16 +: 5 - __field imm4 11 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (op, imm5, imm4) of - when ('0', _, 'xxx1') => __UNALLOCATED - when ('0', _, 'xx1x') => __UNALLOCATED - when ('0', _, 'x1xx') => __UNALLOCATED - when ('0', _, '0000') => __encoding aarch64_vector_transfer_vector_cpy_dup_sisd // DUP_asisdone_only - when ('0', _, '1xxx') => __UNALLOCATED - when ('0', 'x0000', '0000') => __UNALLOCATED - when ('1', _, _) => __UNALLOCATED - when ('01x1', _, '01', '00xx', 'xxx0xxxx1', _) => __UNPREDICTABLE - when ('01x1', _, '0x', '0111', '00xxxxx10', _) => __UNPREDICTABLE - when ('01x1', _, '0x', '10xx', 'xxx00xxx1', _) => // asisdsamefp16 - __field U 29 +: 1 - __field a 23 +: 1 - __field Rm 16 +: 5 - __field opcode 11 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, a, opcode) of - when (_, _, '110') => __UNALLOCATED - when (_, '1', '011') => __UNALLOCATED - when ('0', '0', '011') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_extended_sisd // FMULX_asisdsamefp16_only - when ('0', '0', '100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd // FCMEQ_asisdsamefp16_only - when ('0', '0', '101') => __UNALLOCATED - when ('0', '0', '111') => __encoding aarch64_vector_arithmetic_binary_uniform_recps_fp16_sisd // FRECPS_asisdsamefp16_only - when ('0', '1', '100') => __UNALLOCATED - when ('0', '1', '101') => __UNALLOCATED - when ('0', '1', '111') => __encoding aarch64_vector_arithmetic_binary_uniform_rsqrts_fp16_sisd // FRSQRTS_asisdsamefp16_only - when ('1', '0', '011') => __UNALLOCATED - when ('1', '0', '100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd // FCMGE_asisdsamefp16_only - when ('1', '0', '101') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd // FACGE_asisdsamefp16_only - when ('1', '0', '111') => __UNALLOCATED - when ('1', '1', '010') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp16_sisd // FABD_asisdsamefp16_only - when ('1', '1', '100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd // FCMGT_asisdsamefp16_only - when ('1', '1', '101') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd // FACGT_asisdsamefp16_only - when ('1', '1', '111') => __UNALLOCATED - when ('01x1', _, '0x', '10xx', 'xxx01xxx1', _) => __UNPREDICTABLE - when ('01x1', _, '0x', '1111', '00xxxxx10', _) => // asisdmiscfp16 - __field U 29 +: 1 - __field a 23 +: 1 - __field opcode 12 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, a, opcode) of - when (_, _, '00xxx') => __UNALLOCATED - when (_, _, '010xx') => __UNALLOCATED - when (_, _, '10xxx') => __UNALLOCATED - when (_, _, '1100x') => __UNALLOCATED - when (_, _, '11110') => __UNALLOCATED - when (_, '0', '011xx') => __UNALLOCATED - when (_, '0', '11111') => __UNALLOCATED - when (_, '1', '01111') => __UNALLOCATED - when (_, '1', '11100') => __UNALLOCATED - when ('0', '0', '11010') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd // FCVTNS_asisdmiscfp16_R - when ('0', '0', '11011') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd // FCVTMS_asisdmiscfp16_R - when ('0', '0', '11100') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_sisd // FCVTAS_asisdmiscfp16_R - when ('0', '0', '11101') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_int_sisd // SCVTF_asisdmiscfp16_R - when ('0', '1', '01100') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd // FCMGT_asisdmiscfp16_FZ - when ('0', '1', '01101') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd // FCMEQ_asisdmiscfp16_FZ - when ('0', '1', '01110') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_lessthan_sisd // FCMLT_asisdmiscfp16_FZ - when ('0', '1', '11010') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd // FCVTPS_asisdmiscfp16_R - when ('0', '1', '11011') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd // FCVTZS_asisdmiscfp16_R - when ('0', '1', '11101') => __encoding aarch64_vector_arithmetic_unary_special_recip_fp16_sisd // FRECPE_asisdmiscfp16_R - when ('0', '1', '11111') => __encoding aarch64_vector_arithmetic_unary_special_frecpx_fp16 // FRECPX_asisdmiscfp16_R - when ('1', '0', '11010') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd // FCVTNU_asisdmiscfp16_R - when ('1', '0', '11011') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd // FCVTMU_asisdmiscfp16_R - when ('1', '0', '11100') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_sisd // FCVTAU_asisdmiscfp16_R - when ('1', '0', '11101') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_int_sisd // UCVTF_asisdmiscfp16_R - when ('1', '1', '01100') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd // FCMGE_asisdmiscfp16_FZ - when ('1', '1', '01101') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd // FCMLE_asisdmiscfp16_FZ - when ('1', '1', '01110') => __UNALLOCATED - when ('1', '1', '11010') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd // FCVTPU_asisdmiscfp16_R - when ('1', '1', '11011') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd // FCVTZU_asisdmiscfp16_R - when ('1', '1', '11101') => __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_fp16_sisd // FRSQRTE_asisdmiscfp16_R - when ('1', '1', '11111') => __UNALLOCATED - when ('01x1', _, '0x', 'x0xx', 'xxx1xxxx0', _) => __UNPREDICTABLE - when ('01x1', _, '0x', 'x0xx', 'xxx1xxxx1', _) => // asisdsame2 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field opcode 11 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, opcode) of - when (_, '001x') => __UNALLOCATED - when (_, '01xx') => __UNALLOCATED - when (_, '1xxx') => __UNALLOCATED - when ('0', '0000') => __UNALLOCATED - when ('0', '0001') => __UNALLOCATED - when ('1', '0000') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_sisd // SQRDMLAH_asisdsame2_only - when ('1', '0001') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_sisd // SQRDMLSH_asisdsame2_only - when ('01x1', _, '0x', 'x100', '00xxxxx10', _) => // asisdmisc - __field U 29 +: 1 - __field size 22 +: 2 - __field opcode 12 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, size, opcode) of - when (_, _, '0000x') => __UNALLOCATED - when (_, _, '00010') => __UNALLOCATED - when (_, _, '0010x') => __UNALLOCATED - when (_, _, '00110') => __UNALLOCATED - when (_, _, '01111') => __UNALLOCATED - when (_, _, '1000x') => __UNALLOCATED - when (_, _, '10011') => __UNALLOCATED - when (_, _, '10101') => __UNALLOCATED - when (_, _, '10111') => __UNALLOCATED - when (_, _, '1100x') => __UNALLOCATED - when (_, _, '11110') => __UNALLOCATED - when (_, '0x', '011xx') => __UNALLOCATED - when (_, '0x', '11111') => __UNALLOCATED - when (_, '1x', '10110') => __UNALLOCATED - when (_, '1x', '11100') => __UNALLOCATED - when ('0', _, '00011') => __encoding aarch64_vector_arithmetic_unary_add_saturating_sisd // SUQADD_asisdmisc_R - when ('0', _, '00111') => __encoding aarch64_vector_arithmetic_unary_diff_neg_sat_sisd // SQABS_asisdmisc_R - when ('0', _, '01000') => __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd // CMGT_asisdmisc_Z - when ('0', _, '01001') => __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd // CMEQ_asisdmisc_Z - when ('0', _, '01010') => __encoding aarch64_vector_arithmetic_unary_cmp_int_lessthan_sisd // CMLT_asisdmisc_Z - when ('0', _, '01011') => __encoding aarch64_vector_arithmetic_unary_diff_neg_int_sisd // ABS_asisdmisc_R - when ('0', _, '10010') => __UNALLOCATED - when ('0', _, '10100') => __encoding aarch64_vector_arithmetic_unary_extract_sat_sisd // SQXTN_asisdmisc_N - when ('0', '0x', '10110') => __UNALLOCATED - when ('0', '0x', '11010') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd // FCVTNS_asisdmisc_R - when ('0', '0x', '11011') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd // FCVTMS_asisdmisc_R - when ('0', '0x', '11100') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_tieaway_sisd // FCVTAS_asisdmisc_R - when ('0', '0x', '11101') => __encoding aarch64_vector_arithmetic_unary_float_conv_int_sisd // SCVTF_asisdmisc_R - when ('0', '1x', '01100') => __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_sisd // FCMGT_asisdmisc_FZ - when ('0', '1x', '01101') => __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_sisd // FCMEQ_asisdmisc_FZ - when ('0', '1x', '01110') => __encoding aarch64_vector_arithmetic_unary_cmp_float_lessthan_sisd // FCMLT_asisdmisc_FZ - when ('0', '1x', '11010') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd // FCVTPS_asisdmisc_R - when ('0', '1x', '11011') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd // FCVTZS_asisdmisc_R - when ('0', '1x', '11101') => __encoding aarch64_vector_arithmetic_unary_special_recip_float_sisd // FRECPE_asisdmisc_R - when ('0', '1x', '11111') => __encoding aarch64_vector_arithmetic_unary_special_frecpx // FRECPX_asisdmisc_R - when ('1', _, '00011') => __encoding aarch64_vector_arithmetic_unary_add_saturating_sisd // USQADD_asisdmisc_R - when ('1', _, '00111') => __encoding aarch64_vector_arithmetic_unary_diff_neg_sat_sisd // SQNEG_asisdmisc_R - when ('1', _, '01000') => __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd // CMGE_asisdmisc_Z - when ('1', _, '01001') => __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd // CMLE_asisdmisc_Z - when ('1', _, '01010') => __UNALLOCATED - when ('1', _, '01011') => __encoding aarch64_vector_arithmetic_unary_diff_neg_int_sisd // NEG_asisdmisc_R - when ('1', _, '10010') => __encoding aarch64_vector_arithmetic_unary_extract_sqxtun_sisd // SQXTUN_asisdmisc_N - when ('1', _, '10100') => __encoding aarch64_vector_arithmetic_unary_extract_sat_sisd // UQXTN_asisdmisc_N - when ('1', '0x', '10110') => __encoding aarch64_vector_arithmetic_unary_float_xtn_sisd // FCVTXN_asisdmisc_N - when ('1', '0x', '11010') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd // FCVTNU_asisdmisc_R - when ('1', '0x', '11011') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd // FCVTMU_asisdmisc_R - when ('1', '0x', '11100') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_tieaway_sisd // FCVTAU_asisdmisc_R - when ('1', '0x', '11101') => __encoding aarch64_vector_arithmetic_unary_float_conv_int_sisd // UCVTF_asisdmisc_R - when ('1', '1x', '01100') => __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_sisd // FCMGE_asisdmisc_FZ - when ('1', '1x', '01101') => __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_sisd // FCMLE_asisdmisc_FZ - when ('1', '1x', '01110') => __UNALLOCATED - when ('1', '1x', '11010') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd // FCVTPU_asisdmisc_R - when ('1', '1x', '11011') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd // FCVTZU_asisdmisc_R - when ('1', '1x', '11101') => __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_float_sisd // FRSQRTE_asisdmisc_R - when ('1', '1x', '11111') => __UNALLOCATED - when ('01x1', _, '0x', 'x110', '00xxxxx10', _) => // asisdpair - __field U 29 +: 1 - __field size 22 +: 2 - __field opcode 12 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, size, opcode) of - when (_, _, '00xxx') => __UNALLOCATED - when (_, _, '010xx') => __UNALLOCATED - when (_, _, '01110') => __UNALLOCATED - when (_, _, '10xxx') => __UNALLOCATED - when (_, _, '1100x') => __UNALLOCATED - when (_, _, '11010') => __UNALLOCATED - when (_, _, '111xx') => __UNALLOCATED - when (_, '1x', '01101') => __UNALLOCATED - when ('0', _, '11011') => __encoding aarch64_vector_reduce_add_sisd // ADDP_asisdpair_only - when ('0', '00', '01100') => __encoding aarch64_vector_reduce_fp16_maxnm_sisd // FMAXNMP_asisdpair_only_H - when ('0', '00', '01101') => __encoding aarch64_vector_reduce_fp16_add_sisd // FADDP_asisdpair_only_H - when ('0', '00', '01111') => __encoding aarch64_vector_reduce_fp16_max_sisd // FMAXP_asisdpair_only_H - when ('0', '01', '01100') => __UNALLOCATED - when ('0', '01', '01101') => __UNALLOCATED - when ('0', '01', '01111') => __UNALLOCATED - when ('0', '10', '01100') => __encoding aarch64_vector_reduce_fp16_maxnm_sisd // FMINNMP_asisdpair_only_H - when ('0', '10', '01111') => __encoding aarch64_vector_reduce_fp16_max_sisd // FMINP_asisdpair_only_H - when ('0', '11', '01100') => __UNALLOCATED - when ('0', '11', '01111') => __UNALLOCATED - when ('1', _, '11011') => __UNALLOCATED - when ('1', '0x', '01100') => __encoding aarch64_vector_reduce_fp_maxnm_sisd // FMAXNMP_asisdpair_only_SD - when ('1', '0x', '01101') => __encoding aarch64_vector_reduce_fp_add_sisd // FADDP_asisdpair_only_SD - when ('1', '0x', '01111') => __encoding aarch64_vector_reduce_fp_max_sisd // FMAXP_asisdpair_only_SD - when ('1', '1x', '01100') => __encoding aarch64_vector_reduce_fp_maxnm_sisd // FMINNMP_asisdpair_only_SD - when ('1', '1x', '01111') => __encoding aarch64_vector_reduce_fp_max_sisd // FMINP_asisdpair_only_SD - when ('01x1', _, '0x', 'x1xx', '1xxxxxx10', _) => __UNPREDICTABLE - when ('01x1', _, '0x', 'x1xx', 'x1xxxxx10', _) => __UNPREDICTABLE - when ('01x1', _, '0x', 'x1xx', 'xxxxxxx00', _) => // asisddiff - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, opcode) of - when (_, '00xx') => __UNALLOCATED - when (_, '01xx') => __UNALLOCATED - when (_, '1000') => __UNALLOCATED - when (_, '1010') => __UNALLOCATED - when (_, '1100') => __UNALLOCATED - when (_, '111x') => __UNALLOCATED - when ('0', '1001') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_dmacc_sisd // SQDMLAL_asisddiff_only - when ('0', '1011') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_dmacc_sisd // SQDMLSL_asisddiff_only - when ('0', '1101') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_double_sisd // SQDMULL_asisddiff_only - when ('1', '1001') => __UNALLOCATED - when ('1', '1011') => __UNALLOCATED - when ('1', '1101') => __UNALLOCATED - when ('01x1', _, '0x', 'x1xx', 'xxxxxxxx1', _) => // asisdsame - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field opcode 11 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, size, opcode) of - when (_, _, '00000') => __UNALLOCATED - when (_, _, '0001x') => __UNALLOCATED - when (_, _, '00100') => __UNALLOCATED - when (_, _, '011xx') => __UNALLOCATED - when (_, _, '1001x') => __UNALLOCATED - when (_, '1x', '11011') => __UNALLOCATED - when ('0', _, '00001') => __encoding aarch64_vector_arithmetic_binary_uniform_add_saturating_sisd // SQADD_asisdsame_only - when ('0', _, '00101') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_saturating_sisd // SQSUB_asisdsame_only - when ('0', _, '00110') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd // CMGT_asisdsame_only - when ('0', _, '00111') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd // CMGE_asisdsame_only - when ('0', _, '01000') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd // SSHL_asisdsame_only - when ('0', _, '01001') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd // SQSHL_asisdsame_only - when ('0', _, '01010') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd // SRSHL_asisdsame_only - when ('0', _, '01011') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd // SQRSHL_asisdsame_only - when ('0', _, '10000') => __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_sisd // ADD_asisdsame_only - when ('0', _, '10001') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_sisd // CMTST_asisdsame_only - when ('0', _, '10100') => __UNALLOCATED - when ('0', _, '10101') => __UNALLOCATED - when ('0', _, '10110') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_sisd // SQDMULH_asisdsame_only - when ('0', _, '10111') => __UNALLOCATED - when ('0', '0x', '11000') => __UNALLOCATED - when ('0', '0x', '11001') => __UNALLOCATED - when ('0', '0x', '11010') => __UNALLOCATED - when ('0', '0x', '11011') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_extended_sisd // FMULX_asisdsame_only - when ('0', '0x', '11100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd // FCMEQ_asisdsame_only - when ('0', '0x', '11101') => __UNALLOCATED - when ('0', '0x', '11110') => __UNALLOCATED - when ('0', '0x', '11111') => __encoding aarch64_vector_arithmetic_binary_uniform_recps_sisd // FRECPS_asisdsame_only - when ('0', '1x', '11000') => __UNALLOCATED - when ('0', '1x', '11001') => __UNALLOCATED - when ('0', '1x', '11010') => __UNALLOCATED - when ('0', '1x', '11100') => __UNALLOCATED - when ('0', '1x', '11101') => __UNALLOCATED - when ('0', '1x', '11110') => __UNALLOCATED - when ('0', '1x', '11111') => __encoding aarch64_vector_arithmetic_binary_uniform_rsqrts_sisd // FRSQRTS_asisdsame_only - when ('1', _, '00001') => __encoding aarch64_vector_arithmetic_binary_uniform_add_saturating_sisd // UQADD_asisdsame_only - when ('1', _, '00101') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_saturating_sisd // UQSUB_asisdsame_only - when ('1', _, '00110') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd // CMHI_asisdsame_only - when ('1', _, '00111') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd // CMHS_asisdsame_only - when ('1', _, '01000') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd // USHL_asisdsame_only - when ('1', _, '01001') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd // UQSHL_asisdsame_only - when ('1', _, '01010') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd // URSHL_asisdsame_only - when ('1', _, '01011') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd // UQRSHL_asisdsame_only - when ('1', _, '10000') => __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_sisd // SUB_asisdsame_only - when ('1', _, '10001') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_sisd // CMEQ_asisdsame_only - when ('1', _, '10100') => __UNALLOCATED - when ('1', _, '10101') => __UNALLOCATED - when ('1', _, '10110') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_sisd // SQRDMULH_asisdsame_only - when ('1', _, '10111') => __UNALLOCATED - when ('1', '0x', '11000') => __UNALLOCATED - when ('1', '0x', '11001') => __UNALLOCATED - when ('1', '0x', '11010') => __UNALLOCATED - when ('1', '0x', '11011') => __UNALLOCATED - when ('1', '0x', '11100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd // FCMGE_asisdsame_only - when ('1', '0x', '11101') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd // FACGE_asisdsame_only - when ('1', '0x', '11110') => __UNALLOCATED - when ('1', '0x', '11111') => __UNALLOCATED - when ('1', '1x', '11000') => __UNALLOCATED - when ('1', '1x', '11001') => __UNALLOCATED - when ('1', '1x', '11010') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp_sisd // FABD_asisdsame_only - when ('1', '1x', '11100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd // FCMGT_asisdsame_only - when ('1', '1x', '11101') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd // FACGT_asisdsame_only - when ('1', '1x', '11110') => __UNALLOCATED - when ('1', '1x', '11111') => __UNALLOCATED - when ('01x1', _, '10', _, 'xxxxxxxx1', _) => // asisdshf - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field opcode 11 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, immh, opcode) of - when (_, !'0000', '00001') => __UNALLOCATED - when (_, !'0000', '00011') => __UNALLOCATED - when (_, !'0000', '00101') => __UNALLOCATED - when (_, !'0000', '00111') => __UNALLOCATED - when (_, !'0000', '01001') => __UNALLOCATED - when (_, !'0000', '01011') => __UNALLOCATED - when (_, !'0000', '01101') => __UNALLOCATED - when (_, !'0000', '01111') => __UNALLOCATED - when (_, !'0000', '101xx') => __UNALLOCATED - when (_, !'0000', '110xx') => __UNALLOCATED - when (_, !'0000', '11101') => __UNALLOCATED - when (_, !'0000', '11110') => __UNALLOCATED - when (_, '0000', _) => __UNALLOCATED - when ('0', !'0000', '00000') => __encoding aarch64_vector_shift_right_sisd // SSHR_asisdshf_R - when ('0', !'0000', '00010') => __encoding aarch64_vector_shift_right_sisd // SSRA_asisdshf_R - when ('0', !'0000', '00100') => __encoding aarch64_vector_shift_right_sisd // SRSHR_asisdshf_R - when ('0', !'0000', '00110') => __encoding aarch64_vector_shift_right_sisd // SRSRA_asisdshf_R - when ('0', !'0000', '01000') => __UNALLOCATED - when ('0', !'0000', '01010') => __encoding aarch64_vector_shift_left_sisd // SHL_asisdshf_R - when ('0', !'0000', '01100') => __UNALLOCATED - when ('0', !'0000', '01110') => __encoding aarch64_vector_shift_left_sat_sisd // SQSHL_asisdshf_R - when ('0', !'0000', '10000') => __UNALLOCATED - when ('0', !'0000', '10001') => __UNALLOCATED - when ('0', !'0000', '10010') => __encoding aarch64_vector_shift_right_narrow_uniform_sisd // SQSHRN_asisdshf_N - when ('0', !'0000', '10011') => __encoding aarch64_vector_shift_right_narrow_uniform_sisd // SQRSHRN_asisdshf_N - when ('0', !'0000', '11100') => __encoding aarch64_vector_shift_conv_int_sisd // SCVTF_asisdshf_C - when ('0', !'0000', '11111') => __encoding aarch64_vector_shift_conv_float_sisd // FCVTZS_asisdshf_C - when ('1', !'0000', '00000') => __encoding aarch64_vector_shift_right_sisd // USHR_asisdshf_R - when ('1', !'0000', '00010') => __encoding aarch64_vector_shift_right_sisd // USRA_asisdshf_R - when ('1', !'0000', '00100') => __encoding aarch64_vector_shift_right_sisd // URSHR_asisdshf_R - when ('1', !'0000', '00110') => __encoding aarch64_vector_shift_right_sisd // URSRA_asisdshf_R - when ('1', !'0000', '01000') => __encoding aarch64_vector_shift_right_insert_sisd // SRI_asisdshf_R - when ('1', !'0000', '01010') => __encoding aarch64_vector_shift_left_insert_sisd // SLI_asisdshf_R - when ('1', !'0000', '01100') => __encoding aarch64_vector_shift_left_sat_sisd // SQSHLU_asisdshf_R - when ('1', !'0000', '01110') => __encoding aarch64_vector_shift_left_sat_sisd // UQSHL_asisdshf_R - when ('1', !'0000', '10000') => __encoding aarch64_vector_shift_right_narrow_nonuniform_sisd // SQSHRUN_asisdshf_N - when ('1', !'0000', '10001') => __encoding aarch64_vector_shift_right_narrow_nonuniform_sisd // SQRSHRUN_asisdshf_N - when ('1', !'0000', '10010') => __encoding aarch64_vector_shift_right_narrow_uniform_sisd // UQSHRN_asisdshf_N - when ('1', !'0000', '10011') => __encoding aarch64_vector_shift_right_narrow_uniform_sisd // UQRSHRN_asisdshf_N - when ('1', !'0000', '11100') => __encoding aarch64_vector_shift_conv_int_sisd // UCVTF_asisdshf_C - when ('1', !'0000', '11111') => __encoding aarch64_vector_shift_conv_float_sisd // FCVTZU_asisdshf_C - when ('01x1', _, '11', _, 'xxxxxxxx1', _) => __UNPREDICTABLE - when ('01x1', _, '1x', _, 'xxxxxxxx0', _) => // asisdelem - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field opcode 12 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, size, opcode) of - when (_, _, '0000') => __UNALLOCATED - when (_, _, '0010') => __UNALLOCATED - when (_, _, '0100') => __UNALLOCATED - when (_, _, '0110') => __UNALLOCATED - when (_, _, '1000') => __UNALLOCATED - when (_, _, '1010') => __UNALLOCATED - when (_, _, '1110') => __UNALLOCATED - when (_, '01', '0001') => __UNALLOCATED - when (_, '01', '0101') => __UNALLOCATED - when (_, '01', '1001') => __UNALLOCATED - when ('0', _, '0011') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_double_sisd // SQDMLAL_asisdelem_L - when ('0', _, '0111') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_double_sisd // SQDMLSL_asisdelem_L - when ('0', _, '1011') => __encoding aarch64_vector_arithmetic_binary_element_mul_double_sisd // SQDMULL_asisdelem_L - when ('0', _, '1100') => __encoding aarch64_vector_arithmetic_binary_element_mul_high_sisd // SQDMULH_asisdelem_R - when ('0', _, '1101') => __encoding aarch64_vector_arithmetic_binary_element_mul_high_sisd // SQRDMULH_asisdelem_R - when ('0', _, '1111') => __UNALLOCATED - when ('0', '00', '0001') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp16_sisd // FMLA_asisdelem_RH_H - when ('0', '00', '0101') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp16_sisd // FMLS_asisdelem_RH_H - when ('0', '00', '1001') => __encoding aarch64_vector_arithmetic_binary_element_mul_fp16_sisd // FMUL_asisdelem_RH_H - when ('0', '1x', '0001') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp_sisd // FMLA_asisdelem_R_SD - when ('0', '1x', '0101') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp_sisd // FMLS_asisdelem_R_SD - when ('0', '1x', '1001') => __encoding aarch64_vector_arithmetic_binary_element_mul_fp_sisd // FMUL_asisdelem_R_SD - when ('1', _, '0011') => __UNALLOCATED - when ('1', _, '0111') => __UNALLOCATED - when ('1', _, '1011') => __UNALLOCATED - when ('1', _, '1100') => __UNALLOCATED - when ('1', _, '1101') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_high_sisd // SQRDMLAH_asisdelem_R - when ('1', _, '1111') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_high_sisd // SQRDMLSH_asisdelem_R - when ('1', '00', '0001') => __UNALLOCATED - when ('1', '00', '0101') => __UNALLOCATED - when ('1', '00', '1001') => __encoding aarch64_vector_arithmetic_binary_element_mul_fp16_sisd // FMULX_asisdelem_RH_H - when ('1', '1x', '0001') => __UNALLOCATED - when ('1', '1x', '0101') => __UNALLOCATED - when ('1', '1x', '1001') => __encoding aarch64_vector_arithmetic_binary_element_mul_fp_sisd // FMULX_asisdelem_R_SD - when ('0x00', _, '0x', 'x0xx', 'xxx0xxx00', _) => // asimdtbl - __field Q 30 +: 1 - __field op2 22 +: 2 - __field Rm 16 +: 5 - __field len 13 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (op2, len, op) of - when ('x1', _, _) => __UNALLOCATED - when ('00', '00', '0') => __encoding aarch64_vector_transfer_vector_table // TBL_asimdtbl_L1_1 - when ('00', '00', '1') => __encoding aarch64_vector_transfer_vector_table // TBX_asimdtbl_L1_1 - when ('00', '01', '0') => __encoding aarch64_vector_transfer_vector_table // TBL_asimdtbl_L2_2 - when ('00', '01', '1') => __encoding aarch64_vector_transfer_vector_table // TBX_asimdtbl_L2_2 - when ('00', '10', '0') => __encoding aarch64_vector_transfer_vector_table // TBL_asimdtbl_L3_3 - when ('00', '10', '1') => __encoding aarch64_vector_transfer_vector_table // TBX_asimdtbl_L3_3 - when ('00', '11', '0') => __encoding aarch64_vector_transfer_vector_table // TBL_asimdtbl_L4_4 - when ('00', '11', '1') => __encoding aarch64_vector_transfer_vector_table // TBX_asimdtbl_L4_4 - when ('1x', _, _) => __UNALLOCATED - when ('0x00', _, '0x', 'x0xx', 'xxx0xxx10', _) => // asimdperm - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field opcode 12 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (opcode) of - when ('000') => __UNALLOCATED - when ('001') => __encoding aarch64_vector_transfer_vector_permute_unzip // UZP1_asimdperm_only - when ('010') => __encoding aarch64_vector_transfer_vector_permute_transpose // TRN1_asimdperm_only - when ('011') => __encoding aarch64_vector_transfer_vector_permute_zip // ZIP1_asimdperm_only - when ('100') => __UNALLOCATED - when ('101') => __encoding aarch64_vector_transfer_vector_permute_unzip // UZP2_asimdperm_only - when ('110') => __encoding aarch64_vector_transfer_vector_permute_transpose // TRN2_asimdperm_only - when ('111') => __encoding aarch64_vector_transfer_vector_permute_zip // ZIP2_asimdperm_only - when ('0x10', _, '0x', 'x0xx', 'xxx0xxxx0', _) => // asimdext - __field Q 30 +: 1 - __field op2 22 +: 2 - __field Rm 16 +: 5 - __field imm4 11 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (op2) of - when ('x1') => __UNALLOCATED - when ('00') => __encoding aarch64_vector_transfer_vector_extract // EXT_asimdext_only - when ('1x') => __UNALLOCATED - when ('0xx0', _, '00', '00xx', 'xxx0xxxx1', _) => // asimdins - __field Q 30 +: 1 - __field op 29 +: 1 - __field imm5 16 +: 5 - __field imm4 11 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (Q, op, imm5, imm4) of - when (_, _, 'x0000', _) => __UNALLOCATED - when (_, '0', _, '0000') => __encoding aarch64_vector_transfer_vector_cpy_dup_simd // DUP_asimdins_DV_v - when (_, '0', _, '0001') => __encoding aarch64_vector_transfer_integer_dup // DUP_asimdins_DR_r - when (_, '0', _, '0010') => __UNALLOCATED - when (_, '0', _, '0100') => __UNALLOCATED - when (_, '0', _, '0110') => __UNALLOCATED - when (_, '0', _, '1xxx') => __UNALLOCATED - when ('0', '0', _, '0011') => __UNALLOCATED - when ('0', '0', _, '0101') => __encoding aarch64_vector_transfer_integer_move_signed // SMOV_asimdins_W_w - when ('0', '0', _, '0111') => __encoding aarch64_vector_transfer_integer_move_unsigned // UMOV_asimdins_W_w - when ('0', '1', _, _) => __UNALLOCATED - when ('1', '0', _, '0011') => __encoding aarch64_vector_transfer_integer_insert // INS_asimdins_IR_r - when ('1', '0', _, '0101') => __encoding aarch64_vector_transfer_integer_move_signed // SMOV_asimdins_X_x - when ('1', '0', 'x1000', '0111') => __encoding aarch64_vector_transfer_integer_move_unsigned // UMOV_asimdins_X_x - when ('1', '1', _, _) => __encoding aarch64_vector_transfer_vector_insert // INS_asimdins_IV_v - when ('0xx0', _, '01', '00xx', 'xxx0xxxx1', _) => __UNPREDICTABLE - when ('0xx0', _, '0x', '0111', '00xxxxx10', _) => __UNPREDICTABLE - when ('0xx0', _, '0x', '10xx', 'xxx00xxx1', _) => // asimdsamefp16 - __field Q 30 +: 1 - __field U 29 +: 1 - __field a 23 +: 1 - __field Rm 16 +: 5 - __field opcode 11 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, a, opcode) of - when ('0', '0', '000') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 // FMAXNM_asimdsamefp16_only - when ('0', '0', '001') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_fused // FMLA_asimdsamefp16_only - when ('0', '0', '010') => __encoding aarch64_vector_arithmetic_binary_uniform_add_fp16 // FADD_asimdsamefp16_only - when ('0', '0', '011') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_extended_simd // FMULX_asimdsamefp16_only - when ('0', '0', '100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd // FCMEQ_asimdsamefp16_only - when ('0', '0', '101') => __UNALLOCATED - when ('0', '0', '110') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 // FMAX_asimdsamefp16_only - when ('0', '0', '111') => __encoding aarch64_vector_arithmetic_binary_uniform_recps_fp16_simd // FRECPS_asimdsamefp16_only - when ('0', '1', '000') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 // FMINNM_asimdsamefp16_only - when ('0', '1', '001') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_fused // FMLS_asimdsamefp16_only - when ('0', '1', '010') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp16_simd // FSUB_asimdsamefp16_only - when ('0', '1', '011') => __UNALLOCATED - when ('0', '1', '100') => __UNALLOCATED - when ('0', '1', '101') => __UNALLOCATED - when ('0', '1', '110') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 // FMIN_asimdsamefp16_only - when ('0', '1', '111') => __encoding aarch64_vector_arithmetic_binary_uniform_rsqrts_fp16_simd // FRSQRTS_asimdsamefp16_only - when ('1', '0', '000') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 // FMAXNMP_asimdsamefp16_only - when ('1', '0', '001') => __UNALLOCATED - when ('1', '0', '010') => __encoding aarch64_vector_arithmetic_binary_uniform_add_fp16 // FADDP_asimdsamefp16_only - when ('1', '0', '011') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_product // FMUL_asimdsamefp16_only - when ('1', '0', '100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd // FCMGE_asimdsamefp16_only - when ('1', '0', '101') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd // FACGE_asimdsamefp16_only - when ('1', '0', '110') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 // FMAXP_asimdsamefp16_only - when ('1', '0', '111') => __encoding aarch64_vector_arithmetic_binary_uniform_div_fp16 // FDIV_asimdsamefp16_only - when ('1', '1', '000') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 // FMINNMP_asimdsamefp16_only - when ('1', '1', '001') => __UNALLOCATED - when ('1', '1', '010') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp16_simd // FABD_asimdsamefp16_only - when ('1', '1', '011') => __UNALLOCATED - when ('1', '1', '100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd // FCMGT_asimdsamefp16_only - when ('1', '1', '101') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd // FACGT_asimdsamefp16_only - when ('1', '1', '110') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 // FMINP_asimdsamefp16_only - when ('1', '1', '111') => __UNALLOCATED - when ('0xx0', _, '0x', '10xx', 'xxx01xxx1', _) => __UNPREDICTABLE - when ('0xx0', _, '0x', '1111', '00xxxxx10', _) => // asimdmiscfp16 - __field Q 30 +: 1 - __field U 29 +: 1 - __field a 23 +: 1 - __field opcode 12 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, a, opcode) of - when (_, _, '00xxx') => __UNALLOCATED - when (_, _, '010xx') => __UNALLOCATED - when (_, _, '10xxx') => __UNALLOCATED - when (_, _, '11110') => __UNALLOCATED - when (_, '0', '011xx') => __UNALLOCATED - when (_, '0', '11111') => __UNALLOCATED - when (_, '1', '11100') => __UNALLOCATED - when ('0', '0', '11000') => __encoding aarch64_vector_arithmetic_unary_fp16_round // FRINTN_asimdmiscfp16_R - when ('0', '0', '11001') => __encoding aarch64_vector_arithmetic_unary_fp16_round // FRINTM_asimdmiscfp16_R - when ('0', '0', '11010') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd // FCVTNS_asimdmiscfp16_R - when ('0', '0', '11011') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd // FCVTMS_asimdmiscfp16_R - when ('0', '0', '11100') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_simd // FCVTAS_asimdmiscfp16_R - when ('0', '0', '11101') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_int_simd // SCVTF_asimdmiscfp16_R - when ('0', '1', '01100') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_simd // FCMGT_asimdmiscfp16_FZ - when ('0', '1', '01101') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_simd // FCMEQ_asimdmiscfp16_FZ - when ('0', '1', '01110') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_lessthan_simd // FCMLT_asimdmiscfp16_FZ - when ('0', '1', '01111') => __encoding aarch64_vector_arithmetic_unary_diff_neg_fp16 // FABS_asimdmiscfp16_R - when ('0', '1', '11000') => __encoding aarch64_vector_arithmetic_unary_fp16_round // FRINTP_asimdmiscfp16_R - when ('0', '1', '11001') => __encoding aarch64_vector_arithmetic_unary_fp16_round // FRINTZ_asimdmiscfp16_R - when ('0', '1', '11010') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd // FCVTPS_asimdmiscfp16_R - when ('0', '1', '11011') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd // FCVTZS_asimdmiscfp16_R - when ('0', '1', '11101') => __encoding aarch64_vector_arithmetic_unary_special_recip_fp16_simd // FRECPE_asimdmiscfp16_R - when ('0', '1', '11111') => __UNALLOCATED - when ('1', '0', '11000') => __encoding aarch64_vector_arithmetic_unary_fp16_round // FRINTA_asimdmiscfp16_R - when ('1', '0', '11001') => __encoding aarch64_vector_arithmetic_unary_fp16_round // FRINTX_asimdmiscfp16_R - when ('1', '0', '11010') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd // FCVTNU_asimdmiscfp16_R - when ('1', '0', '11011') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd // FCVTMU_asimdmiscfp16_R - when ('1', '0', '11100') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_simd // FCVTAU_asimdmiscfp16_R - when ('1', '0', '11101') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_int_simd // UCVTF_asimdmiscfp16_R - when ('1', '1', '01100') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_simd // FCMGE_asimdmiscfp16_FZ - when ('1', '1', '01101') => __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_simd // FCMLE_asimdmiscfp16_FZ - when ('1', '1', '01110') => __UNALLOCATED - when ('1', '1', '01111') => __encoding aarch64_vector_arithmetic_unary_diff_neg_fp16 // FNEG_asimdmiscfp16_R - when ('1', '1', '11000') => __UNALLOCATED - when ('1', '1', '11001') => __encoding aarch64_vector_arithmetic_unary_fp16_round // FRINTI_asimdmiscfp16_R - when ('1', '1', '11010') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd // FCVTPU_asimdmiscfp16_R - when ('1', '1', '11011') => __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd // FCVTZU_asimdmiscfp16_R - when ('1', '1', '11101') => __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_fp16_simd // FRSQRTE_asimdmiscfp16_R - when ('1', '1', '11111') => __encoding aarch64_vector_arithmetic_unary_special_sqrt_fp16 // FSQRT_asimdmiscfp16_R - when ('0xx0', _, '0x', 'x0xx', 'xxx1xxxx0', _) => __UNPREDICTABLE - when ('0xx0', _, '0x', 'x0xx', 'xxx1xxxx1', _) => // asimdsame2 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field opcode 11 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (Q, U, size, opcode) of - when (_, _, '0x', '0011') => __UNALLOCATED - when (_, _, '11', '0011') => __UNALLOCATED - when (_, '0', _, '0000') => __UNALLOCATED - when (_, '0', _, '0001') => __UNALLOCATED - when (_, '0', _, '0010') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_dotp // SDOT_asimdsame2_D - when (_, '0', _, '1xxx') => __UNALLOCATED - when (_, '0', '10', '0011') => __encoding aarch64_vector_arithmetic_binary_uniform_mat_mul_int_usdot // USDOT_asimdsame2_D - when (_, '1', _, '0000') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_simd // SQRDMLAH_asimdsame2_only - when (_, '1', _, '0001') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_simd // SQRDMLSH_asimdsame2_only - when (_, '1', _, '0010') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_dotp // UDOT_asimdsame2_D - when (_, '1', _, '10xx') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_complex // FCMLA_asimdsame2_C - when (_, '1', _, '11x0') => __encoding aarch64_vector_arithmetic_binary_uniform_add_fp_complex // FCADD_asimdsame2_C - when (_, '1', '00', '1101') => __UNALLOCATED - when (_, '1', '00', '1111') => __UNALLOCATED - when (_, '1', '01', '1111') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_bfdot // BFDOT_asimdsame2_D - when (_, '1', '1x', '1101') => __UNALLOCATED - when (_, '1', '10', '0011') => __UNALLOCATED - when (_, '1', '10', '1111') => __UNALLOCATED - when (_, '1', '11', '1111') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_acc_bf16_long // BFMLAL_asimdsame2_F_ - when ('0', _, _, '01xx') => __UNALLOCATED - when ('0', '1', '01', '1101') => __UNALLOCATED - when ('1', _, '0x', '01xx') => __UNALLOCATED - when ('1', _, '1x', '011x') => __UNALLOCATED - when ('1', '0', '10', '0100') => __encoding aarch64_vector_arithmetic_binary_uniform_mat_mul_int_mla // SMMLA_asimdsame2_G - when ('1', '0', '10', '0101') => __encoding aarch64_vector_arithmetic_binary_uniform_mat_mul_int_mla // USMMLA_asimdsame2_G - when ('1', '1', '01', '1101') => __encoding aarch64_vector_bfmmla // BFMMLA_asimdsame2_E - when ('1', '1', '10', '0100') => __encoding aarch64_vector_arithmetic_binary_uniform_mat_mul_int_mla // UMMLA_asimdsame2_G - when ('1', '1', '10', '0101') => __UNALLOCATED - when ('0xx0', _, '0x', 'x100', '00xxxxx10', _) => // asimdmisc - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field opcode 12 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, size, opcode) of - when (_, _, '1000x') => __UNALLOCATED - when (_, _, '10101') => __UNALLOCATED - when (_, '0x', '011xx') => __UNALLOCATED - when (_, '1x', '10111') => __UNALLOCATED - when (_, '1x', '11110') => __UNALLOCATED - when (_, '11', '10110') => __UNALLOCATED - when ('0', _, '00000') => __encoding aarch64_vector_arithmetic_unary_rev // REV64_asimdmisc_R - when ('0', _, '00001') => __encoding aarch64_vector_arithmetic_unary_rev // REV16_asimdmisc_R - when ('0', _, '00010') => __encoding aarch64_vector_arithmetic_unary_add_pairwise // SADDLP_asimdmisc_P - when ('0', _, '00011') => __encoding aarch64_vector_arithmetic_unary_add_saturating_simd // SUQADD_asimdmisc_R - when ('0', _, '00100') => __encoding aarch64_vector_arithmetic_unary_clsz // CLS_asimdmisc_R - when ('0', _, '00101') => __encoding aarch64_vector_arithmetic_unary_cnt // CNT_asimdmisc_R - when ('0', _, '00110') => __encoding aarch64_vector_arithmetic_unary_add_pairwise // SADALP_asimdmisc_P - when ('0', _, '00111') => __encoding aarch64_vector_arithmetic_unary_diff_neg_sat_simd // SQABS_asimdmisc_R - when ('0', _, '01000') => __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_simd // CMGT_asimdmisc_Z - when ('0', _, '01001') => __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_simd // CMEQ_asimdmisc_Z - when ('0', _, '01010') => __encoding aarch64_vector_arithmetic_unary_cmp_int_lessthan_simd // CMLT_asimdmisc_Z - when ('0', _, '01011') => __encoding aarch64_vector_arithmetic_unary_diff_neg_int_simd // ABS_asimdmisc_R - when ('0', _, '10010') => __encoding aarch64_vector_arithmetic_unary_extract_nosat // XTN_asimdmisc_N - when ('0', _, '10011') => __UNALLOCATED - when ('0', _, '10100') => __encoding aarch64_vector_arithmetic_unary_extract_sat_simd // SQXTN_asimdmisc_N - when ('0', '0x', '10110') => __encoding aarch64_vector_arithmetic_unary_float_narrow // FCVTN_asimdmisc_N - when ('0', '0x', '10111') => __encoding aarch64_vector_arithmetic_unary_float_widen // FCVTL_asimdmisc_L - when ('0', '0x', '11000') => __encoding aarch64_vector_arithmetic_unary_float_round // FRINTN_asimdmisc_R - when ('0', '0x', '11001') => __encoding aarch64_vector_arithmetic_unary_float_round // FRINTM_asimdmisc_R - when ('0', '0x', '11010') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd // FCVTNS_asimdmisc_R - when ('0', '0x', '11011') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd // FCVTMS_asimdmisc_R - when ('0', '0x', '11100') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_tieaway_simd // FCVTAS_asimdmisc_R - when ('0', '0x', '11101') => __encoding aarch64_vector_arithmetic_unary_float_conv_int_simd // SCVTF_asimdmisc_R - when ('0', '0x', '11110') => __encoding aarch64_vector_arithmetic_unary_float_round_frint_32_64 // FRINT32Z_asimdmisc_R - when ('0', '0x', '11111') => __encoding aarch64_vector_arithmetic_unary_float_round_frint_32_64 // FRINT64Z_asimdmisc_R - when ('0', '1x', '01100') => __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_simd // FCMGT_asimdmisc_FZ - when ('0', '1x', '01101') => __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_simd // FCMEQ_asimdmisc_FZ - when ('0', '1x', '01110') => __encoding aarch64_vector_arithmetic_unary_cmp_float_lessthan_simd // FCMLT_asimdmisc_FZ - when ('0', '1x', '01111') => __encoding aarch64_vector_arithmetic_unary_diff_neg_float // FABS_asimdmisc_R - when ('0', '1x', '11000') => __encoding aarch64_vector_arithmetic_unary_float_round // FRINTP_asimdmisc_R - when ('0', '1x', '11001') => __encoding aarch64_vector_arithmetic_unary_float_round // FRINTZ_asimdmisc_R - when ('0', '1x', '11010') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd // FCVTPS_asimdmisc_R - when ('0', '1x', '11011') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd // FCVTZS_asimdmisc_R - when ('0', '1x', '11100') => __encoding aarch64_vector_arithmetic_unary_special_recip_int // URECPE_asimdmisc_R - when ('0', '1x', '11101') => __encoding aarch64_vector_arithmetic_unary_special_recip_float_simd // FRECPE_asimdmisc_R - when ('0', '1x', '11111') => __UNALLOCATED - when ('0', '10', '10110') => __encoding aarch64_vector_cvt_bf16_vector // BFCVTN_asimdmisc_4S - when ('1', _, '00000') => __encoding aarch64_vector_arithmetic_unary_rev // REV32_asimdmisc_R - when ('1', _, '00001') => __UNALLOCATED - when ('1', _, '00010') => __encoding aarch64_vector_arithmetic_unary_add_pairwise // UADDLP_asimdmisc_P - when ('1', _, '00011') => __encoding aarch64_vector_arithmetic_unary_add_saturating_simd // USQADD_asimdmisc_R - when ('1', _, '00100') => __encoding aarch64_vector_arithmetic_unary_clsz // CLZ_asimdmisc_R - when ('1', _, '00110') => __encoding aarch64_vector_arithmetic_unary_add_pairwise // UADALP_asimdmisc_P - when ('1', _, '00111') => __encoding aarch64_vector_arithmetic_unary_diff_neg_sat_simd // SQNEG_asimdmisc_R - when ('1', _, '01000') => __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_simd // CMGE_asimdmisc_Z - when ('1', _, '01001') => __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_simd // CMLE_asimdmisc_Z - when ('1', _, '01010') => __UNALLOCATED - when ('1', _, '01011') => __encoding aarch64_vector_arithmetic_unary_diff_neg_int_simd // NEG_asimdmisc_R - when ('1', _, '10010') => __encoding aarch64_vector_arithmetic_unary_extract_sqxtun_simd // SQXTUN_asimdmisc_N - when ('1', _, '10011') => __encoding aarch64_vector_arithmetic_unary_shift // SHLL_asimdmisc_S - when ('1', _, '10100') => __encoding aarch64_vector_arithmetic_unary_extract_sat_simd // UQXTN_asimdmisc_N - when ('1', '0x', '10110') => __encoding aarch64_vector_arithmetic_unary_float_xtn_simd // FCVTXN_asimdmisc_N - when ('1', '0x', '10111') => __UNALLOCATED - when ('1', '0x', '11000') => __encoding aarch64_vector_arithmetic_unary_float_round // FRINTA_asimdmisc_R - when ('1', '0x', '11001') => __encoding aarch64_vector_arithmetic_unary_float_round // FRINTX_asimdmisc_R - when ('1', '0x', '11010') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd // FCVTNU_asimdmisc_R - when ('1', '0x', '11011') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd // FCVTMU_asimdmisc_R - when ('1', '0x', '11100') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_tieaway_simd // FCVTAU_asimdmisc_R - when ('1', '0x', '11101') => __encoding aarch64_vector_arithmetic_unary_float_conv_int_simd // UCVTF_asimdmisc_R - when ('1', '0x', '11110') => __encoding aarch64_vector_arithmetic_unary_float_round_frint_32_64 // FRINT32X_asimdmisc_R - when ('1', '0x', '11111') => __encoding aarch64_vector_arithmetic_unary_float_round_frint_32_64 // FRINT64X_asimdmisc_R - when ('1', '00', '00101') => __encoding aarch64_vector_arithmetic_unary_not // NOT_asimdmisc_R - when ('1', '01', '00101') => __encoding aarch64_vector_arithmetic_unary_rbit // RBIT_asimdmisc_R - when ('1', '1x', '00101') => __UNALLOCATED - when ('1', '1x', '01100') => __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_simd // FCMGE_asimdmisc_FZ - when ('1', '1x', '01101') => __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_simd // FCMLE_asimdmisc_FZ - when ('1', '1x', '01110') => __UNALLOCATED - when ('1', '1x', '01111') => __encoding aarch64_vector_arithmetic_unary_diff_neg_float // FNEG_asimdmisc_R - when ('1', '1x', '11000') => __UNALLOCATED - when ('1', '1x', '11001') => __encoding aarch64_vector_arithmetic_unary_float_round // FRINTI_asimdmisc_R - when ('1', '1x', '11010') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd // FCVTPU_asimdmisc_R - when ('1', '1x', '11011') => __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd // FCVTZU_asimdmisc_R - when ('1', '1x', '11100') => __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_int // URSQRTE_asimdmisc_R - when ('1', '1x', '11101') => __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_float_simd // FRSQRTE_asimdmisc_R - when ('1', '1x', '11111') => __encoding aarch64_vector_arithmetic_unary_special_sqrt // FSQRT_asimdmisc_R - when ('1', '10', '10110') => __UNALLOCATED - when ('0xx0', _, '0x', 'x110', '00xxxxx10', _) => // asimdall - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field opcode 12 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, size, opcode) of - when (_, _, '0000x') => __UNALLOCATED - when (_, _, '00010') => __UNALLOCATED - when (_, _, '001xx') => __UNALLOCATED - when (_, _, '0100x') => __UNALLOCATED - when (_, _, '01011') => __UNALLOCATED - when (_, _, '01101') => __UNALLOCATED - when (_, _, '01110') => __UNALLOCATED - when (_, _, '10xxx') => __UNALLOCATED - when (_, _, '1100x') => __UNALLOCATED - when (_, _, '111xx') => __UNALLOCATED - when ('0', _, '00011') => __encoding aarch64_vector_reduce_add_long // SADDLV_asimdall_only - when ('0', _, '01010') => __encoding aarch64_vector_reduce_int_max // SMAXV_asimdall_only - when ('0', _, '11010') => __encoding aarch64_vector_reduce_int_max // SMINV_asimdall_only - when ('0', _, '11011') => __encoding aarch64_vector_reduce_add_simd // ADDV_asimdall_only - when ('0', '00', '01100') => __encoding aarch64_vector_reduce_fp16_maxnm_simd // FMAXNMV_asimdall_only_H - when ('0', '00', '01111') => __encoding aarch64_vector_reduce_fp16_max_simd // FMAXV_asimdall_only_H - when ('0', '01', '01100') => __UNALLOCATED - when ('0', '01', '01111') => __UNALLOCATED - when ('0', '10', '01100') => __encoding aarch64_vector_reduce_fp16_maxnm_simd // FMINNMV_asimdall_only_H - when ('0', '10', '01111') => __encoding aarch64_vector_reduce_fp16_max_simd // FMINV_asimdall_only_H - when ('0', '11', '01100') => __UNALLOCATED - when ('0', '11', '01111') => __UNALLOCATED - when ('1', _, '00011') => __encoding aarch64_vector_reduce_add_long // UADDLV_asimdall_only - when ('1', _, '01010') => __encoding aarch64_vector_reduce_int_max // UMAXV_asimdall_only - when ('1', _, '11010') => __encoding aarch64_vector_reduce_int_max // UMINV_asimdall_only - when ('1', _, '11011') => __UNALLOCATED - when ('1', '0x', '01100') => __encoding aarch64_vector_reduce_fp_maxnm_simd // FMAXNMV_asimdall_only_SD - when ('1', '0x', '01111') => __encoding aarch64_vector_reduce_fp_max_simd // FMAXV_asimdall_only_SD - when ('1', '1x', '01100') => __encoding aarch64_vector_reduce_fp_maxnm_simd // FMINNMV_asimdall_only_SD - when ('1', '1x', '01111') => __encoding aarch64_vector_reduce_fp_max_simd // FMINV_asimdall_only_SD - when ('0xx0', _, '0x', 'x1xx', '1xxxxxx10', _) => __UNPREDICTABLE - when ('0xx0', _, '0x', 'x1xx', 'x1xxxxx10', _) => __UNPREDICTABLE - when ('0xx0', _, '0x', 'x1xx', 'xxxxxxx00', _) => // asimddiff - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, opcode) of - when (_, '1111') => __UNALLOCATED - when ('0', '0000') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_long // SADDL_asimddiff_L - when ('0', '0001') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_wide // SADDW_asimddiff_W - when ('0', '0010') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_long // SSUBL_asimddiff_L - when ('0', '0011') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_wide // SSUBW_asimddiff_W - when ('0', '0100') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_narrow // ADDHN_asimddiff_N - when ('0', '0101') => __encoding aarch64_vector_arithmetic_binary_disparate_diff // SABAL_asimddiff_L - when ('0', '0110') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_narrow // SUBHN_asimddiff_N - when ('0', '0111') => __encoding aarch64_vector_arithmetic_binary_disparate_diff // SABDL_asimddiff_L - when ('0', '1000') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_accum // SMLAL_asimddiff_L - when ('0', '1001') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_dmacc_simd // SQDMLAL_asimddiff_L - when ('0', '1010') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_accum // SMLSL_asimddiff_L - when ('0', '1011') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_dmacc_simd // SQDMLSL_asimddiff_L - when ('0', '1100') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_product // SMULL_asimddiff_L - when ('0', '1101') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_double_simd // SQDMULL_asimddiff_L - when ('0', '1110') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_poly // PMULL_asimddiff_L - when ('1', '0000') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_long // UADDL_asimddiff_L - when ('1', '0001') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_wide // UADDW_asimddiff_W - when ('1', '0010') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_long // USUBL_asimddiff_L - when ('1', '0011') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_wide // USUBW_asimddiff_W - when ('1', '0100') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_narrow // RADDHN_asimddiff_N - when ('1', '0101') => __encoding aarch64_vector_arithmetic_binary_disparate_diff // UABAL_asimddiff_L - when ('1', '0110') => __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_narrow // RSUBHN_asimddiff_N - when ('1', '0111') => __encoding aarch64_vector_arithmetic_binary_disparate_diff // UABDL_asimddiff_L - when ('1', '1000') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_accum // UMLAL_asimddiff_L - when ('1', '1001') => __UNALLOCATED - when ('1', '1010') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_accum // UMLSL_asimddiff_L - when ('1', '1011') => __UNALLOCATED - when ('1', '1100') => __encoding aarch64_vector_arithmetic_binary_disparate_mul_product // UMULL_asimddiff_L - when ('1', '1101') => __UNALLOCATED - when ('1', '1110') => __UNALLOCATED - when ('0xx0', _, '0x', 'x1xx', 'xxxxxxxx1', _) => // asimdsame - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field opcode 11 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, size, opcode) of - when ('0', _, '00000') => __encoding aarch64_vector_arithmetic_binary_uniform_add_halving_truncating // SHADD_asimdsame_only - when ('0', _, '00001') => __encoding aarch64_vector_arithmetic_binary_uniform_add_saturating_simd // SQADD_asimdsame_only - when ('0', _, '00010') => __encoding aarch64_vector_arithmetic_binary_uniform_add_halving_rounding // SRHADD_asimdsame_only - when ('0', _, '00100') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_int // SHSUB_asimdsame_only - when ('0', _, '00101') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_saturating_simd // SQSUB_asimdsame_only - when ('0', _, '00110') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_simd // CMGT_asimdsame_only - when ('0', _, '00111') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_simd // CMGE_asimdsame_only - when ('0', _, '01000') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd // SSHL_asimdsame_only - when ('0', _, '01001') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd // SQSHL_asimdsame_only - when ('0', _, '01010') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd // SRSHL_asimdsame_only - when ('0', _, '01011') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd // SQRSHL_asimdsame_only - when ('0', _, '01100') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_single // SMAX_asimdsame_only - when ('0', _, '01101') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_single // SMIN_asimdsame_only - when ('0', _, '01110') => __encoding aarch64_vector_arithmetic_binary_uniform_diff // SABD_asimdsame_only - when ('0', _, '01111') => __encoding aarch64_vector_arithmetic_binary_uniform_diff // SABA_asimdsame_only - when ('0', _, '10000') => __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_simd // ADD_asimdsame_only - when ('0', _, '10001') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_simd // CMTST_asimdsame_only - when ('0', _, '10010') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_accum // MLA_asimdsame_only - when ('0', _, '10011') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_product // MUL_asimdsame_only - when ('0', _, '10100') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_pair // SMAXP_asimdsame_only - when ('0', _, '10101') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_pair // SMINP_asimdsame_only - when ('0', _, '10110') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_simd // SQDMULH_asimdsame_only - when ('0', _, '10111') => __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_pair // ADDP_asimdsame_only - when ('0', '0x', '11000') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_2008 // FMAXNM_asimdsame_only - when ('0', '0x', '11001') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_fused // FMLA_asimdsame_only - when ('0', '0x', '11010') => __encoding aarch64_vector_arithmetic_binary_uniform_add_fp // FADD_asimdsame_only - when ('0', '0x', '11011') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_extended_simd // FMULX_asimdsame_only - when ('0', '0x', '11100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd // FCMEQ_asimdsame_only - when ('0', '0x', '11110') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_1985 // FMAX_asimdsame_only - when ('0', '0x', '11111') => __encoding aarch64_vector_arithmetic_binary_uniform_recps_simd // FRECPS_asimdsame_only - when ('0', '00', '00011') => __encoding aarch64_vector_arithmetic_binary_uniform_logical_and_orr // AND_asimdsame_only - when ('0', '00', '11101') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_lower // FMLAL_asimdsame_F - when ('0', '01', '00011') => __encoding aarch64_vector_arithmetic_binary_uniform_logical_and_orr // BIC_asimdsame_only - when ('0', '01', '11101') => __UNALLOCATED - when ('0', '1x', '11000') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_2008 // FMINNM_asimdsame_only - when ('0', '1x', '11001') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_fused // FMLS_asimdsame_only - when ('0', '1x', '11010') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp_simd // FSUB_asimdsame_only - when ('0', '1x', '11011') => __UNALLOCATED - when ('0', '1x', '11100') => __UNALLOCATED - when ('0', '1x', '11110') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_1985 // FMIN_asimdsame_only - when ('0', '1x', '11111') => __encoding aarch64_vector_arithmetic_binary_uniform_rsqrts_simd // FRSQRTS_asimdsame_only - when ('0', '10', '00011') => __encoding aarch64_vector_arithmetic_binary_uniform_logical_and_orr // ORR_asimdsame_only - when ('0', '10', '11101') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_lower // FMLSL_asimdsame_F - when ('0', '11', '00011') => __encoding aarch64_vector_arithmetic_binary_uniform_logical_and_orr // ORN_asimdsame_only - when ('0', '11', '11101') => __UNALLOCATED - when ('1', _, '00000') => __encoding aarch64_vector_arithmetic_binary_uniform_add_halving_truncating // UHADD_asimdsame_only - when ('1', _, '00001') => __encoding aarch64_vector_arithmetic_binary_uniform_add_saturating_simd // UQADD_asimdsame_only - when ('1', _, '00010') => __encoding aarch64_vector_arithmetic_binary_uniform_add_halving_rounding // URHADD_asimdsame_only - when ('1', _, '00100') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_int // UHSUB_asimdsame_only - when ('1', _, '00101') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_saturating_simd // UQSUB_asimdsame_only - when ('1', _, '00110') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_simd // CMHI_asimdsame_only - when ('1', _, '00111') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_simd // CMHS_asimdsame_only - when ('1', _, '01000') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd // USHL_asimdsame_only - when ('1', _, '01001') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd // UQSHL_asimdsame_only - when ('1', _, '01010') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd // URSHL_asimdsame_only - when ('1', _, '01011') => __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd // UQRSHL_asimdsame_only - when ('1', _, '01100') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_single // UMAX_asimdsame_only - when ('1', _, '01101') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_single // UMIN_asimdsame_only - when ('1', _, '01110') => __encoding aarch64_vector_arithmetic_binary_uniform_diff // UABD_asimdsame_only - when ('1', _, '01111') => __encoding aarch64_vector_arithmetic_binary_uniform_diff // UABA_asimdsame_only - when ('1', _, '10000') => __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_simd // SUB_asimdsame_only - when ('1', _, '10001') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_simd // CMEQ_asimdsame_only - when ('1', _, '10010') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_accum // MLS_asimdsame_only - when ('1', _, '10011') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_product // PMUL_asimdsame_only - when ('1', _, '10100') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_pair // UMAXP_asimdsame_only - when ('1', _, '10101') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_pair // UMINP_asimdsame_only - when ('1', _, '10110') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_simd // SQRDMULH_asimdsame_only - when ('1', _, '10111') => __UNALLOCATED - when ('1', '0x', '11000') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_2008 // FMAXNMP_asimdsame_only - when ('1', '0x', '11010') => __encoding aarch64_vector_arithmetic_binary_uniform_add_fp // FADDP_asimdsame_only - when ('1', '0x', '11011') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_product // FMUL_asimdsame_only - when ('1', '0x', '11100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd // FCMGE_asimdsame_only - when ('1', '0x', '11101') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd // FACGE_asimdsame_only - when ('1', '0x', '11110') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_1985 // FMAXP_asimdsame_only - when ('1', '0x', '11111') => __encoding aarch64_vector_arithmetic_binary_uniform_div // FDIV_asimdsame_only - when ('1', '00', '00011') => __encoding aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor // EOR_asimdsame_only - when ('1', '00', '11001') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_upper // FMLAL2_asimdsame_F - when ('1', '01', '00011') => __encoding aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor // BSL_asimdsame_only - when ('1', '01', '11001') => __UNALLOCATED - when ('1', '1x', '11000') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_2008 // FMINNMP_asimdsame_only - when ('1', '1x', '11010') => __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp_simd // FABD_asimdsame_only - when ('1', '1x', '11011') => __UNALLOCATED - when ('1', '1x', '11100') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd // FCMGT_asimdsame_only - when ('1', '1x', '11101') => __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd // FACGT_asimdsame_only - when ('1', '1x', '11110') => __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_1985 // FMINP_asimdsame_only - when ('1', '1x', '11111') => __UNALLOCATED - when ('1', '10', '00011') => __encoding aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor // BIT_asimdsame_only - when ('1', '10', '11001') => __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_upper // FMLSL2_asimdsame_F - when ('1', '11', '00011') => __encoding aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor // BIF_asimdsame_only - when ('1', '11', '11001') => __UNALLOCATED - when ('0xx0', _, '10', '0000', 'xxxxxxxx1', _) => // asimdimm - __field Q 30 +: 1 - __field op 29 +: 1 - __field a 18 +: 1 - __field b 17 +: 1 - __field c 16 +: 1 - __field cmode 12 +: 4 - __field o2 11 +: 1 - __field d 9 +: 1 - __field e 8 +: 1 - __field f 7 +: 1 - __field g 6 +: 1 - __field h 5 +: 1 - __field Rd 0 +: 5 - case (Q, op, cmode, o2) of - when (_, '0', '0xxx', '1') => __UNALLOCATED - when (_, '0', '0xx0', '0') => __encoding aarch64_vector_logical // MOVI_asimdimm_L_sl - when (_, '0', '0xx1', '0') => __encoding aarch64_vector_logical // ORR_asimdimm_L_sl - when (_, '0', '10xx', '1') => __UNALLOCATED - when (_, '0', '10x0', '0') => __encoding aarch64_vector_logical // MOVI_asimdimm_L_hl - when (_, '0', '10x1', '0') => __encoding aarch64_vector_logical // ORR_asimdimm_L_hl - when (_, '0', '110x', '0') => __encoding aarch64_vector_logical // MOVI_asimdimm_M_sm - when (_, '0', '110x', '1') => __UNALLOCATED - when (_, '0', '1110', '0') => __encoding aarch64_vector_logical // MOVI_asimdimm_N_b - when (_, '0', '1110', '1') => __UNALLOCATED - when (_, '0', '1111', '0') => __encoding aarch64_vector_logical // FMOV_asimdimm_S_s - when (_, '0', '1111', '1') => __encoding aarch64_vector_fp16_movi // FMOV_asimdimm_H_h - when (_, '1', _, '1') => __UNALLOCATED - when (_, '1', '0xx0', '0') => __encoding aarch64_vector_logical // MVNI_asimdimm_L_sl - when (_, '1', '0xx1', '0') => __encoding aarch64_vector_logical // BIC_asimdimm_L_sl - when (_, '1', '10x0', '0') => __encoding aarch64_vector_logical // MVNI_asimdimm_L_hl - when (_, '1', '10x1', '0') => __encoding aarch64_vector_logical // BIC_asimdimm_L_hl - when (_, '1', '110x', '0') => __encoding aarch64_vector_logical // MVNI_asimdimm_M_sm - when ('0', '1', '1110', '0') => __encoding aarch64_vector_logical // MOVI_asimdimm_D_ds - when ('0', '1', '1111', '0') => __UNALLOCATED - when ('1', '1', '1110', '0') => __encoding aarch64_vector_logical // MOVI_asimdimm_D2_d - when ('1', '1', '1111', '0') => __encoding aarch64_vector_logical // FMOV_asimdimm_D2_d - when ('0xx0', _, '10', !'0000', 'xxxxxxxx1', _) => // asimdshf - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field opcode 11 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, opcode) of - when (_, '00001') => __UNALLOCATED - when (_, '00011') => __UNALLOCATED - when (_, '00101') => __UNALLOCATED - when (_, '00111') => __UNALLOCATED - when (_, '01001') => __UNALLOCATED - when (_, '01011') => __UNALLOCATED - when (_, '01101') => __UNALLOCATED - when (_, '01111') => __UNALLOCATED - when (_, '10101') => __UNALLOCATED - when (_, '1011x') => __UNALLOCATED - when (_, '110xx') => __UNALLOCATED - when (_, '11101') => __UNALLOCATED - when (_, '11110') => __UNALLOCATED - when ('0', '00000') => __encoding aarch64_vector_shift_right_simd // SSHR_asimdshf_R - when ('0', '00010') => __encoding aarch64_vector_shift_right_simd // SSRA_asimdshf_R - when ('0', '00100') => __encoding aarch64_vector_shift_right_simd // SRSHR_asimdshf_R - when ('0', '00110') => __encoding aarch64_vector_shift_right_simd // SRSRA_asimdshf_R - when ('0', '01000') => __UNALLOCATED - when ('0', '01010') => __encoding aarch64_vector_shift_left_simd // SHL_asimdshf_R - when ('0', '01100') => __UNALLOCATED - when ('0', '01110') => __encoding aarch64_vector_shift_left_sat_simd // SQSHL_asimdshf_R - when ('0', '10000') => __encoding aarch64_vector_shift_right_narrow_logical // SHRN_asimdshf_N - when ('0', '10001') => __encoding aarch64_vector_shift_right_narrow_logical // RSHRN_asimdshf_N - when ('0', '10010') => __encoding aarch64_vector_shift_right_narrow_uniform_simd // SQSHRN_asimdshf_N - when ('0', '10011') => __encoding aarch64_vector_shift_right_narrow_uniform_simd // SQRSHRN_asimdshf_N - when ('0', '10100') => __encoding aarch64_vector_shift_left_long // SSHLL_asimdshf_L - when ('0', '11100') => __encoding aarch64_vector_shift_conv_int_simd // SCVTF_asimdshf_C - when ('0', '11111') => __encoding aarch64_vector_shift_conv_float_simd // FCVTZS_asimdshf_C - when ('1', '00000') => __encoding aarch64_vector_shift_right_simd // USHR_asimdshf_R - when ('1', '00010') => __encoding aarch64_vector_shift_right_simd // USRA_asimdshf_R - when ('1', '00100') => __encoding aarch64_vector_shift_right_simd // URSHR_asimdshf_R - when ('1', '00110') => __encoding aarch64_vector_shift_right_simd // URSRA_asimdshf_R - when ('1', '01000') => __encoding aarch64_vector_shift_right_insert_simd // SRI_asimdshf_R - when ('1', '01010') => __encoding aarch64_vector_shift_left_insert_simd // SLI_asimdshf_R - when ('1', '01100') => __encoding aarch64_vector_shift_left_sat_simd // SQSHLU_asimdshf_R - when ('1', '01110') => __encoding aarch64_vector_shift_left_sat_simd // UQSHL_asimdshf_R - when ('1', '10000') => __encoding aarch64_vector_shift_right_narrow_nonuniform_simd // SQSHRUN_asimdshf_N - when ('1', '10001') => __encoding aarch64_vector_shift_right_narrow_nonuniform_simd // SQRSHRUN_asimdshf_N - when ('1', '10010') => __encoding aarch64_vector_shift_right_narrow_uniform_simd // UQSHRN_asimdshf_N - when ('1', '10011') => __encoding aarch64_vector_shift_right_narrow_uniform_simd // UQRSHRN_asimdshf_N - when ('1', '10100') => __encoding aarch64_vector_shift_left_long // USHLL_asimdshf_L - when ('1', '11100') => __encoding aarch64_vector_shift_conv_int_simd // UCVTF_asimdshf_C - when ('1', '11111') => __encoding aarch64_vector_shift_conv_float_simd // FCVTZU_asimdshf_C - when ('0xx0', _, '11', _, 'xxxxxxxx1', _) => __UNPREDICTABLE - when ('0xx0', _, '1x', _, 'xxxxxxxx0', _) => // asimdelem - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field opcode 12 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (U, size, opcode) of - when (_, '01', '1001') => __UNALLOCATED - when ('0', _, '0010') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_long // SMLAL_asimdelem_L - when ('0', _, '0011') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_double_simd // SQDMLAL_asimdelem_L - when ('0', _, '0110') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_long // SMLSL_asimdelem_L - when ('0', _, '0111') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_double_simd // SQDMLSL_asimdelem_L - when ('0', _, '1000') => __encoding aarch64_vector_arithmetic_binary_element_mul_int // MUL_asimdelem_R - when ('0', _, '1010') => __encoding aarch64_vector_arithmetic_binary_element_mul_long // SMULL_asimdelem_L - when ('0', _, '1011') => __encoding aarch64_vector_arithmetic_binary_element_mul_double_simd // SQDMULL_asimdelem_L - when ('0', _, '1100') => __encoding aarch64_vector_arithmetic_binary_element_mul_high_simd // SQDMULH_asimdelem_R - when ('0', _, '1101') => __encoding aarch64_vector_arithmetic_binary_element_mul_high_simd // SQRDMULH_asimdelem_R - when ('0', _, '1110') => __encoding aarch64_vector_arithmetic_binary_element_dotp // SDOT_asimdelem_D - when ('0', '0x', '0000') => __UNALLOCATED - when ('0', '0x', '0100') => __UNALLOCATED - when ('0', '00', '0001') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp16_simd // FMLA_asimdelem_RH_H - when ('0', '00', '0101') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp16_simd // FMLS_asimdelem_RH_H - when ('0', '00', '1001') => __encoding aarch64_vector_arithmetic_binary_element_mul_fp16_simd // FMUL_asimdelem_RH_H - when ('0', '00', '1111') => __encoding aarch64_vector_arithmetic_binary_element_mat_mul_int_dotp // SUDOT_asimdelem_D - when ('0', '01', '0001') => __UNALLOCATED - when ('0', '01', '0101') => __UNALLOCATED - when ('0', '01', '1111') => __encoding aarch64_vector_arithmetic_binary_element_bfdot // BFDOT_asimdelem_E - when ('0', '1x', '0001') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp_simd // FMLA_asimdelem_R_SD - when ('0', '1x', '0101') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp_simd // FMLS_asimdelem_R_SD - when ('0', '1x', '1001') => __encoding aarch64_vector_arithmetic_binary_element_mul_fp_simd // FMUL_asimdelem_R_SD - when ('0', '10', '0000') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_lower // FMLAL_asimdelem_LH - when ('0', '10', '0100') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_lower // FMLSL_asimdelem_LH - when ('0', '10', '1111') => __encoding aarch64_vector_arithmetic_binary_element_mat_mul_int_dotp // USDOT_asimdelem_D - when ('0', '11', '0000') => __UNALLOCATED - when ('0', '11', '0100') => __UNALLOCATED - when ('0', '11', '1111') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_bf16_long // BFMLAL_asimdelem_F - when ('1', _, '0000') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_int // MLA_asimdelem_R - when ('1', _, '0010') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_long // UMLAL_asimdelem_L - when ('1', _, '0100') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_int // MLS_asimdelem_R - when ('1', _, '0110') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_long // UMLSL_asimdelem_L - when ('1', _, '1010') => __encoding aarch64_vector_arithmetic_binary_element_mul_long // UMULL_asimdelem_L - when ('1', _, '1011') => __UNALLOCATED - when ('1', _, '1101') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_high_simd // SQRDMLAH_asimdelem_R - when ('1', _, '1110') => __encoding aarch64_vector_arithmetic_binary_element_dotp // UDOT_asimdelem_D - when ('1', _, '1111') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_high_simd // SQRDMLSH_asimdelem_R - when ('1', '0x', '1000') => __UNALLOCATED - when ('1', '0x', '1100') => __UNALLOCATED - when ('1', '00', '0001') => __UNALLOCATED - when ('1', '00', '0011') => __UNALLOCATED - when ('1', '00', '0101') => __UNALLOCATED - when ('1', '00', '0111') => __UNALLOCATED - when ('1', '00', '1001') => __encoding aarch64_vector_arithmetic_binary_element_mul_fp16_simd // FMULX_asimdelem_RH_H - when ('1', '01', '0xx1') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_complex // FCMLA_asimdelem_C_H - when ('1', '1x', '1001') => __encoding aarch64_vector_arithmetic_binary_element_mul_fp_simd // FMULX_asimdelem_R_SD - when ('1', '10', '0xx1') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_complex // FCMLA_asimdelem_C_S - when ('1', '10', '1000') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_upper // FMLAL2_asimdelem_LH - when ('1', '10', '1100') => __encoding aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_upper // FMLSL2_asimdelem_LH - when ('1', '11', '0001') => __UNALLOCATED - when ('1', '11', '0011') => __UNALLOCATED - when ('1', '11', '0101') => __UNALLOCATED - when ('1', '11', '0111') => __UNALLOCATED - when ('1', '11', '1000') => __UNALLOCATED - when ('1', '11', '1100') => __UNALLOCATED - when ('1100', _, '00', '10xx', 'xxx10xxxx', _) => // crypto3_imm2 - __field Rm 16 +: 5 - __field imm2 12 +: 2 - __field opcode 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (opcode) of - when ('00') => __encoding aarch64_vector_crypto_sm3_sm3tt1a // SM3TT1A_VVV4_crypto3_imm2 - when ('01') => __encoding aarch64_vector_crypto_sm3_sm3tt1b // SM3TT1B_VVV4_crypto3_imm2 - when ('10') => __encoding aarch64_vector_crypto_sm3_sm3tt2a // SM3TT2A_VVV4_crypto3_imm2 - when ('11') => __encoding aarch64_vector_crypto_sm3_sm3tt2b // SM3TT2B_VVV_crypto3_imm2 - when ('1100', _, '00', '11xx', 'xxx1x00xx', _) => // cryptosha512_3 - __field Rm 16 +: 5 - __field O 14 +: 1 - __field opcode 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (O, opcode) of - when ('0', '00') => __encoding aarch64_vector_crypto_sha512_sha512h // SHA512H_QQV_cryptosha512_3 - when ('0', '01') => __encoding aarch64_vector_crypto_sha512_sha512h2 // SHA512H2_QQV_cryptosha512_3 - when ('0', '10') => __encoding aarch64_vector_crypto_sha512_sha512su1 // SHA512SU1_VVV2_cryptosha512_3 - when ('0', '11') => __encoding aarch64_vector_crypto_sha3_rax1 // RAX1_VVV2_cryptosha512_3 - when ('1', '00') => __encoding aarch64_vector_crypto_sm3_sm3partw1 // SM3PARTW1_VVV4_cryptosha512_3 - when ('1', '01') => __encoding aarch64_vector_crypto_sm3_sm3partw2 // SM3PARTW2_VVV4_cryptosha512_3 - when ('1', '10') => __encoding aarch64_vector_crypto_sm4_sm4enckey // SM4EKEY_VVV4_cryptosha512_3 - when ('1', '11') => __UNALLOCATED - when ('1100', _, '00', _, 'xxx0xxxxx', _) => // crypto4 - __field Op0 21 +: 2 - __field Rm 16 +: 5 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (Op0) of - when ('00') => __encoding aarch64_vector_crypto_sha3_eor3 // EOR3_VVV16_crypto4 - when ('01') => __encoding aarch64_vector_crypto_sha3_bcax // BCAX_VVV16_crypto4 - when ('10') => __encoding aarch64_vector_crypto_sm3_sm3ss1 // SM3SS1_VVV4_crypto4 - when ('11') => __UNALLOCATED - when ('1100', _, '01', '00xx', _, _) => // crypto3_imm6 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case () of - when () => __encoding aarch64_vector_crypto_sha3_xar // XAR_VVV2_crypto3_imm6 - when ('1100', _, '01', '1000', '0001000xx', _) => // cryptosha512_2 - __field opcode 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (opcode) of - when ('00') => __encoding aarch64_vector_crypto_sha512_sha512su0 // SHA512SU0_VV2_cryptosha512_2 - when ('01') => __encoding aarch64_vector_crypto_sm4_sm4enc // SM4E_VV4_cryptosha512_2 - when ('1x') => __UNALLOCATED - when ('1xx0', _, '1x', _, _, _) => __UNPREDICTABLE - when ('x0x1', _, '0x', 'x0xx', _, _) => // float2fix - __field sf 31 +: 1 - __field S 29 +: 1 - __field ptype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field scale 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, S, ptype, rmode, opcode, scale) of - when (_, _, _, _, '1xx', _) => __UNALLOCATED - when (_, _, _, 'x0', '00x', _) => __UNALLOCATED - when (_, _, _, 'x1', '01x', _) => __UNALLOCATED - when (_, _, _, '0x', '00x', _) => __UNALLOCATED - when (_, _, _, '1x', '01x', _) => __UNALLOCATED - when (_, _, '10', _, _, _) => __UNALLOCATED - when (_, '1', _, _, _, _) => __UNALLOCATED - when ('0', _, _, _, _, '0xxxxx') => __UNALLOCATED - when ('0', '0', '00', '00', '010', _) => __encoding aarch64_float_convert_fix // SCVTF_S32_float2fix - when ('0', '0', '00', '00', '011', _) => __encoding aarch64_float_convert_fix // UCVTF_S32_float2fix - when ('0', '0', '00', '11', '000', _) => __encoding aarch64_float_convert_fix // FCVTZS_32S_float2fix - when ('0', '0', '00', '11', '001', _) => __encoding aarch64_float_convert_fix // FCVTZU_32S_float2fix - when ('0', '0', '01', '00', '010', _) => __encoding aarch64_float_convert_fix // SCVTF_D32_float2fix - when ('0', '0', '01', '00', '011', _) => __encoding aarch64_float_convert_fix // UCVTF_D32_float2fix - when ('0', '0', '01', '11', '000', _) => __encoding aarch64_float_convert_fix // FCVTZS_32D_float2fix - when ('0', '0', '01', '11', '001', _) => __encoding aarch64_float_convert_fix // FCVTZU_32D_float2fix - when ('0', '0', '11', '00', '010', _) => __encoding aarch64_float_convert_fix // SCVTF_H32_float2fix - when ('0', '0', '11', '00', '011', _) => __encoding aarch64_float_convert_fix // UCVTF_H32_float2fix - when ('0', '0', '11', '11', '000', _) => __encoding aarch64_float_convert_fix // FCVTZS_32H_float2fix - when ('0', '0', '11', '11', '001', _) => __encoding aarch64_float_convert_fix // FCVTZU_32H_float2fix - when ('1', '0', '00', '00', '010', _) => __encoding aarch64_float_convert_fix // SCVTF_S64_float2fix - when ('1', '0', '00', '00', '011', _) => __encoding aarch64_float_convert_fix // UCVTF_S64_float2fix - when ('1', '0', '00', '11', '000', _) => __encoding aarch64_float_convert_fix // FCVTZS_64S_float2fix - when ('1', '0', '00', '11', '001', _) => __encoding aarch64_float_convert_fix // FCVTZU_64S_float2fix - when ('1', '0', '01', '00', '010', _) => __encoding aarch64_float_convert_fix // SCVTF_D64_float2fix - when ('1', '0', '01', '00', '011', _) => __encoding aarch64_float_convert_fix // UCVTF_D64_float2fix - when ('1', '0', '01', '11', '000', _) => __encoding aarch64_float_convert_fix // FCVTZS_64D_float2fix - when ('1', '0', '01', '11', '001', _) => __encoding aarch64_float_convert_fix // FCVTZU_64D_float2fix - when ('1', '0', '11', '00', '010', _) => __encoding aarch64_float_convert_fix // SCVTF_H64_float2fix - when ('1', '0', '11', '00', '011', _) => __encoding aarch64_float_convert_fix // UCVTF_H64_float2fix - when ('1', '0', '11', '11', '000', _) => __encoding aarch64_float_convert_fix // FCVTZS_64H_float2fix - when ('1', '0', '11', '11', '001', _) => __encoding aarch64_float_convert_fix // FCVTZU_64H_float2fix - when ('x0x1', _, '0x', 'x1xx', 'xxx000000', _) => // float2int - __field sf 31 +: 1 - __field S 29 +: 1 - __field ptype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (sf, S, ptype, rmode, opcode) of - when (_, _, _, 'x1', '01x') => __UNALLOCATED - when (_, _, _, 'x1', '10x') => __UNALLOCATED - when (_, _, _, '1x', '01x') => __UNALLOCATED - when (_, _, _, '1x', '10x') => __UNALLOCATED - when (_, '0', '10', _, '0xx') => __UNALLOCATED - when (_, '0', '10', _, '10x') => __UNALLOCATED - when (_, '1', _, _, _) => __UNALLOCATED - when ('0', '0', '00', 'x1', '11x') => __UNALLOCATED - when ('0', '0', '00', '00', '000') => __encoding aarch64_float_convert_int // FCVTNS_32S_float2int - when ('0', '0', '00', '00', '001') => __encoding aarch64_float_convert_int // FCVTNU_32S_float2int - when ('0', '0', '00', '00', '010') => __encoding aarch64_float_convert_int // SCVTF_S32_float2int - when ('0', '0', '00', '00', '011') => __encoding aarch64_float_convert_int // UCVTF_S32_float2int - when ('0', '0', '00', '00', '100') => __encoding aarch64_float_convert_int // FCVTAS_32S_float2int - when ('0', '0', '00', '00', '101') => __encoding aarch64_float_convert_int // FCVTAU_32S_float2int - when ('0', '0', '00', '00', '110') => __encoding aarch64_float_convert_int // FMOV_32S_float2int - when ('0', '0', '00', '00', '111') => __encoding aarch64_float_convert_int // FMOV_S32_float2int - when ('0', '0', '00', '01', '000') => __encoding aarch64_float_convert_int // FCVTPS_32S_float2int - when ('0', '0', '00', '01', '001') => __encoding aarch64_float_convert_int // FCVTPU_32S_float2int - when ('0', '0', '00', '1x', '11x') => __UNALLOCATED - when ('0', '0', '00', '10', '000') => __encoding aarch64_float_convert_int // FCVTMS_32S_float2int - when ('0', '0', '00', '10', '001') => __encoding aarch64_float_convert_int // FCVTMU_32S_float2int - when ('0', '0', '00', '11', '000') => __encoding aarch64_float_convert_int // FCVTZS_32S_float2int - when ('0', '0', '00', '11', '001') => __encoding aarch64_float_convert_int // FCVTZU_32S_float2int - when ('0', '0', '01', '0x', '11x') => __UNALLOCATED - when ('0', '0', '01', '00', '000') => __encoding aarch64_float_convert_int // FCVTNS_32D_float2int - when ('0', '0', '01', '00', '001') => __encoding aarch64_float_convert_int // FCVTNU_32D_float2int - when ('0', '0', '01', '00', '010') => __encoding aarch64_float_convert_int // SCVTF_D32_float2int - when ('0', '0', '01', '00', '011') => __encoding aarch64_float_convert_int // UCVTF_D32_float2int - when ('0', '0', '01', '00', '100') => __encoding aarch64_float_convert_int // FCVTAS_32D_float2int - when ('0', '0', '01', '00', '101') => __encoding aarch64_float_convert_int // FCVTAU_32D_float2int - when ('0', '0', '01', '01', '000') => __encoding aarch64_float_convert_int // FCVTPS_32D_float2int - when ('0', '0', '01', '01', '001') => __encoding aarch64_float_convert_int // FCVTPU_32D_float2int - when ('0', '0', '01', '10', '000') => __encoding aarch64_float_convert_int // FCVTMS_32D_float2int - when ('0', '0', '01', '10', '001') => __encoding aarch64_float_convert_int // FCVTMU_32D_float2int - when ('0', '0', '01', '10', '11x') => __UNALLOCATED - when ('0', '0', '01', '11', '000') => __encoding aarch64_float_convert_int // FCVTZS_32D_float2int - when ('0', '0', '01', '11', '001') => __encoding aarch64_float_convert_int // FCVTZU_32D_float2int - when ('0', '0', '01', '11', '110') => __encoding aarch64_float_convert_int // FJCVTZS_32D_float2int - when ('0', '0', '01', '11', '111') => __UNALLOCATED - when ('0', '0', '10', _, '11x') => __UNALLOCATED - when ('0', '0', '11', '00', '000') => __encoding aarch64_float_convert_int // FCVTNS_32H_float2int - when ('0', '0', '11', '00', '001') => __encoding aarch64_float_convert_int // FCVTNU_32H_float2int - when ('0', '0', '11', '00', '010') => __encoding aarch64_float_convert_int // SCVTF_H32_float2int - when ('0', '0', '11', '00', '011') => __encoding aarch64_float_convert_int // UCVTF_H32_float2int - when ('0', '0', '11', '00', '100') => __encoding aarch64_float_convert_int // FCVTAS_32H_float2int - when ('0', '0', '11', '00', '101') => __encoding aarch64_float_convert_int // FCVTAU_32H_float2int - when ('0', '0', '11', '00', '110') => __encoding aarch64_float_convert_int // FMOV_32H_float2int - when ('0', '0', '11', '00', '111') => __encoding aarch64_float_convert_int // FMOV_H32_float2int - when ('0', '0', '11', '01', '000') => __encoding aarch64_float_convert_int // FCVTPS_32H_float2int - when ('0', '0', '11', '01', '001') => __encoding aarch64_float_convert_int // FCVTPU_32H_float2int - when ('0', '0', '11', '10', '000') => __encoding aarch64_float_convert_int // FCVTMS_32H_float2int - when ('0', '0', '11', '10', '001') => __encoding aarch64_float_convert_int // FCVTMU_32H_float2int - when ('0', '0', '11', '11', '000') => __encoding aarch64_float_convert_int // FCVTZS_32H_float2int - when ('0', '0', '11', '11', '001') => __encoding aarch64_float_convert_int // FCVTZU_32H_float2int - when ('1', '0', '00', _, '11x') => __UNALLOCATED - when ('1', '0', '00', '00', '000') => __encoding aarch64_float_convert_int // FCVTNS_64S_float2int - when ('1', '0', '00', '00', '001') => __encoding aarch64_float_convert_int // FCVTNU_64S_float2int - when ('1', '0', '00', '00', '010') => __encoding aarch64_float_convert_int // SCVTF_S64_float2int - when ('1', '0', '00', '00', '011') => __encoding aarch64_float_convert_int // UCVTF_S64_float2int - when ('1', '0', '00', '00', '100') => __encoding aarch64_float_convert_int // FCVTAS_64S_float2int - when ('1', '0', '00', '00', '101') => __encoding aarch64_float_convert_int // FCVTAU_64S_float2int - when ('1', '0', '00', '01', '000') => __encoding aarch64_float_convert_int // FCVTPS_64S_float2int - when ('1', '0', '00', '01', '001') => __encoding aarch64_float_convert_int // FCVTPU_64S_float2int - when ('1', '0', '00', '10', '000') => __encoding aarch64_float_convert_int // FCVTMS_64S_float2int - when ('1', '0', '00', '10', '001') => __encoding aarch64_float_convert_int // FCVTMU_64S_float2int - when ('1', '0', '00', '11', '000') => __encoding aarch64_float_convert_int // FCVTZS_64S_float2int - when ('1', '0', '00', '11', '001') => __encoding aarch64_float_convert_int // FCVTZU_64S_float2int - when ('1', '0', '01', 'x1', '11x') => __UNALLOCATED - when ('1', '0', '01', '00', '000') => __encoding aarch64_float_convert_int // FCVTNS_64D_float2int - when ('1', '0', '01', '00', '001') => __encoding aarch64_float_convert_int // FCVTNU_64D_float2int - when ('1', '0', '01', '00', '010') => __encoding aarch64_float_convert_int // SCVTF_D64_float2int - when ('1', '0', '01', '00', '011') => __encoding aarch64_float_convert_int // UCVTF_D64_float2int - when ('1', '0', '01', '00', '100') => __encoding aarch64_float_convert_int // FCVTAS_64D_float2int - when ('1', '0', '01', '00', '101') => __encoding aarch64_float_convert_int // FCVTAU_64D_float2int - when ('1', '0', '01', '00', '110') => __encoding aarch64_float_convert_int // FMOV_64D_float2int - when ('1', '0', '01', '00', '111') => __encoding aarch64_float_convert_int // FMOV_D64_float2int - when ('1', '0', '01', '01', '000') => __encoding aarch64_float_convert_int // FCVTPS_64D_float2int - when ('1', '0', '01', '01', '001') => __encoding aarch64_float_convert_int // FCVTPU_64D_float2int - when ('1', '0', '01', '1x', '11x') => __UNALLOCATED - when ('1', '0', '01', '10', '000') => __encoding aarch64_float_convert_int // FCVTMS_64D_float2int - when ('1', '0', '01', '10', '001') => __encoding aarch64_float_convert_int // FCVTMU_64D_float2int - when ('1', '0', '01', '11', '000') => __encoding aarch64_float_convert_int // FCVTZS_64D_float2int - when ('1', '0', '01', '11', '001') => __encoding aarch64_float_convert_int // FCVTZU_64D_float2int - when ('1', '0', '10', 'x0', '11x') => __UNALLOCATED - when ('1', '0', '10', '01', '110') => __encoding aarch64_float_convert_int // FMOV_64VX_float2int - when ('1', '0', '10', '01', '111') => __encoding aarch64_float_convert_int // FMOV_V64I_float2int - when ('1', '0', '10', '1x', '11x') => __UNALLOCATED - when ('1', '0', '11', '00', '000') => __encoding aarch64_float_convert_int // FCVTNS_64H_float2int - when ('1', '0', '11', '00', '001') => __encoding aarch64_float_convert_int // FCVTNU_64H_float2int - when ('1', '0', '11', '00', '010') => __encoding aarch64_float_convert_int // SCVTF_H64_float2int - when ('1', '0', '11', '00', '011') => __encoding aarch64_float_convert_int // UCVTF_H64_float2int - when ('1', '0', '11', '00', '100') => __encoding aarch64_float_convert_int // FCVTAS_64H_float2int - when ('1', '0', '11', '00', '101') => __encoding aarch64_float_convert_int // FCVTAU_64H_float2int - when ('1', '0', '11', '00', '110') => __encoding aarch64_float_convert_int // FMOV_64H_float2int - when ('1', '0', '11', '00', '111') => __encoding aarch64_float_convert_int // FMOV_H64_float2int - when ('1', '0', '11', '01', '000') => __encoding aarch64_float_convert_int // FCVTPS_64H_float2int - when ('1', '0', '11', '01', '001') => __encoding aarch64_float_convert_int // FCVTPU_64H_float2int - when ('1', '0', '11', '10', '000') => __encoding aarch64_float_convert_int // FCVTMS_64H_float2int - when ('1', '0', '11', '10', '001') => __encoding aarch64_float_convert_int // FCVTMU_64H_float2int - when ('1', '0', '11', '11', '000') => __encoding aarch64_float_convert_int // FCVTZS_64H_float2int - when ('1', '0', '11', '11', '001') => __encoding aarch64_float_convert_int // FCVTZU_64H_float2int - when ('x0x1', _, '0x', 'x1xx', 'xxxx10000', _) => // floatdp1 - __field M 31 +: 1 - __field S 29 +: 1 - __field ptype 22 +: 2 - __field opcode 15 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (M, S, ptype, opcode) of - when (_, _, _, '1xxxxx') => __UNALLOCATED - when (_, '1', _, _) => __UNALLOCATED - when ('0', '0', '00', '000000') => __encoding aarch64_float_arithmetic_unary // FMOV_S_floatdp1 - when ('0', '0', '00', '000001') => __encoding aarch64_float_arithmetic_unary // FABS_S_floatdp1 - when ('0', '0', '00', '000010') => __encoding aarch64_float_arithmetic_unary // FNEG_S_floatdp1 - when ('0', '0', '00', '000011') => __encoding aarch64_float_arithmetic_unary // FSQRT_S_floatdp1 - when ('0', '0', '00', '000100') => __UNALLOCATED - when ('0', '0', '00', '000101') => __encoding aarch64_float_convert_fp // FCVT_DS_floatdp1 - when ('0', '0', '00', '000110') => __UNALLOCATED - when ('0', '0', '00', '000111') => __encoding aarch64_float_convert_fp // FCVT_HS_floatdp1 - when ('0', '0', '00', '001000') => __encoding aarch64_float_arithmetic_round_frint // FRINTN_S_floatdp1 - when ('0', '0', '00', '001001') => __encoding aarch64_float_arithmetic_round_frint // FRINTP_S_floatdp1 - when ('0', '0', '00', '001010') => __encoding aarch64_float_arithmetic_round_frint // FRINTM_S_floatdp1 - when ('0', '0', '00', '001011') => __encoding aarch64_float_arithmetic_round_frint // FRINTZ_S_floatdp1 - when ('0', '0', '00', '001100') => __encoding aarch64_float_arithmetic_round_frint // FRINTA_S_floatdp1 - when ('0', '0', '00', '001101') => __UNALLOCATED - when ('0', '0', '00', '001110') => __encoding aarch64_float_arithmetic_round_frint // FRINTX_S_floatdp1 - when ('0', '0', '00', '001111') => __encoding aarch64_float_arithmetic_round_frint // FRINTI_S_floatdp1 - when ('0', '0', '00', '010000') => __encoding aarch64_float_arithmetic_round_frint_32_64 // FRINT32Z_S_floatdp1 - when ('0', '0', '00', '010001') => __encoding aarch64_float_arithmetic_round_frint_32_64 // FRINT32X_S_floatdp1 - when ('0', '0', '00', '010010') => __encoding aarch64_float_arithmetic_round_frint_32_64 // FRINT64Z_S_floatdp1 - when ('0', '0', '00', '010011') => __encoding aarch64_float_arithmetic_round_frint_32_64 // FRINT64X_S_floatdp1 - when ('0', '0', '00', '0101xx') => __UNALLOCATED - when ('0', '0', '00', '011xxx') => __UNALLOCATED - when ('0', '0', '01', '000000') => __encoding aarch64_float_arithmetic_unary // FMOV_D_floatdp1 - when ('0', '0', '01', '000001') => __encoding aarch64_float_arithmetic_unary // FABS_D_floatdp1 - when ('0', '0', '01', '000010') => __encoding aarch64_float_arithmetic_unary // FNEG_D_floatdp1 - when ('0', '0', '01', '000011') => __encoding aarch64_float_arithmetic_unary // FSQRT_D_floatdp1 - when ('0', '0', '01', '000100') => __encoding aarch64_float_convert_fp // FCVT_SD_floatdp1 - when ('0', '0', '01', '000101') => __UNALLOCATED - when ('0', '0', '01', '000110') => __encoding aarch64_vector_cvt_bf16_scalar // BFCVT_BS_floatdp1 - when ('0', '0', '01', '000111') => __encoding aarch64_float_convert_fp // FCVT_HD_floatdp1 - when ('0', '0', '01', '001000') => __encoding aarch64_float_arithmetic_round_frint // FRINTN_D_floatdp1 - when ('0', '0', '01', '001001') => __encoding aarch64_float_arithmetic_round_frint // FRINTP_D_floatdp1 - when ('0', '0', '01', '001010') => __encoding aarch64_float_arithmetic_round_frint // FRINTM_D_floatdp1 - when ('0', '0', '01', '001011') => __encoding aarch64_float_arithmetic_round_frint // FRINTZ_D_floatdp1 - when ('0', '0', '01', '001100') => __encoding aarch64_float_arithmetic_round_frint // FRINTA_D_floatdp1 - when ('0', '0', '01', '001101') => __UNALLOCATED - when ('0', '0', '01', '001110') => __encoding aarch64_float_arithmetic_round_frint // FRINTX_D_floatdp1 - when ('0', '0', '01', '001111') => __encoding aarch64_float_arithmetic_round_frint // FRINTI_D_floatdp1 - when ('0', '0', '01', '010000') => __encoding aarch64_float_arithmetic_round_frint_32_64 // FRINT32Z_D_floatdp1 - when ('0', '0', '01', '010001') => __encoding aarch64_float_arithmetic_round_frint_32_64 // FRINT32X_D_floatdp1 - when ('0', '0', '01', '010010') => __encoding aarch64_float_arithmetic_round_frint_32_64 // FRINT64Z_D_floatdp1 - when ('0', '0', '01', '010011') => __encoding aarch64_float_arithmetic_round_frint_32_64 // FRINT64X_D_floatdp1 - when ('0', '0', '01', '0101xx') => __UNALLOCATED - when ('0', '0', '01', '011xxx') => __UNALLOCATED - when ('0', '0', '10', '0xxxxx') => __UNALLOCATED - when ('0', '0', '11', '000000') => __encoding aarch64_float_arithmetic_unary // FMOV_H_floatdp1 - when ('0', '0', '11', '000001') => __encoding aarch64_float_arithmetic_unary // FABS_H_floatdp1 - when ('0', '0', '11', '000010') => __encoding aarch64_float_arithmetic_unary // FNEG_H_floatdp1 - when ('0', '0', '11', '000011') => __encoding aarch64_float_arithmetic_unary // FSQRT_H_floatdp1 - when ('0', '0', '11', '000100') => __encoding aarch64_float_convert_fp // FCVT_SH_floatdp1 - when ('0', '0', '11', '000101') => __encoding aarch64_float_convert_fp // FCVT_DH_floatdp1 - when ('0', '0', '11', '00011x') => __UNALLOCATED - when ('0', '0', '11', '001000') => __encoding aarch64_float_arithmetic_round_frint // FRINTN_H_floatdp1 - when ('0', '0', '11', '001001') => __encoding aarch64_float_arithmetic_round_frint // FRINTP_H_floatdp1 - when ('0', '0', '11', '001010') => __encoding aarch64_float_arithmetic_round_frint // FRINTM_H_floatdp1 - when ('0', '0', '11', '001011') => __encoding aarch64_float_arithmetic_round_frint // FRINTZ_H_floatdp1 - when ('0', '0', '11', '001100') => __encoding aarch64_float_arithmetic_round_frint // FRINTA_H_floatdp1 - when ('0', '0', '11', '001101') => __UNALLOCATED - when ('0', '0', '11', '001110') => __encoding aarch64_float_arithmetic_round_frint // FRINTX_H_floatdp1 - when ('0', '0', '11', '001111') => __encoding aarch64_float_arithmetic_round_frint // FRINTI_H_floatdp1 - when ('0', '0', '11', '01xxxx') => __UNALLOCATED - when ('1', _, _, _) => __UNALLOCATED - when ('x0x1', _, '0x', 'x1xx', 'xxxxx1000', _) => // floatcmp - __field M 31 +: 1 - __field S 29 +: 1 - __field ptype 22 +: 2 - __field Rm 16 +: 5 - __field op 14 +: 2 - __field Rn 5 +: 5 - __field opcode2 0 +: 5 - case (M, S, ptype, op, opcode2) of - when (_, _, _, _, 'xxxx1') => __UNALLOCATED - when (_, _, _, _, 'xxx1x') => __UNALLOCATED - when (_, _, _, _, 'xx1xx') => __UNALLOCATED - when (_, _, _, 'x1', _) => __UNALLOCATED - when (_, _, _, '1x', _) => __UNALLOCATED - when (_, _, '10', _, _) => __UNALLOCATED - when (_, '1', _, _, _) => __UNALLOCATED - when ('0', '0', '00', '00', '00000') => __encoding aarch64_float_compare_uncond // FCMP_S_floatcmp - when ('0', '0', '00', '00', '01000') => __encoding aarch64_float_compare_uncond // FCMP_SZ_floatcmp - when ('0', '0', '00', '00', '10000') => __encoding aarch64_float_compare_uncond // FCMPE_S_floatcmp - when ('0', '0', '00', '00', '11000') => __encoding aarch64_float_compare_uncond // FCMPE_SZ_floatcmp - when ('0', '0', '01', '00', '00000') => __encoding aarch64_float_compare_uncond // FCMP_D_floatcmp - when ('0', '0', '01', '00', '01000') => __encoding aarch64_float_compare_uncond // FCMP_DZ_floatcmp - when ('0', '0', '01', '00', '10000') => __encoding aarch64_float_compare_uncond // FCMPE_D_floatcmp - when ('0', '0', '01', '00', '11000') => __encoding aarch64_float_compare_uncond // FCMPE_DZ_floatcmp - when ('0', '0', '11', '00', '00000') => __encoding aarch64_float_compare_uncond // FCMP_H_floatcmp - when ('0', '0', '11', '00', '01000') => __encoding aarch64_float_compare_uncond // FCMP_HZ_floatcmp - when ('0', '0', '11', '00', '10000') => __encoding aarch64_float_compare_uncond // FCMPE_H_floatcmp - when ('0', '0', '11', '00', '11000') => __encoding aarch64_float_compare_uncond // FCMPE_HZ_floatcmp - when ('1', _, _, _, _) => __UNALLOCATED - when ('x0x1', _, '0x', 'x1xx', 'xxxxxx100', _) => // floatimm - __field M 31 +: 1 - __field S 29 +: 1 - __field ptype 22 +: 2 - __field imm8 13 +: 8 - __field imm5 5 +: 5 - __field Rd 0 +: 5 - case (M, S, ptype, imm5) of - when (_, _, _, 'xxxx1') => __UNALLOCATED - when (_, _, _, 'xxx1x') => __UNALLOCATED - when (_, _, _, 'xx1xx') => __UNALLOCATED - when (_, _, _, 'x1xxx') => __UNALLOCATED - when (_, _, _, '1xxxx') => __UNALLOCATED - when (_, _, '10', _) => __UNALLOCATED - when (_, '1', _, _) => __UNALLOCATED - when ('0', '0', '00', '00000') => __encoding aarch64_float_move_fp_imm // FMOV_S_floatimm - when ('0', '0', '01', '00000') => __encoding aarch64_float_move_fp_imm // FMOV_D_floatimm - when ('0', '0', '11', '00000') => __encoding aarch64_float_move_fp_imm // FMOV_H_floatimm - when ('1', _, _, _) => __UNALLOCATED - when ('x0x1', _, '0x', 'x1xx', 'xxxxxxx01', _) => // floatccmp - __field M 31 +: 1 - __field S 29 +: 1 - __field ptype 22 +: 2 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field Rn 5 +: 5 - __field op 4 +: 1 - __field nzcv 0 +: 4 - case (M, S, ptype, op) of - when (_, _, '10', _) => __UNALLOCATED - when (_, '1', _, _) => __UNALLOCATED - when ('0', '0', '00', '0') => __encoding aarch64_float_compare_cond // FCCMP_S_floatccmp - when ('0', '0', '00', '1') => __encoding aarch64_float_compare_cond // FCCMPE_S_floatccmp - when ('0', '0', '01', '0') => __encoding aarch64_float_compare_cond // FCCMP_D_floatccmp - when ('0', '0', '01', '1') => __encoding aarch64_float_compare_cond // FCCMPE_D_floatccmp - when ('0', '0', '11', '0') => __encoding aarch64_float_compare_cond // FCCMP_H_floatccmp - when ('0', '0', '11', '1') => __encoding aarch64_float_compare_cond // FCCMPE_H_floatccmp - when ('1', _, _, _) => __UNALLOCATED - when ('x0x1', _, '0x', 'x1xx', 'xxxxxxx10', _) => // floatdp2 - __field M 31 +: 1 - __field S 29 +: 1 - __field ptype 22 +: 2 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (M, S, ptype, opcode) of - when (_, _, _, '1xx1') => __UNALLOCATED - when (_, _, _, '1x1x') => __UNALLOCATED - when (_, _, _, '11xx') => __UNALLOCATED - when (_, _, '10', _) => __UNALLOCATED - when (_, '1', _, _) => __UNALLOCATED - when ('0', '0', '00', '0000') => __encoding aarch64_float_arithmetic_mul_product // FMUL_S_floatdp2 - when ('0', '0', '00', '0001') => __encoding aarch64_float_arithmetic_div // FDIV_S_floatdp2 - when ('0', '0', '00', '0010') => __encoding aarch64_float_arithmetic_add_sub // FADD_S_floatdp2 - when ('0', '0', '00', '0011') => __encoding aarch64_float_arithmetic_add_sub // FSUB_S_floatdp2 - when ('0', '0', '00', '0100') => __encoding aarch64_float_arithmetic_max_min // FMAX_S_floatdp2 - when ('0', '0', '00', '0101') => __encoding aarch64_float_arithmetic_max_min // FMIN_S_floatdp2 - when ('0', '0', '00', '0110') => __encoding aarch64_float_arithmetic_max_min // FMAXNM_S_floatdp2 - when ('0', '0', '00', '0111') => __encoding aarch64_float_arithmetic_max_min // FMINNM_S_floatdp2 - when ('0', '0', '00', '1000') => __encoding aarch64_float_arithmetic_mul_product // FNMUL_S_floatdp2 - when ('0', '0', '01', '0000') => __encoding aarch64_float_arithmetic_mul_product // FMUL_D_floatdp2 - when ('0', '0', '01', '0001') => __encoding aarch64_float_arithmetic_div // FDIV_D_floatdp2 - when ('0', '0', '01', '0010') => __encoding aarch64_float_arithmetic_add_sub // FADD_D_floatdp2 - when ('0', '0', '01', '0011') => __encoding aarch64_float_arithmetic_add_sub // FSUB_D_floatdp2 - when ('0', '0', '01', '0100') => __encoding aarch64_float_arithmetic_max_min // FMAX_D_floatdp2 - when ('0', '0', '01', '0101') => __encoding aarch64_float_arithmetic_max_min // FMIN_D_floatdp2 - when ('0', '0', '01', '0110') => __encoding aarch64_float_arithmetic_max_min // FMAXNM_D_floatdp2 - when ('0', '0', '01', '0111') => __encoding aarch64_float_arithmetic_max_min // FMINNM_D_floatdp2 - when ('0', '0', '01', '1000') => __encoding aarch64_float_arithmetic_mul_product // FNMUL_D_floatdp2 - when ('0', '0', '11', '0000') => __encoding aarch64_float_arithmetic_mul_product // FMUL_H_floatdp2 - when ('0', '0', '11', '0001') => __encoding aarch64_float_arithmetic_div // FDIV_H_floatdp2 - when ('0', '0', '11', '0010') => __encoding aarch64_float_arithmetic_add_sub // FADD_H_floatdp2 - when ('0', '0', '11', '0011') => __encoding aarch64_float_arithmetic_add_sub // FSUB_H_floatdp2 - when ('0', '0', '11', '0100') => __encoding aarch64_float_arithmetic_max_min // FMAX_H_floatdp2 - when ('0', '0', '11', '0101') => __encoding aarch64_float_arithmetic_max_min // FMIN_H_floatdp2 - when ('0', '0', '11', '0110') => __encoding aarch64_float_arithmetic_max_min // FMAXNM_H_floatdp2 - when ('0', '0', '11', '0111') => __encoding aarch64_float_arithmetic_max_min // FMINNM_H_floatdp2 - when ('0', '0', '11', '1000') => __encoding aarch64_float_arithmetic_mul_product // FNMUL_H_floatdp2 - when ('1', _, _, _) => __UNALLOCATED - when ('x0x1', _, '0x', 'x1xx', 'xxxxxxx11', _) => // floatsel - __field M 31 +: 1 - __field S 29 +: 1 - __field ptype 22 +: 2 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (M, S, ptype) of - when (_, _, '10') => __UNALLOCATED - when (_, '1', _) => __UNALLOCATED - when ('0', '0', '00') => __encoding aarch64_float_move_fp_select // FCSEL_S_floatsel - when ('0', '0', '01') => __encoding aarch64_float_move_fp_select // FCSEL_D_floatsel - when ('0', '0', '11') => __encoding aarch64_float_move_fp_select // FCSEL_H_floatsel - when ('1', _, _) => __UNALLOCATED - when ('x0x1', _, '1x', _, _, _) => // floatdp3 - __field M 31 +: 1 - __field S 29 +: 1 - __field ptype 22 +: 2 - __field o1 21 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - case (M, S, ptype, o1, o0) of - when (_, _, '10', _, _) => __UNALLOCATED - when (_, '1', _, _, _) => __UNALLOCATED - when ('0', '0', '00', '0', '0') => __encoding aarch64_float_arithmetic_mul_add_sub // FMADD_S_floatdp3 - when ('0', '0', '00', '0', '1') => __encoding aarch64_float_arithmetic_mul_add_sub // FMSUB_S_floatdp3 - when ('0', '0', '00', '1', '0') => __encoding aarch64_float_arithmetic_mul_add_sub // FNMADD_S_floatdp3 - when ('0', '0', '00', '1', '1') => __encoding aarch64_float_arithmetic_mul_add_sub // FNMSUB_S_floatdp3 - when ('0', '0', '01', '0', '0') => __encoding aarch64_float_arithmetic_mul_add_sub // FMADD_D_floatdp3 - when ('0', '0', '01', '0', '1') => __encoding aarch64_float_arithmetic_mul_add_sub // FMSUB_D_floatdp3 - when ('0', '0', '01', '1', '0') => __encoding aarch64_float_arithmetic_mul_add_sub // FNMADD_D_floatdp3 - when ('0', '0', '01', '1', '1') => __encoding aarch64_float_arithmetic_mul_add_sub // FNMSUB_D_floatdp3 - when ('0', '0', '11', '0', '0') => __encoding aarch64_float_arithmetic_mul_add_sub // FMADD_H_floatdp3 - when ('0', '0', '11', '0', '1') => __encoding aarch64_float_arithmetic_mul_add_sub // FMSUB_H_floatdp3 - when ('0', '0', '11', '1', '0') => __encoding aarch64_float_arithmetic_mul_add_sub // FNMADD_H_floatdp3 - when ('0', '0', '11', '1', '1') => __encoding aarch64_float_arithmetic_mul_add_sub // FNMSUB_H_floatdp3 - when ('1', _, _, _, _) => __UNALLOCATED -__decode T32 - // T32 - case (29 +: 3, 27 +: 2, 0 +: 27) of - when (!'111', _, _) => - // n - case (26 +: 6, 0 +: 26) of - when ('00xxxx', _) => - // sftdpi - case (30 +: 2, 29 +: 1, 27 +: 2, 26 +: 1, 0 +: 26) of - when (_, '0', '11', '0', _) => // addsub16_3l - __field S 25 +: 1 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rd 16 +: 3 - case (S) of - when ('0') => __encoding aarch32_ADD_r_T1_A // ADD_r_T1 - when ('1') => __encoding aarch32_SUB_r_T1_A // SUB_r_T1 - when (_, '0', '11', '1', _) => // addsub16_2l_imm - __field S 25 +: 1 - __field imm3 22 +: 3 - __field Rn 19 +: 3 - __field Rd 16 +: 3 - case (S) of - when ('0') => __encoding aarch32_ADD_i_T1_A // ADD_i_T1 - when ('1') => __encoding aarch32_SUB_i_T1_A // SUB_i_T1 - when (_, '0', !'11', _, _) => // shift16_imm - __field op 27 +: 2 - __field imm5 22 +: 5 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - case () of - when () => __encoding aarch32_MOV_r_T2_A // MOV_r_T2 - when (_, '1', _, _, _) => // addsub16_1l_imm - __field op 27 +: 2 - __field Rd 24 +: 3 - __field imm8 16 +: 8 - case (op) of - when ('00') => __encoding aarch32_MOV_i_T1_A // MOV_i_T1 - when ('01') => __encoding aarch32_CMP_i_T1_A // CMP_i_T1 - when ('10') => __encoding aarch32_ADD_i_T2_A // ADD_i_T2 - when ('11') => __encoding aarch32_SUB_i_T2_A // SUB_i_T2 - when ('010000', _) => // dpint16_2l - __field op 22 +: 4 - __field Rs 19 +: 3 - __field Rd 16 +: 3 - case (op) of - when ('0000') => __encoding aarch32_AND_r_T1_A // AND_r_T1 - when ('0001') => __encoding aarch32_EOR_r_T1_A // EOR_r_T1 - when ('0010') => __encoding aarch32_MOV_rr_T1_A // MOV_rr_T1_LSL - when ('0011') => __encoding aarch32_MOV_rr_T1_A // MOV_rr_T1_LSR - when ('0100') => __encoding aarch32_MOV_rr_T1_A // MOV_rr_T1_ASR - when ('0101') => __encoding aarch32_ADC_r_T1_A // ADC_r_T1 - when ('0110') => __encoding aarch32_SBC_r_T1_A // SBC_r_T1 - when ('0111') => __encoding aarch32_MOV_rr_T1_A // MOV_rr_T1_ROR - when ('1000') => __encoding aarch32_TST_r_T1_A // TST_r_T1 - when ('1001') => __encoding aarch32_RSB_i_T1_A // RSB_i_T1 - when ('1010') => __encoding aarch32_CMP_r_T1_A // CMP_r_T1 - when ('1011') => __encoding aarch32_CMN_r_T1_A // CMN_r_T1 - when ('1100') => __encoding aarch32_ORR_r_T1_A // ORR_r_T1 - when ('1101') => __encoding aarch32_MUL_T1_A // MUL_T1 - when ('1110') => __encoding aarch32_BIC_r_T1_A // BIC_r_T1 - when ('1111') => __encoding aarch32_MVN_r_T1_A // MVN_r_T1 - when ('010001', _) => - // spcd - case (26 +: 6, 24 +: 2, 0 +: 24) of - when (_, '11', _) => // bx16 - __field L 23 +: 1 - __field Rm 19 +: 4 - case (L) of - when ('0') => __encoding aarch32_BX_T1_A // BX_T1 - when ('1') => __encoding aarch32_BLX_r_T1_A // BLX_r_T1 - when (_, !'11', _) => // addsub16_2h - __field op 24 +: 2 - __field D 23 +: 1 - __field Rs 19 +: 4 - __field Rd 16 +: 3 - case (op, D:Rd, Rs) of - when ('00', !'1101', !'1101') => __encoding aarch32_ADD_r_T2_A // ADD_r_T2 - when ('00', _, '1101') => __encoding aarch32_ADD_SP_r_A1_A - when ('00', '1101', !'1101') => __encoding aarch32_ADD_SP_r_A1_A - when ('01', _, _) => __encoding aarch32_CMP_r_T2_A // CMP_r_T2 - when ('10', _, _) => __encoding aarch32_MOV_r_T1_A // MOV_r_T1 - when ('01001x', _) => // ldlit16 - __field Rt 24 +: 3 - __field imm8 16 +: 8 - case () of - when () => __encoding aarch32_LDR_l_T1_A // LDR_l_T1 - when ('0101xx', _) => // ldst16_reg - __field L 27 +: 1 - __field B 26 +: 1 - __field H 25 +: 1 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - case (L, B, H) of - when ('0', '0', '0') => __encoding aarch32_STR_r_T1_A // STR_r_T1 - when ('0', '0', '1') => __encoding aarch32_STRH_r_T1_A // STRH_r_T1 - when ('0', '1', '0') => __encoding aarch32_STRB_r_T1_A // STRB_r_T1 - when ('0', '1', '1') => __encoding aarch32_LDRSB_r_T1_A // LDRSB_r_T1 - when ('1', '0', '0') => __encoding aarch32_LDR_r_T1_A // LDR_r_T1 - when ('1', '0', '1') => __encoding aarch32_LDRH_r_T1_A // LDRH_r_T1 - when ('1', '1', '0') => __encoding aarch32_LDRB_r_T1_A // LDRB_r_T1 - when ('1', '1', '1') => __encoding aarch32_LDRSH_r_T1_A // LDRSH_r_T1 - when ('011xxx', _) => // ldst16_imm - __field B 28 +: 1 - __field L 27 +: 1 - __field imm5 22 +: 5 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - case (B, L) of - when ('0', '0') => __encoding aarch32_STR_i_T1_A // STR_i_T1 - when ('0', '1') => __encoding aarch32_LDR_i_T1_A // LDR_i_T1 - when ('1', '0') => __encoding aarch32_STRB_i_T1_A // STRB_i_T1 - when ('1', '1') => __encoding aarch32_LDRB_i_T1_A // LDRB_i_T1 - when ('1000xx', _) => // ldsth16_imm - __field L 27 +: 1 - __field imm5 22 +: 5 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - case (L) of - when ('0') => __encoding aarch32_STRH_i_T1_A // STRH_i_T1 - when ('1') => __encoding aarch32_LDRH_i_T1_A // LDRH_i_T1 - when ('1001xx', _) => // ldst16_sp - __field L 27 +: 1 - __field Rt 24 +: 3 - __field imm8 16 +: 8 - case (L) of - when ('0') => __encoding aarch32_STR_i_T2_A // STR_i_T2 - when ('1') => __encoding aarch32_LDR_i_T2_A // LDR_i_T2 - when ('1010xx', _) => // addpcsp16 - __field SP 27 +: 1 - __field Rd 24 +: 3 - __field imm8 16 +: 8 - case (SP) of - when ('0') => __encoding aarch32_ADR_T1_A // ADR_T1 - when ('1') => __encoding aarch32_ADD_SP_i_T1_A // ADD_SP_i_T1 - when ('1011xx', _) => - // misc16 - case (28 +: 4, 24 +: 4, 22 +: 2, 21 +: 1, 20 +: 1, 16 +: 4, 0 +: 16) of - when (_, '0000', _, _, _, _, _) => // adjsp16 - __field S 23 +: 1 - __field imm7 16 +: 7 - case (S) of - when ('0') => __encoding aarch32_ADD_SP_i_T2_A // ADD_SP_i_T2 - when ('1') => __encoding aarch32_SUB_SP_i_T1_A // SUB_SP_i_T1 - when (_, '0010', _, _, _, _, _) => // ext16 - __field U 23 +: 1 - __field B 22 +: 1 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - case (U, B) of - when ('0', '0') => __encoding aarch32_SXTH_T1_A // SXTH_T1 - when ('0', '1') => __encoding aarch32_SXTB_T1_A // SXTB_T1 - when ('1', '0') => __encoding aarch32_UXTH_T1_A // UXTH_T1 - when ('1', '1') => __encoding aarch32_UXTB_T1_A // UXTB_T1 - when (_, '0110', '00', '0', _, _, _) => // setpan16 - __field imm1 19 +: 1 - case () of - when () => __encoding aarch32_SETPAN_T1_A // SETPAN_T1 - when (_, '0110', '00', '1', _, _, _) => __UNPREDICTABLE - when (_, '0110', '01', _, _, _, _) => // cps16 - __field op 21 +: 1 - __field flags 16 +: 5 - case (op, flags) of - when ('0', _) => __encoding aarch32_SETEND_T1_A // SETEND_T1 - when ('1', _) => __encoding aarch32_CPS_T1_AS // CPSID_T1_AS - when (_, '0110', '1x', _, _, _, _) => __UNPREDICTABLE - when (_, '0111', _, _, _, _, _) => __UNPREDICTABLE - when (_, '1000', _, _, _, _, _) => __UNPREDICTABLE - when (_, '1010', '10', _, _, _, _) => // hlt16 - __field imm6 16 +: 6 - case () of - when () => __encoding aarch32_HLT_T1_A // HLT_T1 - when (_, '1010', !'10', _, _, _, _) => // rev16 - __field op 22 +: 2 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - case (op) of - when ('00') => __encoding aarch32_REV_T1_A // REV_T1 - when ('01') => __encoding aarch32_REV16_T1_A // REV16_T1 - when ('11') => __encoding aarch32_REVSH_T1_A // REVSH_T1 - when (_, '1110', _, _, _, _, _) => // bkpt16 - __field imm8 16 +: 8 - case () of - when () => __encoding aarch32_BKPT_T1_A // BKPT_T1 - when (_, '1111', _, _, _, '0000', _) => // hints16 - __field hint 20 +: 4 - case (hint) of - when ('0000') => __encoding aarch32_NOP_T1_A // NOP_T1 - when ('0001') => __encoding aarch32_YIELD_T1_A // YIELD_T1 - when ('0010') => __encoding aarch32_WFE_T1_A // WFE_T1 - when ('0011') => __encoding aarch32_WFI_T1_A // WFI_T1 - when ('0100') => __encoding aarch32_SEV_T1_A // SEV_T1 - when ('0101') => __encoding aarch32_SEVL_T1_A // SEVL_T1 - when ('011x') => __NOP - when ('1xxx') => __NOP - when (_, '1111', _, _, _, !'0000', _) => // it16 - __field firstcond 20 +: 4 - __field mask 16 +: 4 - case () of - when () => __encoding aarch32_IT_T1_A // IT_T1 - when (_, 'x0x1', _, _, _, _, _) => // cbznz16 - __field op 27 +: 1 - __field i 25 +: 1 - __field imm5 19 +: 5 - __field Rn 16 +: 3 - case () of - when () => __encoding aarch32_CBNZ_T1_A // CBNZ_T1 - when (_, 'x10x', _, _, _, _, _) => // pushpop16 - __field L 27 +: 1 - __field P 24 +: 1 - __field register_list 16 +: 8 - case (L) of - when ('0') => __encoding aarch32_PUSH_T1_A // PUSH_T1 - when ('1') => __encoding aarch32_POP_T1_A // POP_T1 - when ('1100xx', _) => // ldstm16 - __field L 27 +: 1 - __field Rn 24 +: 3 - __field register_list 16 +: 8 - case (L) of - when ('0') => __encoding aarch32_STM_T1_A // STM_T1 - when ('1') => __encoding aarch32_LDM_T1_A // LDM_T1 - when ('1101xx', _) => - // brc - case (28 +: 4, 24 +: 4, 0 +: 24) of - when (_, '111x', _) => // except16 - __field S 24 +: 1 - __field imm8 16 +: 8 - case (S) of - when ('0') => __encoding aarch32_UDF_T1_A // UDF_T1 - when ('1') => __encoding aarch32_SVC_T1_A // SVC_T1 - when (_, !'111x', _) => // bcond16 - __field cond 24 +: 4 - __field imm8 16 +: 8 - case () of - when () => __encoding aarch32_B_T1_A // B_T1 - when ('111', '00', _) => // b16 - __field imm11 16 +: 11 - case () of - when () => __encoding aarch32_B_T2_A // B_T2 - when ('111', !'00', _) => - // w - case (29 +: 3, 25 +: 4, 20 +: 5, 16 +: 4, 15 +: 1, 0 +: 15) of - when (_, 'x11x', _, _, _, _) => - // cpaf - case (29 +: 3, 28 +: 1, 26 +: 2, 24 +: 2, 12 +: 12, 9 +: 3, 5 +: 4, 4 +: 1, 0 +: 4) of - when (_, _, _, '0x', _, '111', _, _, _) => - // sysldst_mov64 - case (29 +: 3, 28 +: 1, 25 +: 3, 21 +: 4, 12 +: 9, 9 +: 3, 0 +: 9) of - when (_, _, _, '00x0', _, _, _) => // cp_mov64 - __field o0 28 +: 1 - __field D 22 +: 1 - __field L 20 +: 1 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field cp15 8 +: 1 - __field opc1 4 +: 4 - __field CRm 0 +: 4 - case (o0, D, L) of - when ('0', '0', _) => __UNALLOCATED - when ('0', '1', '0') => __encoding aarch32_MCRR_T1A1_A // MCRR_T1 - when ('0', '1', '1') => __encoding aarch32_MRRC_T1A1_A // MRRC_T1 - when ('1', '0', _) => __UNALLOCATED - when ('1', '1', _) => __UNALLOCATED - when (_, _, _, !'00x0', _, _, _) => // cp_ldst - __field o0 28 +: 1 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field CRd 12 +: 4 - __field cp15 8 +: 1 - __field imm8 0 +: 8 - case (o0, P:U:W, D, L, Rn, CRd, cp15) of - when (_, !'000', _, _, _, !'0101', '0') => __UNALLOCATED - when (_, !'000', _, _, _, _, '1') => __UNALLOCATED - when (_, !'000', '1', _, _, '0101', '0') => __UNALLOCATED - when ('0', !'000', '0', '1', '1111', '0101', '0') => __encoding aarch32_LDC_l_T1A1_A // LDC_l_T1 - when ('0', '0x1', '0', '0', _, '0101', '0') => __encoding aarch32_STC_T1A1_A // STC_T1_post - when ('0', '0x1', '0', '1', !'1111', '0101', '0') => __encoding aarch32_LDC_i_T1A1_A // LDC_i_T1_post - when ('0', '010', '0', '0', _, '0101', '0') => __encoding aarch32_STC_T1A1_A // STC_T1_unind - when ('0', '010', '0', '1', !'1111', '0101', '0') => __encoding aarch32_LDC_i_T1A1_A // LDC_i_T1_unind - when ('0', '1x0', '0', '0', _, '0101', '0') => __encoding aarch32_STC_T1A1_A // STC_T1_off - when ('0', '1x0', '0', '1', !'1111', '0101', '0') => __encoding aarch32_LDC_i_T1A1_A // LDC_i_T1_off - when ('0', '1x1', '0', '0', _, '0101', '0') => __encoding aarch32_STC_T1A1_A // STC_T1_pre - when ('0', '1x1', '0', '1', !'1111', '0101', '0') => __encoding aarch32_LDC_i_T1A1_A // LDC_i_T1_pre - when ('1', !'000', '0', _, _, '0101', '0') => __UNALLOCATED - when (_, _, _, '10', _, '10x', _, '0', _) => - // fpdp - case (29 +: 3, 28 +: 1, 24 +: 4, 20 +: 4, 16 +: 4, 12 +: 4, 10 +: 2, 8 +: 2, 7 +: 1, 6 +: 1, 5 +: 1, 4 +: 1, 0 +: 4) of - when (_, '0', _, '1x11', _, _, _, _, _, '1', _, _, _) => // fp_2r - __field D 22 +: 1 - __field o1 19 +: 1 - __field opc2 16 +: 3 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field o3 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (o1, opc2, size, o3) of - when (_, _, '00', _) => __UNALLOCATED - when ('0', '000', '01', '0') => __UNALLOCATED - when ('0', '000', _, '1') => __encoding aarch32_VABS_T2_A // VABS_T2_D - when ('0', '000', '10', '0') => __encoding aarch32_VMOV_r_T2A2_A // VMOV_r_T2_S - when ('0', '000', '11', '0') => __encoding aarch32_VMOV_r_T2A2_A // VMOV_r_T2_D - when ('0', '001', _, '0') => __encoding aarch32_VNEG_T2_A // VNEG_T2_D - when ('0', '001', _, '1') => __encoding aarch32_VSQRT_T1_A // VSQRT_T1_D - when ('0', '010', _, '0') => __encoding aarch32_VCVTB_T1A1_A // VCVTB_T1_DH - when ('0', '010', '01', _) => __UNALLOCATED - when ('0', '010', _, '1') => __encoding aarch32_VCVTB_T1A1_A // VCVTT_T1_DH - when ('0', '011', '01', '0') => __encoding aarch32_VCVTB_bf16_T1A1_A // VCVTB_T1_bfs - when ('0', '011', '01', '1') => __encoding aarch32_VCVTT_T1A1_A // VCVTT_T1_bfs - when ('0', '011', '10', '0') => __encoding aarch32_VCVTB_T1A1_A // VCVTB_T1_HS - when ('0', '011', '10', '1') => __encoding aarch32_VCVTB_T1A1_A // VCVTT_T1_HS - when ('0', '011', '11', '0') => __encoding aarch32_VCVTB_T1A1_A // VCVTB_T1_HD - when ('0', '011', '11', '1') => __encoding aarch32_VCVTB_T1A1_A // VCVTT_T1_HD - when ('0', '100', _, '0') => __encoding aarch32_VCMP_A1_A - when ('0', '100', _, '1') => __encoding aarch32_VCMP_A1_A - when ('0', '101', _, '0') => __encoding aarch32_VCMP_A1_A - when ('0', '101', _, '1') => __encoding aarch32_VCMP_A1_A - when ('0', '110', _, '0') => __encoding aarch32_VRINTZ_vfp_T1_A // VRINTR_vfp_T1_D - when ('0', '110', _, '1') => __encoding aarch32_VRINTZ_vfp_T1_A // VRINTZ_vfp_T1_D - when ('0', '111', _, '0') => __encoding aarch32_VRINTX_vfp_T1_A // VRINTX_vfp_T1_D - when ('0', '111', '01', '1') => __UNALLOCATED - when ('0', '111', '10', '1') => __encoding aarch32_VCVT_ds_T1A1_A // VCVT_ds_T1 - when ('0', '111', '11', '1') => __encoding aarch32_VCVT_ds_T1A1_A // VCVT_sd_T1 - when ('1', '000', _, _) => __encoding aarch32_VCVT_iv_T1_A // VCVT_vi_T1_D - when ('1', '001', '01', _) => __UNALLOCATED - when ('1', '001', '10', _) => __UNALLOCATED - when ('1', '001', '11', '0') => __UNALLOCATED - when ('1', '001', '11', '1') => __encoding aarch32_VJCVT_T1_A // VJCVT_T1 - when ('1', '01x', _, _) => __encoding aarch32_VCVT_xv_T1_A // VCVT_toxv_T1_D - when ('1', '100', _, '0') => __encoding aarch32_VCVT_iv_T1_A // VCVTR_uiv_T1_D - when ('1', '100', _, '1') => __encoding aarch32_VCVT_iv_T1_A // VCVT_uiv_T1_D - when ('1', '101', _, '0') => __encoding aarch32_VCVT_iv_T1_A // VCVTR_siv_T1_D - when ('1', '101', _, '1') => __encoding aarch32_VCVT_iv_T1_A // VCVT_siv_T1_D - when ('1', '11x', _, _) => __encoding aarch32_VCVT_xv_T1_A // VCVT_xv_T1_D - when (_, '0', _, '1x11', _, _, _, _, _, '0', _, _, _) => // fp_movi - __field D 22 +: 1 - __field imm4H 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm4L 0 +: 4 - case (size) of - when ('00') => __UNALLOCATED - when ('01') => __encoding aarch32_VMOV_i_T2_A // VMOV_i_T2_H - when ('10') => __encoding aarch32_VMOV_i_T2_A // VMOV_i_T2_S - when ('11') => __encoding aarch32_VMOV_i_T2_A // VMOV_i_T2_D - when (_, '0', _, !'1x11', _, _, _, _, _, _, _, _, _) => // fp_3r - __field o0 23 +: 1 - __field D 22 +: 1 - __field o1 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field o2 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (o0:o1, size, o2) of - when (!'111', '00', _) => __UNALLOCATED - when ('000', _, '0') => __encoding aarch32_VMLA_f_T2_A // VMLA_f_T2_D - when ('000', _, '1') => __encoding aarch32_VMLA_f_T2_A // VMLS_f_T2_D - when ('001', _, '0') => __encoding aarch32_VNMLA_T1_A // VNMLS_T1_D - when ('001', _, '1') => __encoding aarch32_VNMLA_T1_A // VNMLA_T1_D - when ('010', _, '0') => __encoding aarch32_VMUL_f_T2_A // VMUL_f_T2_D - when ('010', _, '1') => __encoding aarch32_VNMLA_T2_A // VNMUL_T1_D - when ('011', _, '0') => __encoding aarch32_VADD_f_T2_A // VADD_f_T2_D - when ('011', _, '1') => __encoding aarch32_VSUB_f_T2_A // VSUB_f_T2_D - when ('100', _, '0') => __encoding aarch32_VDIV_T1_A // VDIV_T1_D - when ('101', _, '0') => __encoding aarch32_VFNMA_T1_A // VFNMS_T1_D - when ('101', _, '1') => __encoding aarch32_VFNMA_T1_A // VFNMA_T1_D - when ('110', _, '0') => __encoding aarch32_VFMA_T2_A // VFMA_T2_D - when ('110', _, '1') => __encoding aarch32_VFMA_T2_A // VFMS_T2_D - when (_, '1', _, '0xxx', _, _, _, !'00', _, '0', _, _, _) => // fp_csel - __field D 22 +: 1 - __field cc 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (cc, size) of - when ('00', _) => __encoding aarch32_VSEL_T1_A // VSELEQ_T1_D - when ('01', _) => __encoding aarch32_VSEL_T1_A // VSELVS_T1_D - when (_, '01') => __UNALLOCATED - when ('10', _) => __encoding aarch32_VSEL_T1_A // VSELGE_T1_D - when ('11', _) => __encoding aarch32_VSEL_T1_A // VSELGT_T1_D - when (_, '1', _, '1x00', _, _, _, !'00', _, _, _, _, _) => // fp_minmax - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (size, op) of - when (_, '0') => __encoding aarch32_VMAXNM_T2_A // VMAXNM_T2_D - when ('01', _) => __UNALLOCATED - when (_, '1') => __encoding aarch32_VMAXNM_T2_A // VMINNM_T2_D - when (_, '1', _, '1x11', '0000', _, _, !'00', _, '1', _, _, _) => // fp_extins - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (size, op) of - when ('01', _) => __UNALLOCATED - when ('10', '0') => __encoding aarch32_VMOVX_T1_A // VMOVX_T1 - when ('10', '1') => __encoding aarch32_VINS_T1_A // VINS_T1 - when ('11', _) => __UNALLOCATED - when (_, '1', _, '1x11', '1xxx', _, _, !'00', _, '1', _, _, _) => // fp_toint - __field D 22 +: 1 - __field o1 18 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (o1, RM, size) of - when ('0', '00', _) => __encoding aarch32_VRINTA_vfp_T1_A // VRINTA_vfp_T1_D - when ('0', '01', _) => __encoding aarch32_VRINTA_vfp_T1_A // VRINTN_vfp_T1_D - when (_, _, '01') => __UNALLOCATED - when ('0', '10', _) => __encoding aarch32_VRINTA_vfp_T1_A // VRINTP_vfp_T1_D - when ('0', '11', _) => __encoding aarch32_VRINTA_vfp_T1_A // VRINTM_vfp_T1_D - when ('1', '00', _) => __encoding aarch32_VCVTA_vfp_T1_A // VCVTA_vfp_T1_D - when ('1', '01', _) => __encoding aarch32_VCVTA_vfp_T1_A // VCVTN_vfp_T1_D - when ('1', '10', _) => __encoding aarch32_VCVTA_vfp_T1_A // VCVTP_vfp_T1_D - when ('1', '11', _) => __encoding aarch32_VCVTA_vfp_T1_A // VCVTM_vfp_T1_D - when (_, _, _, '10', _, '111', _, '1', _) => // cp_mov32 - __field o0 28 +: 1 - __field opc1 21 +: 3 - __field L 20 +: 1 - __field CRn 16 +: 4 - __field Rt 12 +: 4 - __field cp15 8 +: 1 - __field opc2 5 +: 3 - __field CRm 0 +: 4 - case (o0, L) of - when ('0', '0') => __encoding aarch32_MCR_T1A1_A // MCR_T1 - when ('0', '1') => __encoding aarch32_MRC_T1A1_A // MRC_T1 - when ('1', _) => __UNALLOCATED - when (_, _, _, '11', _, _, _, _, _) => - // simddp - case (29 +: 3, 28 +: 1, 24 +: 4, 23 +: 1, 5 +: 18, 4 +: 1, 0 +: 4) of - when (_, _, _, '0', _, _, _) => // simd_3same - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field opc 8 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field o1 4 +: 1 - __field Vm 0 +: 4 - case (U, size, opc, Q, o1) of - when ('0', '0x', '1100', _, '1') => __encoding aarch32_VFMA_T1_A // VFMA_T1_Q - when ('0', '0x', '1101', _, '0') => __encoding aarch32_VADD_f_T1_A // VADD_f_T1_Q - when ('0', '0x', '1101', _, '1') => __encoding aarch32_VMLA_f_T1_A // VMLA_f_T1_Q - when ('0', '0x', '1110', _, '0') => __encoding aarch32_VCEQ_r_T1A1_A - when ('0', '0x', '1111', _, '0') => __encoding aarch32_VMAX_f_T1_A // VMAX_f_T1_Q - when ('0', '0x', '1111', _, '1') => __encoding aarch32_VRECPS_T1_A // VRECPS_T1_Q - when (_, _, '0000', _, '0') => __encoding aarch32_VHADD_T1A1_A // VHADD_T1_Q - when ('0', '00', '0001', _, '1') => __encoding aarch32_VAND_r_T1A1_A // VAND_r_T1_Q - when (_, _, '0000', _, '1') => __encoding aarch32_VQADD_T1A1_A // VQADD_T1_Q - when (_, _, '0001', _, '0') => __encoding aarch32_VRHADD_T1A1_A // VRHADD_T1_Q - when ('0', '00', '1100', _, '0') => __encoding aarch32_SHA1C_T1_A // SHA1C_T1 - when (_, _, '0010', _, '0') => __encoding aarch32_VHADD_T1A1_A // VHSUB_T1_Q - when ('0', '01', '0001', _, '1') => __encoding aarch32_VBIC_r_T1A1_A // VBIC_r_T1_Q - when (_, _, '0010', _, '1') => __encoding aarch32_VQSUB_T1A1_A // VQSUB_T1_Q - when (_, _, '0011', _, '0') => __encoding aarch32_VCGT_r_T1A1_A - when (_, _, '0011', _, '1') => __encoding aarch32_VCGE_r_T1A1_A - when ('0', '01', '1100', _, '0') => __encoding aarch32_SHA1P_T1_A // SHA1P_T1 - when ('0', '1x', '1100', _, '1') => __encoding aarch32_VFMA_T1_A // VFMS_T1_Q - when ('0', '1x', '1101', _, '0') => __encoding aarch32_VSUB_f_T1_A // VSUB_f_T1_Q - when ('0', '1x', '1101', _, '1') => __encoding aarch32_VMLA_f_T1_A // VMLS_f_T1_Q - when ('0', '1x', '1110', _, '0') => __UNALLOCATED - when ('0', '1x', '1111', _, '0') => __encoding aarch32_VMAX_f_T1_A // VMIN_f_T1_Q - when ('0', '1x', '1111', _, '1') => __encoding aarch32_VRSQRTS_T1_A // VRSQRTS_T1_Q - when (_, _, '0100', _, '0') => __encoding aarch32_VSHL_r_T1A1_A // VSHL_r_T1_Q - when ('0', _, '1000', _, '0') => __encoding aarch32_VADD_i_T1A1_A // VADD_i_T1_Q - when ('0', '10', '0001', _, '1') => __encoding aarch32_VORR_r_T1A1_A // VORR_r_T1_Q - when ('0', _, '1000', _, '1') => __encoding aarch32_VTST_T1A1_A // VTST_T1_Q - when (_, _, '0100', _, '1') => __encoding aarch32_VQSHL_r_T1A1_A // VQSHL_r_T1_Q - when ('0', _, '1001', _, '0') => __encoding aarch32_VMLA_i_T1A1_A // VMLA_i_T1_Q - when (_, _, '0101', _, '0') => __encoding aarch32_VRSHL_T1A1_A // VRSHL_T1_Q - when (_, _, '0101', _, '1') => __encoding aarch32_VQRSHL_T1A1_A // VQRSHL_T1_Q - when ('0', _, '1011', _, '0') => __encoding aarch32_VQDMULH_T1A1_A // VQDMULH_T1_Q - when ('0', '10', '1100', _, '0') => __encoding aarch32_SHA1M_T1_A // SHA1M_T1 - when ('0', _, '1011', _, '1') => __encoding aarch32_VPADD_i_T1A1_A // VPADD_i_T1 - when (_, _, '0110', _, '0') => __encoding aarch32_VMAX_i_T1A1_A // VMAX_i_T1_Q - when ('0', '11', '0001', _, '1') => __encoding aarch32_VORN_r_T1A1_A // VORN_r_T1_Q - when (_, _, '0110', _, '1') => __encoding aarch32_VMAX_i_T1A1_A // VMIN_i_T1_Q - when (_, _, '0111', _, '0') => __encoding aarch32_VABD_i_T1A1_A // VABD_i_T1_Q - when (_, _, '0111', _, '1') => __encoding aarch32_VABA_T1A1_A // VABA_T1_Q - when ('0', '11', '1100', _, '0') => __encoding aarch32_SHA1SU0_T1_A // SHA1SU0_T1 - when ('1', '0x', '1101', _, '0') => __encoding aarch32_VPADD_f_T1_A // VPADD_f_T1 - when ('1', '0x', '1101', _, '1') => __encoding aarch32_VMUL_f_T1_A // VMUL_f_T1_Q - when ('1', '0x', '1110', _, '0') => __encoding aarch32_VCGE_r_T1A1_A - when ('1', '0x', '1110', _, '1') => __encoding aarch32_VACGE_T1_A // VACGE_T1_Q - when ('1', '0x', '1111', '0', '0') => __encoding aarch32_VPMAX_f_T1_A // VPMAX_f_T1 - when ('1', '0x', '1111', _, '1') => __encoding aarch32_VMAXNM_T1_A // VMAXNM_T1_Q - when ('1', '00', '0001', _, '1') => __encoding aarch32_VEOR_T1A1_A // VEOR_T1_Q - when (_, _, '1001', _, '1') => __encoding aarch32_VMUL_i_T1A1_A // VMUL_i_T1_Q - when ('1', '00', '1100', _, '0') => __encoding aarch32_SHA256H_T1_A // SHA256H_T1 - when (_, _, '1010', '0', '0') => __encoding aarch32_VPMAX_i_T1A1_A // VPMAX_i_T1 - when ('1', '01', '0001', _, '1') => __encoding aarch32_VBIF_T1A1_A // VBSL_T1_Q - when (_, _, '1010', '0', '1') => __encoding aarch32_VPMAX_i_T1A1_A // VPMIN_i_T1 - when (_, _, '1010', '1', _) => __UNALLOCATED - when ('1', '01', '1100', _, '0') => __encoding aarch32_SHA256H2_T1_A // SHA256H2_T1 - when ('1', '1x', '1101', _, '0') => __encoding aarch32_VABD_f_T1_A // VABD_f_T1_Q - when ('1', '1x', '1110', _, '0') => __encoding aarch32_VCGT_r_T1A1_A - when ('1', '1x', '1110', _, '1') => __encoding aarch32_VACGE_T1_A // VACGT_T1_Q - when ('1', '1x', '1111', '0', '0') => __encoding aarch32_VPMAX_f_T1_A // VPMIN_f_T1 - when ('1', '1x', '1111', _, '1') => __encoding aarch32_VMAXNM_T1_A // VMINNM_T1_Q - when ('1', _, '1000', _, '0') => __encoding aarch32_VSUB_i_T1A1_A // VSUB_i_T1_Q - when ('1', '10', '0001', _, '1') => __encoding aarch32_VBIF_T1A1_A // VBIT_T1_Q - when ('1', _, '1000', _, '1') => __encoding aarch32_VCEQ_r_T1A1_A - when ('1', _, '1001', _, '0') => __encoding aarch32_VMLA_i_T1A1_A // VMLS_i_T1_Q - when ('1', _, '1011', _, '0') => __encoding aarch32_VQRDMULH_T1A1_A // VQRDMULH_T1_Q - when ('1', '10', '1100', _, '0') => __encoding aarch32_SHA256SU1_T1_A // SHA256SU1_T1 - when ('1', _, '1011', _, '1') => __encoding aarch32_VQRDMLAH_T1_A // VQRDMLAH_T1_Q - when ('1', '11', '0001', _, '1') => __encoding aarch32_VBIF_T1A1_A // VBIF_T1_Q - when ('1', _, '1100', _, '1') => __encoding aarch32_VQRDMLSH_T1_A // VQRDMLSH_T1_Q - when ('1', _, '1111', '1', '0') => __UNALLOCATED - when (_, _, _, '1', _, '0', _) => - // t_simd_mulreg - case (29 +: 3, 28 +: 1, 23 +: 5, 22 +: 1, 20 +: 2, 12 +: 8, 10 +: 2, 7 +: 3, 6 +: 1, 5 +: 1, 4 +: 1, 0 +: 4) of - when (_, '0', _, _, '11', _, _, _, _, _, _, _) => // simd_ext - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field imm4 8 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case () of - when () => __encoding aarch32_VEXT_T1A1_A // VEXT_T1_Q - when (_, '1', _, _, '11', _, '0x', _, _, _, _, _) => // simd_2r_misc - __field D 22 +: 1 - __field size 18 +: 2 - __field opc1 16 +: 2 - __field Vd 12 +: 4 - __field opc2 7 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (size, opc1, opc2, Q) of - when (_, '00', '0000', _) => __encoding aarch32_VREV16_T1A1_A // VREV64_T1_Q - when (_, '00', '0001', _) => __encoding aarch32_VREV16_T1A1_A // VREV32_T1_Q - when (_, '00', '0010', _) => __encoding aarch32_VREV16_T1A1_A // VREV16_T1_Q - when (_, '00', '0011', _) => __UNALLOCATED - when (_, '00', '010x', _) => __encoding aarch32_VPADDL_T1A1_A // VPADDL_T1_Q - when (_, '00', '0110', '0') => __encoding aarch32_AESE_T1_A // AESE_T1 - when (_, '00', '0110', '1') => __encoding aarch32_AESD_T1_A // AESD_T1 - when (_, '00', '0111', '0') => __encoding aarch32_AESMC_T1_A // AESMC_T1 - when (_, '00', '0111', '1') => __encoding aarch32_AESIMC_T1_A // AESIMC_T1 - when (_, '00', '1000', _) => __encoding aarch32_VCLS_T1A1_A // VCLS_T1_Q - when ('00', '10', '0000', _) => __encoding aarch32_VSWP_T1A1_A // VSWP_T1_Q - when (_, '00', '1001', _) => __encoding aarch32_VCLZ_T1A1_A // VCLZ_T1_Q - when (_, '00', '1010', _) => __encoding aarch32_VCNT_T1A1_A // VCNT_T1_Q - when (_, '00', '1011', _) => __encoding aarch32_VMVN_r_T1A1_A // VMVN_r_T1_Q - when ('00', '10', '1100', '1') => __UNALLOCATED - when (_, '00', '110x', _) => __encoding aarch32_VPADAL_T1A1_A // VPADAL_T1_Q - when (_, '00', '1110', _) => __encoding aarch32_VQABS_T1A1_A // VQABS_T1_Q - when (_, '00', '1111', _) => __encoding aarch32_VQNEG_T1A1_A // VQNEG_T1_Q - when (_, '01', 'x000', _) => __encoding aarch32_VCGT_i_T1_A // VCGT_i_T1_Q - when (_, '01', 'x001', _) => __encoding aarch32_VCGE_i_T1_A // VCGE_i_T1_Q - when (_, '01', 'x010', _) => __encoding aarch32_VCEQ_i_T1_A // VCEQ_i_T1_Q - when (_, '01', 'x011', _) => __encoding aarch32_VCLE_i_T1_A // VCLE_i_T1_Q - when (_, '01', 'x100', _) => __encoding aarch32_VCLT_i_T1_A // VCLT_i_T1_Q - when (_, '01', 'x110', _) => __encoding aarch32_VABS_T1_A // VABS_T1_Q - when (_, '01', 'x111', _) => __encoding aarch32_VNEG_T1_A // VNEG_T1_Q - when (_, '01', '0101', '1') => __encoding aarch32_SHA1H_T1_A // SHA1H_T1 - when ('01', '10', '1100', '1') => __encoding aarch32_VCVT_T1A1_A // VCVT_bfs_T1 - when (_, '10', '0001', _) => __encoding aarch32_VTRN_T1A1_A // VTRN_T1_Q - when (_, '10', '0010', _) => __encoding aarch32_VUZP_T1A1_A // VUZP_T1_Q - when (_, '10', '0011', _) => __encoding aarch32_VZIP_T1A1_A // VZIP_T1_Q - when (_, '10', '0100', '0') => __encoding aarch32_VMOVN_T1A1_A // VMOVN_T1 - when (_, '10', '0100', '1') => __encoding aarch32_VQMOVN_T1A1_A // VQMOVUN_T1 - when (_, '10', '0101', _) => __encoding aarch32_VQMOVN_T1A1_A // VQMOVN_T1 - when (_, '10', '0110', '0') => __encoding aarch32_VSHLL_T2A2_A // VSHLL_T2 - when (_, '10', '0111', '0') => __encoding aarch32_SHA1SU1_T1_A // SHA1SU1_T1 - when (_, '10', '0111', '1') => __encoding aarch32_SHA256SU0_T1_A // SHA256SU0_T1 - when (_, '10', '1000', _) => __encoding aarch32_VRINTA_asimd_T1_A // VRINTN_asimd_T1_Q - when (_, '10', '1001', _) => __encoding aarch32_VRINTX_asimd_T1_A // VRINTX_asimd_T1_Q - when (_, '10', '1010', _) => __encoding aarch32_VRINTA_asimd_T1_A // VRINTA_asimd_T1_Q - when (_, '10', '1011', _) => __encoding aarch32_VRINTZ_asimd_T1_A // VRINTZ_asimd_T1_Q - when ('10', '10', '1100', '1') => __UNALLOCATED - when (_, '10', '1100', '0') => __encoding aarch32_VCVT_hs_T1A1_A // VCVT_hs_T1 - when (_, '10', '1101', _) => __encoding aarch32_VRINTA_asimd_T1_A // VRINTM_asimd_T1_Q - when (_, '10', '1110', '0') => __encoding aarch32_VCVT_hs_T1A1_A // VCVT_sh_T1 - when (_, '10', '1110', '1') => __UNALLOCATED - when (_, '10', '1111', _) => __encoding aarch32_VRINTA_asimd_T1_A // VRINTP_asimd_T1_Q - when (_, '11', '000x', _) => __encoding aarch32_VCVTA_asimd_T1_A // VCVTA_asimd_T1_Q - when (_, '11', '001x', _) => __encoding aarch32_VCVTA_asimd_T1_A // VCVTN_asimd_T1_Q - when (_, '11', '010x', _) => __encoding aarch32_VCVTA_asimd_T1_A // VCVTP_asimd_T1_Q - when (_, '11', '011x', _) => __encoding aarch32_VCVTA_asimd_T1_A // VCVTM_asimd_T1_Q - when (_, '11', '10x0', _) => __encoding aarch32_VRECPE_T1_A // VRECPE_T1_Q - when (_, '11', '10x1', _) => __encoding aarch32_VRSQRTE_T1_A // VRSQRTE_T1_Q - when ('11', '10', '1100', '1') => __UNALLOCATED - when (_, '11', '11xx', _) => __encoding aarch32_VCVT_is_T1_A // VCVT_is_T1_Q - when (_, '1', _, _, '11', _, '10', _, _, _, _, _) => // simd_tbl - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field len 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case () of - when () => __encoding aarch32_VTBL_T1A1_A // VTBX_T1 - when (_, '1', _, _, '11', _, '11', _, _, _, _, _) => // simd_dup_sc - __field D 22 +: 1 - __field imm4 16 +: 4 - __field Vd 12 +: 4 - __field opc 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (opc) of - when ('000') => __encoding aarch32_VDUP_s_T1A1_A // VDUP_s_T1_Q - when ('001') => __UNALLOCATED - when ('01x') => __UNALLOCATED - when ('1xx') => __UNALLOCATED - when (_, _, _, _, !'11', _, _, _, '0', _, _, _) => // simd_3diff - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field opc 8 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (U, opc) of - when (_, '0000') => __encoding aarch32_VADDL_T1A1_A // VADDL_T1 - when (_, '0001') => __encoding aarch32_VADDL_T1A1_A // VADDW_T1 - when (_, '0010') => __encoding aarch32_VSUBL_T1A1_A // VSUBL_T1 - when ('0', '0100') => __encoding aarch32_VADDHN_T1A1_A // VADDHN_T1 - when (_, '0011') => __encoding aarch32_VSUBL_T1A1_A // VSUBW_T1 - when ('0', '0110') => __encoding aarch32_VSUBHN_T1A1_A // VSUBHN_T1 - when ('0', '1001') => __encoding aarch32_VQDMLAL_T1A1_A // VQDMLAL_T1 - when (_, '0101') => __encoding aarch32_VABA_T2A2_A // VABAL_T1 - when ('0', '1011') => __encoding aarch32_VQDMLSL_T1A1_A // VQDMLSL_T1 - when ('0', '1101') => __encoding aarch32_VQDMULL_T1A1_A // VQDMULL_T1 - when (_, '0111') => __encoding aarch32_VABD_i_T2A2_A // VABDL_i_T1 - when (_, '1000') => __encoding aarch32_VMLA_i_T2A2_A // VMLAL_i_T1 - when (_, '1010') => __encoding aarch32_VMLA_i_T2A2_A // VMLSL_i_T1 - when ('1', '0100') => __encoding aarch32_VRADDHN_T1A1_A // VRADDHN_T1 - when ('1', '0110') => __encoding aarch32_VRSUBHN_T1A1_A // VRSUBHN_T1 - when (_, '11x0') => __encoding aarch32_VMUL_i_T2_A // VMULL_i_T1 - when ('1', '1001') => __UNALLOCATED - when ('1', '1011') => __UNALLOCATED - when ('1', '1101') => __UNALLOCATED - when (_, '1111') => __UNALLOCATED - when (_, _, _, _, !'11', _, _, _, '1', _, _, _) => // simd_2r_sc - __field Q 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field opc 8 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (Q, opc) of - when (_, '000x') => __encoding aarch32_VMLA_s_T1_A // VMLA_s_T1_Q - when ('0', '0011') => __encoding aarch32_VQDMLAL_T2A2_A // VQDMLAL_T2 - when (_, '0010') => __encoding aarch32_VMLA_s_T2A2_A // VMLAL_s_T1 - when ('0', '0111') => __encoding aarch32_VQDMLSL_T2A2_A // VQDMLSL_T2 - when (_, '010x') => __encoding aarch32_VMLA_s_T1_A // VMLS_s_T1_Q - when ('0', '1011') => __encoding aarch32_VQDMULL_T2A2_A // VQDMULL_T2 - when (_, '0110') => __encoding aarch32_VMLA_s_T2A2_A // VMLSL_s_T1 - when (_, '100x') => __encoding aarch32_VMUL_s_T1_A // VMUL_s_T1_Q - when ('1', '0011') => __UNALLOCATED - when (_, '1010') => __encoding aarch32_VMUL_s_T2A2_A // VMULL_s_T1 - when ('1', '0111') => __UNALLOCATED - when (_, '1100') => __encoding aarch32_VQDMULH_T2A2_A // VQDMULH_T2_Q - when (_, '1101') => __encoding aarch32_VQRDMULH_T2A2_A // VQRDMULH_T2_Q - when ('1', '1011') => __UNALLOCATED - when (_, '1110') => __encoding aarch32_VQRDMLAH_T2_A // VQRDMLAH_T2_Q - when (_, '1111') => __encoding aarch32_VQRDMLSH_T2_A // VQRDMLSH_T2_Q - when (_, _, _, '1', _, '1', _) => - // t_simd_12reg - case (29 +: 3, 28 +: 1, 23 +: 5, 22 +: 1, 7 +: 15, 5 +: 2, 4 +: 1, 0 +: 4) of - when (_, _, _, _, '000xxxxxxxxxxx0', _, _, _) => // simd_1r_imm - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - case (cmode, op) of - when ('0xx0', '0') => __encoding aarch32_VMOV_i_T1A1_A - when ('0xx0', '1') => __encoding aarch32_VMVN_i_T1A1_A - when ('0xx1', '0') => __encoding aarch32_VORR_i_T1A1_A - when ('0xx1', '1') => __encoding aarch32_VBIC_i_T1A1_A - when ('10x0', '0') => __encoding aarch32_VMOV_i_T1A1_A - when ('10x0', '1') => __encoding aarch32_VMVN_i_T1A1_A - when ('10x1', '0') => __encoding aarch32_VORR_i_T1A1_A - when ('10x1', '1') => __encoding aarch32_VBIC_i_T1A1_A - when ('11xx', '0') => __encoding aarch32_VMOV_i_T1A1_A - when ('110x', '1') => __encoding aarch32_VMVN_i_T1A1_A - when ('1110', '1') => __encoding aarch32_VMOV_i_T1A1_A - when ('1111', '1') => __UNALLOCATED - when (_, _, _, _, !'000xxxxxxxxxxx0', _, _, _) => // simd_2r_shift - __field U 28 +: 1 - __field D 22 +: 1 - __field imm3H 19 +: 3 - __field imm3L 16 +: 3 - __field Vd 12 +: 4 - __field opc 8 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (U, imm3H:L, imm3L, opc, Q) of - when (_, !'0000', _, '0000', _) => __encoding aarch32_VSHR_T1A1_A // VSHR_T1_Q - when (_, !'0000', _, '0001', _) => __encoding aarch32_VSRA_T1A1_A // VSRA_T1_Q - when (_, !'0000', '000', '1010', '0') => __encoding aarch32_VMOVL_T1A1_A // VMOVL_T1 - when (_, !'0000', _, '0010', _) => __encoding aarch32_VRSHR_T1A1_A // VRSHR_T1_Q - when (_, !'0000', _, '0011', _) => __encoding aarch32_VRSRA_T1A1_A // VRSRA_T1_Q - when (_, !'0000', _, '0111', _) => __encoding aarch32_VQSHL_i_T1A1_A // VQSHL_i_T1_Q - when (_, !'0000', _, '1001', '0') => __encoding aarch32_VQSHRN_T1A1_A // VQSHRN_T1 - when (_, !'0000', _, '1001', '1') => __encoding aarch32_VQRSHRN_T1A1_A // VQRSHRN_T1 - when (_, !'0000', _, '1010', '0') => __encoding aarch32_VSHLL_T1A1_A // VSHLL_T1 - when (_, !'0000', _, '11xx', _) => __encoding aarch32_VCVT_xs_T1_A // VCVT_xs_T1_Q - when ('0', !'0000', _, '0101', _) => __encoding aarch32_VSHL_i_T1A1_A // VSHL_i_T1_Q - when ('0', !'0000', _, '1000', '0') => __encoding aarch32_VSHRN_T1A1_A // VSHRN_T1 - when ('0', !'0000', _, '1000', '1') => __encoding aarch32_VRSHRN_T1A1_A // VRSHRN_T1 - when ('1', !'0000', _, '0100', _) => __encoding aarch32_VSRI_T1A1_A // VSRI_T1_Q - when ('1', !'0000', _, '0101', _) => __encoding aarch32_VSLI_T1A1_A // VSLI_T1_Q - when ('1', !'0000', _, '0110', _) => __encoding aarch32_VQSHL_i_T1A1_A // VQSHLU_i_T1_Q - when ('1', !'0000', _, '1000', '0') => __encoding aarch32_VQSHRN_T1A1_A // VQSHRUN_T1 - when ('1', !'0000', _, '1000', '1') => __encoding aarch32_VQRSHRN_T1A1_A // VQRSHRUN_T1 - when (_, '0', _, '0x', _, '10x', _, _, _) => - // simdldst_mov64 - case (25 +: 7, 21 +: 4, 12 +: 9, 10 +: 2, 0 +: 10) of - when (_, '00x0', _, _, _) => // simdfp_mov64 - __field D 22 +: 1 - __field op 20 +: 1 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field size 8 +: 2 - __field opc2 6 +: 2 - __field M 5 +: 1 - __field o3 4 +: 1 - __field Vm 0 +: 4 - case (D, op, size, opc2, o3) of - when ('0', _, _, _, _) => __UNALLOCATED - when ('1', _, _, _, '0') => __UNALLOCATED - when ('1', _, '0x', '00', '1') => __UNALLOCATED - when ('1', _, _, '01', _) => __UNALLOCATED - when ('1', '0', '10', '00', '1') => __encoding aarch32_VMOV_ss_T1A1_A // VMOV_toss_T1 - when ('1', '0', '11', '00', '1') => __encoding aarch32_VMOV_d_T1A1_A // VMOV_tod_T1 - when ('1', _, _, '1x', _) => __UNALLOCATED - when ('1', '1', '10', '00', '1') => __encoding aarch32_VMOV_ss_T1A1_A // VMOV_ss_T1 - when ('1', '1', '11', '00', '1') => __encoding aarch32_VMOV_d_T1A1_A // VMOV_d_T1 - when (_, !'00x0', _, _, _) => // simdfp_ldst - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm8 0 +: 8 - case (P, U, W, L, Rn, size, imm8) of - when ('0', '0', '1', _, _, _, _) => __UNALLOCATED - when ('0', '1', _, _, _, '0x', _) => __UNALLOCATED - when ('0', '1', _, '0', _, '10', _) => __encoding aarch32_VSTM_T2A2_A // VSTM_T2 - when ('0', '1', _, '0', _, '11', 'xxxxxxx0') => __encoding aarch32_VSTM_T1A1_A // VSTM_T1 - when ('0', '1', _, '0', _, '11', 'xxxxxxx1') => __encoding aarch32_VSTM_T1A1_A // FSTMIAX_T1 - when ('0', '1', _, '1', _, '10', _) => __encoding aarch32_VLDM_T2A2_A // VLDM_T2 - when ('0', '1', _, '1', _, '11', 'xxxxxxx0') => __encoding aarch32_VLDM_T1A1_A // VLDM_T1 - when ('0', '1', _, '1', _, '11', 'xxxxxxx1') => __encoding aarch32_VLDM_T1A1_A // FLDMIAX_T1 - when ('1', _, '0', '0', _, _, _) => __encoding aarch32_VSTR_T1_A // VSTR_T1_D - when ('1', _, '0', _, _, '00', _) => __UNALLOCATED - when ('1', _, '0', '1', !'1111', _, _) => __encoding aarch32_VLDR_T1_A // VLDR_T1_D - when ('1', '0', '1', _, _, '0x', _) => __UNALLOCATED - when ('1', '0', '1', '0', _, '10', _) => __encoding aarch32_VSTM_T2A2_A // VSTMDB_T2 - when ('1', '0', '1', '0', _, '11', 'xxxxxxx0') => __encoding aarch32_VSTM_T1A1_A // VSTMDB_T1 - when ('1', '0', '1', '0', _, '11', 'xxxxxxx1') => __encoding aarch32_VSTM_T1A1_A // FSTMDBX_T1 - when ('1', '0', '1', '1', _, '10', _) => __encoding aarch32_VLDM_T2A2_A // VLDMDB_T2 - when ('1', '0', '1', '1', _, '11', 'xxxxxxx0') => __encoding aarch32_VLDM_T1A1_A // VLDMDB_T1 - when ('1', '0', '1', '1', _, '11', 'xxxxxxx1') => __encoding aarch32_VLDM_T1A1_A // FLDMDBX_T1 - when ('1', _, '0', '1', '1111', _, _) => __encoding aarch32_VLDR_T1_A // VLDR_l_T1_D - when ('1', '1', '1', _, _, _, _) => __UNALLOCATED - when (_, '0', _, '10', _, '10x', _, '1', _) => - // fpsimd_mov32 - case (24 +: 8, 21 +: 3, 12 +: 9, 9 +: 3, 8 +: 1, 5 +: 3, 0 +: 5) of - when (_, '000', _, _, '0', _, _) => // fp_mov32 - __field op 20 +: 1 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - case () of - when () => __encoding aarch32_VMOV_s_T1_A // VMOV_s_T1 - when (_, '111', _, _, '0', _, _) => // fp_msr - __field L 20 +: 1 - __field reg 16 +: 4 - __field Rt 12 +: 4 - case (L) of - when ('0') => __encoding aarch32_VMSR_T1A1_AS // VMSR_T1_AS - when ('1') => __encoding aarch32_VMRS_T1A1_AS // VMRS_T1_AS - when (_, _, _, _, '1', _, _) => // simd_dup_el - __field opc1 21 +: 3 - __field L 20 +: 1 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - __field opc2 5 +: 2 - case (opc1, L, opc2) of - when ('0xx', '0', _) => __encoding aarch32_VMOV_rs_T1A1_A // VMOV_rs_T1 - when (_, '1', _) => __encoding aarch32_VMOV_sr_T1A1_A // VMOV_sr_T1 - when ('1xx', '0', '0x') => __encoding aarch32_VDUP_r_T1A1_A // VDUP_r_T1 - when ('1xx', '0', '1x') => __UNALLOCATED - when (_, '1', _, '0x', _, '1x0', _, _, _) => // simd_3sameext - __field op1 23 +: 2 - __field D 22 +: 1 - __field op2 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op3 10 +: 1 - __field op4 8 +: 1 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - case (op1, op2, op3, op4, Q, U) of - when ('x1', '0x', '0', '0', '0', '0') => __encoding aarch32_VCADD_T1_A // VCADD_T1_D - when ('x1', '0x', '0', '0', '0', '1') => __UNALLOCATED - when ('x1', '0x', '0', '0', '1', '0') => __encoding aarch32_VCADD_T1_A // VCADD_T1_Q - when ('x1', '0x', '0', '0', '1', '1') => __UNALLOCATED - when ('00', '0x', '0', '0', _, _) => __UNALLOCATED - when ('00', '0x', '0', '1', _, _) => __UNALLOCATED - when ('00', '00', '1', '0', '0', '0') => __UNALLOCATED - when ('00', '00', '1', '0', '0', '1') => __UNALLOCATED - when ('00', '00', '1', '0', '1', '0') => __encoding aarch32_VMMLA_T1_A // VMMLA_T1_Q - when ('00', '00', '1', '0', '1', '1') => __UNALLOCATED - when ('00', '00', '1', '1', '0', '0') => __encoding aarch32_VDOT_bf16_T1_A // VDOT_T1_D - when ('00', '00', '1', '1', '0', '1') => __UNALLOCATED - when ('00', '00', '1', '1', '1', '0') => __encoding aarch32_VDOT_bf16_T1_A // VDOT_T1_Q - when ('00', '00', '1', '1', '1', '1') => __UNALLOCATED - when ('00', '01', '1', '0', _, _) => __UNALLOCATED - when ('00', '01', '1', '1', _, _) => __UNALLOCATED - when ('00', '10', '0', '0', '0', '1') => __encoding aarch32_VFMAL_T1_A // VFMAL_T1_D - when ('00', '10', '0', '1', _, _) => __UNALLOCATED - when ('00', '10', '1', '0', '0', _) => __UNALLOCATED - when ('00', '10', '1', '0', '1', '0') => __encoding aarch32_MMLA_T1_A // VSMMLA_T1_Q - when ('00', '10', '1', '0', '1', '1') => __encoding aarch32_MMLA_T1_A // VUMMLA_T1_Q - when ('00', '10', '1', '1', '0', '0') => __encoding aarch32_VDOT_T1_A // VSDOT_T1_D - when ('00', '10', '1', '1', '0', '1') => __encoding aarch32_VDOT_T1_A // VUDOT_T1_D - when ('00', '10', '1', '1', '1', '0') => __encoding aarch32_VDOT_T1_A // VSDOT_T1_Q - when ('00', '10', '1', '1', '1', '1') => __encoding aarch32_VDOT_T1_A // VUDOT_T1_Q - when ('00', '11', '0', '0', _, '1') => __encoding aarch32_VFMA_bf_T1_A // VFMA_bf_T1_Q - when ('00', '11', '0', '0', '1', '1') => __encoding aarch32_VFMAL_T1_A // VFMAL_T1_Q - when ('00', '11', '0', '1', _, _) => __UNALLOCATED - when ('00', '11', '1', '0', _, _) => __UNALLOCATED - when ('00', '11', '1', '1', _, _) => __UNALLOCATED - when ('01', '10', '0', '0', _, '1') => __encoding aarch32_VFMAL_T1_A // VFMSL_T1_Q - when ('01', '10', '0', '1', _, _) => __UNALLOCATED - when ('01', '10', '1', '0', '0', _) => __UNALLOCATED - when ('01', '10', '1', '0', '1', '0') => __encoding aarch32_MMLA_T1_A // VUSMMLA_T1_Q - when ('01', '10', '1', '0', '1', '1') => __UNALLOCATED - when ('01', '10', '1', '1', '0', '0') => __encoding aarch32_VUSDOT_T1_A // VUSDOT_T1_D - when ('01', '10', '1', '1', _, '1') => __UNALLOCATED - when ('01', '10', '1', '1', '1', '0') => __encoding aarch32_VUSDOT_T1_A // VUSDOT_T1_Q - when ('01', '11', _, _, _, _) => __UNALLOCATED - when (_, '1x', '0', '0', _, '0') => __encoding aarch32_VCMLA_T1_A // VCMLA_T1_Q - when ('10', '11', _, _, _, _) => __UNALLOCATED - when ('11', '11', _, _, _, _) => __UNALLOCATED - when (_, '1', _, '10', _, '1x0', _, _, _) => // simd_2r_scext - __field op1 23 +: 1 - __field D 22 +: 1 - __field op2 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op3 10 +: 1 - __field op4 8 +: 1 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - case (op1, op2, op3, op4, Q, U) of - when ('0', _, '0', '0', _, '0') => __encoding aarch32_VCMLA_idx_T1_A // VCMLA_s_T1_QH - when ('0', '00', '0', '0', _, '1') => __encoding aarch32_VFMAL_i_T1_A // VFMAL_s_T1_Q - when ('0', '00', '0', '1', _, _) => __UNALLOCATED - when ('0', '00', '1', '0', _, _) => __UNALLOCATED - when ('0', '00', '1', '1', '0', '0') => __encoding aarch32_VDOT_bf16_i_T1_A // VDOT_s_T1_D - when ('0', '00', '1', '1', _, '1') => __UNALLOCATED - when ('0', '00', '1', '1', '1', '0') => __encoding aarch32_VDOT_bf16_i_T1_A // VDOT_s_T1_Q - when ('0', '01', '0', '0', _, '0') => __UNALLOCATED - when ('0', '01', '0', '0', '0', '1') => __encoding aarch32_VFMAL_i_T1_A // VFMSL_s_T1_D - when ('0', '01', '0', '0', '1', '1') => __encoding aarch32_VFMAL_i_T1_A // VFMSL_s_T1_Q - when ('0', '01', '0', '1', _, _) => __UNALLOCATED - when ('0', '01', '1', '0', _, _) => __UNALLOCATED - when ('0', '10', '0', _, _, _) => __UNALLOCATED - when ('0', '10', '1', '0', _, _) => __UNALLOCATED - when ('0', '10', '1', '1', '0', '0') => __encoding aarch32_VDOT_s_T1_A // VSDOT_s_T1_D - when ('0', '10', '1', '1', '0', '1') => __encoding aarch32_VDOT_s_T1_A // VUDOT_s_T1_D - when ('0', '10', '1', '1', '1', '0') => __encoding aarch32_VDOT_s_T1_A // VSDOT_s_T1_Q - when ('0', '10', '1', '1', '1', '1') => __encoding aarch32_VDOT_s_T1_A // VUDOT_s_T1_Q - when ('0', '11', '0', '0', _, '0') => __UNALLOCATED - when ('0', '11', '0', '0', _, '1') => __encoding aarch32_VFMA_bfs_T1_A // VFMA_bfs_T1_Q - when ('0', '11', '0', '1', _, _) => __UNALLOCATED - when ('0', '11', '1', _, _, _) => __UNALLOCATED - when ('1', _, '0', '0', _, '0') => __encoding aarch32_VCMLA_idx_T1_A // VCMLA_s_T1_QS - when ('1', '00', '1', '1', '0', '0') => __encoding aarch32_DOT_T1_A // VUSDOT_s_T1_D - when ('1', '00', '1', '1', '0', '1') => __encoding aarch32_DOT_T1_A // VSUDOT_s_T1_D - when ('1', '00', '1', '1', '1', '0') => __encoding aarch32_DOT_T1_A // VUSDOT_s_T1_Q - when ('1', '00', '1', '1', '1', '1') => __encoding aarch32_DOT_T1_A // VSUDOT_s_T1_Q - when ('1', _, '0', '1', _, _) => __UNALLOCATED - when ('1', '01', '1', '1', _, _) => __UNALLOCATED - when ('1', '1x', '1', '1', _, _) => __UNALLOCATED - when ('1', _, '1', '0', _, _) => __UNALLOCATED - when (_, '0100', 'xx0xx', _, _, _) => // ldstm - __field opc 23 +: 2 - __field W 21 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field P 15 +: 1 - __field M 14 +: 1 - __field register_list 0 +: 14 - case (opc, L) of - when ('00', '0') => __encoding aarch32_SRS_A1_AS - when ('00', '1') => __encoding aarch32_RFE_A1_AS - when ('01', '0') => __encoding aarch32_STM_T2_A // STM_T2 - when ('01', '1') => __encoding aarch32_LDM_T2_A // LDM_T2 - when ('10', '0') => __encoding aarch32_STMDB_T1_A // STMDB_T1 - when ('10', '1') => __encoding aarch32_LDMDB_T1_A // LDMDB_T1 - when ('11', '0') => __encoding aarch32_SRS_A1_AS - when ('11', '1') => __encoding aarch32_RFE_A1_AS - when (_, '0100', 'xx1xx', _, _, _) => - // dstd - case (25 +: 7, 21 +: 4, 20 +: 1, 16 +: 4, 8 +: 8, 5 +: 3, 0 +: 5) of - when (_, '0010', _, _, _, _, _) => // ldstex - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - case (L) of - when ('0') => __encoding aarch32_STREX_T1_A // STREX_T1 - when ('1') => __encoding aarch32_LDREX_T1_A // LDREX_T1 - when (_, '0110', '0', _, _, '000', _) => __UNPREDICTABLE - when (_, '0110', '1', _, _, '000', _) => // tblbr - __field Rn 16 +: 4 - __field H 4 +: 1 - __field Rm 0 +: 4 - case () of - when () => __encoding aarch32_TBB_T1_A // TBH_T1 - when (_, '0110', _, _, _, '01x', _) => // ldstex_bhd - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field sz 4 +: 2 - __field Rd 0 +: 4 - case (L, sz) of - when ('0', '00') => __encoding aarch32_STREXB_T1_A // STREXB_T1 - when ('0', '01') => __encoding aarch32_STREXH_T1_A // STREXH_T1 - when ('0', '10') => __UNALLOCATED - when ('0', '11') => __encoding aarch32_STREXD_T1_A // STREXD_T1 - when ('1', '00') => __encoding aarch32_LDREXB_T1_A // LDREXB_T1 - when ('1', '01') => __encoding aarch32_LDREXH_T1_A // LDREXH_T1 - when ('1', '10') => __UNALLOCATED - when ('1', '11') => __encoding aarch32_LDREXD_T1_A // LDREXD_T1 - when (_, '0110', _, _, _, '1xx', _) => // ldastl - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field op 6 +: 1 - __field sz 4 +: 2 - __field Rd 0 +: 4 - case (L, op, sz) of - when ('0', '0', '00') => __encoding aarch32_STLB_T1_A // STLB_T1 - when ('0', '0', '01') => __encoding aarch32_STLH_T1_A // STLH_T1 - when ('0', '0', '10') => __encoding aarch32_STL_T1_A // STL_T1 - when ('0', '0', '11') => __UNALLOCATED - when ('0', '1', '00') => __encoding aarch32_STLEXB_T1_A // STLEXB_T1 - when ('0', '1', '01') => __encoding aarch32_STLEXH_T1_A // STLEXH_T1 - when ('0', '1', '10') => __encoding aarch32_STLEX_T1_A // STLEX_T1 - when ('0', '1', '11') => __encoding aarch32_STLEXD_T1_A // STLEXD_T1 - when ('1', '0', '00') => __encoding aarch32_LDAB_T1_A // LDAB_T1 - when ('1', '0', '01') => __encoding aarch32_LDAH_T1_A // LDAH_T1 - when ('1', '0', '10') => __encoding aarch32_LDA_T1_A // LDA_T1 - when ('1', '0', '11') => __UNALLOCATED - when ('1', '1', '00') => __encoding aarch32_LDAEXB_T1_A // LDAEXB_T1 - when ('1', '1', '01') => __encoding aarch32_LDAEXH_T1_A // LDAEXH_T1 - when ('1', '1', '10') => __encoding aarch32_LDAEX_T1_A // LDAEX_T1 - when ('1', '1', '11') => __encoding aarch32_LDAEXD_T1_A // LDAEXD_T1 - when (_, '0x11', _, !'1111', _, _, _) => // ldstd_post - __field U 23 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field imm8 0 +: 8 - case (L) of - when ('0') => __encoding aarch32_STRD_i_T1_A // STRD_i_T1_post - when ('1') => __encoding aarch32_LDRD_i_T1_A // LDRD_i_T1_post - when (_, '1x10', _, !'1111', _, _, _) => // ldstd_imm - __field U 23 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field imm8 0 +: 8 - case (L) of - when ('0') => __encoding aarch32_STRD_i_T1_A // STRD_i_T1_off - when ('1') => __encoding aarch32_LDRD_i_T1_A // LDRD_i_T1_off - when (_, '1x11', _, !'1111', _, _, _) => // ldstd_pre - __field U 23 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field imm8 0 +: 8 - case (L) of - when ('0') => __encoding aarch32_STRD_i_T1_A // STRD_i_T1_pre - when ('1') => __encoding aarch32_LDRD_i_T1_A // LDRD_i_T1_pre - when (_, !'0xx0', _, '1111', _, _, _) => // lddlit - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field L 20 +: 1 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field imm8 0 +: 8 - case (L) of - when ('1') => __encoding aarch32_LDRD_l_T1_A // LDRD_l_T1 - when (_, '0101', _, _, _, _) => // dpint_shiftr - __field op1 21 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - case (op1, S, Rn, imm3:imm2:stype, Rd) of - when ('0000', '0', _, _, _) => __encoding aarch32_AND_r_T2_A // AND_r_T2_RRX - when ('0000', '1', _, !'0000011', !'1111') => __encoding aarch32_AND_r_T2_A // ANDS_r_T2 - when ('0000', '1', _, !'0000011', '1111') => __encoding aarch32_TST_r_T2_A // TST_r_T2 - when ('0000', '1', _, '0000011', !'1111') => __encoding aarch32_AND_r_T2_A // ANDS_r_T2_RRX - when ('0000', '1', _, '0000011', '1111') => __encoding aarch32_TST_r_T2_A // TST_r_T2_RRX - when ('0001', _, _, _, _) => __encoding aarch32_BIC_r_T2_A // BICS_r_T2_RRX - when ('0010', '0', !'1111', _, _) => __encoding aarch32_ORR_r_T2_A // ORR_r_T2_RRX - when ('0010', '0', '1111', _, _) => __encoding aarch32_MOV_r_T3_A // MOV_r_T3_RRX - when ('0010', '1', !'1111', _, _) => __encoding aarch32_ORR_r_T2_A // ORRS_r_T2_RRX - when ('0010', '1', '1111', _, _) => __encoding aarch32_MOV_r_T3_A // MOVS_r_T3_RRX - when ('0011', '0', !'1111', _, _) => __encoding aarch32_ORN_r_T1_A // ORN_r_T1_RRX - when ('0011', '0', '1111', _, _) => __encoding aarch32_MVN_r_T2_A // MVN_r_T2_RRX - when ('0011', '1', !'1111', _, _) => __encoding aarch32_ORN_r_T1_A // ORNS_r_T1_RRX - when ('0011', '1', '1111', _, _) => __encoding aarch32_MVN_r_T2_A // MVNS_r_T2_RRX - when ('0100', '0', _, _, _) => __encoding aarch32_EOR_r_T2_A // EOR_r_T2_RRX - when ('0100', '1', _, !'0000011', !'1111') => __encoding aarch32_EOR_r_T2_A // EORS_r_T2 - when ('0100', '1', _, !'0000011', '1111') => __encoding aarch32_TEQ_r_T1_A // TEQ_r_T1 - when ('0100', '1', _, '0000011', !'1111') => __encoding aarch32_EOR_r_T2_A // EORS_r_T2_RRX - when ('0100', '1', _, '0000011', '1111') => __encoding aarch32_TEQ_r_T1_A // TEQ_r_T1_RRX - when ('0101', _, _, _, _) => __UNALLOCATED - when ('0110', '0', _, 'xxxxx00', _) => __encoding aarch32_PKH_T1_A // PKHBT_T1 - when ('0110', '0', _, 'xxxxx01', _) => __UNALLOCATED - when ('0110', '0', _, 'xxxxx10', _) => __encoding aarch32_PKH_T1_A // PKHTB_T1 - when ('0110', '0', _, 'xxxxx11', _) => __UNALLOCATED - when ('0111', _, _, _, _) => __UNALLOCATED - when ('1000', '0', !'1101', _, _) => __encoding aarch32_ADD_r_T3_A // ADD_r_T3_RRX - when ('1000', '0', '1101', _, _) => __encoding aarch32_ADD_SP_r_T3_A // ADD_SP_r_T3_RRX - when ('1000', '1', !'1101', _, !'1111') => __encoding aarch32_ADD_r_T3_A // ADDS_r_T3_RRX - when ('1000', '1', '1101', _, !'1111') => __encoding aarch32_ADD_SP_r_T3_A // ADDS_SP_r_T3_RRX - when ('1000', '1', _, _, '1111') => __encoding aarch32_CMN_r_T2_A // CMN_r_T2_RRX - when ('1001', _, _, _, _) => __UNALLOCATED - when ('1010', _, _, _, _) => __encoding aarch32_ADC_r_T2_A // ADCS_r_T2_RRX - when ('1011', _, _, _, _) => __encoding aarch32_SBC_r_T2_A // SBCS_r_T2_RRX - when ('1100', _, _, _, _) => __UNALLOCATED - when ('1101', '0', !'1101', _, _) => __encoding aarch32_SUB_r_T2_A // SUB_r_T2_RRX - when ('1101', '0', '1101', _, _) => __encoding aarch32_SUB_SP_r_T1_A // SUB_SP_r_T1_RRX - when ('1101', '1', !'1101', _, !'1111') => __encoding aarch32_SUB_r_T2_A // SUBS_r_T2_RRX - when ('1101', '1', '1101', _, !'1111') => __encoding aarch32_SUB_SP_r_T1_A // SUBS_SP_r_T1_RRX - when ('1101', '1', _, _, '1111') => __encoding aarch32_CMP_r_T3_A // CMP_r_T3_RRX - when ('1110', _, _, _, _) => __encoding aarch32_RSB_r_T1_A // RSBS_r_T1_RRX - when ('1111', _, _, _, _) => __UNALLOCATED - when (_, '10xx', _, _, '1', _) => - // bcrtrl - case (27 +: 5, 26 +: 1, 22 +: 4, 20 +: 2, 16 +: 4, 15 +: 1, 12 +: 3, 11 +: 1, 8 +: 3, 6 +: 2, 5 +: 1, 0 +: 5) of - when (_, '0', '1110', '0x', _, _, '0x0', _, _, _, '0', _) => // msr_spec - __field R 20 +: 1 - __field Rn 16 +: 4 - __field mask 8 +: 4 - case () of - when () => __encoding aarch32_MSR_r_T1_AS // MSR_r_T1_AS - when (_, '0', '1110', '0x', _, _, '0x0', _, _, _, '1', _) => // msr_bank - __field R 20 +: 1 - __field Rn 16 +: 4 - __field m1 8 +: 4 - __field m 4 +: 1 - case () of - when () => __encoding aarch32_MSR_br_T1_AS // MSR_br_T1_AS - when (_, '0', '1110', '10', _, _, '0x0', _, '000', _, _, _) => // hints - __field hint 4 +: 4 - __field option 0 +: 4 - case (hint, option) of - when ('0000', '0000') => __encoding aarch32_NOP_T2_A // NOP_T2 - when ('0000', '0001') => __encoding aarch32_YIELD_T2_A // YIELD_T2 - when ('0000', '0010') => __encoding aarch32_WFE_T2_A // WFE_T2 - when ('0000', '0011') => __encoding aarch32_WFI_T2_A // WFI_T2 - when ('0000', '0100') => __encoding aarch32_SEV_T2_A // SEV_T2 - when ('0000', '0101') => __encoding aarch32_SEVL_T2_A // SEVL_T2 - when ('0000', '011x') => __NOP - when ('0000', '1xxx') => __NOP - when ('0001', '0000') => __encoding aarch32_ESB_T1_A // ESB_T1 - when ('0001', '0001') => __NOP - when ('0001', '0010') => __encoding aarch32_TSB_T1_A // TSB_T1 - when ('0001', '0011') => __NOP - when ('0001', '0100') => __encoding aarch32_CSDB_T1_A // CSDB_T1 - when ('0001', '0101') => __NOP - when ('0001', '011x') => __NOP - when ('0001', '1xxx') => __NOP - when ('001x', _) => __NOP - when ('01xx', _) => __NOP - when ('10xx', _) => __NOP - when ('110x', _) => __NOP - when ('1110', _) => __NOP - when ('1111', _) => __encoding aarch32_DBG_T1_A // DBG_T1 - when (_, '0', '1110', '10', _, _, '0x0', _, !'000', _, _, _) => // cps - __field imod 9 +: 2 - __field M 8 +: 1 - __field A 7 +: 1 - __field I 6 +: 1 - __field F 5 +: 1 - __field mode 0 +: 5 - case (imod, M) of - when ('00', '1') => __encoding aarch32_CPS_T2_AS // CPS_T2_AS - when ('01', _) => __UNALLOCATED - when ('10', _) => __encoding aarch32_CPS_T2_AS // CPSIE_T2_ASM - when ('11', _) => __encoding aarch32_CPS_T2_AS // CPSID_T2_ASM - when (_, '0', '1110', '11', _, _, '0x0', _, _, _, _, _) => // system - __field opc 4 +: 4 - __field option 0 +: 4 - case (opc, option) of - when ('000x', _) => __UNALLOCATED - when ('0010', _) => __encoding aarch32_CLREX_T1_A // CLREX_T1 - when ('0011', _) => __UNALLOCATED - when ('0100', !'0x00') => __encoding aarch32_DSB_T1_A // DSB_T1 - when ('0100', '0000') => __encoding aarch32_SSBB_T1_A // SSBB_T1 - when ('0100', '0100') => __encoding aarch32_PSSBB_T1_A // PSSBB_T1 - when ('0101', _) => __encoding aarch32_DMB_T1_A // DMB_T1 - when ('0110', _) => __encoding aarch32_ISB_T1_A // ISB_T1 - when ('0111', _) => __encoding aarch32_SB_T1_A // SB_T1 - when ('1xxx', _) => __UNALLOCATED - when (_, '0', '1111', '00', _, _, '0x0', _, _, _, _, _) => // bx_jaz - __field Rm 16 +: 4 - case () of - when () => __encoding aarch32_BXJ_T1_A // BXJ_T1 - when (_, '0', '1111', '01', _, _, '0x0', _, _, _, _, _) => // eret - __field Rn 16 +: 4 - __field imm8 0 +: 8 - case (Rn, imm8) of - when (_, !'00000000') => __encoding aarch32_SUB_i_T5_AS // SUBS_PC_T5_AS - when ('1110', '00000000') => __encoding aarch32_ERET_T1_A // ERET_T1 - when (_, '0', '1111', '1x', _, _, '0x0', _, _, _, '0', _) => // mrs_spec - __field R 20 +: 1 - __field Rd 8 +: 4 - case () of - when () => __encoding aarch32_MRS_T1_AS // MRS_T1_AS - when (_, '0', '1111', '1x', _, _, '0x0', _, _, _, '1', _) => // mrs_bank - __field R 20 +: 1 - __field m1 16 +: 4 - __field Rd 8 +: 4 - __field m 4 +: 1 - case () of - when () => __encoding aarch32_MRS_br_T1_AS // MRS_br_T1_AS - when (_, '1', '1110', '00', _, _, '000', _, _, _, _, _) => // dcps - __field imm4 16 +: 4 - __field imm10 2 +: 10 - __field opt 0 +: 2 - case (imm4, imm10, opt) of - when (!'1111', _, _) => __UNALLOCATED - when ('1111', !'0000000000', _) => __UNALLOCATED - when ('1111', '0000000000', '00') => __UNALLOCATED - when ('1111', '0000000000', '01') => __encoding aarch32_DCPS1_T1_A // DCPS1_T1 - when ('1111', '0000000000', '10') => __encoding aarch32_DCPS2_T1_A // DCPS2_T1 - when ('1111', '0000000000', '11') => __encoding aarch32_DCPS3_T1_A // DCPS3_T1 - when (_, '1', '1110', '00', _, _, '010', _, _, _, _, _) => __UNPREDICTABLE - when (_, '1', '1110', '01', _, _, '0x0', _, _, _, _, _) => __UNPREDICTABLE - when (_, '1', '1110', '1x', _, _, '0x0', _, _, _, _, _) => __UNPREDICTABLE - when (_, '1', '1111', '0x', _, _, '0x0', _, _, _, _, _) => __UNPREDICTABLE - when (_, '1', '1111', '1x', _, _, '0x0', _, _, _, _, _) => // except - __field o1 20 +: 1 - __field imm4 16 +: 4 - __field o2 13 +: 1 - __field imm12 0 +: 12 - case (o1, o2) of - when ('0', '0') => __encoding aarch32_HVC_T1_A // HVC_T1 - when ('0', '1') => __UNALLOCATED - when ('1', '0') => __encoding aarch32_SMC_T1_AS // SMC_T1_AS - when ('1', '1') => __encoding aarch32_UDF_T2_A // UDF_T2 - when (_, _, !'111x', _, _, _, '0x0', _, _, _, _, _) => // bcond - __field S 26 +: 1 - __field cond 22 +: 4 - __field imm6 16 +: 6 - __field J1 13 +: 1 - __field J2 11 +: 1 - __field imm11 0 +: 11 - case () of - when () => __encoding aarch32_B_T3_A // B_T3 - when (_, _, _, _, _, _, '0x1', _, _, _, _, _) => // b - __field S 26 +: 1 - __field imm10 16 +: 10 - __field J1 13 +: 1 - __field J2 11 +: 1 - __field imm11 0 +: 11 - case () of - when () => __encoding aarch32_B_T4_A // B_T4 - when (_, _, _, _, _, _, '1x0', _, _, _, _, _) => // blx - __field S 26 +: 1 - __field imm10 16 +: 10 - __field J1 13 +: 1 - __field J2 11 +: 1 - __field imm11 0 +: 11 - case () of - when () => __encoding aarch32_BL_i_T2_A // BL_i_T2 - when (_, _, _, _, _, _, '1x1', _, _, _, _, _) => // bl - __field S 26 +: 1 - __field imm10 16 +: 10 - __field J1 13 +: 1 - __field J2 11 +: 1 - __field imm11 0 +: 11 - case () of - when () => __encoding aarch32_BL_i_T1_A // BL_i_T1 - when (_, '10x0', _, _, '0', _) => // dpint_immm - __field i 26 +: 1 - __field op1 21 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - case (op1, S, Rn, Rd) of - when ('0000', '0', _, _) => __encoding aarch32_AND_i_T1_A // AND_i_T1 - when ('0000', '1', _, !'1111') => __encoding aarch32_AND_i_T1_A // ANDS_i_T1 - when ('0000', '1', _, '1111') => __encoding aarch32_TST_i_T1_A // TST_i_T1 - when ('0001', _, _, _) => __encoding aarch32_BIC_i_T1_A // BICS_i_T1 - when ('0010', '0', !'1111', _) => __encoding aarch32_ORR_i_T1_A // ORR_i_T1 - when ('0010', '0', '1111', _) => __encoding aarch32_MOV_i_T2_A // MOV_i_T2 - when ('0010', '1', !'1111', _) => __encoding aarch32_ORR_i_T1_A // ORRS_i_T1 - when ('0010', '1', '1111', _) => __encoding aarch32_MOV_i_T2_A // MOVS_i_T2 - when ('0011', '0', !'1111', _) => __encoding aarch32_ORN_i_T1_A // ORN_i_T1 - when ('0011', '0', '1111', _) => __encoding aarch32_MVN_i_T1_A // MVN_i_T1 - when ('0011', '1', !'1111', _) => __encoding aarch32_ORN_i_T1_A // ORNS_i_T1 - when ('0011', '1', '1111', _) => __encoding aarch32_MVN_i_T1_A // MVNS_i_T1 - when ('0100', '0', _, _) => __encoding aarch32_EOR_i_T1_A // EOR_i_T1 - when ('0100', '1', _, !'1111') => __encoding aarch32_EOR_i_T1_A // EORS_i_T1 - when ('0100', '1', _, '1111') => __encoding aarch32_TEQ_i_T1_A // TEQ_i_T1 - when ('0101', _, _, _) => __UNALLOCATED - when ('011x', _, _, _) => __UNALLOCATED - when ('1000', '0', !'1101', _) => __encoding aarch32_ADD_i_T3_A // ADD_i_T3 - when ('1000', '0', '1101', _) => __encoding aarch32_ADD_SP_i_T3_A // ADD_SP_i_T3 - when ('1000', '1', !'1101', !'1111') => __encoding aarch32_ADD_i_T3_A // ADDS_i_T3 - when ('1000', '1', '1101', !'1111') => __encoding aarch32_ADD_SP_i_T3_A // ADDS_SP_i_T3 - when ('1000', '1', _, '1111') => __encoding aarch32_CMN_i_T1_A // CMN_i_T1 - when ('1001', _, _, _) => __UNALLOCATED - when ('1010', _, _, _) => __encoding aarch32_ADC_i_T1_A // ADCS_i_T1 - when ('1011', _, _, _) => __encoding aarch32_SBC_i_T1_A // SBCS_i_T1 - when ('1100', _, _, _) => __UNALLOCATED - when ('1101', '0', !'1101', _) => __encoding aarch32_SUB_i_T3_A // SUB_i_T3 - when ('1101', '0', '1101', _) => __encoding aarch32_SUB_SP_i_T2_A // SUB_SP_i_T2 - when ('1101', '1', !'1101', !'1111') => __encoding aarch32_SUB_i_T3_A // SUBS_i_T3 - when ('1101', '1', '1101', !'1111') => __encoding aarch32_SUB_SP_i_T2_A // SUBS_SP_i_T2 - when ('1101', '1', _, '1111') => __encoding aarch32_CMP_i_T2_A // CMP_i_T2 - when ('1110', _, _, _) => __encoding aarch32_RSB_i_T2_A // RSBS_i_T2 - when ('1111', _, _, _) => __UNALLOCATED - when (_, '10x1', _, _, '0', _) => - // imm - case (27 +: 5, 26 +: 1, 25 +: 1, 24 +: 1, 23 +: 1, 21 +: 2, 20 +: 1, 16 +: 4, 15 +: 1, 0 +: 15) of - when (_, _, _, '0', _, '0x', _, _, _, _) => // dpint_imms - __field i 26 +: 1 - __field o1 23 +: 1 - __field o2 21 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - case (o1, o2, Rn) of - when ('0', '0', !'11x1') => __encoding aarch32_ADD_i_T4_A // ADD_i_T4 - when ('0', '0', '1101') => __encoding aarch32_ADD_SP_i_T4_A // ADD_SP_i_T4 - when ('0', '0', '1111') => __encoding aarch32_ADR_A1_A - when ('0', '1', _) => __UNALLOCATED - when ('1', '0', _) => __UNALLOCATED - when ('1', '1', !'11x1') => __encoding aarch32_SUB_i_T4_A // SUB_i_T4 - when ('1', '1', '1101') => __encoding aarch32_SUB_SP_i_T3_A // SUB_SP_i_T3 - when ('1', '1', '1111') => __encoding aarch32_ADR_A1_A - when (_, _, _, '0', _, '10', _, _, _, _) => // movw - __field i 26 +: 1 - __field o1 23 +: 1 - __field imm4 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - case (o1) of - when ('0') => __encoding aarch32_MOV_i_T3_A // MOV_i_T3 - when ('1') => __encoding aarch32_MOVT_T1_A // MOVT_T1 - when (_, _, _, '0', _, '11', _, _, _, _) => __UNPREDICTABLE - when (_, _, _, '1', _, _, _, _, _, _) => // sat_bit - __field op1 21 +: 3 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field widthm1 0 +: 5 - case (op1, Rn, imm3:imm2) of - when ('000', _, _) => __encoding aarch32_SSAT_T1_A // SSAT_T1_LSL - when ('001', _, !'00000') => __encoding aarch32_SSAT_T1_A // SSAT_T1_ASR - when ('001', _, '00000') => __encoding aarch32_SSAT16_T1_A // SSAT16_T1 - when ('010', _, _) => __encoding aarch32_SBFX_T1_A // SBFX_T1 - when ('011', !'1111', _) => __encoding aarch32_BFI_T1_A // BFI_T1 - when ('011', '1111', _) => __encoding aarch32_BFC_T1_A // BFC_T1 - when ('100', _, _) => __encoding aarch32_USAT_T1_A // USAT_T1_LSL - when ('101', _, !'00000') => __encoding aarch32_USAT_T1_A // USAT_T1_ASR - when ('101', _, '00000') => __encoding aarch32_USAT16_T1_A // USAT16_T1 - when ('110', _, _) => __encoding aarch32_UBFX_T1_A // UBFX_T1 - when ('111', _, _) => __UNALLOCATED - when (_, '1100', '1xxx0', _, _, _) => - // vldst - case (24 +: 8, 23 +: 1, 21 +: 2, 20 +: 1, 12 +: 8, 10 +: 2, 0 +: 10) of - when (_, '0', _, _, _, _, _) => // asimldstms - __field D 22 +: 1 - __field L 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - case (L, itype) of - when ('0', '000x') => __encoding aarch32_VST4_m_T1A1_A // VST4_m_T1_posti - when ('0', '0010') => __encoding aarch32_VST1_m_T1A1_A - when ('0', '0011') => __encoding aarch32_VST2_m_T1A1_A - when ('0', '010x') => __encoding aarch32_VST3_m_T1A1_A // VST3_m_T1_posti - when ('0', '0110') => __encoding aarch32_VST1_m_T1A1_A - when ('0', '0111') => __encoding aarch32_VST1_m_T1A1_A - when ('0', '100x') => __encoding aarch32_VST2_m_T1A1_A - when ('0', '1010') => __encoding aarch32_VST1_m_T1A1_A - when ('1', '000x') => __encoding aarch32_VLD4_m_T1A1_A // VLD4_m_T1_posti - when ('1', '0010') => __encoding aarch32_VLD1_m_T1A1_A - when ('1', '0011') => __encoding aarch32_VLD2_m_T1A1_A - when ('1', '010x') => __encoding aarch32_VLD3_m_T1A1_A // VLD3_m_T1_posti - when (_, '1011') => __UNALLOCATED - when ('1', '0110') => __encoding aarch32_VLD1_m_T1A1_A - when ('1', '0111') => __encoding aarch32_VLD1_m_T1A1_A - when (_, '11xx') => __UNALLOCATED - when ('1', '100x') => __encoding aarch32_VLD2_m_T1A1_A - when ('1', '1010') => __encoding aarch32_VLD1_m_T1A1_A - when (_, '1', _, _, _, '11', _) => // asimldall - __field D 22 +: 1 - __field L 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field N 8 +: 2 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - case (L, N, a) of - when ('0', _, _) => __UNALLOCATED - when ('1', '00', _) => __encoding aarch32_VLD1_a_T1A1_A // VLD1_a_T1_posti - when ('1', '01', _) => __encoding aarch32_VLD2_a_T1A1_A // VLD2_a_T1_posti - when ('1', '10', '0') => __encoding aarch32_VLD3_a_T1A1_A // VLD3_a_T1_posti - when ('1', '10', '1') => __UNALLOCATED - when ('1', '11', _) => __encoding aarch32_VLD4_a_T1A1_A // VLD4_a_T1_posti - when (_, '1', _, _, _, !'11', _) => // asimldstss - __field D 22 +: 1 - __field L 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field N 8 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - case (L, size, N) of - when ('0', '00', '00') => __encoding aarch32_VST1_1_T1A1_A - when ('0', '00', '01') => __encoding aarch32_VST2_1_T1A1_A - when ('0', '00', '10') => __encoding aarch32_VST3_1_T1A1_A - when ('0', '00', '11') => __encoding aarch32_VST4_1_T1A1_A - when ('0', '01', '00') => __encoding aarch32_VST1_1_T1A1_A - when ('0', '01', '01') => __encoding aarch32_VST2_1_T1A1_A - when ('0', '01', '10') => __encoding aarch32_VST3_1_T1A1_A - when ('0', '01', '11') => __encoding aarch32_VST4_1_T1A1_A - when ('0', '10', '00') => __encoding aarch32_VST1_1_T1A1_A - when ('0', '10', '01') => __encoding aarch32_VST2_1_T1A1_A - when ('0', '10', '10') => __encoding aarch32_VST3_1_T1A1_A - when ('0', '10', '11') => __encoding aarch32_VST4_1_T1A1_A - when ('1', '00', '00') => __encoding aarch32_VLD1_1_T1A1_A - when ('1', '00', '01') => __encoding aarch32_VLD2_1_T1A1_A - when ('1', '00', '10') => __encoding aarch32_VLD3_1_T1A1_A - when ('1', '00', '11') => __encoding aarch32_VLD4_1_T1A1_A - when ('1', '01', '00') => __encoding aarch32_VLD1_1_T1A1_A - when ('1', '01', '01') => __encoding aarch32_VLD2_1_T1A1_A - when ('1', '01', '10') => __encoding aarch32_VLD3_1_T1A1_A - when ('1', '01', '11') => __encoding aarch32_VLD4_1_T1A1_A - when ('1', '10', '00') => __encoding aarch32_VLD1_1_T1A1_A - when ('1', '10', '01') => __encoding aarch32_VLD2_1_T1A1_A - when ('1', '10', '10') => __encoding aarch32_VLD3_1_T1A1_A - when ('1', '10', '11') => __encoding aarch32_VLD4_1_T1A1_A - when (_, '1100', !'1xxx0', _, _, _) => - // ldst - case (25 +: 7, 23 +: 2, 21 +: 2, 20 +: 1, 16 +: 4, 12 +: 4, 6 +: 6, 0 +: 6) of - when (_, '00', _, _, !'1111', _, '000000', _) => // ldst_unsigned_reg - __field size 21 +: 2 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - case (size, L, Rt) of - when ('00', '0', _) => __encoding aarch32_STRB_r_T2_A // STRB_r_T2 - when ('00', '1', !'1111') => __encoding aarch32_LDRB_r_T2_A // LDRB_r_T2 - when ('00', '1', '1111') => __encoding aarch32_PLD_r_T1_A // PLD_r_T1 - when ('01', '0', _) => __encoding aarch32_STRH_r_T2_A // STRH_r_T2 - when ('01', '1', !'1111') => __encoding aarch32_LDRH_r_T2_A // LDRH_r_T2 - when ('01', '1', '1111') => __encoding aarch32_PLD_r_T1_A // PLDW_r_T1 - when ('10', '0', _) => __encoding aarch32_STR_r_T2_A // STR_r_T2 - when ('10', '1', _) => __encoding aarch32_LDR_r_T2_A // LDR_r_T2 - when ('11', _, _) => __UNALLOCATED - when (_, '00', _, _, !'1111', _, '000001', _) => __UNPREDICTABLE - when (_, '00', _, _, !'1111', _, '00001x', _) => __UNPREDICTABLE - when (_, '00', _, _, !'1111', _, '0001xx', _) => __UNPREDICTABLE - when (_, '00', _, _, !'1111', _, '001xxx', _) => __UNPREDICTABLE - when (_, '00', _, _, !'1111', _, '01xxxx', _) => __UNPREDICTABLE - when (_, '00', _, _, !'1111', _, '10x0xx', _) => __UNPREDICTABLE - when (_, '00', _, _, !'1111', _, '10x1xx', _) => // ldst_unsigned_post - __field size 21 +: 2 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field U 9 +: 1 - __field imm8 0 +: 8 - case (size, L) of - when ('00', '0') => __encoding aarch32_STRB_i_T3_A // STRB_i_T3_post - when ('00', '1') => __encoding aarch32_LDRB_i_T3_A // LDRB_i_T3_post - when ('01', '0') => __encoding aarch32_STRH_i_T3_A // STRH_i_T3_post - when ('01', '1') => __encoding aarch32_LDRH_i_T3_A // LDRH_i_T3_post - when ('10', '0') => __encoding aarch32_STR_i_T4_A // STR_i_T4_post - when ('10', '1') => __encoding aarch32_LDR_i_T4_A // LDR_i_T4_post - when ('11', _) => __UNALLOCATED - when (_, '00', _, _, !'1111', _, '1100xx', _) => // ldst_unsigned_nimm - __field size 21 +: 2 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - case (size, L, Rt) of - when ('00', '0', _) => __encoding aarch32_STRB_i_T3_A // STRB_i_T3_offn - when ('00', '1', !'1111') => __encoding aarch32_LDRB_i_T3_A // LDRB_i_T3_off - when ('00', '1', '1111') => __encoding aarch32_PLD_i_T2_A // PLD_i_T2 - when ('01', '0', _) => __encoding aarch32_STRH_i_T3_A // STRH_i_T3_offn - when ('01', '1', !'1111') => __encoding aarch32_LDRH_i_T3_A // LDRH_i_T3_off - when ('01', '1', '1111') => __encoding aarch32_PLD_i_T2_A // PLDW_i_T2 - when ('10', '0', _) => __encoding aarch32_STR_i_T4_A // STR_i_T4_off - when ('10', '1', _) => __encoding aarch32_LDR_i_T4_A // LDR_i_T4_off - when ('11', _, _) => __UNALLOCATED - when (_, '00', _, _, !'1111', _, '1110xx', _) => // ldst_unsigned_unpriv - __field size 21 +: 2 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - case (size, L) of - when ('00', '0') => __encoding aarch32_STRBT_T1_A // STRBT_T1 - when ('00', '1') => __encoding aarch32_LDRBT_T1_A // LDRBT_T1 - when ('01', '0') => __encoding aarch32_STRHT_T1_A // STRHT_T1 - when ('01', '1') => __encoding aarch32_LDRHT_T1_A // LDRHT_T1 - when ('10', '0') => __encoding aarch32_STRT_T1_A // STRT_T1 - when ('10', '1') => __encoding aarch32_LDRT_T1_A // LDRT_T1 - when ('11', _) => __UNALLOCATED - when (_, '00', _, _, !'1111', _, '11x1xx', _) => // ldst_unsigned_pre - __field size 21 +: 2 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field U 9 +: 1 - __field imm8 0 +: 8 - case (size, L) of - when ('00', '0') => __encoding aarch32_STRB_i_T3_A // STRB_i_T3_pre - when ('00', '1') => __encoding aarch32_LDRB_i_T3_A // LDRB_i_T3_pre - when ('01', '0') => __encoding aarch32_STRH_i_T3_A // STRH_i_T3_pre - when ('01', '1') => __encoding aarch32_LDRH_i_T3_A // LDRH_i_T3_pre - when ('10', '0') => __encoding aarch32_STR_i_T4_A // STR_i_T4_pre - when ('10', '1') => __encoding aarch32_LDR_i_T4_A // LDR_i_T4_pre - when ('11', _) => __UNALLOCATED - when (_, '01', _, _, !'1111', _, _, _) => // ldst_unsigned_pimm - __field size 21 +: 2 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - case (size, L, Rt) of - when ('00', '0', _) => __encoding aarch32_STRB_i_T2_A // STRB_i_T2 - when ('00', '1', !'1111') => __encoding aarch32_LDRB_i_T2_A // LDRB_i_T2 - when ('00', '1', '1111') => __encoding aarch32_PLD_i_T1_A // PLD_i_T1 - when ('01', '0', _) => __encoding aarch32_STRH_i_T2_A // STRH_i_T2 - when ('01', '1', !'1111') => __encoding aarch32_LDRH_i_T2_A // LDRH_i_T2 - when ('01', '1', '1111') => __encoding aarch32_PLD_i_T1_A // PLDW_i_T1 - when ('10', '0', _) => __encoding aarch32_STR_i_T3_A // STR_i_T3 - when ('10', '1', _) => __encoding aarch32_LDR_i_T3_A // LDR_i_T3 - when (_, '0x', _, _, '1111', _, _, _) => // ldlit_unsigned - __field U 23 +: 1 - __field size 21 +: 2 - __field L 20 +: 1 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - case (size, L, Rt) of - when ('0x', '1', '1111') => __encoding aarch32_PLD_l_T1_A // PLD_l_T1 - when ('00', '1', !'1111') => __encoding aarch32_LDRB_l_T1_A // LDRB_l_T1 - when ('01', '1', !'1111') => __encoding aarch32_LDRH_l_T1_A // LDRH_l_T1 - when ('10', '1', _) => __encoding aarch32_LDR_l_T2_A // LDR_l_T2 - when ('11', _, _) => __UNALLOCATED - when (_, '10', _, '1', !'1111', _, '000000', _) => // ldst_signed_reg - __field size 21 +: 2 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - case (size, Rt) of - when ('00', !'1111') => __encoding aarch32_LDRSB_r_T2_A // LDRSB_r_T2 - when ('00', '1111') => __encoding aarch32_PLI_r_T1_A // PLI_r_T1 - when ('01', !'1111') => __encoding aarch32_LDRSH_r_T2_A // LDRSH_r_T2 - when ('01', '1111') => __NOP - when ('1x', _) => __UNALLOCATED - when (_, '10', _, '1', !'1111', _, '000001', _) => __UNPREDICTABLE - when (_, '10', _, '1', !'1111', _, '00001x', _) => __UNPREDICTABLE - when (_, '10', _, '1', !'1111', _, '0001xx', _) => __UNPREDICTABLE - when (_, '10', _, '1', !'1111', _, '001xxx', _) => __UNPREDICTABLE - when (_, '10', _, '1', !'1111', _, '01xxxx', _) => __UNPREDICTABLE - when (_, '10', _, '1', !'1111', _, '10x0xx', _) => __UNPREDICTABLE - when (_, '10', _, '1', !'1111', _, '10x1xx', _) => // ldst_signed_post - __field size 21 +: 2 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field U 9 +: 1 - __field imm8 0 +: 8 - case (size) of - when ('00') => __encoding aarch32_LDRSB_i_T2_A // LDRSB_i_T2_post - when ('01') => __encoding aarch32_LDRSH_i_T2_A // LDRSH_i_T2_post - when ('1x') => __UNALLOCATED - when (_, '10', _, '1', !'1111', _, '1100xx', _) => // ldst_signed_nimm - __field size 21 +: 2 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - case (size, Rt) of - when ('00', !'1111') => __encoding aarch32_LDRSB_i_T2_A // LDRSB_i_T2_off - when ('00', '1111') => __encoding aarch32_PLI_i_T2_A // PLI_i_T2 - when ('01', !'1111') => __encoding aarch32_LDRSH_i_T2_A // LDRSH_i_T2_off - when ('01', '1111') => __NOP - when ('1x', _) => __UNALLOCATED - when (_, '10', _, '1', !'1111', _, '1110xx', _) => // ldst_signed_unpriv - __field size 21 +: 2 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - case (size) of - when ('00') => __encoding aarch32_LDRSBT_T1_A // LDRSBT_T1 - when ('01') => __encoding aarch32_LDRSHT_T1_A // LDRSHT_T1 - when ('1x') => __UNALLOCATED - when (_, '10', _, '1', !'1111', _, '11x1xx', _) => // ldst_signed_pre - __field size 21 +: 2 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field U 9 +: 1 - __field imm8 0 +: 8 - case (size) of - when ('00') => __encoding aarch32_LDRSB_i_T2_A // LDRSB_i_T2_pre - when ('01') => __encoding aarch32_LDRSH_i_T2_A // LDRSH_i_T2_pre - when ('1x') => __UNALLOCATED - when (_, '11', _, '1', !'1111', _, _, _) => // ldst_signed_pimm - __field size 21 +: 2 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - case (size, Rt) of - when ('00', !'1111') => __encoding aarch32_LDRSB_i_T1_A // LDRSB_i_T1 - when ('00', '1111') => __encoding aarch32_PLI_i_T1_A // PLI_i_T1 - when ('01', !'1111') => __encoding aarch32_LDRSH_i_T1_A // LDRSH_i_T1 - when ('01', '1111') => __NOP - when (_, '1x', _, '1', '1111', _, _, _) => // ldlit_signed - __field U 23 +: 1 - __field size 21 +: 2 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - case (size, Rt) of - when ('00', !'1111') => __encoding aarch32_LDRSB_l_T1_A // LDRSB_l_T1 - when ('00', '1111') => __encoding aarch32_PLI_i_T3_A // PLI_i_T3 - when ('01', !'1111') => __encoding aarch32_LDRSH_l_T1_A // LDRSH_l_T1 - when ('01', '1111') => __NOP - when ('1x', _) => __UNALLOCATED - when (_, '1101', '0xxxx', _, _, _) => - // reg - case (24 +: 8, 23 +: 1, 16 +: 7, 12 +: 4, 8 +: 4, 4 +: 4, 0 +: 4) of - when (_, '0', _, _, _, '0000', _) => // shiftr - __field stype 21 +: 2 - __field S 20 +: 1 - __field Rm 16 +: 4 - __field Rd 8 +: 4 - __field Rs 0 +: 4 - case () of - when () => __encoding aarch32_MOV_rr_T2_A // MOVS_rr_T2 - when (_, '0', _, _, _, '0001', _) => __UNPREDICTABLE - when (_, '0', _, _, _, '001x', _) => __UNPREDICTABLE - when (_, '0', _, _, _, '01xx', _) => __UNPREDICTABLE - when (_, '0', _, _, _, '1xxx', _) => // extendr - __field op1 21 +: 2 - __field U 20 +: 1 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - case (op1, U, Rn) of - when ('00', '0', !'1111') => __encoding aarch32_SXTAH_T1_A // SXTAH_T1 - when ('00', '0', '1111') => __encoding aarch32_SXTH_T2_A // SXTH_T2 - when ('00', '1', !'1111') => __encoding aarch32_UXTAH_T1_A // UXTAH_T1 - when ('00', '1', '1111') => __encoding aarch32_UXTH_T2_A // UXTH_T2 - when ('01', '0', !'1111') => __encoding aarch32_SXTAB16_T1_A // SXTAB16_T1 - when ('01', '0', '1111') => __encoding aarch32_SXTB16_T1_A // SXTB16_T1 - when ('01', '1', !'1111') => __encoding aarch32_UXTAB16_T1_A // UXTAB16_T1 - when ('01', '1', '1111') => __encoding aarch32_UXTB16_T1_A // UXTB16_T1 - when ('10', '0', !'1111') => __encoding aarch32_SXTAB_T1_A // SXTAB_T1 - when ('10', '0', '1111') => __encoding aarch32_SXTB_T2_A // SXTB_T2 - when ('10', '1', !'1111') => __encoding aarch32_UXTAB_T1_A // UXTAB_T1 - when ('10', '1', '1111') => __encoding aarch32_UXTB_T2_A // UXTB_T2 - when ('11', _, _) => __UNALLOCATED - when (_, '1', _, _, _, '0xxx', _) => // addsub_par - __field op1 20 +: 3 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field U 6 +: 1 - __field H 5 +: 1 - __field S 4 +: 1 - __field Rm 0 +: 4 - case (op1, U, H, S) of - when ('000', '0', '0', '0') => __encoding aarch32_SADD8_T1_A // SADD8_T1 - when ('000', '0', '0', '1') => __encoding aarch32_QADD8_T1_A // QADD8_T1 - when ('000', '0', '1', '0') => __encoding aarch32_SHADD8_T1_A // SHADD8_T1 - when ('000', '0', '1', '1') => __UNALLOCATED - when ('000', '1', '0', '0') => __encoding aarch32_UADD8_T1_A // UADD8_T1 - when ('000', '1', '0', '1') => __encoding aarch32_UQADD8_T1_A // UQADD8_T1 - when ('000', '1', '1', '0') => __encoding aarch32_UHADD8_T1_A // UHADD8_T1 - when ('000', '1', '1', '1') => __UNALLOCATED - when ('001', '0', '0', '0') => __encoding aarch32_SADD16_T1_A // SADD16_T1 - when ('001', '0', '0', '1') => __encoding aarch32_QADD16_T1_A // QADD16_T1 - when ('001', '0', '1', '0') => __encoding aarch32_SHADD16_T1_A // SHADD16_T1 - when ('001', '0', '1', '1') => __UNALLOCATED - when ('001', '1', '0', '0') => __encoding aarch32_UADD16_T1_A // UADD16_T1 - when ('001', '1', '0', '1') => __encoding aarch32_UQADD16_T1_A // UQADD16_T1 - when ('001', '1', '1', '0') => __encoding aarch32_UHADD16_T1_A // UHADD16_T1 - when ('001', '1', '1', '1') => __UNALLOCATED - when ('010', '0', '0', '0') => __encoding aarch32_SASX_T1_A // SASX_T1 - when ('010', '0', '0', '1') => __encoding aarch32_QASX_T1_A // QASX_T1 - when ('010', '0', '1', '0') => __encoding aarch32_SHASX_T1_A // SHASX_T1 - when ('010', '0', '1', '1') => __UNALLOCATED - when ('010', '1', '0', '0') => __encoding aarch32_UASX_T1_A // UASX_T1 - when ('010', '1', '0', '1') => __encoding aarch32_UQASX_T1_A // UQASX_T1 - when ('010', '1', '1', '0') => __encoding aarch32_UHASX_T1_A // UHASX_T1 - when ('010', '1', '1', '1') => __UNALLOCATED - when ('100', '0', '0', '0') => __encoding aarch32_SSUB8_T1_A // SSUB8_T1 - when ('100', '0', '0', '1') => __encoding aarch32_QSUB8_T1_A // QSUB8_T1 - when ('100', '0', '1', '0') => __encoding aarch32_SHSUB8_T1_A // SHSUB8_T1 - when ('100', '0', '1', '1') => __UNALLOCATED - when ('100', '1', '0', '0') => __encoding aarch32_USUB8_T1_A // USUB8_T1 - when ('100', '1', '0', '1') => __encoding aarch32_UQSUB8_T1_A // UQSUB8_T1 - when ('100', '1', '1', '0') => __encoding aarch32_UHSUB8_T1_A // UHSUB8_T1 - when ('100', '1', '1', '1') => __UNALLOCATED - when ('101', '0', '0', '0') => __encoding aarch32_SSUB16_T1_A // SSUB16_T1 - when ('101', '0', '0', '1') => __encoding aarch32_QSUB16_T1_A // QSUB16_T1 - when ('101', '0', '1', '0') => __encoding aarch32_SHSUB16_T1_A // SHSUB16_T1 - when ('101', '0', '1', '1') => __UNALLOCATED - when ('101', '1', '0', '0') => __encoding aarch32_USUB16_T1_A // USUB16_T1 - when ('101', '1', '0', '1') => __encoding aarch32_UQSUB16_T1_A // UQSUB16_T1 - when ('101', '1', '1', '0') => __encoding aarch32_UHSUB16_T1_A // UHSUB16_T1 - when ('101', '1', '1', '1') => __UNALLOCATED - when ('110', '0', '0', '0') => __encoding aarch32_SSAX_T1_A // SSAX_T1 - when ('110', '0', '0', '1') => __encoding aarch32_QSAX_T1_A // QSAX_T1 - when ('110', '0', '1', '0') => __encoding aarch32_SHSAX_T1_A // SHSAX_T1 - when ('110', '0', '1', '1') => __UNALLOCATED - when ('110', '1', '0', '0') => __encoding aarch32_USAX_T1_A // USAX_T1 - when ('110', '1', '0', '1') => __encoding aarch32_UQSAX_T1_A // UQSAX_T1 - when ('110', '1', '1', '0') => __encoding aarch32_UHSAX_T1_A // UHSAX_T1 - when ('110', '1', '1', '1') => __UNALLOCATED - when ('111', _, _, _) => __UNALLOCATED - when (_, '1', _, _, _, '10xx', _) => // dpint_2r - __field op1 20 +: 3 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field op2 4 +: 2 - __field Rm 0 +: 4 - case (op1, op2) of - when ('000', '00') => __encoding aarch32_QADD_T1_A // QADD_T1 - when ('000', '01') => __encoding aarch32_QDADD_T1_A // QDADD_T1 - when ('000', '10') => __encoding aarch32_QSUB_T1_A // QSUB_T1 - when ('000', '11') => __encoding aarch32_QDSUB_T1_A // QDSUB_T1 - when ('001', '00') => __encoding aarch32_REV_T2_A // REV_T2 - when ('001', '01') => __encoding aarch32_REV16_T2_A // REV16_T2 - when ('001', '10') => __encoding aarch32_RBIT_T1_A // RBIT_T1 - when ('001', '11') => __encoding aarch32_REVSH_T2_A // REVSH_T2 - when ('010', '00') => __encoding aarch32_SEL_T1_A // SEL_T1 - when ('010', '01') => __UNALLOCATED - when ('010', '1x') => __UNALLOCATED - when ('011', '00') => __encoding aarch32_CLZ_T1_A // CLZ_T1 - when ('011', '01') => __UNALLOCATED - when ('011', '1x') => __UNALLOCATED - when ('100', '00') => __encoding aarch32_CRC32_T1_A // CRC32B_T1 - when ('100', '01') => __encoding aarch32_CRC32_T1_A // CRC32H_T1 - when ('100', '10') => __encoding aarch32_CRC32_T1_A // CRC32W_T1 - when ('100', '11') => __UNPREDICTABLE - when ('101', '00') => __encoding aarch32_CRC32_T1_A // CRC32CB_T1 - when ('101', '01') => __encoding aarch32_CRC32_T1_A // CRC32CH_T1 - when ('101', '10') => __encoding aarch32_CRC32_T1_A // CRC32CW_T1 - when ('101', '11') => __UNPREDICTABLE - when ('11x', _) => __UNALLOCATED - when (_, '1', _, _, _, '11xx', _) => __UNPREDICTABLE - when (_, '1101', '10xxx', _, _, _) => - // mul - case (23 +: 9, 8 +: 15, 6 +: 2, 0 +: 6) of - when (_, _, '00', _) => // mul_abd - __field op1 20 +: 3 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field op2 4 +: 2 - __field Rm 0 +: 4 - case (op1, Ra, op2) of - when ('000', !'1111', '00') => __encoding aarch32_MLA_T1_A // MLA_T1 - when ('000', _, '01') => __encoding aarch32_MLS_T1_A // MLS_T1 - when ('000', _, '1x') => __UNALLOCATED - when ('000', '1111', '00') => __encoding aarch32_MUL_T2_A // MUL_T2 - when ('001', !'1111', '00') => __encoding aarch32_SMLABB_T1_A // SMLABB_T1 - when ('001', !'1111', '01') => __encoding aarch32_SMLABB_T1_A // SMLABT_T1 - when ('001', !'1111', '10') => __encoding aarch32_SMLABB_T1_A // SMLATB_T1 - when ('001', !'1111', '11') => __encoding aarch32_SMLABB_T1_A // SMLATT_T1 - when ('001', '1111', '00') => __encoding aarch32_SMULBB_T1_A // SMULBB_T1 - when ('001', '1111', '01') => __encoding aarch32_SMULBB_T1_A // SMULBT_T1 - when ('001', '1111', '10') => __encoding aarch32_SMULBB_T1_A // SMULTB_T1 - when ('001', '1111', '11') => __encoding aarch32_SMULBB_T1_A // SMULTT_T1 - when ('010', !'1111', '00') => __encoding aarch32_SMLAD_T1_A // SMLAD_T1 - when ('010', !'1111', '01') => __encoding aarch32_SMLAD_T1_A // SMLADX_T1 - when ('010', _, '1x') => __UNALLOCATED - when ('010', '1111', '00') => __encoding aarch32_SMUAD_T1_A // SMUAD_T1 - when ('010', '1111', '01') => __encoding aarch32_SMUAD_T1_A // SMUADX_T1 - when ('011', !'1111', '00') => __encoding aarch32_SMLAWB_T1_A // SMLAWB_T1 - when ('011', !'1111', '01') => __encoding aarch32_SMLAWB_T1_A // SMLAWT_T1 - when ('011', _, '1x') => __UNALLOCATED - when ('011', '1111', '00') => __encoding aarch32_SMULWB_T1_A // SMULWB_T1 - when ('011', '1111', '01') => __encoding aarch32_SMULWB_T1_A // SMULWT_T1 - when ('100', !'1111', '00') => __encoding aarch32_SMLSD_T1_A // SMLSD_T1 - when ('100', !'1111', '01') => __encoding aarch32_SMLSD_T1_A // SMLSDX_T1 - when ('100', _, '1x') => __UNALLOCATED - when ('100', '1111', '00') => __encoding aarch32_SMUSD_T1_A // SMUSD_T1 - when ('100', '1111', '01') => __encoding aarch32_SMUSD_T1_A // SMUSDX_T1 - when ('101', !'1111', '00') => __encoding aarch32_SMMLA_T1_A // SMMLA_T1 - when ('101', !'1111', '01') => __encoding aarch32_SMMLA_T1_A // SMMLAR_T1 - when ('101', _, '1x') => __UNALLOCATED - when ('101', '1111', '00') => __encoding aarch32_SMMUL_T1_A // SMMUL_T1 - when ('101', '1111', '01') => __encoding aarch32_SMMUL_T1_A // SMMULR_T1 - when ('110', _, '00') => __encoding aarch32_SMMLS_T1_A // SMMLS_T1 - when ('110', _, '01') => __encoding aarch32_SMMLS_T1_A // SMMLSR_T1 - when ('110', _, '1x') => __UNALLOCATED - when ('111', !'1111', '00') => __encoding aarch32_USADA8_T1_A // USADA8_T1 - when ('111', _, '01') => __UNALLOCATED - when ('111', _, '1x') => __UNALLOCATED - when ('111', '1111', '00') => __encoding aarch32_USAD8_T1_A // USAD8_T1 - when (_, _, '01', _) => __UNPREDICTABLE - when (_, _, '1x', _) => __UNPREDICTABLE - when (_, '1101', '11xxx', _, _, _) => // lmul_div - __field op1 20 +: 3 - __field Rn 16 +: 4 - __field RdLo 12 +: 4 - __field RdHi 8 +: 4 - __field op2 4 +: 4 - __field Rm 0 +: 4 - case (op1, op2) of - when ('000', !'0000') => __UNALLOCATED - when ('000', '0000') => __encoding aarch32_SMULL_T1_A // SMULL_T1 - when ('001', !'1111') => __UNALLOCATED - when ('001', '1111') => __encoding aarch32_SDIV_T1_A // SDIV_T1 - when ('010', !'0000') => __UNALLOCATED - when ('010', '0000') => __encoding aarch32_UMULL_T1_A // UMULL_T1 - when ('011', !'1111') => __UNALLOCATED - when ('011', '1111') => __encoding aarch32_UDIV_T1_A // UDIV_T1 - when ('100', '0000') => __encoding aarch32_SMLAL_T1_A // SMLAL_T1 - when ('100', '0001') => __UNALLOCATED - when ('100', '001x') => __UNALLOCATED - when ('100', '01xx') => __UNALLOCATED - when ('100', '1000') => __encoding aarch32_SMLALBB_T1_A // SMLALBB_T1 - when ('100', '1001') => __encoding aarch32_SMLALBB_T1_A // SMLALBT_T1 - when ('100', '1010') => __encoding aarch32_SMLALBB_T1_A // SMLALTB_T1 - when ('100', '1011') => __encoding aarch32_SMLALBB_T1_A // SMLALTT_T1 - when ('100', '1100') => __encoding aarch32_SMLALD_T1_A // SMLALD_T1 - when ('100', '1101') => __encoding aarch32_SMLALD_T1_A // SMLALDX_T1 - when ('100', '111x') => __UNALLOCATED - when ('101', '0xxx') => __UNALLOCATED - when ('101', '10xx') => __UNALLOCATED - when ('101', '1100') => __encoding aarch32_SMLSLD_T1_A // SMLSLD_T1 - when ('101', '1101') => __encoding aarch32_SMLSLD_T1_A // SMLSLDX_T1 - when ('101', '111x') => __UNALLOCATED - when ('110', '0000') => __encoding aarch32_UMLAL_T1_A // UMLAL_T1 - when ('110', '0001') => __UNALLOCATED - when ('110', '001x') => __UNALLOCATED - when ('110', '010x') => __UNALLOCATED - when ('110', '0110') => __encoding aarch32_UMAAL_T1_A // UMAAL_T1 - when ('110', '0111') => __UNALLOCATED - when ('110', '1xxx') => __UNALLOCATED - when ('111', _) => __UNALLOCATED -__decode A32 - // A32 - case (28 +: 4, 25 +: 3, 5 +: 20, 4 +: 1, 0 +: 4) of - when (!'1111', '00x', _, _, _) => - // dp - case (28 +: 4, 26 +: 2, 25 +: 1, 20 +: 5, 8 +: 12, 7 +: 1, 5 +: 2, 4 +: 1, 0 +: 4) of - when (_, _, '0', _, _, '1', !'00', '1', _) => - // xldst - case (28 +: 4, 25 +: 3, 23 +: 2, 22 +: 1, 8 +: 14, 7 +: 1, 5 +: 2, 4 +: 1, 0 +: 4) of - when (_, _, _, '0', _, _, _, _, _) => // ldstxreg - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field o1 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field op2 5 +: 2 - __field Rm 0 +: 4 - case (P, W, o1, op2) of - when ('0', '0', '0', '01') => __encoding aarch32_STRH_r_A1_A // STRH_r_A1_post - when ('0', '0', '0', '10') => __encoding aarch32_LDRD_r_A1_A // LDRD_r_A1_post - when ('0', '0', '0', '11') => __encoding aarch32_STRD_r_A1_A // STRD_r_A1_post - when ('0', '0', '1', '01') => __encoding aarch32_LDRH_r_A1_A // LDRH_r_A1_post - when ('0', '0', '1', '10') => __encoding aarch32_LDRSB_r_A1_A // LDRSB_r_A1_post - when ('0', '0', '1', '11') => __encoding aarch32_LDRSH_r_A1_A // LDRSH_r_A1_post - when ('0', '1', '0', '01') => __encoding aarch32_STRHT_A2_A // STRHT_A2 - when ('0', '1', '0', '10') => __UNALLOCATED - when ('0', '1', '0', '11') => __UNALLOCATED - when ('0', '1', '1', '01') => __encoding aarch32_LDRHT_A2_A // LDRHT_A2 - when ('0', '1', '1', '10') => __encoding aarch32_LDRSBT_A2_A // LDRSBT_A2 - when ('0', '1', '1', '11') => __encoding aarch32_LDRSHT_A2_A // LDRSHT_A2 - when ('1', _, '0', '01') => __encoding aarch32_STRH_r_A1_A // STRH_r_A1_pre - when ('1', _, '0', '10') => __encoding aarch32_LDRD_r_A1_A // LDRD_r_A1_pre - when ('1', _, '0', '11') => __encoding aarch32_STRD_r_A1_A // STRD_r_A1_pre - when ('1', _, '1', '01') => __encoding aarch32_LDRH_r_A1_A // LDRH_r_A1_pre - when ('1', _, '1', '10') => __encoding aarch32_LDRSB_r_A1_A // LDRSB_r_A1_pre - when ('1', _, '1', '11') => __encoding aarch32_LDRSH_r_A1_A // LDRSH_r_A1_pre - when (_, _, _, '1', _, _, _, _, _) => // ldstximm - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field o1 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field op2 5 +: 2 - __field imm4L 0 +: 4 - case (P:W, o1, Rn, op2) of - when (_, '0', '1111', '10') => __encoding aarch32_LDRD_l_A1_A // LDRD_l_A1 - when (!'01', '1', '1111', '01') => __encoding aarch32_LDRH_l_A1_A // LDRH_l_A1 - when (!'01', '1', '1111', '10') => __encoding aarch32_LDRSB_l_A1_A // LDRSB_l_A1 - when (!'01', '1', '1111', '11') => __encoding aarch32_LDRSH_l_A1_A // LDRSH_l_A1 - when ('00', '0', !'1111', '10') => __encoding aarch32_LDRD_i_A1_A // LDRD_i_A1_post - when ('00', '0', _, '01') => __encoding aarch32_STRH_i_A1_A // STRH_i_A1_post - when ('00', '0', _, '11') => __encoding aarch32_STRD_i_A1_A // STRD_i_A1_post - when ('00', '1', !'1111', '01') => __encoding aarch32_LDRH_i_A1_A // LDRH_i_A1_post - when ('00', '1', !'1111', '10') => __encoding aarch32_LDRSB_i_A1_A // LDRSB_i_A1_post - when ('00', '1', !'1111', '11') => __encoding aarch32_LDRSH_i_A1_A // LDRSH_i_A1_post - when ('01', '0', !'1111', '10') => __UNALLOCATED - when ('01', '0', _, '01') => __encoding aarch32_STRHT_A1_A // STRHT_A1 - when ('01', '0', _, '11') => __UNALLOCATED - when ('01', '1', _, '01') => __encoding aarch32_LDRHT_A1_A // LDRHT_A1 - when ('01', '1', _, '10') => __encoding aarch32_LDRSBT_A1_A // LDRSBT_A1 - when ('01', '1', _, '11') => __encoding aarch32_LDRSHT_A1_A // LDRSHT_A1 - when ('10', '0', !'1111', '10') => __encoding aarch32_LDRD_i_A1_A // LDRD_i_A1_off - when ('10', '0', _, '01') => __encoding aarch32_STRH_i_A1_A // STRH_i_A1_off - when ('10', '0', _, '11') => __encoding aarch32_STRD_i_A1_A // STRD_i_A1_off - when ('10', '1', !'1111', '01') => __encoding aarch32_LDRH_i_A1_A // LDRH_i_A1_off - when ('10', '1', !'1111', '10') => __encoding aarch32_LDRSB_i_A1_A // LDRSB_i_A1_off - when ('10', '1', !'1111', '11') => __encoding aarch32_LDRSH_i_A1_A // LDRSH_i_A1_off - when ('11', '0', !'1111', '10') => __encoding aarch32_LDRD_i_A1_A // LDRD_i_A1_pre - when ('11', '0', _, '01') => __encoding aarch32_STRH_i_A1_A // STRH_i_A1_pre - when ('11', '0', _, '11') => __encoding aarch32_STRD_i_A1_A // STRD_i_A1_pre - when ('11', '1', !'1111', '01') => __encoding aarch32_LDRH_i_A1_A // LDRH_i_A1_pre - when ('11', '1', !'1111', '10') => __encoding aarch32_LDRSB_i_A1_A // LDRSB_i_A1_pre - when ('11', '1', !'1111', '11') => __encoding aarch32_LDRSH_i_A1_A // LDRSH_i_A1_pre - when (_, _, '0', '0xxxx', _, '1', '00', '1', _) => // mul_word - __field cond 28 +: 4 - __field opc 21 +: 3 - __field S 20 +: 1 - __field RdHi 16 +: 4 - __field RdLo 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - case (opc, S) of - when ('000', _) => __encoding aarch32_MUL_A1_A // MULS_A1 - when ('001', _) => __encoding aarch32_MLA_A1_A // MLAS_A1 - when ('010', '0') => __encoding aarch32_UMAAL_A1_A // UMAAL_A1 - when ('010', '1') => __UNALLOCATED - when ('011', '0') => __encoding aarch32_MLS_A1_A // MLS_A1 - when ('011', '1') => __UNALLOCATED - when ('100', _) => __encoding aarch32_UMULL_A1_A // UMULLS_A1 - when ('101', _) => __encoding aarch32_UMLAL_A1_A // UMLALS_A1 - when ('110', _) => __encoding aarch32_SMULL_A1_A // SMULLS_A1 - when ('111', _) => __encoding aarch32_SMLAL_A1_A // SMLALS_A1 - when (_, _, '0', '1xxxx', _, '1', '00', '1', _) => - // sync - case (28 +: 4, 24 +: 4, 23 +: 1, 12 +: 11, 10 +: 2, 8 +: 2, 4 +: 4, 0 +: 4) of - when (_, _, '0', _, _, _, _, _) => __UNPREDICTABLE - when (_, _, '1', _, _, _, _, _) => // ldst_excl - __field cond 28 +: 4 - __field size 21 +: 2 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field xRd 12 +: 4 - __field ex 9 +: 1 - __field ord 8 +: 1 - __field xRt 0 +: 4 - case (size, L, ex, ord) of - when ('00', '0', '0', '0') => __encoding aarch32_STL_A1_A // STL_A1 - when ('00', '0', '0', '1') => __UNALLOCATED - when ('00', '0', '1', '0') => __encoding aarch32_STLEX_A1_A // STLEX_A1 - when ('00', '0', '1', '1') => __encoding aarch32_STREX_A1_A // STREX_A1 - when ('00', '1', '0', '0') => __encoding aarch32_LDA_A1_A // LDA_A1 - when ('00', '1', '0', '1') => __UNALLOCATED - when ('00', '1', '1', '0') => __encoding aarch32_LDAEX_A1_A // LDAEX_A1 - when ('00', '1', '1', '1') => __encoding aarch32_LDREX_A1_A // LDREX_A1 - when ('01', '0', '0', _) => __UNALLOCATED - when ('01', '0', '1', '0') => __encoding aarch32_STLEXD_A1_A // STLEXD_A1 - when ('01', '0', '1', '1') => __encoding aarch32_STREXD_A1_A // STREXD_A1 - when ('01', '1', '0', _) => __UNALLOCATED - when ('01', '1', '1', '0') => __encoding aarch32_LDAEXD_A1_A // LDAEXD_A1 - when ('01', '1', '1', '1') => __encoding aarch32_LDREXD_A1_A // LDREXD_A1 - when ('10', '0', '0', '0') => __encoding aarch32_STLB_A1_A // STLB_A1 - when ('10', '0', '0', '1') => __UNALLOCATED - when ('10', '0', '1', '0') => __encoding aarch32_STLEXB_A1_A // STLEXB_A1 - when ('10', '0', '1', '1') => __encoding aarch32_STREXB_A1_A // STREXB_A1 - when ('10', '1', '0', '0') => __encoding aarch32_LDAB_A1_A // LDAB_A1 - when ('10', '1', '0', '1') => __UNALLOCATED - when ('10', '1', '1', '0') => __encoding aarch32_LDAEXB_A1_A // LDAEXB_A1 - when ('10', '1', '1', '1') => __encoding aarch32_LDREXB_A1_A // LDREXB_A1 - when ('11', '0', '0', '0') => __encoding aarch32_STLH_A1_A // STLH_A1 - when ('11', '0', '0', '1') => __UNALLOCATED - when ('11', '0', '1', '0') => __encoding aarch32_STLEXH_A1_A // STLEXH_A1 - when ('11', '0', '1', '1') => __encoding aarch32_STREXH_A1_A // STREXH_A1 - when ('11', '1', '0', '0') => __encoding aarch32_LDAH_A1_A // LDAH_A1 - when ('11', '1', '0', '1') => __UNALLOCATED - when ('11', '1', '1', '0') => __encoding aarch32_LDAEXH_A1_A // LDAEXH_A1 - when ('11', '1', '1', '1') => __encoding aarch32_LDREXH_A1_A // LDREXH_A1 - when (_, _, '0', '10xx0', _, '0', _, _, _) => - // dpmisc - case (28 +: 4, 23 +: 5, 21 +: 2, 20 +: 1, 8 +: 12, 7 +: 1, 4 +: 3, 0 +: 4) of - when (_, _, '00', _, _, _, '001', _) => __UNPREDICTABLE - when (_, _, '00', _, _, _, '010', _) => __UNPREDICTABLE - when (_, _, '00', _, _, _, '011', _) => __UNPREDICTABLE - when (_, _, '00', _, _, _, '110', _) => __UNPREDICTABLE - when (_, _, '01', _, _, _, '001', _) => // bx_reg - __field cond 28 +: 4 - __field Rm 0 +: 4 - case () of - when () => __encoding aarch32_BX_A1_A // BX_A1 - when (_, _, '01', _, _, _, '010', _) => // bxj_reg - __field cond 28 +: 4 - __field Rm 0 +: 4 - case () of - when () => __encoding aarch32_BXJ_A1_A // BXJ_A1 - when (_, _, '01', _, _, _, '011', _) => // blx_reg - __field cond 28 +: 4 - __field Rm 0 +: 4 - case () of - when () => __encoding aarch32_BLX_r_A1_A // BLX_r_A1 - when (_, _, '01', _, _, _, '110', _) => __UNPREDICTABLE - when (_, _, '10', _, _, _, '001', _) => __UNPREDICTABLE - when (_, _, '10', _, _, _, '010', _) => __UNPREDICTABLE - when (_, _, '10', _, _, _, '011', _) => __UNPREDICTABLE - when (_, _, '10', _, _, _, '110', _) => __UNPREDICTABLE - when (_, _, '11', _, _, _, '001', _) => // clz - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - case () of - when () => __encoding aarch32_CLZ_A1_A // CLZ_A1 - when (_, _, '11', _, _, _, '010', _) => __UNPREDICTABLE - when (_, _, '11', _, _, _, '011', _) => __UNPREDICTABLE - when (_, _, '11', _, _, _, '110', _) => // eret - __field cond 28 +: 4 - case () of - when () => __encoding aarch32_ERET_A1_A // ERET_A1 - when (_, _, _, _, _, _, '111', _) => // except - __field cond 28 +: 4 - __field opc 21 +: 2 - __field imm12 8 +: 12 - __field imm4 0 +: 4 - case (opc) of - when ('00') => __encoding aarch32_HLT_A1_A // HLT_A1 - when ('01') => __encoding aarch32_BKPT_A1_A // BKPT_A1 - when ('10') => __encoding aarch32_HVC_A1_A // HVC_A1 - when ('11') => __encoding aarch32_SMC_A1_AS // SMC_A1_AS - when (_, _, _, _, _, _, '000', _) => // movsr_reg - __field cond 28 +: 4 - __field opc 21 +: 2 - __field mask 16 +: 4 - __field Rd 12 +: 4 - __field B 9 +: 1 - __field m 8 +: 1 - __field Rn 0 +: 4 - case (opc, B) of - when ('x0', '0') => __encoding aarch32_MRS_A1_AS // MRS_A1_AS - when ('x0', '1') => __encoding aarch32_MRS_br_A1_AS // MRS_br_A1_AS - when ('x1', '0') => __encoding aarch32_MSR_r_A1_AS // MSR_r_A1_AS - when ('x1', '1') => __encoding aarch32_MSR_br_A1_AS // MSR_br_A1_AS - when (_, _, _, _, _, _, '100', _) => // crc32 - __field cond 28 +: 4 - __field sz 21 +: 2 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field C 9 +: 1 - __field Rm 0 +: 4 - case (sz, C) of - when ('00', '0') => __encoding aarch32_CRC32_A1_A // CRC32B_A1 - when ('00', '1') => __encoding aarch32_CRC32_A1_A // CRC32CB_A1 - when ('01', '0') => __encoding aarch32_CRC32_A1_A // CRC32H_A1 - when ('01', '1') => __encoding aarch32_CRC32_A1_A // CRC32CH_A1 - when ('10', '0') => __encoding aarch32_CRC32_A1_A // CRC32W_A1 - when ('10', '1') => __encoding aarch32_CRC32_A1_A // CRC32CW_A1 - when ('11', _) => __UNPREDICTABLE - when (_, _, _, _, _, _, '101', _) => // intsat - __field cond 28 +: 4 - __field opc 21 +: 2 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - case (opc) of - when ('00') => __encoding aarch32_QADD_A1_A // QADD_A1 - when ('01') => __encoding aarch32_QSUB_A1_A // QSUB_A1 - when ('10') => __encoding aarch32_QDADD_A1_A // QDADD_A1 - when ('11') => __encoding aarch32_QDSUB_A1_A // QDSUB_A1 - when (_, _, '0', '10xx0', _, '1', _, '0', _) => // mul_half - __field cond 28 +: 4 - __field opc 21 +: 2 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field M 6 +: 1 - __field N 5 +: 1 - __field Rn 0 +: 4 - case (opc, M, N) of - when ('00', _, _) => __encoding aarch32_SMLABB_A1_A // SMLATT_A1 - when ('01', '0', '0') => __encoding aarch32_SMLAWB_A1_A // SMLAWB_A1 - when ('01', '0', '1') => __encoding aarch32_SMULWB_A1_A // SMULWB_A1 - when ('01', '1', '0') => __encoding aarch32_SMLAWB_A1_A // SMLAWT_A1 - when ('01', '1', '1') => __encoding aarch32_SMULWB_A1_A // SMULWT_A1 - when ('10', _, _) => __encoding aarch32_SMLALBB_A1_A // SMLALTT_A1 - when ('11', _, _) => __encoding aarch32_SMULBB_A1_A // SMULTT_A1 - when (_, _, '0', !'10xx0', _, _, _, '0', _) => - // dpregis - case (28 +: 4, 25 +: 3, 23 +: 2, 21 +: 2, 20 +: 1, 5 +: 15, 4 +: 1, 0 +: 4) of - when (_, _, '0x', _, _, _, _, _) => // intdp3reg_immsh - __field cond 28 +: 4 - __field opc 21 +: 3 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - case (opc, S, Rn) of - when ('000', _, _) => __encoding aarch32_AND_r_A1_A // ANDS_r_A1_RRX - when ('001', _, _) => __encoding aarch32_EOR_r_A1_A // EORS_r_A1_RRX - when ('010', '0', !'1101') => __encoding aarch32_SUB_r_A1_A // SUB_r_A1_RRX - when ('010', '0', '1101') => __encoding aarch32_SUB_SP_r_A1_A // SUB_SP_r_A1_RRX - when ('010', '1', !'1101') => __encoding aarch32_SUB_r_A1_A // SUBS_r_A1_RRX - when ('010', '1', '1101') => __encoding aarch32_SUB_SP_r_A1_A // SUBS_SP_r_A1_RRX - when ('011', _, _) => __encoding aarch32_RSB_r_A1_A // RSBS_r_A1_RRX - when ('100', '0', !'1101') => __encoding aarch32_ADD_r_A1_A // ADD_r_A1_RRX - when ('100', '0', '1101') => __encoding aarch32_ADD_SP_r_A1_A // ADD_SP_r_A1_RRX - when ('100', '1', !'1101') => __encoding aarch32_ADD_r_A1_A // ADDS_r_A1_RRX - when ('100', '1', '1101') => __encoding aarch32_ADD_SP_r_A1_A // ADDS_SP_r_A1_RRX - when ('101', _, _) => __encoding aarch32_ADC_r_A1_A // ADCS_r_A1_RRX - when ('110', _, _) => __encoding aarch32_SBC_r_A1_A // SBCS_r_A1_RRX - when ('111', _, _) => __encoding aarch32_RSC_r_A1_A // RSCS_r_A1_RRX - when (_, _, '10', _, '1', _, _, _) => // intdp2reg_immsh - __field cond 28 +: 4 - __field opc 21 +: 2 - __field Rn 16 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - case (opc) of - when ('00') => __encoding aarch32_TST_r_A1_A // TST_r_A1_RRX - when ('01') => __encoding aarch32_TEQ_r_A1_A // TEQ_r_A1_RRX - when ('10') => __encoding aarch32_CMP_r_A1_A // CMP_r_A1_RRX - when ('11') => __encoding aarch32_CMN_r_A1_A // CMN_r_A1_RRX - when (_, _, '11', _, _, _, _, _) => // logic3reg_immsh - __field cond 28 +: 4 - __field opc 21 +: 2 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - case (opc) of - when ('00') => __encoding aarch32_ORR_r_A1_A // ORRS_r_A1_RRX - when ('01') => __encoding aarch32_MOV_r_A1_A // MOVS_r_A1_RRX - when ('10') => __encoding aarch32_BIC_r_A1_A // BICS_r_A1_RRX - when ('11') => __encoding aarch32_MVN_r_A1_A // MVNS_r_A1_RRX - when (_, _, '0', !'10xx0', _, '0', _, '1', _) => - // dpregrs - case (28 +: 4, 25 +: 3, 23 +: 2, 21 +: 2, 20 +: 1, 8 +: 12, 7 +: 1, 5 +: 2, 4 +: 1, 0 +: 4) of - when (_, _, '0x', _, _, _, _, _, _, _) => // intdp3reg_regsh - __field cond 28 +: 4 - __field opc 21 +: 3 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - case (opc) of - when ('000') => __encoding aarch32_AND_rr_A1_A // ANDS_rr_A1 - when ('001') => __encoding aarch32_EOR_rr_A1_A // EORS_rr_A1 - when ('010') => __encoding aarch32_SUB_rr_A1_A // SUBS_rr_A1 - when ('011') => __encoding aarch32_RSB_rr_A1_A // RSBS_rr_A1 - when ('100') => __encoding aarch32_ADD_rr_A1_A // ADDS_rr_A1 - when ('101') => __encoding aarch32_ADC_rr_A1_A // ADCS_rr_A1 - when ('110') => __encoding aarch32_SBC_rr_A1_A // SBCS_rr_A1 - when ('111') => __encoding aarch32_RSC_rr_A1_A // RSCS_rr_A1 - when (_, _, '10', _, '1', _, _, _, _, _) => // intdp2reg_regsh - __field cond 28 +: 4 - __field opc 21 +: 2 - __field Rn 16 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - case (opc) of - when ('00') => __encoding aarch32_TST_rr_A1_A // TST_rr_A1 - when ('01') => __encoding aarch32_TEQ_rr_A1_A // TEQ_rr_A1 - when ('10') => __encoding aarch32_CMP_rr_A1_A // CMP_rr_A1 - when ('11') => __encoding aarch32_CMN_rr_A1_A // CMN_rr_A1 - when (_, _, '11', _, _, _, _, _, _, _) => // logic3reg_regsh - __field cond 28 +: 4 - __field opc 21 +: 2 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - case (opc) of - when ('00') => __encoding aarch32_ORR_rr_A1_A // ORRS_rr_A1 - when ('01') => __encoding aarch32_MOV_rr_A1_A // MOVS_rr_A1 - when ('10') => __encoding aarch32_BIC_rr_A1_A // BICS_rr_A1 - when ('11') => __encoding aarch32_MVN_rr_A1_A // MVNS_rr_A1 - when (_, _, '1', _, _, _, _, _, _) => - // dpimm - case (28 +: 4, 25 +: 3, 23 +: 2, 22 +: 1, 20 +: 2, 0 +: 20) of - when (_, _, '0x', _, _, _) => // intdp2reg_imm - __field cond 28 +: 4 - __field opc 21 +: 3 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - case (opc, S, Rn) of - when ('000', _, _) => __encoding aarch32_AND_i_A1_A // ANDS_i_A1 - when ('001', _, _) => __encoding aarch32_EOR_i_A1_A // EORS_i_A1 - when ('010', '0', !'11x1') => __encoding aarch32_SUB_i_A1_A // SUB_i_A1 - when ('010', '0', '1101') => __encoding aarch32_SUB_SP_i_A1_A // SUB_SP_i_A1 - when ('010', '0', '1111') => __encoding aarch32_ADR_A1_A - when ('010', '1', !'1101') => __encoding aarch32_SUB_i_A1_A // SUBS_i_A1 - when ('010', '1', '1101') => __encoding aarch32_SUB_SP_i_A1_A // SUBS_SP_i_A1 - when ('011', _, _) => __encoding aarch32_RSB_i_A1_A // RSBS_i_A1 - when ('100', '0', !'11x1') => __encoding aarch32_ADD_i_A1_A // ADD_i_A1 - when ('100', '0', '1101') => __encoding aarch32_ADD_SP_i_A1_A // ADD_SP_i_A1 - when ('100', '0', '1111') => __encoding aarch32_ADR_A1_A - when ('100', '1', !'1101') => __encoding aarch32_ADD_i_A1_A // ADDS_i_A1 - when ('100', '1', '1101') => __encoding aarch32_ADD_SP_i_A1_A // ADDS_SP_i_A1 - when ('101', _, _) => __encoding aarch32_ADC_i_A1_A // ADCS_i_A1 - when ('110', _, _) => __encoding aarch32_SBC_i_A1_A // SBCS_i_A1 - when ('111', _, _) => __encoding aarch32_RSC_i_A1_A // RSCS_i_A1 - when (_, _, '10', _, '00', _) => // movw - __field cond 28 +: 4 - __field H 22 +: 1 - __field imm4 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - case (H) of - when ('0') => __encoding aarch32_MOV_i_A2_A // MOV_i_A2 - when ('1') => __encoding aarch32_MOVT_A1_A // MOVT_A1 - when (_, _, '10', _, '10', _) => // movsr_hint_imm - __field cond 28 +: 4 - __field R 22 +: 1 - __field imm4 16 +: 4 - __field imm12 0 +: 12 - case (R:imm4, imm12) of - when (!'00000', _) => __encoding aarch32_MSR_i_A1_AS // MSR_i_A1_AS - when ('00000', 'xxxx00000000') => __encoding aarch32_NOP_A1_A // NOP_A1 - when ('00000', 'xxxx00000001') => __encoding aarch32_YIELD_A1_A // YIELD_A1 - when ('00000', 'xxxx00000010') => __encoding aarch32_WFE_A1_A // WFE_A1 - when ('00000', 'xxxx00000011') => __encoding aarch32_WFI_A1_A // WFI_A1 - when ('00000', 'xxxx00000100') => __encoding aarch32_SEV_A1_A // SEV_A1 - when ('00000', 'xxxx00000101') => __encoding aarch32_SEVL_A1_A // SEVL_A1 - when ('00000', 'xxxx0000011x') => __NOP - when ('00000', 'xxxx00001xxx') => __NOP - when ('00000', 'xxxx00010000') => __encoding aarch32_ESB_A1_A // ESB_A1 - when ('00000', 'xxxx00010001') => __NOP - when ('00000', 'xxxx00010010') => __encoding aarch32_TSB_A1_A // TSB_A1 - when ('00000', 'xxxx00010011') => __NOP - when ('00000', 'xxxx00010100') => __encoding aarch32_CSDB_A1_A // CSDB_A1 - when ('00000', 'xxxx00010101') => __NOP - when ('00000', 'xxxx00011xxx') => __NOP - when ('00000', 'xxxx0001111x') => __NOP - when ('00000', 'xxxx001xxxxx') => __NOP - when ('00000', 'xxxx01xxxxxx') => __NOP - when ('00000', 'xxxx10xxxxxx') => __NOP - when ('00000', 'xxxx110xxxxx') => __NOP - when ('00000', 'xxxx1110xxxx') => __NOP - when ('00000', 'xxxx1111xxxx') => __encoding aarch32_DBG_A1_A // DBG_A1 - when (_, _, '10', _, 'x1', _) => // intdp1reg_imm - __field cond 28 +: 4 - __field opc 21 +: 2 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - case (opc) of - when ('00') => __encoding aarch32_TST_i_A1_A // TST_i_A1 - when ('01') => __encoding aarch32_TEQ_i_A1_A // TEQ_i_A1 - when ('10') => __encoding aarch32_CMP_i_A1_A // CMP_i_A1 - when ('11') => __encoding aarch32_CMN_i_A1_A // CMN_i_A1 - when (_, _, '11', _, _, _) => // log2reg_imm - __field cond 28 +: 4 - __field opc 21 +: 2 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - case (opc) of - when ('00') => __encoding aarch32_ORR_i_A1_A // ORRS_i_A1 - when ('01') => __encoding aarch32_MOV_i_A1_A // MOVS_i_A1 - when ('10') => __encoding aarch32_BIC_i_A1_A // BICS_i_A1 - when ('11') => __encoding aarch32_MVN_i_A1_A // MVNS_i_A1 - when (!'1111', '010', _, _, _) => // ldstimm - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field o2 22 +: 1 - __field W 21 +: 1 - __field o1 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - case (P:W, o2, o1, Rn) of - when (!'01', '0', '1', '1111') => __encoding aarch32_LDR_l_A1_A // LDR_l_A1 - when (!'01', '1', '1', '1111') => __encoding aarch32_LDRB_l_A1_A // LDRB_l_A1 - when ('00', '0', '0', _) => __encoding aarch32_STR_i_A1_A // STR_i_A1_post - when ('00', '0', '1', !'1111') => __encoding aarch32_LDR_i_A1_A // LDR_i_A1_post - when ('00', '1', '0', _) => __encoding aarch32_STRB_i_A1_A // STRB_i_A1_post - when ('00', '1', '1', !'1111') => __encoding aarch32_LDRB_i_A1_A // LDRB_i_A1_post - when ('01', '0', '0', _) => __encoding aarch32_STRT_A1_A // STRT_A1 - when ('01', '0', '1', _) => __encoding aarch32_LDRT_A1_A // LDRT_A1 - when ('01', '1', '0', _) => __encoding aarch32_STRBT_A1_A // STRBT_A1 - when ('01', '1', '1', _) => __encoding aarch32_LDRBT_A1_A // LDRBT_A1 - when ('10', '0', '0', _) => __encoding aarch32_STR_i_A1_A // STR_i_A1_off - when ('10', '0', '1', !'1111') => __encoding aarch32_LDR_i_A1_A // LDR_i_A1_off - when ('10', '1', '0', _) => __encoding aarch32_STRB_i_A1_A // STRB_i_A1_off - when ('10', '1', '1', !'1111') => __encoding aarch32_LDRB_i_A1_A // LDRB_i_A1_off - when ('11', '0', '0', _) => __encoding aarch32_STR_i_A1_A // STR_i_A1_pre - when ('11', '0', '1', !'1111') => __encoding aarch32_LDR_i_A1_A // LDR_i_A1_pre - when ('11', '1', '0', _) => __encoding aarch32_STRB_i_A1_A // STRB_i_A1_pre - when ('11', '1', '1', !'1111') => __encoding aarch32_LDRB_i_A1_A // LDRB_i_A1_pre - when (!'1111', '011', _, '0', _) => // ldstreg - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field o2 22 +: 1 - __field W 21 +: 1 - __field o1 20 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - case (P, o2, W, o1) of - when ('0', '0', '0', '0') => __encoding aarch32_STR_r_A1_A // STR_r_A1_post - when ('0', '0', '0', '1') => __encoding aarch32_LDR_r_A1_A // LDR_r_A1_post - when ('0', '0', '1', '0') => __encoding aarch32_STRT_A2_A // STRT_A2 - when ('0', '0', '1', '1') => __encoding aarch32_LDRT_A2_A // LDRT_A2 - when ('0', '1', '0', '0') => __encoding aarch32_STRB_r_A1_A // STRB_r_A1_post - when ('0', '1', '0', '1') => __encoding aarch32_LDRB_r_A1_A // LDRB_r_A1_post - when ('0', '1', '1', '0') => __encoding aarch32_STRBT_A2_A // STRBT_A2 - when ('0', '1', '1', '1') => __encoding aarch32_LDRBT_A2_A // LDRBT_A2 - when ('1', '0', _, '0') => __encoding aarch32_STR_r_A1_A // STR_r_A1_pre - when ('1', '0', _, '1') => __encoding aarch32_LDR_r_A1_A // LDR_r_A1_pre - when ('1', '1', _, '0') => __encoding aarch32_STRB_r_A1_A // STRB_r_A1_pre - when ('1', '1', _, '1') => __encoding aarch32_LDRB_r_A1_A // LDRB_r_A1_pre - when (!'1111', '011', _, '1', _) => - // media - case (28 +: 4, 25 +: 3, 20 +: 5, 8 +: 12, 5 +: 3, 4 +: 1, 0 +: 4) of - when (_, _, '00xxx', _, _, _, _) => // parallel - __field cond 28 +: 4 - __field op1 20 +: 3 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field B 7 +: 1 - __field op2 5 +: 2 - __field Rm 0 +: 4 - case (op1, B, op2) of - when ('000', _, _) => __UNALLOCATED - when ('001', '0', '00') => __encoding aarch32_SADD16_A1_A // SADD16_A1 - when ('001', '0', '01') => __encoding aarch32_SASX_A1_A // SASX_A1 - when ('001', '0', '10') => __encoding aarch32_SSAX_A1_A // SSAX_A1 - when ('001', '0', '11') => __encoding aarch32_SSUB16_A1_A // SSUB16_A1 - when ('001', '1', '00') => __encoding aarch32_SADD8_A1_A // SADD8_A1 - when ('001', '1', '01') => __UNALLOCATED - when ('001', '1', '10') => __UNALLOCATED - when ('001', '1', '11') => __encoding aarch32_SSUB8_A1_A // SSUB8_A1 - when ('010', '0', '00') => __encoding aarch32_QADD16_A1_A // QADD16_A1 - when ('010', '0', '01') => __encoding aarch32_QASX_A1_A // QASX_A1 - when ('010', '0', '10') => __encoding aarch32_QSAX_A1_A // QSAX_A1 - when ('010', '0', '11') => __encoding aarch32_QSUB16_A1_A // QSUB16_A1 - when ('010', '1', '00') => __encoding aarch32_QADD8_A1_A // QADD8_A1 - when ('010', '1', '01') => __UNALLOCATED - when ('010', '1', '10') => __UNALLOCATED - when ('010', '1', '11') => __encoding aarch32_QSUB8_A1_A // QSUB8_A1 - when ('011', '0', '00') => __encoding aarch32_SHADD16_A1_A // SHADD16_A1 - when ('011', '0', '01') => __encoding aarch32_SHASX_A1_A // SHASX_A1 - when ('011', '0', '10') => __encoding aarch32_SHSAX_A1_A // SHSAX_A1 - when ('011', '0', '11') => __encoding aarch32_SHSUB16_A1_A // SHSUB16_A1 - when ('011', '1', '00') => __encoding aarch32_SHADD8_A1_A // SHADD8_A1 - when ('011', '1', '01') => __UNALLOCATED - when ('011', '1', '10') => __UNALLOCATED - when ('011', '1', '11') => __encoding aarch32_SHSUB8_A1_A // SHSUB8_A1 - when ('100', _, _) => __UNALLOCATED - when ('101', '0', '00') => __encoding aarch32_UADD16_A1_A // UADD16_A1 - when ('101', '0', '01') => __encoding aarch32_UASX_A1_A // UASX_A1 - when ('101', '0', '10') => __encoding aarch32_USAX_A1_A // USAX_A1 - when ('101', '0', '11') => __encoding aarch32_USUB16_A1_A // USUB16_A1 - when ('101', '1', '00') => __encoding aarch32_UADD8_A1_A // UADD8_A1 - when ('101', '1', '01') => __UNALLOCATED - when ('101', '1', '10') => __UNALLOCATED - when ('101', '1', '11') => __encoding aarch32_USUB8_A1_A // USUB8_A1 - when ('110', '0', '00') => __encoding aarch32_UQADD16_A1_A // UQADD16_A1 - when ('110', '0', '01') => __encoding aarch32_UQASX_A1_A // UQASX_A1 - when ('110', '0', '10') => __encoding aarch32_UQSAX_A1_A // UQSAX_A1 - when ('110', '0', '11') => __encoding aarch32_UQSUB16_A1_A // UQSUB16_A1 - when ('110', '1', '00') => __encoding aarch32_UQADD8_A1_A // UQADD8_A1 - when ('110', '1', '01') => __UNALLOCATED - when ('110', '1', '10') => __UNALLOCATED - when ('110', '1', '11') => __encoding aarch32_UQSUB8_A1_A // UQSUB8_A1 - when ('111', '0', '00') => __encoding aarch32_UHADD16_A1_A // UHADD16_A1 - when ('111', '0', '01') => __encoding aarch32_UHASX_A1_A // UHASX_A1 - when ('111', '0', '10') => __encoding aarch32_UHSAX_A1_A // UHSAX_A1 - when ('111', '0', '11') => __encoding aarch32_UHSUB16_A1_A // UHSUB16_A1 - when ('111', '1', '00') => __encoding aarch32_UHADD8_A1_A // UHADD8_A1 - when ('111', '1', '01') => __UNALLOCATED - when ('111', '1', '10') => __UNALLOCATED - when ('111', '1', '11') => __encoding aarch32_UHSUB8_A1_A // UHSUB8_A1 - when (_, _, '01000', _, '101', _, _) => // selbytes - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - case () of - when () => __encoding aarch32_SEL_A1_A // SEL_A1 - when (_, _, '01000', _, '001', _, _) => __UNPREDICTABLE - when (_, _, '01000', _, 'xx0', _, _) => // pack - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field tb 6 +: 1 - __field Rm 0 +: 4 - case () of - when () => __encoding aarch32_PKH_A1_A // PKHTB_A1 - when (_, _, '01001', _, 'x01', _, _) => __UNPREDICTABLE - when (_, _, '01001', _, 'xx0', _, _) => __UNPREDICTABLE - when (_, _, '0110x', _, 'x01', _, _) => __UNPREDICTABLE - when (_, _, '0110x', _, 'xx0', _, _) => __UNPREDICTABLE - when (_, _, '01x10', _, '001', _, _) => // sat16 - __field cond 28 +: 4 - __field U 22 +: 1 - __field sat_imm 16 +: 4 - __field Rd 12 +: 4 - __field Rn 0 +: 4 - case (U) of - when ('0') => __encoding aarch32_SSAT16_A1_A // SSAT16_A1 - when ('1') => __encoding aarch32_USAT16_A1_A // USAT16_A1 - when (_, _, '01x10', _, '101', _, _) => __UNPREDICTABLE - when (_, _, '01x11', _, 'x01', _, _) => // reverse - __field cond 28 +: 4 - __field o1 22 +: 1 - __field Rd 12 +: 4 - __field o2 7 +: 1 - __field Rm 0 +: 4 - case (o1, o2) of - when ('0', '0') => __encoding aarch32_REV_A1_A // REV_A1 - when ('0', '1') => __encoding aarch32_REV16_A1_A // REV16_A1 - when ('1', '0') => __encoding aarch32_RBIT_A1_A // RBIT_A1 - when ('1', '1') => __encoding aarch32_REVSH_A1_A // REVSH_A1 - when (_, _, '01x1x', _, 'xx0', _, _) => // sat32 - __field cond 28 +: 4 - __field U 22 +: 1 - __field sat_imm 16 +: 5 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field sh 6 +: 1 - __field Rn 0 +: 4 - case (U) of - when ('0') => __encoding aarch32_SSAT_A1_A // SSAT_A1_ASR - when ('1') => __encoding aarch32_USAT_A1_A // USAT_A1_ASR - when (_, _, '01xxx', _, '111', _, _) => __UNPREDICTABLE - when (_, _, '01xxx', _, '011', _, _) => // extend - __field cond 28 +: 4 - __field U 22 +: 1 - __field op 20 +: 2 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - case (U, op, Rn) of - when ('0', '00', !'1111') => __encoding aarch32_SXTAB16_A1_A // SXTAB16_A1 - when ('0', '00', '1111') => __encoding aarch32_SXTB16_A1_A // SXTB16_A1 - when ('0', '10', !'1111') => __encoding aarch32_SXTAB_A1_A // SXTAB_A1 - when ('0', '10', '1111') => __encoding aarch32_SXTB_A1_A // SXTB_A1 - when ('0', '11', !'1111') => __encoding aarch32_SXTAH_A1_A // SXTAH_A1 - when ('0', '11', '1111') => __encoding aarch32_SXTH_A1_A // SXTH_A1 - when ('1', '00', !'1111') => __encoding aarch32_UXTAB16_A1_A // UXTAB16_A1 - when ('1', '00', '1111') => __encoding aarch32_UXTB16_A1_A // UXTB16_A1 - when ('1', '10', !'1111') => __encoding aarch32_UXTAB_A1_A // UXTAB_A1 - when ('1', '10', '1111') => __encoding aarch32_UXTB_A1_A // UXTB_A1 - when ('1', '11', !'1111') => __encoding aarch32_UXTAH_A1_A // UXTAH_A1 - when ('1', '11', '1111') => __encoding aarch32_UXTH_A1_A // UXTH_A1 - when (_, _, '10xxx', _, _, _, _) => // smul_div - __field cond 28 +: 4 - __field op1 20 +: 3 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field op2 5 +: 3 - __field Rn 0 +: 4 - case (op1, Ra, op2) of - when ('000', !'1111', '000') => __encoding aarch32_SMLAD_A1_A // SMLAD_A1 - when ('000', !'1111', '001') => __encoding aarch32_SMLAD_A1_A // SMLADX_A1 - when ('000', !'1111', '010') => __encoding aarch32_SMLSD_A1_A // SMLSD_A1 - when ('000', !'1111', '011') => __encoding aarch32_SMLSD_A1_A // SMLSDX_A1 - when ('000', _, '1xx') => __UNALLOCATED - when ('000', '1111', '000') => __encoding aarch32_SMUAD_A1_A // SMUAD_A1 - when ('000', '1111', '001') => __encoding aarch32_SMUAD_A1_A // SMUADX_A1 - when ('000', '1111', '010') => __encoding aarch32_SMUSD_A1_A // SMUSD_A1 - when ('000', '1111', '011') => __encoding aarch32_SMUSD_A1_A // SMUSDX_A1 - when ('001', _, '000') => __encoding aarch32_SDIV_A1_A // SDIV_A1 - when ('001', _, !'000') => __UNALLOCATED - when ('010', _, _) => __UNALLOCATED - when ('011', _, '000') => __encoding aarch32_UDIV_A1_A // UDIV_A1 - when ('011', _, !'000') => __UNALLOCATED - when ('100', _, '000') => __encoding aarch32_SMLALD_A1_A // SMLALD_A1 - when ('100', _, '001') => __encoding aarch32_SMLALD_A1_A // SMLALDX_A1 - when ('100', _, '010') => __encoding aarch32_SMLSLD_A1_A // SMLSLD_A1 - when ('100', _, '011') => __encoding aarch32_SMLSLD_A1_A // SMLSLDX_A1 - when ('100', _, '1xx') => __UNALLOCATED - when ('101', !'1111', '000') => __encoding aarch32_SMMLA_A1_A // SMMLA_A1 - when ('101', !'1111', '001') => __encoding aarch32_SMMLA_A1_A // SMMLAR_A1 - when ('101', _, '01x') => __UNALLOCATED - when ('101', _, '10x') => __UNALLOCATED - when ('101', _, '110') => __encoding aarch32_SMMLS_A1_A // SMMLS_A1 - when ('101', _, '111') => __encoding aarch32_SMMLS_A1_A // SMMLSR_A1 - when ('101', '1111', '000') => __encoding aarch32_SMMUL_A1_A // SMMUL_A1 - when ('101', '1111', '001') => __encoding aarch32_SMMUL_A1_A // SMMULR_A1 - when ('11x', _, _) => __UNALLOCATED - when (_, _, '11000', _, '000', _, _) => // usad - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - case (Ra) of - when (!'1111') => __encoding aarch32_USADA8_A1_A // USADA8_A1 - when ('1111') => __encoding aarch32_USAD8_A1_A // USAD8_A1 - when (_, _, '11000', _, '100', _, _) => __UNPREDICTABLE - when (_, _, '11001', _, 'x00', _, _) => __UNPREDICTABLE - when (_, _, '1101x', _, 'x00', _, _) => __UNPREDICTABLE - when (_, _, '110xx', _, '111', _, _) => __UNPREDICTABLE - when (_, _, '1110x', _, '111', _, _) => __UNPREDICTABLE - when (_, _, '1110x', _, 'x00', _, _) => // bfi - __field cond 28 +: 4 - __field msb 16 +: 5 - __field Rd 12 +: 4 - __field lsb 7 +: 5 - __field Rn 0 +: 4 - case (Rn) of - when (!'1111') => __encoding aarch32_BFI_A1_A // BFI_A1 - when ('1111') => __encoding aarch32_BFC_A1_A // BFC_A1 - when (_, _, '11110', _, '111', _, _) => __UNPREDICTABLE - when (_, _, '11111', _, '111', _, _) => // udf - __field cond 28 +: 4 - __field imm12 8 +: 12 - __field imm4 0 +: 4 - case (cond) of - when ('0xxx') => __UNALLOCATED - when ('10xx') => __UNALLOCATED - when ('110x') => __UNALLOCATED - when ('1110') => __encoding aarch32_UDF_A1_A // UDF_A1 - when (_, _, '1111x', _, 'x00', _, _) => __UNPREDICTABLE - when (_, _, '11x0x', _, 'x10', _, _) => __UNPREDICTABLE - when (_, _, '11x1x', _, 'x10', _, _) => // bfx - __field cond 28 +: 4 - __field U 22 +: 1 - __field widthm1 16 +: 5 - __field Rd 12 +: 4 - __field lsb 7 +: 5 - __field Rn 0 +: 4 - case (U) of - when ('0') => __encoding aarch32_SBFX_A1_A // SBFX_A1 - when ('1') => __encoding aarch32_UBFX_A1_A // UBFX_A1 - when (_, _, '11xxx', _, '011', _, _) => __UNPREDICTABLE - when (_, _, '11xxx', _, 'x01', _, _) => __UNPREDICTABLE - when (_, '10x', _, _, _) => - // brblk - case (28 +: 4, 26 +: 2, 25 +: 1, 0 +: 25) of - when ('1111', _, '0', _) => // ldstexcept - __field P 24 +: 1 - __field U 23 +: 1 - __field S 22 +: 1 - __field W 21 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field op 5 +: 11 - __field mode 0 +: 5 - case (P, U, S, L) of - when (_, _, '0', '0') => __UNALLOCATED - when ('0', '0', '0', '1') => __encoding aarch32_RFE_A1_AS // RFEDA_A1_AS - when ('0', '0', '1', '0') => __encoding aarch32_SRS_A1_AS // SRSDA_A1_AS - when ('0', '1', '0', '1') => __encoding aarch32_RFE_A1_AS // RFEIA_A1_AS - when ('0', '1', '1', '0') => __encoding aarch32_SRS_A1_AS // SRSIA_A1_AS - when ('1', '0', '0', '1') => __encoding aarch32_RFE_A1_AS // RFEDB_A1_AS - when ('1', '0', '1', '0') => __encoding aarch32_SRS_A1_AS // SRSDB_A1_AS - when (_, _, '1', '1') => __UNALLOCATED - when ('1', '1', '0', '1') => __encoding aarch32_RFE_A1_AS // RFEIB_A1_AS - when ('1', '1', '1', '0') => __encoding aarch32_SRS_A1_AS // SRSIB_A1_AS - when (!'1111', _, '0', _) => // ldstm - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field op 22 +: 1 - __field W 21 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - case (P, U, op, L, register_list) of - when ('0', '0', '0', '0', _) => __encoding aarch32_STMDA_A1_A // STMDA_A1 - when ('0', '0', '0', '1', _) => __encoding aarch32_LDMDA_A1_A // LDMDA_A1 - when ('0', '1', '0', '0', _) => __encoding aarch32_STM_A1_A // STM_A1 - when ('0', '1', '0', '1', _) => __encoding aarch32_LDM_A1_A // LDM_A1 - when (_, _, '1', '0', _) => __encoding aarch32_STM_u_A1_AS // STM_u_A1_AS - when ('1', '0', '0', '0', _) => __encoding aarch32_STMDB_A1_A // STMDB_A1 - when ('1', '0', '0', '1', _) => __encoding aarch32_LDMDB_A1_A // LDMDB_A1 - when (_, _, '1', '1', '0xxxxxxxxxxxxxxx') => __encoding aarch32_LDM_u_A1_AS // LDM_u_A1_AS - when ('1', '1', '0', '0', _) => __encoding aarch32_STMIB_A1_A // STMIB_A1 - when ('1', '1', '0', '1', _) => __encoding aarch32_LDMIB_A1_A // LDMIB_A1 - when (_, _, '1', '1', '1xxxxxxxxxxxxxxx') => __encoding aarch32_LDM_e_A1_AS // LDM_e_A1_AS - when (_, _, '1', _) => // b_imm - __field cond 28 +: 4 - __field H 24 +: 1 - __field imm24 0 +: 24 - case (cond, H) of - when (!'1111', '0') => __encoding aarch32_B_A1_A // B_A1 - when (!'1111', '1') => __encoding aarch32_BL_i_A1_A - when ('1111', _) => __encoding aarch32_BL_i_A1_A - when (_, '11x', _, _, _) => - // cops_as - case (28 +: 4, 26 +: 2, 24 +: 2, 12 +: 12, 9 +: 3, 5 +: 4, 4 +: 1, 0 +: 4) of - when (_, _, '0x', _, '111', _, _, _) => - // sysldst_mov64 - case (28 +: 4, 25 +: 3, 21 +: 4, 12 +: 9, 9 +: 3, 0 +: 9) of - when (_, _, '00x0', _, _, _) => // movcpgp64 - __field cond 28 +: 4 - __field D 22 +: 1 - __field L 20 +: 1 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field cp15 8 +: 1 - __field opc1 4 +: 4 - __field CRm 0 +: 4 - case (cond, D, L) of - when (!'1111', '1', '0') => __encoding aarch32_MCRR_T1A1_A // MCRR_A1 - when (!'1111', '1', '1') => __encoding aarch32_MRRC_T1A1_A // MRRC_A1 - when (_, '0', _) => __UNALLOCATED - when ('1111', '1', _) => __UNALLOCATED - when (_, _, !'00x0', _, _, _) => // ldstcp - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field CRd 12 +: 4 - __field cp15 8 +: 1 - __field imm8 0 +: 8 - case (cond, P:U:W, D, L, Rn, CRd, cp15) of - when (!'1111', !'000', '0', _, _, !'0101', '0') => __UNALLOCATED - when (!'1111', !'000', '0', '1', '1111', '0101', '0') => __encoding aarch32_LDC_l_T1A1_A // LDC_l_A1 - when (!'1111', !'000', _, _, _, _, '1') => __UNALLOCATED - when (!'1111', !'000', '1', _, _, '0101', '0') => __UNALLOCATED - when (!'1111', '0x1', '0', '0', _, '0101', '0') => __encoding aarch32_STC_T1A1_A // STC_A1_post - when (!'1111', '0x1', '0', '1', !'1111', '0101', '0') => __encoding aarch32_LDC_i_T1A1_A // LDC_i_A1_post - when (!'1111', '010', '0', '0', _, '0101', '0') => __encoding aarch32_STC_T1A1_A // STC_A1_unind - when (!'1111', '010', '0', '1', !'1111', '0101', '0') => __encoding aarch32_LDC_i_T1A1_A // LDC_i_A1_unind - when (!'1111', '1x0', '0', '0', _, '0101', '0') => __encoding aarch32_STC_T1A1_A // STC_A1_off - when (!'1111', '1x0', '0', '1', !'1111', '0101', '0') => __encoding aarch32_LDC_i_T1A1_A // LDC_i_A1_off - when (!'1111', '1x1', '0', '0', _, '0101', '0') => __encoding aarch32_STC_T1A1_A // STC_A1_pre - when (!'1111', '1x1', '0', '1', !'1111', '0101', '0') => __encoding aarch32_LDC_i_T1A1_A // LDC_i_A1_pre - when ('1111', !'000', _, _, _, _, _) => __UNALLOCATED - when (_, _, '10', _, '10x', _, '0', _) => - // fpdp - case (28 +: 4, 24 +: 4, 20 +: 4, 16 +: 4, 12 +: 4, 10 +: 2, 8 +: 2, 7 +: 1, 6 +: 1, 5 +: 1, 4 +: 1, 0 +: 4) of - when ('1111', _, '0xxx', _, _, _, !'00', _, '0', _, _, _) => // fpcsel - __field D 22 +: 1 - __field cc 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (cc, size) of - when ('00', _) => __encoding aarch32_VSEL_A1_A // VSELEQ_A1_D - when ('01', _) => __encoding aarch32_VSEL_A1_A // VSELVS_A1_D - when (_, '01') => __UNALLOCATED - when ('10', _) => __encoding aarch32_VSEL_A1_A // VSELGE_A1_D - when ('11', _) => __encoding aarch32_VSEL_A1_A // VSELGT_A1_D - when ('1111', _, '1x00', _, _, _, !'00', _, _, _, _, _) => // fpminmaxnm - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (size, op) of - when (_, '0') => __encoding aarch32_VMAXNM_A2_A // VMAXNM_A2_D - when ('01', _) => __UNALLOCATED - when (_, '1') => __encoding aarch32_VMAXNM_A2_A // VMINNM_A2_D - when ('1111', _, '1x11', '0000', _, _, !'00', _, '1', _, _, _) => // fpextins - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (size, op) of - when ('01', _) => __UNALLOCATED - when ('10', '0') => __encoding aarch32_VMOVX_A1_A // VMOVX_A1 - when ('10', '1') => __encoding aarch32_VINS_A1_A // VINS_A1 - when ('11', _) => __UNALLOCATED - when ('1111', _, '1x11', '1xxx', _, _, !'00', _, '1', _, _, _) => // fpcvtrnd - __field D 22 +: 1 - __field o1 18 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (o1, RM, size) of - when ('0', '00', _) => __encoding aarch32_VRINTA_vfp_A1_A // VRINTA_vfp_A1_D - when ('0', '01', _) => __encoding aarch32_VRINTA_vfp_A1_A // VRINTN_vfp_A1_D - when (_, _, '01') => __UNALLOCATED - when ('0', '10', _) => __encoding aarch32_VRINTA_vfp_A1_A // VRINTP_vfp_A1_D - when ('0', '11', _) => __encoding aarch32_VRINTA_vfp_A1_A // VRINTM_vfp_A1_D - when ('1', '00', _) => __encoding aarch32_VCVTA_vfp_A1_A // VCVTA_vfp_A1_D - when ('1', '01', _) => __encoding aarch32_VCVTA_vfp_A1_A // VCVTN_vfp_A1_D - when ('1', '10', _) => __encoding aarch32_VCVTA_vfp_A1_A // VCVTP_vfp_A1_D - when ('1', '11', _) => __encoding aarch32_VCVTA_vfp_A1_A // VCVTM_vfp_A1_D - when (!'1111', _, '1x11', _, _, _, _, _, '1', _, _, _) => // fpdp2reg - __field cond 28 +: 4 - __field D 22 +: 1 - __field o1 19 +: 1 - __field opc2 16 +: 3 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field o3 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (o1, opc2, size, o3) of - when (_, _, '00', _) => __UNALLOCATED - when ('0', '000', '01', '0') => __UNALLOCATED - when ('0', '000', _, '1') => __encoding aarch32_VABS_A2_A // VABS_A2_D - when ('0', '000', '10', '0') => __encoding aarch32_VMOV_r_T2A2_A // VMOV_r_A2_S - when ('0', '000', '11', '0') => __encoding aarch32_VMOV_r_T2A2_A // VMOV_r_A2_D - when ('0', '001', _, '0') => __encoding aarch32_VNEG_A2_A // VNEG_A2_D - when ('0', '001', _, '1') => __encoding aarch32_VSQRT_A1_A // VSQRT_A1_D - when ('0', '010', _, '0') => __encoding aarch32_VCVTB_T1A1_A // VCVTB_A1_DH - when ('0', '010', '01', _) => __UNALLOCATED - when ('0', '010', _, '1') => __encoding aarch32_VCVTB_T1A1_A // VCVTT_A1_DH - when ('0', '011', '01', '0') => __encoding aarch32_VCVTB_bf16_T1A1_A // VCVTB_A1_bfs - when ('0', '011', '01', '1') => __encoding aarch32_VCVTT_T1A1_A // VCVTT_A1_bfs - when ('0', '011', '10', '0') => __encoding aarch32_VCVTB_T1A1_A // VCVTB_A1_HS - when ('0', '011', '10', '1') => __encoding aarch32_VCVTB_T1A1_A // VCVTT_A1_HS - when ('0', '011', '11', '0') => __encoding aarch32_VCVTB_T1A1_A // VCVTB_A1_HD - when ('0', '011', '11', '1') => __encoding aarch32_VCVTB_T1A1_A // VCVTT_A1_HD - when ('0', '100', _, '0') => __encoding aarch32_VCMP_A1_A - when ('0', '100', _, '1') => __encoding aarch32_VCMP_A1_A - when ('0', '101', _, '0') => __encoding aarch32_VCMP_A1_A - when ('0', '101', _, '1') => __encoding aarch32_VCMP_A1_A - when ('0', '110', _, '0') => __encoding aarch32_VRINTZ_vfp_A1_A // VRINTR_vfp_A1_D - when ('0', '110', _, '1') => __encoding aarch32_VRINTZ_vfp_A1_A // VRINTZ_vfp_A1_D - when ('0', '111', _, '0') => __encoding aarch32_VRINTX_vfp_A1_A // VRINTX_vfp_A1_D - when ('0', '111', '01', '1') => __UNALLOCATED - when ('0', '111', '10', '1') => __encoding aarch32_VCVT_ds_T1A1_A // VCVT_ds_A1 - when ('0', '111', '11', '1') => __encoding aarch32_VCVT_ds_T1A1_A // VCVT_sd_A1 - when ('1', '000', _, _) => __encoding aarch32_VCVT_iv_A1_A // VCVT_vi_A1_D - when ('1', '001', '01', _) => __UNALLOCATED - when ('1', '001', '10', _) => __UNALLOCATED - when ('1', '001', '11', '0') => __UNALLOCATED - when ('1', '001', '11', '1') => __encoding aarch32_VJCVT_A1_A // VJCVT_A1 - when ('1', '01x', _, _) => __encoding aarch32_VCVT_xv_A1_A // VCVT_toxv_A1_D - when ('1', '100', _, '0') => __encoding aarch32_VCVT_iv_A1_A // VCVTR_uiv_A1_D - when ('1', '100', _, '1') => __encoding aarch32_VCVT_iv_A1_A // VCVT_uiv_A1_D - when ('1', '101', _, '0') => __encoding aarch32_VCVT_iv_A1_A // VCVTR_siv_A1_D - when ('1', '101', _, '1') => __encoding aarch32_VCVT_iv_A1_A // VCVT_siv_A1_D - when ('1', '11x', _, _) => __encoding aarch32_VCVT_xv_A1_A // VCVT_xv_A1_D - when (!'1111', _, '1x11', _, _, _, _, _, '0', _, _, _) => // fpimm - __field cond 28 +: 4 - __field D 22 +: 1 - __field imm4H 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm4L 0 +: 4 - case (size) of - when ('00') => __UNALLOCATED - when ('01') => __encoding aarch32_VMOV_i_A2_A // VMOV_i_A2_H - when ('10') => __encoding aarch32_VMOV_i_A2_A // VMOV_i_A2_S - when ('11') => __encoding aarch32_VMOV_i_A2_A // VMOV_i_A2_D - when (!'1111', _, !'1x11', _, _, _, _, _, _, _, _, _) => // fpdp3reg - __field cond 28 +: 4 - __field o0 23 +: 1 - __field D 22 +: 1 - __field o1 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field o2 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (o0:o1, size, o2) of - when (!'111', '00', _) => __UNALLOCATED - when ('000', _, '0') => __encoding aarch32_VMLA_f_A2_A // VMLA_f_A2_D - when ('000', _, '1') => __encoding aarch32_VMLA_f_A2_A // VMLS_f_A2_D - when ('001', _, '0') => __encoding aarch32_VNMLA_A1_A // VNMLS_A1_D - when ('001', _, '1') => __encoding aarch32_VNMLA_A1_A // VNMLA_A1_D - when ('010', _, '0') => __encoding aarch32_VMUL_f_A2_A // VMUL_f_A2_D - when ('010', _, '1') => __encoding aarch32_VNMLA_A2_A // VNMUL_A1_D - when ('011', _, '0') => __encoding aarch32_VADD_f_A2_A // VADD_f_A2_D - when ('011', _, '1') => __encoding aarch32_VSUB_f_A2_A // VSUB_f_A2_D - when ('100', _, '0') => __encoding aarch32_VDIV_A1_A // VDIV_A1_D - when ('101', _, '0') => __encoding aarch32_VFNMA_A1_A // VFNMS_A1_D - when ('101', _, '1') => __encoding aarch32_VFNMA_A1_A // VFNMA_A1_D - when ('110', _, '0') => __encoding aarch32_VFMA_A2_A // VFMA_A2_D - when ('110', _, '1') => __encoding aarch32_VFMA_A2_A // VFMS_A2_D - when (_, _, '10', _, '111', _, '1', _) => // movcpgp32 - __field cond 28 +: 4 - __field opc1 21 +: 3 - __field L 20 +: 1 - __field CRn 16 +: 4 - __field Rt 12 +: 4 - __field cp15 8 +: 1 - __field opc2 5 +: 3 - __field CRm 0 +: 4 - case (cond, L) of - when (!'1111', '0') => __encoding aarch32_MCR_T1A1_A // MCR_A1 - when (!'1111', '1') => __encoding aarch32_MRC_T1A1_A // MRC_A1 - when ('1111', _) => __UNALLOCATED - when (_, _, '11', _, _, _, _, _) => - // svcall - case (28 +: 4, 24 +: 4, 0 +: 24) of - when ('1111', _, _) => __UNPREDICTABLE - when (!'1111', _, _) => // svc - __field cond 28 +: 4 - __field imm24 0 +: 24 - case () of - when () => __encoding aarch32_SVC_A1_A // SVC_A1 - when ('1111', _, '0x', _, '1x0', _, _, _) => // simd3reg_sameext - __field op1 23 +: 2 - __field D 22 +: 1 - __field op2 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op3 10 +: 1 - __field op4 8 +: 1 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - case (op1, op2, op3, op4, Q, U) of - when ('x1', '0x', '0', '0', '0', '0') => __encoding aarch32_VCADD_A1_A // VCADD_A1_D - when ('x1', '0x', '0', '0', '0', '1') => __UNALLOCATED - when ('x1', '0x', '0', '0', '1', '0') => __encoding aarch32_VCADD_A1_A // VCADD_A1_Q - when ('x1', '0x', '0', '0', '1', '1') => __UNALLOCATED - when ('00', '0x', '0', '0', _, _) => __UNALLOCATED - when ('00', '0x', '0', '1', _, _) => __UNALLOCATED - when ('00', '00', '1', '0', '0', '0') => __UNALLOCATED - when ('00', '00', '1', '0', '0', '1') => __UNALLOCATED - when ('00', '00', '1', '0', '1', '0') => __encoding aarch32_VMMLA_A1_A // VMMLA_A1_Q - when ('00', '00', '1', '0', '1', '1') => __UNALLOCATED - when ('00', '00', '1', '1', '0', '0') => __encoding aarch32_VDOT_bf16_A1_A // VDOT_A1_D - when ('00', '00', '1', '1', '0', '1') => __UNALLOCATED - when ('00', '00', '1', '1', '1', '0') => __encoding aarch32_VDOT_bf16_A1_A // VDOT_A1_Q - when ('00', '00', '1', '1', '1', '1') => __UNALLOCATED - when ('00', '01', '1', '0', _, _) => __UNALLOCATED - when ('00', '01', '1', '1', _, _) => __UNALLOCATED - when ('00', '10', '0', '0', _, '1') => __encoding aarch32_VFMAL_A1_A // VFMAL_A1_Q - when ('00', '10', '0', '1', _, _) => __UNALLOCATED - when ('00', '10', '1', '0', '0', _) => __UNALLOCATED - when ('00', '10', '1', '0', '1', '0') => __encoding aarch32_MMLA_A1_A // VSMMLA_A1_Q - when ('00', '10', '1', '0', '1', '1') => __encoding aarch32_MMLA_A1_A // VUMMLA_A1_Q - when ('00', '10', '1', '1', '0', '0') => __encoding aarch32_VDOT_A1_A // VSDOT_A1_D - when ('00', '10', '1', '1', '0', '1') => __encoding aarch32_VDOT_A1_A // VUDOT_A1_D - when ('00', '10', '1', '1', '1', '0') => __encoding aarch32_VDOT_A1_A // VSDOT_A1_Q - when ('00', '10', '1', '1', '1', '1') => __encoding aarch32_VDOT_A1_A // VUDOT_A1_Q - when ('00', '11', '0', '0', _, '1') => __encoding aarch32_VFMA_bf_A1_A // VFMA_bf_A1_Q - when ('00', '11', '0', '1', _, _) => __UNALLOCATED - when ('00', '11', '1', '0', _, _) => __UNALLOCATED - when ('00', '11', '1', '1', _, _) => __UNALLOCATED - when ('01', '10', '0', '0', _, '1') => __encoding aarch32_VFMAL_A1_A // VFMSL_A1_Q - when ('01', '10', '0', '1', _, _) => __UNALLOCATED - when ('01', '10', '1', '0', '0', _) => __UNALLOCATED - when ('01', '10', '1', '0', '1', '0') => __encoding aarch32_MMLA_A1_A // VUSMMLA_A1_Q - when ('01', '10', '1', '0', '1', '1') => __UNALLOCATED - when ('01', '10', '1', '1', '0', '0') => __encoding aarch32_VUSDOT_A1_A // VUSDOT_A1_D - when ('01', '10', '1', '1', _, '1') => __UNALLOCATED - when ('01', '10', '1', '1', '1', '0') => __encoding aarch32_VUSDOT_A1_A // VUSDOT_A1_Q - when ('01', '11', _, _, _, _) => __UNALLOCATED - when (_, '1x', '0', '0', _, '0') => __encoding aarch32_VCMLA_A1_A // VCMLA_A1_Q - when ('10', '11', _, _, _, _) => __UNALLOCATED - when ('11', '11', _, _, _, _) => __UNALLOCATED - when ('1111', _, '10', _, '1x0', _, _, _) => // simd2reg_scalarext - __field op1 23 +: 1 - __field D 22 +: 1 - __field op2 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op3 10 +: 1 - __field op4 8 +: 1 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - case (op1, op2, op3, op4, Q, U) of - when ('0', _, '0', '0', _, '0') => __encoding aarch32_VCMLA_idx_A1_A // VCMLA_s_A1_QH - when ('0', '00', '0', '0', _, '1') => __encoding aarch32_VFMAL_i_A1_A // VFMAL_s_A1_Q - when ('0', '00', '0', '1', _, _) => __UNALLOCATED - when ('0', '00', '1', '0', _, _) => __UNALLOCATED - when ('0', '00', '1', '1', '0', '0') => __encoding aarch32_VDOT_bf16_i_A1_A // VDOT_s_A1_D - when ('0', '00', '1', '1', _, '1') => __UNALLOCATED - when ('0', '00', '1', '1', '1', '0') => __encoding aarch32_VDOT_bf16_i_A1_A // VDOT_s_A1_Q - when ('0', '01', '0', '0', _, '0') => __UNALLOCATED - when ('0', '01', '0', '0', '0', '1') => __encoding aarch32_VFMAL_i_A1_A // VFMSL_s_A1_D - when ('0', '01', '0', '0', '1', '1') => __encoding aarch32_VFMAL_i_A1_A // VFMSL_s_A1_Q - when ('0', '01', '0', '1', _, _) => __UNALLOCATED - when ('0', '01', '1', '0', _, _) => __UNALLOCATED - when ('0', '10', '0', _, _, _) => __UNALLOCATED - when ('0', '10', '1', '0', _, _) => __UNALLOCATED - when ('0', '10', '1', '1', '0', '0') => __encoding aarch32_VDOT_s_A1_A // VSDOT_s_A1_D - when ('0', '10', '1', '1', '0', '1') => __encoding aarch32_VDOT_s_A1_A // VUDOT_s_A1_D - when ('0', '10', '1', '1', '1', '0') => __encoding aarch32_VDOT_s_A1_A // VSDOT_s_A1_Q - when ('0', '10', '1', '1', '1', '1') => __encoding aarch32_VDOT_s_A1_A // VUDOT_s_A1_Q - when ('0', '11', '0', '0', _, '0') => __UNALLOCATED - when ('0', '11', '0', '0', _, '1') => __encoding aarch32_VFMA_bfs_A1_A // VFMA_bfs_A1_Q - when ('0', '11', '0', '1', _, _) => __UNALLOCATED - when ('0', '11', '1', _, _, _) => __UNALLOCATED - when ('1', _, '0', '0', _, '0') => __encoding aarch32_VCMLA_idx_A1_A // VCMLA_s_A1_QS - when ('1', '00', '1', '1', '0', '0') => __encoding aarch32_DOT_A1_A // VUSDOT_s_A1_D - when ('1', '00', '1', '1', '0', '1') => __encoding aarch32_DOT_A1_A // VSUDOT_s_A1_D - when ('1', '00', '1', '1', '1', '0') => __encoding aarch32_DOT_A1_A // VUSDOT_s_A1_Q - when ('1', '00', '1', '1', '1', '1') => __encoding aarch32_DOT_A1_A // VSUDOT_s_A1_Q - when ('1', _, '0', '1', _, _) => __UNALLOCATED - when ('1', '01', '1', '1', _, _) => __UNALLOCATED - when ('1', '1x', '1', '1', _, _) => __UNALLOCATED - when ('1', _, '1', '0', _, _) => __UNALLOCATED - when (!'1111', _, '0x', _, '10x', _, _, _) => - // simdldst_mov64 - case (28 +: 4, 25 +: 3, 21 +: 4, 12 +: 9, 10 +: 2, 0 +: 10) of - when (_, _, '00x0', _, _, _) => // movsimdfpgp64 - __field cond 28 +: 4 - __field D 22 +: 1 - __field op 20 +: 1 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field size 8 +: 2 - __field opc2 6 +: 2 - __field M 5 +: 1 - __field o3 4 +: 1 - __field Vm 0 +: 4 - case (D, op, size, opc2, o3) of - when ('0', _, _, _, _) => __UNALLOCATED - when ('1', _, _, _, '0') => __UNALLOCATED - when ('1', _, '0x', '00', '1') => __UNALLOCATED - when ('1', _, _, '01', _) => __UNALLOCATED - when ('1', '0', '10', '00', '1') => __encoding aarch32_VMOV_ss_T1A1_A // VMOV_toss_A1 - when ('1', '0', '11', '00', '1') => __encoding aarch32_VMOV_d_T1A1_A // VMOV_tod_A1 - when ('1', _, _, '1x', _) => __UNALLOCATED - when ('1', '1', '10', '00', '1') => __encoding aarch32_VMOV_ss_T1A1_A // VMOV_ss_A1 - when ('1', '1', '11', '00', '1') => __encoding aarch32_VMOV_d_T1A1_A // VMOV_d_A1 - when (_, _, !'00x0', _, _, _) => // ldstsimdfp - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field L 20 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm8 0 +: 8 - case (P, U, W, L, Rn, size, imm8) of - when ('0', '0', '1', _, _, _, _) => __UNALLOCATED - when ('0', '1', _, _, _, '0x', _) => __UNALLOCATED - when ('0', '1', _, '0', _, '10', _) => __encoding aarch32_VSTM_T2A2_A // VSTM_A2 - when ('0', '1', _, '0', _, '11', 'xxxxxxx0') => __encoding aarch32_VSTM_T1A1_A // VSTM_A1 - when ('0', '1', _, '0', _, '11', 'xxxxxxx1') => __encoding aarch32_VSTM_T1A1_A // FSTMIAX_A1 - when ('0', '1', _, '1', _, '10', _) => __encoding aarch32_VLDM_T2A2_A // VLDM_A2 - when ('0', '1', _, '1', _, '11', 'xxxxxxx0') => __encoding aarch32_VLDM_T1A1_A // VLDM_A1 - when ('0', '1', _, '1', _, '11', 'xxxxxxx1') => __encoding aarch32_VLDM_T1A1_A // FLDMIAX_A1 - when ('1', _, '0', '0', _, _, _) => __encoding aarch32_VSTR_A1_A // VSTR_A1_D - when ('1', _, '0', _, _, '00', _) => __UNALLOCATED - when ('1', _, '0', '1', !'1111', _, _) => __encoding aarch32_VLDR_A1_A // VLDR_A1_D - when ('1', '0', '1', _, _, '0x', _) => __UNALLOCATED - when ('1', '0', '1', '0', _, '10', _) => __encoding aarch32_VSTM_T2A2_A // VSTMDB_A2 - when ('1', '0', '1', '0', _, '11', 'xxxxxxx0') => __encoding aarch32_VSTM_T1A1_A // VSTMDB_A1 - when ('1', '0', '1', '0', _, '11', 'xxxxxxx1') => __encoding aarch32_VSTM_T1A1_A // FSTMDBX_A1 - when ('1', '0', '1', '1', _, '10', _) => __encoding aarch32_VLDM_T2A2_A // VLDMDB_A2 - when ('1', '0', '1', '1', _, '11', 'xxxxxxx0') => __encoding aarch32_VLDM_T1A1_A // VLDMDB_A1 - when ('1', '0', '1', '1', _, '11', 'xxxxxxx1') => __encoding aarch32_VLDM_T1A1_A // FLDMDBX_A1 - when ('1', _, '0', '1', '1111', _, _) => __encoding aarch32_VLDR_A1_A // VLDR_l_A1_D - when ('1', '1', '1', _, _, _, _) => __UNALLOCATED - when (!'1111', _, '10', _, '10x', _, '1', _) => - // fpsimd_mov32 - case (28 +: 4, 24 +: 4, 21 +: 3, 12 +: 9, 10 +: 2, 8 +: 2, 5 +: 3, 0 +: 5) of - when (_, _, '000', _, _, '01', _, _) => // movfpgp16 - __field cond 28 +: 4 - __field op 20 +: 1 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - case () of - when () => __encoding aarch32_VMOV_h_A1_A // VMOV_h_A1 - when (_, _, '000', _, _, '10', _, _) => // movfpgp32 - __field cond 28 +: 4 - __field op 20 +: 1 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - case () of - when () => __encoding aarch32_VMOV_s_A1_A // VMOV_s_A1 - when (_, _, '111', _, _, '10', _, _) => // movfpsr - __field cond 28 +: 4 - __field L 20 +: 1 - __field reg 16 +: 4 - __field Rt 12 +: 4 - case (L) of - when ('0') => __encoding aarch32_VMSR_T1A1_AS // VMSR_A1_AS - when ('1') => __encoding aarch32_VMRS_T1A1_AS // VMRS_A1_AS - when (_, _, _, _, _, '11', _, _) => // movsimdgp - __field cond 28 +: 4 - __field opc1 21 +: 3 - __field L 20 +: 1 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - __field opc2 5 +: 2 - case (opc1, L, opc2) of - when ('0xx', '0', _) => __encoding aarch32_VMOV_rs_T1A1_A // VMOV_rs_A1 - when (_, '1', _) => __encoding aarch32_VMOV_sr_T1A1_A // VMOV_sr_A1 - when ('1xx', '0', '0x') => __encoding aarch32_VDUP_r_T1A1_A // VDUP_r_A1 - when ('1xx', '0', '1x') => __UNALLOCATED - when ('1111', '0xx', _, _, _) => - // uncond_as - case (27 +: 5, 25 +: 2, 21 +: 4, 20 +: 1, 0 +: 20) of - when (_, '00', _, _, _) => - // uncondmisc - case (25 +: 7, 20 +: 5, 8 +: 12, 4 +: 4, 0 +: 4) of - when (_, '0xxxx', _, _, _) => __UNPREDICTABLE - when (_, '10000', _, 'xx0x', _) => // cps - __field imod 18 +: 2 - __field M 17 +: 1 - __field op 16 +: 1 - __field E 9 +: 1 - __field A 8 +: 1 - __field I 7 +: 1 - __field F 6 +: 1 - __field mode 0 +: 5 - case (imod, M, op, mode) of - when (_, _, '1', '0xxxx') => __encoding aarch32_SETEND_A1_A // SETEND_A1 - when (_, _, '0', _) => __encoding aarch32_CPS_A1_AS // CPSID_A1_ASM - when (_, _, '1', '1xxxx') => __UNALLOCATED - when (_, '10001', _, '1000', _) => __UNPREDICTABLE - when (_, '10001', _, 'x100', _) => __UNPREDICTABLE - when (_, '10001', _, 'xx01', _) => __UNPREDICTABLE - when (_, '10001', _, '0000', _) => // setpan - __field imm1 9 +: 1 - case () of - when () => __encoding aarch32_SETPAN_A1_A // SETPAN_A1 - when (_, '1000x', _, '0111', _) => __UNPREDICTABLE - when (_, '10010', _, '0111', _) => __UNALLOCATED - when (_, '10011', _, '0111', _) => __UNPREDICTABLE - when (_, '1001x', _, 'xx0x', _) => __UNPREDICTABLE - when (_, '100xx', _, '0011', _) => __UNPREDICTABLE - when (_, '100xx', _, '0x10', _) => __UNPREDICTABLE - when (_, '100xx', _, '1x1x', _) => __UNPREDICTABLE - when (_, '101xx', _, _, _) => __UNPREDICTABLE - when (_, '11xxx', _, _, _) => __UNPREDICTABLE - when (_, '01', _, _, _) => - // advsimddp - case (25 +: 7, 24 +: 1, 23 +: 1, 5 +: 18, 4 +: 1, 0 +: 4) of - when (_, _, '0', _, _, _) => // simd3reg_same - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field opc 8 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field o1 4 +: 1 - __field Vm 0 +: 4 - case (U, size, opc, Q, o1) of - when ('0', '0x', '1100', _, '1') => __encoding aarch32_VFMA_A1_A // VFMA_A1_Q - when ('0', '0x', '1101', _, '0') => __encoding aarch32_VADD_f_A1_A // VADD_f_A1_Q - when ('0', '0x', '1101', _, '1') => __encoding aarch32_VMLA_f_A1_A // VMLA_f_A1_Q - when ('0', '0x', '1110', _, '0') => __encoding aarch32_VCEQ_r_T1A1_A - when ('0', '0x', '1111', _, '0') => __encoding aarch32_VMAX_f_A1_A // VMAX_f_A1_Q - when ('0', '0x', '1111', _, '1') => __encoding aarch32_VRECPS_A1_A // VRECPS_A1_Q - when (_, _, '0000', _, '0') => __encoding aarch32_VHADD_T1A1_A // VHADD_A1_Q - when ('0', '00', '0001', _, '1') => __encoding aarch32_VAND_r_T1A1_A // VAND_r_A1_Q - when (_, _, '0000', _, '1') => __encoding aarch32_VQADD_T1A1_A // VQADD_A1_Q - when (_, _, '0001', _, '0') => __encoding aarch32_VRHADD_T1A1_A // VRHADD_A1_Q - when ('0', '00', '1100', _, '0') => __encoding aarch32_SHA1C_A1_A // SHA1C_A1 - when (_, _, '0010', _, '0') => __encoding aarch32_VHADD_T1A1_A // VHSUB_A1_Q - when ('0', '01', '0001', _, '1') => __encoding aarch32_VBIC_r_T1A1_A // VBIC_r_A1_Q - when (_, _, '0010', _, '1') => __encoding aarch32_VQSUB_T1A1_A // VQSUB_A1_Q - when (_, _, '0011', _, '0') => __encoding aarch32_VCGT_r_T1A1_A - when (_, _, '0011', _, '1') => __encoding aarch32_VCGE_r_T1A1_A - when ('0', '01', '1100', _, '0') => __encoding aarch32_SHA1P_A1_A // SHA1P_A1 - when ('0', '1x', '1100', _, '1') => __encoding aarch32_VFMA_A1_A // VFMS_A1_Q - when ('0', '1x', '1101', _, '0') => __encoding aarch32_VSUB_f_A1_A // VSUB_f_A1_Q - when ('0', '1x', '1101', _, '1') => __encoding aarch32_VMLA_f_A1_A // VMLS_f_A1_Q - when ('0', '1x', '1110', _, '0') => __UNALLOCATED - when ('0', '1x', '1111', _, '0') => __encoding aarch32_VMAX_f_A1_A // VMIN_f_A1_Q - when ('0', '1x', '1111', _, '1') => __encoding aarch32_VRSQRTS_A1_A // VRSQRTS_A1_Q - when (_, _, '0100', _, '0') => __encoding aarch32_VSHL_r_T1A1_A // VSHL_r_A1_Q - when ('0', _, '1000', _, '0') => __encoding aarch32_VADD_i_T1A1_A // VADD_i_A1_Q - when ('0', '10', '0001', _, '1') => __encoding aarch32_VORR_r_T1A1_A // VORR_r_A1_Q - when ('0', _, '1000', _, '1') => __encoding aarch32_VTST_T1A1_A // VTST_A1_Q - when (_, _, '0100', _, '1') => __encoding aarch32_VQSHL_r_T1A1_A // VQSHL_r_A1_Q - when ('0', _, '1001', _, '0') => __encoding aarch32_VMLA_i_T1A1_A // VMLA_i_A1_Q - when (_, _, '0101', _, '0') => __encoding aarch32_VRSHL_T1A1_A // VRSHL_A1_Q - when (_, _, '0101', _, '1') => __encoding aarch32_VQRSHL_T1A1_A // VQRSHL_A1_Q - when ('0', _, '1011', _, '0') => __encoding aarch32_VQDMULH_T1A1_A // VQDMULH_A1_Q - when ('0', '10', '1100', _, '0') => __encoding aarch32_SHA1M_A1_A // SHA1M_A1 - when ('0', _, '1011', _, '1') => __encoding aarch32_VPADD_i_T1A1_A // VPADD_i_A1 - when (_, _, '0110', _, '0') => __encoding aarch32_VMAX_i_T1A1_A // VMAX_i_A1_Q - when ('0', '11', '0001', _, '1') => __encoding aarch32_VORN_r_T1A1_A // VORN_r_A1_Q - when (_, _, '0110', _, '1') => __encoding aarch32_VMAX_i_T1A1_A // VMIN_i_A1_Q - when (_, _, '0111', _, '0') => __encoding aarch32_VABD_i_T1A1_A // VABD_i_A1_Q - when (_, _, '0111', _, '1') => __encoding aarch32_VABA_T1A1_A // VABA_A1_Q - when ('0', '11', '1100', _, '0') => __encoding aarch32_SHA1SU0_A1_A // SHA1SU0_A1 - when ('1', '0x', '1101', _, '0') => __encoding aarch32_VPADD_f_A1_A // VPADD_f_A1 - when ('1', '0x', '1101', _, '1') => __encoding aarch32_VMUL_f_A1_A // VMUL_f_A1_Q - when ('1', '0x', '1110', _, '0') => __encoding aarch32_VCGE_r_T1A1_A - when ('1', '0x', '1110', _, '1') => __encoding aarch32_VACGE_A1_A // VACGE_A1_Q - when ('1', '0x', '1111', '0', '0') => __encoding aarch32_VPMAX_f_A1_A // VPMAX_f_A1 - when ('1', '0x', '1111', _, '1') => __encoding aarch32_VMAXNM_A1_A // VMAXNM_A1_Q - when ('1', '00', '0001', _, '1') => __encoding aarch32_VEOR_T1A1_A // VEOR_A1_Q - when (_, _, '1001', _, '1') => __encoding aarch32_VMUL_i_T1A1_A // VMUL_i_A1_Q - when ('1', '00', '1100', _, '0') => __encoding aarch32_SHA256H_A1_A // SHA256H_A1 - when (_, _, '1010', '0', '0') => __encoding aarch32_VPMAX_i_T1A1_A // VPMAX_i_A1 - when ('1', '01', '0001', _, '1') => __encoding aarch32_VBIF_T1A1_A // VBSL_A1_Q - when (_, _, '1010', '0', '1') => __encoding aarch32_VPMAX_i_T1A1_A // VPMIN_i_A1 - when (_, _, '1010', '1', _) => __UNALLOCATED - when ('1', '01', '1100', _, '0') => __encoding aarch32_SHA256H2_A1_A // SHA256H2_A1 - when ('1', '1x', '1101', _, '0') => __encoding aarch32_VABD_f_A1_A // VABD_f_A1_Q - when ('1', '1x', '1110', _, '0') => __encoding aarch32_VCGT_r_T1A1_A - when ('1', '1x', '1110', _, '1') => __encoding aarch32_VACGE_A1_A // VACGT_A1_Q - when ('1', '1x', '1111', '0', '0') => __encoding aarch32_VPMAX_f_A1_A // VPMIN_f_A1 - when ('1', '1x', '1111', _, '1') => __encoding aarch32_VMAXNM_A1_A // VMINNM_A1_Q - when ('1', _, '1000', _, '0') => __encoding aarch32_VSUB_i_T1A1_A // VSUB_i_A1_Q - when ('1', '10', '0001', _, '1') => __encoding aarch32_VBIF_T1A1_A // VBIT_A1_Q - when ('1', _, '1000', _, '1') => __encoding aarch32_VCEQ_r_T1A1_A - when ('1', _, '1001', _, '0') => __encoding aarch32_VMLA_i_T1A1_A // VMLS_i_A1_Q - when ('1', _, '1011', _, '0') => __encoding aarch32_VQRDMULH_T1A1_A // VQRDMULH_A1_Q - when ('1', '10', '1100', _, '0') => __encoding aarch32_SHA256SU1_A1_A // SHA256SU1_A1 - when ('1', _, '1011', _, '1') => __encoding aarch32_VQRDMLAH_A1_A // VQRDMLAH_A1_Q - when ('1', '11', '0001', _, '1') => __encoding aarch32_VBIF_T1A1_A // VBIF_A1_Q - when ('1', _, '1100', _, '1') => __encoding aarch32_VQRDMLSH_A1_A // VQRDMLSH_A1_Q - when ('1', _, '1111', '1', '0') => __UNALLOCATED - when (_, _, '1', _, '0', _) => - // a_simd_mulreg - case (25 +: 7, 24 +: 1, 23 +: 1, 22 +: 1, 20 +: 2, 12 +: 8, 10 +: 2, 7 +: 3, 6 +: 1, 5 +: 1, 4 +: 1, 0 +: 4) of - when (_, '0', _, _, '11', _, _, _, _, _, _, _) => // simd3reg_ext - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field imm4 8 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case () of - when () => __encoding aarch32_VEXT_T1A1_A // VEXT_A1_Q - when (_, '1', _, _, '11', _, '0x', _, _, _, _, _) => // simd2reg_misc - __field D 22 +: 1 - __field size 18 +: 2 - __field opc1 16 +: 2 - __field Vd 12 +: 4 - __field opc2 7 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (size, opc1, opc2, Q) of - when (_, '00', '0000', _) => __encoding aarch32_VREV16_T1A1_A // VREV64_A1_Q - when (_, '00', '0001', _) => __encoding aarch32_VREV16_T1A1_A // VREV32_A1_Q - when (_, '00', '0010', _) => __encoding aarch32_VREV16_T1A1_A // VREV16_A1_Q - when (_, '00', '0011', _) => __UNALLOCATED - when (_, '00', '010x', _) => __encoding aarch32_VPADDL_T1A1_A // VPADDL_A1_Q - when (_, '00', '0110', '0') => __encoding aarch32_AESE_A1_A // AESE_A1 - when (_, '00', '0110', '1') => __encoding aarch32_AESD_A1_A // AESD_A1 - when (_, '00', '0111', '0') => __encoding aarch32_AESMC_A1_A // AESMC_A1 - when (_, '00', '0111', '1') => __encoding aarch32_AESIMC_A1_A // AESIMC_A1 - when (_, '00', '1000', _) => __encoding aarch32_VCLS_T1A1_A // VCLS_A1_Q - when ('00', '10', '0000', _) => __encoding aarch32_VSWP_T1A1_A // VSWP_A1_Q - when (_, '00', '1001', _) => __encoding aarch32_VCLZ_T1A1_A // VCLZ_A1_Q - when (_, '00', '1010', _) => __encoding aarch32_VCNT_T1A1_A // VCNT_A1_Q - when (_, '00', '1011', _) => __encoding aarch32_VMVN_r_T1A1_A // VMVN_r_A1_Q - when ('00', '10', '1100', '1') => __UNALLOCATED - when (_, '00', '110x', _) => __encoding aarch32_VPADAL_T1A1_A // VPADAL_A1_Q - when (_, '00', '1110', _) => __encoding aarch32_VQABS_T1A1_A // VQABS_A1_Q - when (_, '00', '1111', _) => __encoding aarch32_VQNEG_T1A1_A // VQNEG_A1_Q - when (_, '01', 'x000', _) => __encoding aarch32_VCGT_i_A1_A // VCGT_i_A1_Q - when (_, '01', 'x001', _) => __encoding aarch32_VCGE_i_A1_A // VCGE_i_A1_Q - when (_, '01', 'x010', _) => __encoding aarch32_VCEQ_i_A1_A // VCEQ_i_A1_Q - when (_, '01', 'x011', _) => __encoding aarch32_VCLE_i_A1_A // VCLE_i_A1_Q - when (_, '01', 'x100', _) => __encoding aarch32_VCLT_i_A1_A // VCLT_i_A1_Q - when (_, '01', 'x110', _) => __encoding aarch32_VABS_A1_A // VABS_A1_Q - when (_, '01', 'x111', _) => __encoding aarch32_VNEG_A1_A // VNEG_A1_Q - when (_, '01', '0101', '1') => __encoding aarch32_SHA1H_A1_A // SHA1H_A1 - when ('01', '10', '1100', '1') => __encoding aarch32_VCVT_T1A1_A // VCVT_bfs_A1 - when (_, '10', '0001', _) => __encoding aarch32_VTRN_T1A1_A // VTRN_A1_Q - when (_, '10', '0010', _) => __encoding aarch32_VUZP_T1A1_A // VUZP_A1_Q - when (_, '10', '0011', _) => __encoding aarch32_VZIP_T1A1_A // VZIP_A1_Q - when (_, '10', '0100', '0') => __encoding aarch32_VMOVN_T1A1_A // VMOVN_A1 - when (_, '10', '0100', '1') => __encoding aarch32_VQMOVN_T1A1_A // VQMOVUN_A1 - when (_, '10', '0101', _) => __encoding aarch32_VQMOVN_T1A1_A // VQMOVN_A1 - when (_, '10', '0110', '0') => __encoding aarch32_VSHLL_T2A2_A // VSHLL_A2 - when (_, '10', '0111', '0') => __encoding aarch32_SHA1SU1_A1_A // SHA1SU1_A1 - when (_, '10', '0111', '1') => __encoding aarch32_SHA256SU0_A1_A // SHA256SU0_A1 - when (_, '10', '1000', _) => __encoding aarch32_VRINTA_asimd_A1_A // VRINTN_asimd_A1_Q - when (_, '10', '1001', _) => __encoding aarch32_VRINTX_asimd_A1_A // VRINTX_asimd_A1_Q - when (_, '10', '1010', _) => __encoding aarch32_VRINTA_asimd_A1_A // VRINTA_asimd_A1_Q - when (_, '10', '1011', _) => __encoding aarch32_VRINTZ_asimd_A1_A // VRINTZ_asimd_A1_Q - when ('10', '10', '1100', '1') => __UNALLOCATED - when (_, '10', '1100', '0') => __encoding aarch32_VCVT_hs_T1A1_A // VCVT_hs_A1 - when (_, '10', '1101', _) => __encoding aarch32_VRINTA_asimd_A1_A // VRINTM_asimd_A1_Q - when (_, '10', '1110', '0') => __encoding aarch32_VCVT_hs_T1A1_A // VCVT_sh_A1 - when (_, '10', '1110', '1') => __UNALLOCATED - when (_, '10', '1111', _) => __encoding aarch32_VRINTA_asimd_A1_A // VRINTP_asimd_A1_Q - when (_, '11', '000x', _) => __encoding aarch32_VCVTA_asimd_A1_A // VCVTA_asimd_A1_Q - when (_, '11', '001x', _) => __encoding aarch32_VCVTA_asimd_A1_A // VCVTN_asimd_A1_Q - when (_, '11', '010x', _) => __encoding aarch32_VCVTA_asimd_A1_A // VCVTP_asimd_A1_Q - when (_, '11', '011x', _) => __encoding aarch32_VCVTA_asimd_A1_A // VCVTM_asimd_A1_Q - when (_, '11', '10x0', _) => __encoding aarch32_VRECPE_A1_A // VRECPE_A1_Q - when (_, '11', '10x1', _) => __encoding aarch32_VRSQRTE_A1_A // VRSQRTE_A1_Q - when ('11', '10', '1100', '1') => __UNALLOCATED - when (_, '11', '11xx', _) => __encoding aarch32_VCVT_is_A1_A // VCVT_is_A1_Q - when (_, '1', _, _, '11', _, '10', _, _, _, _, _) => // simd3reg_tbl - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field len 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case () of - when () => __encoding aarch32_VTBL_T1A1_A // VTBX_A1 - when (_, '1', _, _, '11', _, '11', _, _, _, _, _) => // simd2reg_dup - __field D 22 +: 1 - __field imm4 16 +: 4 - __field Vd 12 +: 4 - __field opc 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (opc) of - when ('000') => __encoding aarch32_VDUP_s_T1A1_A // VDUP_s_A1_Q - when ('001') => __UNALLOCATED - when ('01x') => __UNALLOCATED - when ('1xx') => __UNALLOCATED - when (_, _, _, _, !'11', _, _, _, '0', _, _, _) => // simd3reg_diff - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field opc 8 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (U, opc) of - when (_, '0000') => __encoding aarch32_VADDL_T1A1_A // VADDL_A1 - when (_, '0001') => __encoding aarch32_VADDL_T1A1_A // VADDW_A1 - when (_, '0010') => __encoding aarch32_VSUBL_T1A1_A // VSUBL_A1 - when ('0', '0100') => __encoding aarch32_VADDHN_T1A1_A // VADDHN_A1 - when (_, '0011') => __encoding aarch32_VSUBL_T1A1_A // VSUBW_A1 - when ('0', '0110') => __encoding aarch32_VSUBHN_T1A1_A // VSUBHN_A1 - when ('0', '1001') => __encoding aarch32_VQDMLAL_T1A1_A // VQDMLAL_A1 - when (_, '0101') => __encoding aarch32_VABA_T2A2_A // VABAL_A1 - when ('0', '1011') => __encoding aarch32_VQDMLSL_T1A1_A // VQDMLSL_A1 - when ('0', '1101') => __encoding aarch32_VQDMULL_T1A1_A // VQDMULL_A1 - when (_, '0111') => __encoding aarch32_VABD_i_T2A2_A // VABDL_i_A1 - when (_, '1000') => __encoding aarch32_VMLA_i_T2A2_A // VMLAL_i_A1 - when (_, '1010') => __encoding aarch32_VMLA_i_T2A2_A // VMLSL_i_A1 - when ('1', '0100') => __encoding aarch32_VRADDHN_T1A1_A // VRADDHN_A1 - when ('1', '0110') => __encoding aarch32_VRSUBHN_T1A1_A // VRSUBHN_A1 - when (_, '11x0') => __encoding aarch32_VMUL_i_A2_A // VMULL_i_A1 - when ('1', '1001') => __UNALLOCATED - when ('1', '1011') => __UNALLOCATED - when ('1', '1101') => __UNALLOCATED - when (_, '1111') => __UNALLOCATED - when (_, _, _, _, !'11', _, _, _, '1', _, _, _) => // simd2reg_scalar - __field Q 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field opc 8 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (Q, opc) of - when (_, '000x') => __encoding aarch32_VMLA_s_A1_A // VMLA_s_A1_Q - when ('0', '0011') => __encoding aarch32_VQDMLAL_T2A2_A // VQDMLAL_A2 - when (_, '0010') => __encoding aarch32_VMLA_s_T2A2_A // VMLAL_s_A1 - when ('0', '0111') => __encoding aarch32_VQDMLSL_T2A2_A // VQDMLSL_A2 - when (_, '010x') => __encoding aarch32_VMLA_s_A1_A // VMLS_s_A1_Q - when ('0', '1011') => __encoding aarch32_VQDMULL_T2A2_A // VQDMULL_A2 - when (_, '0110') => __encoding aarch32_VMLA_s_T2A2_A // VMLSL_s_A1 - when (_, '100x') => __encoding aarch32_VMUL_s_A1_A // VMUL_s_A1_Q - when ('1', '0011') => __UNALLOCATED - when (_, '1010') => __encoding aarch32_VMUL_s_T2A2_A // VMULL_s_A1 - when ('1', '0111') => __UNALLOCATED - when (_, '1100') => __encoding aarch32_VQDMULH_T2A2_A // VQDMULH_A2_Q - when (_, '1101') => __encoding aarch32_VQRDMULH_T2A2_A // VQRDMULH_A2_Q - when ('1', '1011') => __UNALLOCATED - when (_, '1110') => __encoding aarch32_VQRDMLAH_A2_A // VQRDMLAH_A2_Q - when (_, '1111') => __encoding aarch32_VQRDMLSH_A2_A // VQRDMLSH_A2_Q - when (_, _, '1', _, '1', _) => - // a_simd_12reg - case (25 +: 7, 24 +: 1, 23 +: 1, 22 +: 1, 7 +: 15, 5 +: 2, 4 +: 1, 0 +: 4) of - when (_, _, _, _, '000xxxxxxxxxxx0', _, _, _) => // simd1reg_imm - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - case (cmode, op) of - when ('0xx0', '0') => __encoding aarch32_VMOV_i_T1A1_A - when ('0xx0', '1') => __encoding aarch32_VMVN_i_T1A1_A - when ('0xx1', '0') => __encoding aarch32_VORR_i_T1A1_A - when ('0xx1', '1') => __encoding aarch32_VBIC_i_T1A1_A - when ('10x0', '0') => __encoding aarch32_VMOV_i_T1A1_A - when ('10x0', '1') => __encoding aarch32_VMVN_i_T1A1_A - when ('10x1', '0') => __encoding aarch32_VORR_i_T1A1_A - when ('10x1', '1') => __encoding aarch32_VBIC_i_T1A1_A - when ('11xx', '0') => __encoding aarch32_VMOV_i_T1A1_A - when ('110x', '1') => __encoding aarch32_VMVN_i_T1A1_A - when ('1110', '1') => __encoding aarch32_VMOV_i_T1A1_A - when ('1111', '1') => __UNALLOCATED - when (_, _, _, _, !'000xxxxxxxxxxx0', _, _, _) => // simd2reg_shift - __field U 24 +: 1 - __field D 22 +: 1 - __field imm3H 19 +: 3 - __field imm3L 16 +: 3 - __field Vd 12 +: 4 - __field opc 8 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - case (U, imm3H:L, imm3L, opc, Q) of - when (_, !'0000', _, '0000', _) => __encoding aarch32_VSHR_T1A1_A // VSHR_A1_Q - when (_, !'0000', _, '0001', _) => __encoding aarch32_VSRA_T1A1_A // VSRA_A1_Q - when (_, !'0000', '000', '1010', '0') => __encoding aarch32_VMOVL_T1A1_A // VMOVL_A1 - when (_, !'0000', _, '0010', _) => __encoding aarch32_VRSHR_T1A1_A // VRSHR_A1_Q - when (_, !'0000', _, '0011', _) => __encoding aarch32_VRSRA_T1A1_A // VRSRA_A1_D - when (_, !'0000', _, '0111', _) => __encoding aarch32_VQSHL_i_T1A1_A // VQSHL_i_A1_Q - when (_, !'0000', _, '1001', '0') => __encoding aarch32_VQSHRN_T1A1_A // VQSHRN_A1 - when (_, !'0000', _, '1001', '1') => __encoding aarch32_VQRSHRN_T1A1_A // VQRSHRN_A1 - when (_, !'0000', _, '1010', '0') => __encoding aarch32_VSHLL_T1A1_A // VSHLL_A1 - when (_, !'0000', _, '11xx', _) => __encoding aarch32_VCVT_xs_A1_A // VCVT_xs_A1_Q - when ('0', !'0000', _, '0101', _) => __encoding aarch32_VSHL_i_T1A1_A // VSHL_i_A1_Q - when ('0', !'0000', _, '1000', '0') => __encoding aarch32_VSHRN_T1A1_A // VSHRN_A1 - when ('0', !'0000', _, '1000', '1') => __encoding aarch32_VRSHRN_T1A1_A // VRSHRN_A1 - when ('1', !'0000', _, '0100', _) => __encoding aarch32_VSRI_T1A1_A // VSRI_A1_Q - when ('1', !'0000', _, '0101', _) => __encoding aarch32_VSLI_T1A1_A // VSLI_A1_Q - when ('1', !'0000', _, '0110', _) => __encoding aarch32_VQSHL_i_T1A1_A // VQSHLU_i_A1_Q - when ('1', !'0000', _, '1000', '0') => __encoding aarch32_VQSHRN_T1A1_A // VQSHRUN_A1 - when ('1', !'0000', _, '1000', '1') => __encoding aarch32_VQRSHRN_T1A1_A // VQRSHRUN_A1 - when (_, '1x', _, '1', _) => - // uncondhints - case (26 +: 6, 21 +: 5, 20 +: 1, 5 +: 15, 4 +: 1, 0 +: 4) of - when (_, '00xx1', _, _, _, _) => __UNALLOCATED - when (_, '01001', _, _, _, _) => __UNALLOCATED - when (_, '01011', _, _, _, _) => // barriers - __field opcode 4 +: 4 - __field option 0 +: 4 - case (opcode, option) of - when ('0000', _) => __UNPREDICTABLE - when ('0001', _) => __encoding aarch32_CLREX_A1_A // CLREX_A1 - when ('001x', _) => __UNPREDICTABLE - when ('0100', !'0x00') => __encoding aarch32_DSB_A1_A // DSB_A1 - when ('0100', '0000') => __encoding aarch32_SSBB_A1_A // SSBB_A1 - when ('0100', '0100') => __encoding aarch32_PSSBB_A1_A // PSSBB_A1 - when ('0101', _) => __encoding aarch32_DMB_A1_A // DMB_A1 - when ('0110', _) => __encoding aarch32_ISB_A1_A // ISB_A1 - when ('0111', _) => __encoding aarch32_SB_A1_A // SB_A1 - when ('1xxx', _) => __UNPREDICTABLE - when (_, '011x1', _, _, _, _) => __UNALLOCATED - when (_, '0xxx0', _, _, _, _) => // preload_imm - __field D 24 +: 1 - __field U 23 +: 1 - __field R 22 +: 1 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - case (D, R, Rn) of - when ('0', '0', _) => __NOP - when ('0', '1', _) => __encoding aarch32_PLI_i_A1_A // PLI_i_A1 - when ('1', _, '1111') => __encoding aarch32_PLD_l_A1_A // PLD_l_A1 - when ('1', '0', !'1111') => __encoding aarch32_PLD_i_A1_A // PLDW_i_A1 - when ('1', '1', !'1111') => __encoding aarch32_PLD_i_A1_A // PLD_i_A1 - when (_, '1xxx0', _, _, '0', _) => // preload_reg - __field D 24 +: 1 - __field U 23 +: 1 - __field o2 22 +: 1 - __field Rn 16 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - case (D, o2) of - when ('0', '0') => __NOP - when ('0', '1') => __encoding aarch32_PLI_r_A1_A // PLI_r_A1_RRX - when ('1', '0') => __encoding aarch32_PLD_r_A1_A // PLDW_r_A1_RRX - when ('1', '1') => __encoding aarch32_PLD_r_A1_A // PLD_r_A1_RRX - when (_, '1xxx1', _, _, '0', _) => __UNALLOCATED - when (_, '1xxxx', _, _, '1', _) => __UNPREDICTABLE - when (_, '10', _, '0', _) => - // advsimdls - case (24 +: 8, 23 +: 1, 21 +: 2, 20 +: 1, 12 +: 8, 10 +: 2, 0 +: 10) of - when (_, '0', _, _, _, _, _) => // ldstv_ms - __field D 22 +: 1 - __field L 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - case (L, itype) of - when ('0', '000x') => __encoding aarch32_VST4_m_T1A1_A // VST4_m_A1_posti - when ('0', '0010') => __encoding aarch32_VST1_m_T1A1_A - when ('0', '0011') => __encoding aarch32_VST2_m_T1A1_A - when ('0', '010x') => __encoding aarch32_VST3_m_T1A1_A // VST3_m_A1_posti - when ('0', '0110') => __encoding aarch32_VST1_m_T1A1_A - when ('0', '0111') => __encoding aarch32_VST1_m_T1A1_A - when ('0', '100x') => __encoding aarch32_VST2_m_T1A1_A - when ('0', '1010') => __encoding aarch32_VST1_m_T1A1_A - when ('1', '000x') => __encoding aarch32_VLD4_m_T1A1_A // VLD4_m_A1_posti - when ('1', '0010') => __encoding aarch32_VLD1_m_T1A1_A - when ('1', '0011') => __encoding aarch32_VLD2_m_T1A1_A - when ('1', '010x') => __encoding aarch32_VLD3_m_T1A1_A // VLD3_m_A1_posti - when (_, '1011') => __UNALLOCATED - when ('1', '0110') => __encoding aarch32_VLD1_m_T1A1_A - when ('1', '0111') => __encoding aarch32_VLD1_m_T1A1_A - when (_, '11xx') => __UNALLOCATED - when ('1', '100x') => __encoding aarch32_VLD2_m_T1A1_A - when ('1', '1010') => __encoding aarch32_VLD1_m_T1A1_A - when (_, '1', _, _, _, '11', _) => // ldv_ssall - __field D 22 +: 1 - __field L 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field N 8 +: 2 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - case (L, N, a) of - when ('0', _, _) => __UNALLOCATED - when ('1', '00', _) => __encoding aarch32_VLD1_a_T1A1_A // VLD1_a_A1_posti - when ('1', '01', _) => __encoding aarch32_VLD2_a_T1A1_A // VLD2_a_A1_posti - when ('1', '10', '0') => __encoding aarch32_VLD3_a_T1A1_A // VLD3_a_A1_posti - when ('1', '10', '1') => __UNALLOCATED - when ('1', '11', _) => __encoding aarch32_VLD4_a_T1A1_A // VLD4_a_A1_posti - when (_, '1', _, _, _, !'11', _) => // ldstv_ssone - __field D 22 +: 1 - __field L 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field N 8 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - case (L, size, N, Rm) of - when ('0', '00', '00', _) => __encoding aarch32_VST1_1_T1A1_A - when ('0', '00', '01', _) => __encoding aarch32_VST2_1_T1A1_A - when ('0', '00', '10', _) => __encoding aarch32_VST3_1_T1A1_A - when ('0', '00', '11', _) => __encoding aarch32_VST4_1_T1A1_A // VST4_1_A1_posti - when ('0', '01', '00', _) => __encoding aarch32_VST1_1_T1A1_A - when ('0', '01', '01', _) => __encoding aarch32_VST2_1_T1A1_A - when ('0', '01', '10', _) => __encoding aarch32_VST3_1_T1A1_A - when ('0', '01', '11', _) => __encoding aarch32_VST4_1_T2A2_A // VST4_1_A2_posti - when ('0', '10', '00', _) => __encoding aarch32_VST1_1_T1A1_A - when ('0', '10', '01', _) => __encoding aarch32_VST2_1_T1A1_A - when ('0', '10', '10', _) => __encoding aarch32_VST3_1_T1A1_A - when ('0', '10', '11', !'11x1') => __encoding aarch32_VST4_1_T3A3_A // VST4_1_A3_postr - when ('0', '10', '11', '1101') => __encoding aarch32_VST4_1_T3A3_A // VST4_1_A3_posti - when ('0', '10', '11', '1111') => __encoding aarch32_VST4_1_T3A3_A // VST4_1_A3_nowb - when ('1', '00', '00', _) => __encoding aarch32_VLD1_1_T1A1_A - when ('1', '00', '01', _) => __encoding aarch32_VLD2_1_T1A1_A - when ('1', '00', '10', _) => __encoding aarch32_VLD3_1_T1A1_A - when ('1', '00', '11', _) => __encoding aarch32_VLD4_1_T1A1_A - when ('1', '01', '00', _) => __encoding aarch32_VLD1_1_T1A1_A - when ('1', '01', '01', _) => __encoding aarch32_VLD2_1_T1A1_A - when ('1', '01', '10', _) => __encoding aarch32_VLD3_1_T1A1_A - when ('1', '01', '11', _) => __encoding aarch32_VLD4_1_T1A1_A - when ('1', '10', '00', _) => __encoding aarch32_VLD1_1_T1A1_A - when ('1', '10', '01', _) => __encoding aarch32_VLD2_1_T1A1_A - when ('1', '10', '10', _) => __encoding aarch32_VLD3_1_T1A1_A - when ('1', '10', '11', _) => __encoding aarch32_VLD4_1_T1A1_A - when (_, '11', _, '0', _) => __UNPREDICTABLE diff --git a/mra_tools/arch/arch_instrs.asl b/mra_tools/arch/arch_instrs.asl deleted file mode 100644 index 8f165ae5..00000000 --- a/mra_tools/arch/arch_instrs.asl +++ /dev/null @@ -1,91584 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// Proprietary Notice -// -// This document is protected by copyright and other related rights -// and the practice or implementation of the information contained in -// this document may be protected by one or more patents or pending -// patent applications. No part of this document may be reproduced in any -// form by any means without the express prior written permission of -// Arm. No license, express or implied, by estoppel or otherwise to -// any intellectual property rights is granted by this document unless -// specifically stated. -// -// Your access to the information in this document is conditional upon -// your acceptance that you will not use or permit others to use the -// information for the purposes of determining whether implementations -// infringe any third party patents. -// -// THIS DOCUMENT IS PROVIDED "AS IS". ARM PROVIDES NO REPRESENTATIONS -// AND NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT -// LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY -// QUALITY, NON-INFRINGEMENT OR FITNESS FOR A PARTICULAR PURPOSE WITH -// RESPECT TO THE DOCUMENT. For the avoidance of doubt, Arm makes no -// representation with respect to, and has undertaken no analysis to -// identify or understand the scope and content of, patents, copyrights, -// trade secrets, or other rights. -// -// This document may include technical inaccuracies or typographical -// errors. -// -// TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL ARM BE -// LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION ANY DIRECT, -// INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES, -// HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT -// OF ANY USE OF THIS DOCUMENT, EVEN IF ARM HAS BEEN ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGES. -// -// This document consists solely of commercial items. You shall be -// responsible for ensuring that any use, duplication or disclosure of -// this document complies fully with any relevant export laws and -// regulations to assure that this document or any portion thereof is not -// exported, directly or indirectly, in violation of such export -// laws. Use of the word "partner" in reference to Arm's customers is not -// intended to create or refer to any partnership relationship with any -// other company. Arm may make changes to this document at any time and -// without notice. -// -// If any of the provisions contained in these terms conflict with -// any of the provisions of any click through or signed written agreement -// covering this document with Arm, then the click through or signed -// written agreement prevails over and supersedes the conflicting -// provisions of these terms. This document may be translated into other -// languages for convenience, and you agree that if there is any conflict -// between the English version of this document and any translation, the -// terms of the English version of the Agreement shall prevail. -// -// The Arm corporate logo and words marked with (R) or (TM)(TM) -// are registered trademarks or trademarks of Arm Limited (or its -// subsidiaries) in the US and/or elsewhere. All rights reserved. Other -// brands and names mentioned in this document may be the trademarks of -// their respective owners. Please follow Arm's trademark usage -// guidelines at -// http://www.arm.com/company/policies/trademarks. -// -// Copyright (C) 2019 Arm Limited (or its affiliates). All rights reserved. -// -// Arm Limited. Company 02557590 registered in England. -// -// 110 Fulbourn Road, Cambridge, England CB1 9NJ. -// -// LES-PRE-20349 -//////////////////////////////////////////////////////////////////////// - -__instruction aarch32_VFMAL_i_A - __encoding aarch32_VFMAL_i_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field S 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x01xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - - integer d = UInt(D:Vd); - integer n = if Q == '1' then UInt(N:Vn) else UInt(Vn:N); - integer m = if Q == '1' then UInt(Vm[2:0]) else UInt(Vm[2:0]:M); - - integer index = if Q == '1' then UInt(M:Vm[3]) else UInt(Vm[3]); - integer esize = 32; - integer regs = if Q=='1' then 2 else 1; - integer datasize = if Q=='1' then 64 else 32; - boolean sub_op = S=='1'; - - __encoding aarch32_VFMAL_i_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field S 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x01xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - - integer d = UInt(D:Vd); - integer n = if Q == '1' then UInt(N:Vn) else UInt(Vn:N); - integer m = if Q == '1' then UInt(Vm[2:0]) else UInt(Vm[2:0]:M); - - integer index = if Q == '1' then UInt(M:Vm[3]) else UInt(Vm[3]); - integer esize = 32; - integer regs = if Q=='1' then 2 else 1; - integer datasize = if Q=='1' then 64 else 32; - boolean sub_op = S=='1'; - - __execute - CheckAdvSIMDEnabled(); - bits(datasize) operand1 ; - bits(datasize) operand2 ; - bits(64) operand3; - bits(64) result; - bits(esize DIV 2) element1; - bits(esize DIV 2) element2; - - if Q=='0' then - operand1 = S[n][datasize-1:0]; - operand2 = S[m][datasize-1:0]; - else - operand1 = D[n][datasize-1:0]; - operand2 = D[m][datasize-1:0]; - element2 = Elem[operand2, index, esize DIV 2]; - for r = 0 to regs-1 - operand3 = D[d+r]; - for e = 0 to 1 - element1 = Elem[operand1, 2*r+e, esize DIV 2]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAddH(Elem[operand3, e, esize], element1, element2, StandardFPSCRValue()); - D[d+r] = result; - -__instruction aarch32_VCVTA_vfp_A - __encoding aarch32_VCVTA_vfp_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111110 xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '0'); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - - __encoding aarch32_VCVTA_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111110 xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '0'); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - - __execute - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = FPToFixed(S[m][15:0], 0, unsigned, FPSCR, rounding); - when 32 - S[d] = FPToFixed(S[m], 0, unsigned, FPSCR, rounding); - when 64 - S[d] = FPToFixed(D[m], 0, unsigned, FPSCR, rounding); - -__instruction aarch32_VSUBHN_A - __encoding aarch32_VSUBHN_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx0110 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VSUBHN_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx0110 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - result = Elem[Qin[n>>1],e,2*esize] - Elem[Qin[m>>1],e,2*esize]; - Elem[D[d],e,esize] = result[2*esize-1:esize]; - -__instruction aarch32_VST4_m_A - __encoding aarch32_VST4_m_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x00xxxx xxxx000x xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - case itype of - when '0000' - inc = 1; - when '0001' - inc = 2; - otherwise - SEE "Related encodings"; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST4_m_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x00xxxx xxxx000x xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - case itype of - when '0000' - inc = 1; - when '0001' - inc = 2; - otherwise - SEE "Related encodings"; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = TRUE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - for e = 0 to elements-1 - MemU[address, ebytes] = Elem[D[d], e]; - MemU[address+ebytes, ebytes] = Elem[D[d2],e]; - MemU[address+2*ebytes,ebytes] = Elem[D[d3],e]; - MemU[address+3*ebytes,ebytes] = Elem[D[d4],e]; - address = address + 4*ebytes; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 32; - -__instruction aarch32_VLD1_a_A - __encoding aarch32_VLD1_a_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx1100 xxxxxxxx' - __guard TRUE - __decode - if size == '11' || (size == '00' && a == '1') then UNDEFINED; - ebytes = 1 << UInt(size); regs = if T == '0' then 1 else 2; - alignment = if a == '0' then 1 else ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD1_a_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx1100 xxxxxxxx' - __guard TRUE - __decode - if size == '11' || (size == '00' && a == '1') then UNDEFINED; - ebytes = 1 << UInt(size); regs = if T == '0' then 1 else 2; - alignment = if a == '0' then 1 else ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - bits(64) replicated_element = Replicate(MemU[address,ebytes]); - for r = 0 to regs-1 - D[d+r] = replicated_element; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + ebytes; - -__instruction aarch32_VHADD_A - __encoding aarch32_VHADD_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0000 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - add = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VHADD_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0000 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - add = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Int(Elem[D[n+r],e,esize], unsigned); - op2 = Int(Elem[D[m+r],e,esize], unsigned); - result = if add then op1+op2 else op1-op2; - Elem[D[d+r],e,esize] = result[esize:1]; - -__instruction aarch32_ERET_AS - __encoding aarch32_ERET_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0001 0110xxxx xxxxxxxx 0110xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '0' - __decode - // No additional decoding required - - __encoding aarch32_ERET_T1_A - __instruction_set T32 - __opcode '11110011 11011110 10x0xxxx 00000000' - __guard TRUE - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - if !Halted() then - if PSTATE.M IN {M32_User,M32_System} then - UNPREDICTABLE; // UNDEFINED or NOP - else - new_pc_value = if PSTATE.EL == EL2 then ELR_hyp else R[14]; - AArch32.ExceptionReturn(new_pc_value, SPSR[]); - else // Perform DRPS operation in Debug state - if PSTATE.M == M32_User then - UNDEFINED; - elsif PSTATE.M == M32_System then - UNPREDICTABLE; // UNDEFINED or NOP - else - SynchronizeContext(); - SetPSTATEFromPSR(SPSR[]); - // PSTATE.{N,Z,C,V,Q,GE,SS,A,I,F} are not observable and ignored in Debug state, so - // behave as if UNKNOWN. - PSTATE.[N,Z,C,V,Q,GE,SS,A,I,F] = bits(13) UNKNOWN; - // In AArch32 Debug state, all instructions are T32 and unconditional. - PSTATE.IT = '00000000'; PSTATE.T = '1'; // PSTATE.J is RES0 - DLR = bits(32) UNKNOWN; DSPSR = bits(32) UNKNOWN; - UpdateEDSCRFields(); // Update EDSCR PE state flags - -__instruction aarch32_SEL_A - __encoding aarch32_SEL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1000xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SEL_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1010xxxx 1111xxxx 1000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - R[d][7:0] = if PSTATE.GE[0] == '1' then R[n][7:0] else R[m][7:0]; - R[d][15:8] = if PSTATE.GE[1] == '1' then R[n][15:8] else R[m][15:8]; - R[d][23:16] = if PSTATE.GE[2] == '1' then R[n][23:16] else R[m][23:16]; - R[d][31:24] = if PSTATE.GE[3] == '1' then R[n][31:24] else R[m][31:24]; - -__instruction aarch32_CMP_rr_A - __encoding aarch32_CMP_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0101xxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - shift_t = DecodeRegShift(stype); - if n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], NOT(shifted), '1'); - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VSUB_f_A - __encoding aarch32_VSUB_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x1xxxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSUB_f_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 0x11xxxx xxxx10xx x1x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - advsimd = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VSUB_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x1xxxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSUB_f_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 0x11xxxx xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - advsimd = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = FPSub(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize], StandardFPSCRValue()); - else // VFP instruction - case esize of - when 16 - S[d] = Zeros(16) : FPSub(S[n][15:0], S[m][15:0], FPSCR); - when 32 - S[d] = FPSub(S[n], S[m], FPSCR); - when 64 - D[d] = FPSub(D[n], D[m], FPSCR); - -__instruction aarch32_LDRB_l_A - __encoding aarch32_LDRB_l_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx010x x1x11111 xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "LDRBT"; - t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); - add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 || wback then UNPREDICTABLE; - - __encoding aarch32_LDRB_l_T1_A - __instruction_set T32 - __field U 23 +: 1 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 x0011111 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rt == '1111' then SEE "PLD"; - t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - base = Align(PC,4); - address = if add then (base + imm32) else (base - imm32); - R[t] = ZeroExtend(MemU[address,1], 32); - -__instruction aarch32_ORR_rr_A - __encoding aarch32_ORR_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 100xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] OR shifted; - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VMOV_d_A - __encoding aarch32_VMOV_d_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field op 20 +: 1 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1100 010xxxxx xxxx1011 00x1xxxx' - __guard cond != '1111' - __decode - to_arm_registers = (op == '1'); t = UInt(Rt); t2 = UInt(Rt2); m = UInt(M:Vm); - if t == 15 || t2 == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - if to_arm_registers && t == t2 then UNPREDICTABLE; - - __encoding aarch32_VMOV_d_T1A1_A - __instruction_set T32 - __field op 20 +: 1 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101100 010xxxxx xxxx1011 00x1xxxx' - __guard TRUE - __decode - to_arm_registers = (op == '1'); t = UInt(Rt); t2 = UInt(Rt2); m = UInt(M:Vm); - if t == 15 || t2 == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - if to_arm_registers && t == t2 then UNPREDICTABLE; - - __execute __conditional - CheckVFPEnabled(TRUE); - if to_arm_registers then - R[t] = D[m][31:0]; - R[t2] = D[m][63:32]; - else - D[m][31:0] = R[t]; - D[m][63:32] = R[t2]; - -__instruction aarch32_VFNMA_A - __encoding aarch32_VFNMA_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x01xxxx xxxx10xx x1x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - op1_neg = (op == '1'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VFNMA_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x01xxxx xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - op1_neg = (op == '1'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - case esize of - when 16 - op16 = if op1_neg then FPNeg(S[n][15:0]) else S[n][15:0]; - S[d] = Zeros(16) : FPMulAdd(FPNeg(S[d][15:0]), op16, S[m][15:0], FPSCR); - when 32 - op32 = if op1_neg then FPNeg(S[n]) else S[n]; - S[d] = FPMulAdd(FPNeg(S[d]), op32, S[m], FPSCR); - when 64 - op64 = if op1_neg then FPNeg(D[n]) else D[n]; - D[d] = FPMulAdd(FPNeg(D[d]), op64, D[m], FPSCR); - -__instruction aarch32_YIELD_A - __encoding aarch32_YIELD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 00000001' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_YIELD_T1_A - __instruction_set T16 - __opcode '10111111 00010000 00000000 00000000' - __guard TRUE - __decode - // No additional decoding required - - __encoding aarch32_YIELD_T2_A - __instruction_set T32 - __opcode '11110011 1010xxxx 10x0x000 00000001' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - // No additional decoding required - - __execute __conditional - Hint_Yield(); - -__instruction aarch32_LDRB_i_A - __encoding aarch32_LDRB_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx010x x1x1xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if Rn == '1111' then SEE "LDRB (literal)"; - if P == '0' && W == '1' then SEE "LDRBT"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 || (wback && n == t) then UNPREDICTABLE; - - __encoding aarch32_LDRB_i_T1_A - __instruction_set T16 - __field imm5 22 +: 5 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '01111xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); - index = TRUE; add = TRUE; wback = FALSE; - - __encoding aarch32_LDRB_i_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 1001xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rt == '1111' then SEE "PLD"; - if Rn == '1111' then SEE "LDRB (literal)"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = TRUE; add = TRUE; wback = FALSE; - // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_LDRB_i_T3_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field P 10 +: 1 - __field U 9 +: 1 - __field W 8 +: 1 - __field imm8 0 +: 8 - __opcode '11111000 0001xxxx xxxx1xxx xxxxxxxx' - __guard TRUE - __decode - if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "PLD, PLDW (immediate)"; - if Rn == '1111' then SEE "LDRB (literal)"; - if P == '1' && U == '1' && W == '0' then SEE "LDRBT"; - if P == '0' && W == '0' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute - if CurrentInstrSet() == InstrSet_A32 then - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - R[t] = ZeroExtend(MemU[address,1], 32); - if wback then R[n] = offset_addr; - else - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - R[t] = ZeroExtend(MemU[address,1], 32); - if wback then R[n] = offset_addr; - -__instruction aarch32_USAX_A - __encoding aarch32_USAX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0101xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_USAX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1110xxxx 1111xxxx 0100xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum = UInt(R[n][15:0]) + UInt(R[m][31:16]); - diff = UInt(R[n][31:16]) - UInt(R[m][15:0]); - R[d][15:0] = sum[15:0]; - R[d][31:16] = diff[15:0]; - PSTATE.GE[1:0] = if sum >= 0x10000 then '11' else '00'; - PSTATE.GE[3:2] = if diff >= 0 then '11' else '00'; - -__instruction aarch32_VADDL_A - __encoding aarch32_VADDL_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0001 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' || (op == '1' && Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; is_vaddw = (op == '1'); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VADDL_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0001 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' || (op == '1' && Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; is_vaddw = (op == '1'); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - if is_vaddw then - op1 = Int(Elem[Qin[n>>1],e,2*esize], unsigned); - else - op1 = Int(Elem[Din[n],e,esize], unsigned); - result = op1 + Int(Elem[Din[m],e,esize],unsigned); - Elem[Q[d>>1],e,2*esize] = result[2*esize-1:0]; - -__instruction aarch32_STRB_r_A - __encoding aarch32_STRB_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx011x x1x0xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "STRBT"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if t == 15 || m == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_STRB_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '0101010x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_STRB_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111000 0000xxxx xxxx0000 00xxxxxx' - __guard TRUE - __decode - if Rn == '1111' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if t == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if index then offset_addr else R[n]; - MemU[address,1] = R[t][7:0]; - if wback then R[n] = offset_addr; - -__instruction aarch32_VABD_i_A - __encoding aarch32_VABD_i_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0111 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (U == '1'); long_destination = FALSE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VABD_i_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0111 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (U == '1'); long_destination = FALSE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; - op2 = Elem[Din[m+r],e,esize]; - absdiff = Abs(Int(op1,unsigned) - Int(op2,unsigned)); - if long_destination then - Elem[Q[d>>1],e,2*esize] = absdiff[2*esize-1:0]; - else - Elem[D[d+r],e,esize] = absdiff[esize-1:0]; - -__instruction aarch32_VST4_1_A - __encoding aarch32_VST4_1_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx0011 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if size != '00' then SEE "Related encodings"; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - alignment = if index_align[0] == '0' then 1 else 4; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST4_1_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx0111 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if size != '01' then SEE "Related encodings"; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 8; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST4_1_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx1011 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if size != '10' then SEE "Related encodings"; - if index_align[1:0] == '11' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - alignment = if index_align[1:0] == '00' then 1 else 4 << UInt(index_align[1:0]); - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST4_1_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx0011 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if size != '00' then SEE "Related encodings"; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - alignment = if index_align[0] == '0' then 1 else 4; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST4_1_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx0111 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if size != '01' then SEE "Related encodings"; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 8; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST4_1_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx1011 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if size != '10' then SEE "Related encodings"; - if index_align[1:0] == '11' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - alignment = if index_align[1:0] == '00' then 1 else 4 << UInt(index_align[1:0]); - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = TRUE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - MemU[address, ebytes] = Elem[D[d], index]; - MemU[address+ebytes, ebytes] = Elem[D[d2],index]; - MemU[address+2*ebytes,ebytes] = Elem[D[d3],index]; - MemU[address+3*ebytes,ebytes] = Elem[D[d4],index]; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 4*ebytes; - -__instruction aarch32_VMVN_r_A - __encoding aarch32_VMVN_r_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0101 1xx0xxxx' - __guard TRUE - __decode - if size != '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMVN_r_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0101 1xx0xxxx' - __guard TRUE - __decode - if size != '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - D[d+r] = NOT(D[m+r]); - -__instruction aarch32_QDADD_A - __encoding aarch32_QDADD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0100xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QDADD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 1001xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (doubled, sat1) = SignedSatQ(2 * SInt(R[n]), 32); - (R[d], sat2) = SignedSatQ(SInt(R[m]) + SInt(doubled), 32); - if sat1 || sat2 then - PSTATE.Q = '1'; - -__instruction aarch32_VQSUB_A - __encoding aarch32_VQSUB_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0010 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQSUB_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0010 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - diff = Int(Elem[D[n+r],e,esize], unsigned) - Int(Elem[D[m+r],e,esize], unsigned); - (Elem[D[d+r],e,esize], sat) = SatQ(diff, esize, unsigned); - if sat then FPSCR.QC = '1'; - -__instruction aarch32_UMLAL_A - __encoding aarch32_UMLAL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field RdHi 16 +: 4 - __field RdLo 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0000 101xxxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if dHi == dLo then UNPREDICTABLE; - - __encoding aarch32_UMLAL_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field RdLo 12 +: 4 - __field RdHi 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 1110xxxx xxxxxxxx 0000xxxx' - __guard TRUE - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - if dHi == dLo then UNPREDICTABLE; - - __execute __conditional - result = UInt(R[n]) * UInt(R[m]) + UInt(R[dHi]:R[dLo]); - R[dHi] = result[63:32]; - R[dLo] = result[31:0]; - if setflags then - PSTATE.N = result[63]; - PSTATE.Z = IsZeroBit(result[63:0]); - // PSTATE.C, PSTATE.V unchanged - -__instruction aarch32_SEVL_A - __encoding aarch32_SEVL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 00000101' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_SEVL_T1_A - __instruction_set T16 - __opcode '10111111 01010000 00000000 00000000' - __guard TRUE - __decode - // No additional decoding required - - __encoding aarch32_SEVL_T2_A - __instruction_set T32 - __opcode '11110011 1010xxxx 10x0x000 00000101' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - // No additional decoding required - - __execute __conditional - SendEventLocal(); - -__instruction aarch32_VLD3_1_A - __encoding aarch32_VLD3_1_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx0010 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD3 (single 3-element structure to all lanes)"; - if index_align[0] != '0' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD3_1_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx0110 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD3 (single 3-element structure to all lanes)"; - if index_align[0] != '0' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD3_1_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD3 (single 3-element structure to all lanes)"; - if index_align[1:0] != '00' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD3_1_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx0010 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD3 (single 3-element structure to all lanes)"; - if index_align[0] != '0' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD3_1_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx0110 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD3 (single 3-element structure to all lanes)"; - if index_align[0] != '0' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD3_1_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD3 (single 3-element structure to all lanes)"; - if index_align[1:0] != '00' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; - Elem[D[d], index] = MemU[address,ebytes]; - Elem[D[d2],index] = MemU[address+ebytes,ebytes]; - Elem[D[d3],index] = MemU[address+2*ebytes,ebytes]; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 3*ebytes; - -__instruction aarch32_STLEXB_A - __encoding aarch32_STLEXB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1100xxxx xxxxxx10 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t then UNPREDICTABLE; - - __encoding aarch32_STLEXB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rd 0 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 1100xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - if AArch32.ExclusiveMonitorsPass(address,1) then - MemO[address, 1] = R[t][7:0]; - R[d] = ZeroExtend('0'); - else - R[d] = ZeroExtend('1'); - -__instruction aarch32_UQADD16_A - __encoding aarch32_UQADD16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0110xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UQADD16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 0101xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = UInt(R[n][15:0]) + UInt(R[m][15:0]); - sum2 = UInt(R[n][31:16]) + UInt(R[m][31:16]); - R[d][15:0] = UnsignedSat(sum1, 16); - R[d][31:16] = UnsignedSat(sum2, 16); - -__instruction aarch32_VFMA_A - __encoding aarch32_VFMA_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x1xxxxx xxxx1100 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - advsimd = TRUE; op1_neg = (op == '1'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VFMA_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x10xxxx xxxx10xx x1x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - advsimd = FALSE; op1_neg = (op == '1'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VFMA_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x1xxxxx xxxx1100 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - advsimd = TRUE; op1_neg = (op == '1'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VFMA_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x10xxxx xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - advsimd = FALSE; op1_neg = (op == '1'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - bits(esize) op1 = Elem[D[n+r],e,esize]; - if op1_neg then op1 = FPNeg(op1); - Elem[D[d+r],e,esize] = FPMulAdd(Elem[D[d+r],e,esize], - op1, Elem[D[m+r],e,esize], StandardFPSCRValue()); - - else // VFP instruction - case esize of - when 16 - op16 = if op1_neg then FPNeg(S[n][15:0]) else S[n][15:0]; - S[d] = Zeros(16) : FPMulAdd(S[d][15:0], op16, S[m][15:0], FPSCR); - when 32 - op32 = if op1_neg then FPNeg(S[n]) else S[n]; - S[d] = FPMulAdd(S[d], op32, S[m], FPSCR); - when 64 - op64 = if op1_neg then FPNeg(D[n]) else D[n]; - D[d] = FPMulAdd(D[d], op64, D[m], FPSCR); - -__instruction aarch32_VCVTA_asimd_A - __encoding aarch32_VCVTA_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field RM 8 +: 2 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx11 xxxx0010 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCVTA_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field RM 8 +: 2 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx11 xxxx0010 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - bits(esize) result; - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = FPToFixed(Elem[D[m+r],e,esize], 0, unsigned, - StandardFPSCRValue(), rounding); - -__instruction aarch32_CRC32_A - __encoding aarch32_CRC32_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field sz 21 +: 2 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field C 9 +: 1 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0xx0xxxx xxxxxx0x 0100xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 8 == '0' - __decode - if ! HaveCRCExt() then UNDEFINED; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - size = 8 << UInt(sz); - crc32c = (C == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if size == 64 then UNPREDICTABLE; - if cond != '1110' then UNPREDICTABLE; - - __encoding aarch32_CRC32_T1_A - __instruction_set T32 - __field C 20 +: 1 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field sz 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 1100xxxx 1111xxxx 10xxxxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if ! HaveCRCExt() then UNDEFINED; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - size = 8 << UInt(sz); - crc32c = (C == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if size == 64 then UNPREDICTABLE; - - __execute __conditional - - acc = R[n]; // accumulator - val = R[m][size-1:0]; // input value - poly = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)[31:0]; - tempacc = BitReverse(acc):Zeros(size); - tempval = BitReverse(val):Zeros(32); - // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation - R[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly)); - -__instruction aarch32_VEXT_A - __encoding aarch32_VEXT_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field imm4 8 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1x11xxxx xxxxxxxx xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if Q == '0' && imm4[3] == '1' then UNDEFINED; - quadword_operation = (Q == '1'); position = 8 * UInt(imm4); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VEXT_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field imm4 8 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1x11xxxx xxxxxxxx xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if Q == '0' && imm4[3] == '1' then UNDEFINED; - quadword_operation = (Q == '1'); position = 8 * UInt(imm4); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - if quadword_operation then - Q[d>>1] = (Q[m>>1]:Q[n>>1])[position+127:position]; - else - D[d] = (D[m]:D[n])[position+63:position]; - -__instruction aarch32_VRINTZ_vfp_A - __encoding aarch32_VRINTZ_vfp_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110110 xxxx10xx 01x0xxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VRINTZ_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110110 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = Zeros(16) : FPRoundInt(S[m][15:0], FPSCR, rounding, exact); - when 32 - S[d] = FPRoundInt(S[m], FPSCR, rounding, exact); - when 64 - D[d] = FPRoundInt(D[m], FPSCR, rounding, exact); - -__instruction aarch32_RSB_r_A - __encoding aarch32_RSB_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 011xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_RSB_r_T1_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101011 110xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(NOT(R[n]), shifted, '1'); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VCVT_xv_A - __encoding aarch32_VCVT_xv_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field op 18 +: 1 - __field U 16 +: 1 - __field Vd 12 +: 4 - __field sf 8 +: 2 - __field sx 7 +: 1 - __field i 5 +: 1 - __field imm4 0 +: 4 - __opcode 'xxxx1110 1x111x1x xxxx10xx x1x0xxxx' - __guard cond != '1111' - __decode - if sf == '00' || (sf == '01' && !HaveFP16Ext()) then UNDEFINED; - if sf == '01' && cond != '1110' then UNPREDICTABLE; - to_fixed = (op == '1'); unsigned = (U == '1'); - size = if sx == '0' then 16 else 32; - frac_bits = size - UInt(imm4:i); - case sf of - when '01' fp_size = 16; d = UInt(Vd:D); - when '10' fp_size = 32; d = UInt(Vd:D); - when '11' fp_size = 64; d = UInt(D:Vd); - - if frac_bits < 0 then UNPREDICTABLE; - - __encoding aarch32_VCVT_xv_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 18 +: 1 - __field U 16 +: 1 - __field Vd 12 +: 4 - __field sf 8 +: 2 - __field sx 7 +: 1 - __field i 5 +: 1 - __field imm4 0 +: 4 - __opcode '11101110 1x111x1x xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if sf == '00' || (sf == '01' && !HaveFP16Ext()) then UNDEFINED; - if sf == '01' && InITBlock() then UNPREDICTABLE; - to_fixed = (op == '1'); unsigned = (U == '1'); - size = if sx == '0' then 16 else 32; - frac_bits = size - UInt(imm4:i); - case sf of - when '01' fp_size = 16; d = UInt(Vd:D); - when '10' fp_size = 32; d = UInt(Vd:D); - when '11' fp_size = 64; d = UInt(D:Vd); - - if frac_bits < 0 then UNPREDICTABLE; - - __execute __conditional - CheckVFPEnabled(TRUE); - if to_fixed then - bits(size) result; - case fp_size of - when 16 - result = FPToFixed(S[d][15:0], frac_bits, unsigned, FPSCR, FPRounding_ZERO); - S[d] = Extend(result, 32, unsigned); - when 32 - result = FPToFixed(S[d], frac_bits, unsigned, FPSCR, FPRounding_ZERO); - S[d] = Extend(result, 32, unsigned); - when 64 - result = FPToFixed(D[d], frac_bits, unsigned, FPSCR, FPRounding_ZERO); - D[d] = Extend(result, 64, unsigned); - else - case fp_size of - when 16 - bits(16) fp16 = FixedToFP(S[d][size-1:0], frac_bits, unsigned, FPSCR, FPRounding_TIEEVEN); - S[d] = Zeros(16):fp16; - when 32 - S[d] = FixedToFP(S[d][size-1:0], frac_bits, unsigned, FPSCR, FPRounding_TIEEVEN); - when 64 - D[d] = FixedToFP(D[d][size-1:0], frac_bits, unsigned, FPSCR, FPRounding_TIEEVEN); - -__instruction aarch32_VQRSHRN_A - __encoding aarch32_VQRSHRN_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx100x 01x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if U == '0' && op == '0' then SEE "VRSHRN"; - if Vm[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '01xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '1xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - src_unsigned = (U == '1' && op == '1'); dest_unsigned = (U == '1'); - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VQRSHRN_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx100x 01x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if U == '0' && op == '0' then SEE "VRSHRN"; - if Vm[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '01xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '1xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - src_unsigned = (U == '1' && op == '1'); dest_unsigned = (U == '1'); - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - round_const = 1 << (shift_amount - 1); - for e = 0 to elements-1 - operand = Int(Elem[Qin[m>>1],e,2*esize], src_unsigned); - (result, sat) = SatQ((operand + round_const) >> shift_amount, esize, dest_unsigned); - Elem[D[d],e,esize] = result; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_VBIF_A - __encoding aarch32_VBIF_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x10xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if op == '00' then SEE "VEOR"; - if op == '01' then operation = VBitOps_VBSL; - if op == '10' then operation = VBitOps_VBIT; - if op == '11' then operation = VBitOps_VBIF; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VBIF_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x10xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if op == '00' then SEE "VEOR"; - if op == '01' then operation = VBitOps_VBSL; - if op == '10' then operation = VBitOps_VBIT; - if op == '11' then operation = VBitOps_VBIF; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - case operation of - when VBitOps_VBIF D[d+r] = (D[d+r] AND D[m+r]) OR (D[n+r] AND NOT(D[m+r])); - when VBitOps_VBIT D[d+r] = (D[n+r] AND D[m+r]) OR (D[d+r] AND NOT(D[m+r])); - when VBitOps_VBSL D[d+r] = (D[n+r] AND D[d+r]) OR (D[m+r] AND NOT(D[d+r])); - -__instruction aarch32_VQDMULL_A - __encoding aarch32_VQDMULL_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx1101 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - scalar_form = FALSE; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 8 << UInt(size); elements = 64 DIV esize; - - __encoding aarch32_VQDMULL_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx1011 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VQDMULL_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx1101 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - scalar_form = FALSE; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 8 << UInt(size); elements = 64 DIV esize; - - __encoding aarch32_VQDMULL_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx1011 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - if scalar_form then op2 = SInt(Elem[Din[m],index,esize]); - for e = 0 to elements-1 - if !scalar_form then op2 = SInt(Elem[Din[m],e,esize]); - op1 = SInt(Elem[Din[n],e,esize]); - // The following only saturates if both op1 and op2 equal -(2^(esize-1)) - (product, sat) = SignedSatQ(2*op1*op2, 2*esize); - Elem[Q[d>>1],e,2*esize] = product; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_SMUSD_A - __encoding aarch32_SMUSD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Rm 8 +: 4 - __field M 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0000xxxx 1111xxxx 01x1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SMUSD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0100xxxx 1111xxxx 000xxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand2 = if m_swap then ROR(R[m],16) else R[m]; - product1 = SInt(R[n][15:0]) * SInt(operand2[15:0]); - product2 = SInt(R[n][31:16]) * SInt(operand2[31:16]); - result = product1 - product2; - R[d] = result[31:0]; - // Signed overflow cannot occur - -__instruction aarch32_VMOV_ss_A - __encoding aarch32_VMOV_ss_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field op 20 +: 1 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1100 010xxxxx xxxx1010 00x1xxxx' - __guard cond != '1111' - __decode - to_arm_registers = (op == '1'); t = UInt(Rt); t2 = UInt(Rt2); m = UInt(Vm:M); - if t == 15 || t2 == 15 || m == 31 then UNPREDICTABLE; - if to_arm_registers && t == t2 then UNPREDICTABLE; - - __encoding aarch32_VMOV_ss_T1A1_A - __instruction_set T32 - __field op 20 +: 1 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101100 010xxxxx xxxx1010 00x1xxxx' - __guard TRUE - __decode - to_arm_registers = (op == '1'); t = UInt(Rt); t2 = UInt(Rt2); m = UInt(Vm:M); - if t == 15 || t2 == 15 || m == 31 then UNPREDICTABLE; - if to_arm_registers && t == t2 then UNPREDICTABLE; - - __execute __conditional - CheckVFPEnabled(TRUE); - if to_arm_registers then - R[t] = S[m]; - R[t2] = S[m+1]; - else - S[m] = R[t]; - S[m+1] = R[t2]; - -__instruction aarch32_VORR_i_A - __encoding aarch32_VORR_i_T1A1_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx0xx1 0x01xxxx' - __guard TRUE - __decode - if cmode[0] == '0' || cmode[3:2] == '11' then SEE "VMOV (immediate)"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('0', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VORR_i_T2A2_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx10x1 0x01xxxx' - __guard TRUE - __decode - if cmode[0] == '0' || cmode[3:2] == '11' then SEE "VMOV (immediate)"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('0', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VORR_i_T1A1_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx0xx1 0x01xxxx' - __guard TRUE - __decode - if cmode[0] == '0' || cmode[3:2] == '11' then SEE "VMOV (immediate)"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('0', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VORR_i_T2A2_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx10x1 0x01xxxx' - __guard TRUE - __decode - if cmode[0] == '0' || cmode[3:2] == '11' then SEE "VMOV (immediate)"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('0', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - D[d+r] = D[d+r] OR imm64; - -__instruction aarch32_SBC_r_A - __encoding aarch32_SBC_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 110xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_SBC_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rdn 16 +: 3 - __opcode '01000001 10xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_SBC_r_T2_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101011 011xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], NOT(shifted), PSTATE.C); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VCVTB_A - __encoding aarch32_VCVTB_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field op 16 +: 1 - __field Vd 12 +: 4 - __field sz 8 +: 1 - __field T 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x11001x xxxx101x 01x0xxxx' - __guard cond != '1111' - __decode - uses_double = (sz == '1'); convert_from_half = (op == '0'); - lowbit = (if T == '1' then 16 else 0); - if uses_double then - if convert_from_half then - d = UInt(D:Vd); m = UInt(Vm:M); - else - d = UInt(Vd:D); m = UInt(M:Vm); - else - d = UInt(Vd:D); m = UInt(Vm:M); - - __encoding aarch32_VCVTB_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 16 +: 1 - __field Vd 12 +: 4 - __field sz 8 +: 1 - __field T 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x11001x xxxx101x 01x0xxxx' - __guard TRUE - __decode - uses_double = (sz == '1'); convert_from_half = (op == '0'); - lowbit = (if T == '1' then 16 else 0); - if uses_double then - if convert_from_half then - d = UInt(D:Vd); m = UInt(Vm:M); - else - d = UInt(Vd:D); m = UInt(M:Vm); - else - d = UInt(Vd:D); m = UInt(Vm:M); - - __execute __conditional - CheckVFPEnabled(TRUE); - bits(16) hp; - if convert_from_half then - hp = S[m][lowbit+15:lowbit]; - if uses_double then - D[d] = FPConvert(hp, FPSCR); - else - S[d] = FPConvert(hp, FPSCR); - else - if uses_double then - hp = FPConvert(D[m], FPSCR); - else - hp = FPConvert(S[m], FPSCR); - S[d][lowbit+15:lowbit] = hp; - -__instruction aarch32_BXJ_A - __encoding aarch32_BXJ_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0010xxxx xxxxxxxx 0010xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - m = UInt(Rm); - if m == 15 then UNPREDICTABLE; - - __encoding aarch32_BXJ_T1_A - __instruction_set T32 - __field Rm 16 +: 4 - __opcode '11110011 1100xxxx 10x0xxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 4 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - m = UInt(Rm); - if m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - BXWritePC(R[m], BranchType_INDIR); - -__instruction aarch32_SHA1SU0_A - __encoding aarch32_SHA1SU0_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x11xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if !HaveSHA1Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_SHA1SU0_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x11xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA1Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - op1 = Q[d>>1]; op2 = Q[n>>1]; op3 = Q[m>>1]; - op2 = op2[63:0] : op1[127:64]; - Q[d>>1] = op1 EOR op2 EOR op3; - -__instruction aarch32_LDRH_r_A - __encoding aarch32_LDRH_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx000x x0x1xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if P == '0' && W == '1' then SEE "LDRHT"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - (shift_t, shift_n) = (SRType_LSL, 0); - if t == 15 || m == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_LDRH_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '0101101x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_LDRH_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111000 0011xxxx xxxx0000 00xxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "LDRH (literal)"; - if Rt == '1111' then SEE "PLDW (register)"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if index then offset_addr else R[n]; - data = MemU[address,2]; - if wback then R[n] = offset_addr; - R[t] = ZeroExtend(data, 32); - -__instruction aarch32_VDOT_A - __encoding aarch32_VDOT_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x10xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if !HaveDOTPExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - boolean signed = U=='0'; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer esize = 32; - integer regs = if Q == '1' then 2 else 1; - - __encoding aarch32_VDOT_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x10xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveDOTPExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - boolean signed = U=='0'; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer esize = 32; - integer regs = if Q == '1' then 2 else 1; - - __execute - bits(64) operand1; - bits(64) operand2; - bits(64) result; - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - operand1 = D[n+r]; - operand2 = D[m+r]; - result = D[d+r]; - integer element1, element2; - for e = 0 to 1 - integer res = 0; - for i = 0 to 3 - if signed then - element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = SInt(Elem[operand2, 4 * e + i, esize DIV 4]); - else - element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = UInt(Elem[operand2, 4 * e + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = Elem[result, e, esize] + res; - D[d+r] = result; - -__instruction aarch32_VQSHL_i_A - __encoding aarch32_VQSHL_i_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx011x xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if U == '0' && op == '0' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = UInt(imm6) - 8; - when '001xxxx' esize = 16; elements = 4; shift_amount = UInt(imm6) - 16; - when '01xxxxx' esize = 32; elements = 2; shift_amount = UInt(imm6) - 32; - when '1xxxxxx' esize = 64; elements = 1; shift_amount = UInt(imm6); - src_unsigned = (U == '1' && op == '1'); dest_unsigned = (U == '1'); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQSHL_i_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx011x xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if U == '0' && op == '0' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = UInt(imm6) - 8; - when '001xxxx' esize = 16; elements = 4; shift_amount = UInt(imm6) - 16; - when '01xxxxx' esize = 32; elements = 2; shift_amount = UInt(imm6) - 32; - when '1xxxxxx' esize = 64; elements = 1; shift_amount = UInt(imm6); - src_unsigned = (U == '1' && op == '1'); dest_unsigned = (U == '1'); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - operand = Int(Elem[D[m+r],e,esize], src_unsigned); - (result, sat) = SatQ(operand << shift_amount, esize, dest_unsigned); - Elem[D[d+r],e,esize] = result; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_AESMC_A - __encoding aarch32_AESMC_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0011 10x0xxxx' - __guard TRUE - __decode - if !HaveAESExt() then UNDEFINED; - if size != '00' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_AESMC_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0011 10x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAESExt() then UNDEFINED; - if size != '00' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - Q[d>>1] = AESMixColumns(Q[m>>1]); - -__instruction aarch32_BLX_r_A - __encoding aarch32_BLX_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0010xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - m = UInt(Rm); - if m == 15 then UNPREDICTABLE; - - __encoding aarch32_BLX_r_T1_A - __instruction_set T16 - __field Rm 19 +: 4 - __opcode '01000111 1xxxxxxx 00000000 00000000' - __guard TRUE - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - m = UInt(Rm); - if m == 15 then UNPREDICTABLE; - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - target = R[m]; - if CurrentInstrSet() == InstrSet_A32 then - next_instr_addr = PC - 4; - LR = next_instr_addr; - else - next_instr_addr = PC - 2; - LR = next_instr_addr[31:1] : '1'; - BXWritePC(target, BranchType_INDCALL); - -__instruction aarch32_EOR_i_A - __encoding aarch32_EOR_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 001xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); - (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C); - - __encoding aarch32_EOR_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x00 100xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rd == '1111' && S == '1' then SEE "TEQ (immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); - (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C); - if (d == 15 && !setflags) || n == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = R[n] EOR imm32; - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_LDRSB_l_A - __encoding aarch32_LDRSB_l_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x11111 xxxxxxxx 1101xxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "LDRSBT"; - t = UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); - add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 || wback then UNPREDICTABLE; - - __encoding aarch32_LDRSB_l_T1_A - __instruction_set T32 - __field U 23 +: 1 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111001 x0011111 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rt == '1111' then SEE "PLI"; - t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - base = Align(PC,4); - address = if add then (base + imm32) else (base - imm32); - R[t] = SignExtend(MemU[address,1], 32); - -__instruction aarch32_VADD_i_A - __encoding aarch32_VADD_i_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0xxxxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VADD_i_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0xxxxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = Elem[D[n+r],e,esize] + Elem[D[m+r],e,esize]; - -__instruction aarch32_VQDMLAL_A - __encoding aarch32_VQDMLAL_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx1001 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - add = (op == '0'); - scalar_form = FALSE; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 8 << UInt(size); elements = 64 DIV esize; - - __encoding aarch32_VQDMLAL_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx0011 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - add = (op == '0'); - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VQDMLAL_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx1001 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - add = (op == '0'); - scalar_form = FALSE; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 8 << UInt(size); elements = 64 DIV esize; - - __encoding aarch32_VQDMLAL_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx0011 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - add = (op == '0'); - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - if scalar_form then op2 = SInt(Elem[Din[m],index,esize]); - for e = 0 to elements-1 - if !scalar_form then op2 = SInt(Elem[Din[m],e,esize]); - op1 = SInt(Elem[Din[n],e,esize]); - // The following only saturates if both op1 and op2 equal -(2^(esize-1)) - (product, sat1) = SignedSatQ(2*op1*op2, 2*esize); - if add then - result = SInt(Elem[Qin[d>>1],e,2*esize]) + SInt(product); - else - result = SInt(Elem[Qin[d>>1],e,2*esize]) - SInt(product); - (Elem[Q[d>>1],e,2*esize], sat2) = SignedSatQ(result, 2*esize); - if sat1 || sat2 then FPSCR.QC = '1'; - -__instruction aarch32_CMN_i_A - __encoding aarch32_CMN_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 0111xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); imm32 = A32ExpandImm(imm12); - - __encoding aarch32_CMN_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field imm8 0 +: 8 - __opcode '11110x01 0001xxxx 0xxx1111 xxxxxxxx' - __guard TRUE - __decode - n = UInt(Rn); imm32 = T32ExpandImm(i:imm3:imm8); - if n == 15 then UNPREDICTABLE; - - __execute __conditional - (result, nzcv) = AddWithCarry(R[n], imm32, '0'); - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VCVTA_vfp_A - __encoding aarch32_VCVTA_vfp_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111101 xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '0'); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - - __encoding aarch32_VCVTA_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111101 xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '0'); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - - __execute - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = FPToFixed(S[m][15:0], 0, unsigned, FPSCR, rounding); - when 32 - S[d] = FPToFixed(S[m], 0, unsigned, FPSCR, rounding); - when 64 - S[d] = FPToFixed(D[m], 0, unsigned, FPSCR, rounding); - -__instruction aarch32_PLD_i_A - __encoding aarch32_PLD_i_A1_A - __instruction_set A32 - __field U 23 +: 1 - __field R 22 +: 1 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - __opcode '11110101 xx01xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - if Rn == '1111' then SEE "PLD (literal)"; - n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); is_pldw = (R == '0'); - - __encoding aarch32_PLD_i_T1_A - __instruction_set T32 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 10x1xxxx 1111xxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "PLD (literal)"; - n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); add = TRUE; is_pldw = (W == '1'); - - __encoding aarch32_PLD_i_T2_A - __instruction_set T32 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field imm8 0 +: 8 - __opcode '11111000 00x1xxxx 11111100 xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "PLD (literal)"; - n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); add = FALSE; is_pldw = (W == '1'); - - __execute __conditional - address = if add then (R[n] + imm32) else (R[n] - imm32); - if is_pldw then - Hint_PreloadDataForWrite(address); - else - Hint_PreloadData(address); - -__instruction aarch32_VCLT_i_A - __encoding aarch32_VCLT_i_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx01 xxxx0x10 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCLT_i_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx01 xxxx0x10 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - if floating_point then - bits(esize) zero = FPZero('0'); - test_passed = FPCompareGT(zero, Elem[D[m+r],e,esize], StandardFPSCRValue()); - else - test_passed = (SInt(Elem[D[m+r],e,esize]) < 0); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_VMLA_s_A - __encoding aarch32_VMLA_s_A1_A - __instruction_set A32 - __field Q 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field F 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx000x x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || (F == '1' && size == '01' && !HaveFP16Ext()) then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - add = (op == '0'); floating_point = (F == '1'); long_destination = FALSE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VMLA_s_T1_A - __instruction_set T32 - __field Q 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field F 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx000x x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || (F == '1' && size == '01' && !HaveFP16Ext()) then UNDEFINED; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - add = (op == '0'); floating_point = (F == '1'); long_destination = FALSE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - op2 = Elem[Din[m],index,esize]; op2val = Int(op2, unsigned); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; op1val = Int(op1, unsigned); - if floating_point then - fp_addend = if add then FPMul(op1,op2,StandardFPSCRValue()) else FPNeg(FPMul(op1,op2,StandardFPSCRValue())); - Elem[D[d+r],e,esize] = FPAdd(Elem[Din[d+r],e,esize], fp_addend, StandardFPSCRValue()); - else - addend = if add then op1val*op2val else -op1val*op2val; - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend; - -__instruction aarch32_MRRC_A - __encoding aarch32_MRRC_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field coproc 8 +: 4 - __field opc1 4 +: 4 - __field CRm 0 +: 4 - __opcode 'xxxx1100 0101xxxx xxxx111x xxxxxxxx' - __guard cond != '1111' - __decode - t = UInt(Rt); t2 = UInt(Rt2); cp = if coproc[0] == '0' then 14 else 15; - if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_MRRC_T1A1_A - __instruction_set T32 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field coproc 8 +: 4 - __field opc1 4 +: 4 - __field CRm 0 +: 4 - __opcode '11101100 0101xxxx xxxx111x xxxxxxxx' - __guard TRUE - __decode - t = UInt(Rt); t2 = UInt(Rt2); cp = if coproc[0] == '0' then 14 else 15; - if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - value = AArch32.SysRegRead64(cp, ThisInstr()); - R[t] = value[31:0]; - R[t2] = value[63:32]; - -__instruction aarch32_VDUP_r_A - __encoding aarch32_VDUP_r_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field B 22 +: 1 - __field Q 21 +: 1 - __field Vd 16 +: 4 - __field Rt 12 +: 4 - __field D 7 +: 1 - __field E 5 +: 1 - __opcode 'xxxx1110 1xx0xxxx xxxx1011 x0x1xxxx' - __guard cond != '1111' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if Q == '1' && Vd[0] == '1' then UNDEFINED; - d = UInt(D:Vd); t = UInt(Rt); regs = if Q == '0' then 1 else 2; - case B:E of - when '00' esize = 32; elements = 2; - when '01' esize = 16; elements = 4; - when '10' esize = 8; elements = 8; - when '11' UNDEFINED; - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_VDUP_r_T1A1_A - __instruction_set T32 - __field B 22 +: 1 - __field Q 21 +: 1 - __field Vd 16 +: 4 - __field Rt 12 +: 4 - __field D 7 +: 1 - __field E 5 +: 1 - __opcode '11101110 1xx0xxxx xxxx1011 x0x1xxxx' - __guard TRUE - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if Q == '1' && Vd[0] == '1' then UNDEFINED; - d = UInt(D:Vd); t = UInt(Rt); regs = if Q == '0' then 1 else 2; - case B:E of - when '00' esize = 32; elements = 2; - when '01' esize = 16; elements = 4; - when '10' esize = 8; elements = 8; - when '11' UNDEFINED; - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - CheckAdvSIMDEnabled(); - scalar = R[t][esize-1:0]; - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = scalar; - -__instruction aarch32_VBIF_A - __encoding aarch32_VBIF_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x01xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if op == '00' then SEE "VEOR"; - if op == '01' then operation = VBitOps_VBSL; - if op == '10' then operation = VBitOps_VBIT; - if op == '11' then operation = VBitOps_VBIF; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VBIF_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x01xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if op == '00' then SEE "VEOR"; - if op == '01' then operation = VBitOps_VBSL; - if op == '10' then operation = VBitOps_VBIT; - if op == '11' then operation = VBitOps_VBIF; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - case operation of - when VBitOps_VBIF D[d+r] = (D[d+r] AND D[m+r]) OR (D[n+r] AND NOT(D[m+r])); - when VBitOps_VBIT D[d+r] = (D[n+r] AND D[m+r]) OR (D[d+r] AND NOT(D[m+r])); - when VBitOps_VBSL D[d+r] = (D[n+r] AND D[d+r]) OR (D[m+r] AND NOT(D[d+r])); - -__instruction aarch32_SHADD16_A - __encoding aarch32_SHADD16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0011xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SHADD16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 0010xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = SInt(R[n][15:0]) + SInt(R[m][15:0]); - sum2 = SInt(R[n][31:16]) + SInt(R[m][31:16]); - R[d][15:0] = sum1[16:1]; - R[d][31:16] = sum2[16:1]; - -__instruction aarch32_VHADD_A - __encoding aarch32_VHADD_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0010 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - add = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VHADD_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0010 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - add = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Int(Elem[D[n+r],e,esize], unsigned); - op2 = Int(Elem[D[m+r],e,esize], unsigned); - result = if add then op1+op2 else op1-op2; - Elem[D[d+r],e,esize] = result[esize:1]; - -__instruction aarch32_IT_A - __encoding aarch32_IT_T1_A - __instruction_set T16 - __field firstcond 20 +: 4 - __field mask 16 +: 4 - __opcode '10111111 xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - if mask == '0000' then SEE "Related encodings"; - if firstcond == '1111' || (firstcond == '1110' && BitCount(mask) != 1) then UNPREDICTABLE; - if InITBlock() then UNPREDICTABLE; - - __execute - AArch32.CheckITEnabled(mask); - PSTATE.IT[7:0] = firstcond:mask; - ShouldAdvanceIT = FALSE; - -__instruction aarch32_SXTAH_A - __encoding aarch32_SXTAH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1011xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if Rn == '1111' then SEE "SXTH"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SXTAH_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 0000xxxx 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - if Rn == '1111' then SEE "SXTH"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d] = R[n] + SignExtend(rotated[15:0], 32); - -__instruction aarch32_MMLA_A - __encoding aarch32_MMLA_A1_A - __instruction_set A32 - __field B 23 +: 1 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x10xxxx xxxx1100 x1x1xxxx' - __guard TRUE - __decode - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - case B:U of - when '00' op1_unsigned = FALSE; op2_unsigned = FALSE; - when '01' op1_unsigned = TRUE; op2_unsigned = TRUE; - when '10' op1_unsigned = TRUE; op2_unsigned = FALSE; - when '11' UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - - __encoding aarch32_MMLA_T1_A - __instruction_set T32 - __field B 23 +: 1 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x10xxxx xxxx1100 x1x1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - case B:U of - when '00' op1_unsigned = FALSE; op2_unsigned = FALSE; - when '01' op1_unsigned = TRUE; op2_unsigned = TRUE; - when '10' op1_unsigned = TRUE; op2_unsigned = FALSE; - when '11' UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - - __execute - CheckAdvSIMDEnabled(); - bits(128) operand1 = Q[n>>1]; - bits(128) operand2 = Q[m>>1]; - bits(128) addend = Q[d>>1]; - - Q[d>>1] = MatMulAdd(addend, operand1, operand2, op1_unsigned, op2_unsigned); - -__instruction aarch32_CPS_AS - __encoding aarch32_CPS_A1_AS - __instruction_set A32 - __field imod 18 +: 2 - __field M 17 +: 1 - __field A 8 +: 1 - __field I 7 +: 1 - __field F 6 +: 1 - __field mode 0 +: 5 - __opcode '11110001 0000xxx0 xxxxxxxx xx0xxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __decode - if mode != '00000' && M == '0' then UNPREDICTABLE; - if (imod[1] == '1' && A:I:F == '000') || (imod[1] == '0' && A:I:F != '000') then UNPREDICTABLE; - enable = (imod == '10'); disable = (imod == '11'); changemode = (M == '1'); - affectA = (A == '1'); affectI = (I == '1'); affectF = (F == '1'); - if (imod == '00' && M == '0') || imod == '01' then UNPREDICTABLE; - - __encoding aarch32_CPS_T1_AS - __instruction_set T16 - __field im 20 +: 1 - __field A 18 +: 1 - __field I 17 +: 1 - __field F 16 +: 1 - __opcode '10110110 011xxxxx 00000000 00000000' - __guard TRUE - __unpredictable_unless 19 == '0' - __decode - if A:I:F == '000' then UNPREDICTABLE; - enable = (im == '0'); disable = (im == '1'); changemode = FALSE; - affectA = (A == '1'); affectI = (I == '1'); affectF = (F == '1'); - if InITBlock() then UNPREDICTABLE; - - __encoding aarch32_CPS_T2_AS - __instruction_set T32 - __field imod 9 +: 2 - __field M 8 +: 1 - __field A 7 +: 1 - __field I 6 +: 1 - __field F 5 +: 1 - __field mode 0 +: 5 - __opcode '11110011 1010xxxx 10x0xxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - if imod == '00' && M == '0' then SEE "Hint instructions"; - if mode != '00000' && M == '0' then UNPREDICTABLE; - if (imod[1] == '1' && A:I:F == '000') || (imod[1] == '0' && A:I:F != '000') then UNPREDICTABLE; - enable = (imod == '10'); disable = (imod == '11'); changemode = (M == '1'); - affectA = (A == '1'); affectI = (I == '1'); affectF = (F == '1'); - if imod == '01' || InITBlock() then UNPREDICTABLE; - - __execute - if CurrentInstrSet() == InstrSet_A32 then - if PSTATE.EL != EL0 then - if enable then - if affectA then PSTATE.A = '0'; - if affectI then PSTATE.I = '0'; - if affectF then PSTATE.F = '0'; - if disable then - if affectA then PSTATE.A = '1'; - if affectI then PSTATE.I = '1'; - if affectF then PSTATE.F = '1'; - if changemode then - // AArch32.WriteModeByInstr() sets PSTATE.IL to 1 if this is an illegal mode change. - AArch32.WriteModeByInstr(mode); - else - if PSTATE.EL != EL0 then - if enable then - if affectA then PSTATE.A = '0'; - if affectI then PSTATE.I = '0'; - if affectF then PSTATE.F = '0'; - if disable then - if affectA then PSTATE.A = '1'; - if affectI then PSTATE.I = '1'; - if affectF then PSTATE.F = '1'; - if changemode then - // AArch32.WriteModeByInstr() sets PSTATE.IL to 1 if this is an illegal mode change. - AArch32.WriteModeByInstr(mode); - -__instruction aarch32_SDIV_A - __encoding aarch32_SDIV_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0001xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - if d == 15 || n == 15 || m == 15 || a != 15 then UNPREDICTABLE; - - __encoding aarch32_SDIV_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 1001xxxx xxxxxxxx 1111xxxx' - __guard TRUE - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - if d == 15 || n == 15 || m == 15 || a != 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - if SInt(R[m]) == 0 then - result = 0; - else - result = RoundTowardsZero(Real(SInt(R[n])) / Real(SInt(R[m]))); - R[d] = result[31:0]; - -__instruction aarch32_VMAX_f_A - __encoding aarch32_VMAX_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x1xxxxx xxxx1111 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - maximum = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMAX_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x1xxxxx xxxx1111 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - maximum = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[n+r],e,esize]; op2 = Elem[D[m+r],e,esize]; - if maximum then - Elem[D[d+r],e,esize] = FPMax(op1, op2, StandardFPSCRValue()); - else - Elem[D[d+r],e,esize] = FPMin(op1, op2, StandardFPSCRValue()); - -__instruction aarch32_VCVTA_vfp_A - __encoding aarch32_VCVTA_vfp_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111100 xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '0'); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - - __encoding aarch32_VCVTA_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111100 xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '0'); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - - __execute - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = FPToFixed(S[m][15:0], 0, unsigned, FPSCR, rounding); - when 32 - S[d] = FPToFixed(S[m], 0, unsigned, FPSCR, rounding); - when 64 - S[d] = FPToFixed(D[m], 0, unsigned, FPSCR, rounding); - -__instruction aarch32_VABA_A - __encoding aarch32_VABA_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0111 xxx1xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (U == '1'); long_destination = FALSE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VABA_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0111 xxx1xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (U == '1'); long_destination = FALSE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; - op2 = Elem[Din[m+r],e,esize]; - absdiff = Abs(Int(op1,unsigned) - Int(op2,unsigned)); - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + absdiff; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + absdiff; - -__instruction aarch32_SVC_A - __encoding aarch32_SVC_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field imm24 0 +: 24 - __opcode 'xxxx1111 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - imm32 = ZeroExtend(imm24, 32); - - __encoding aarch32_SVC_T1_A - __instruction_set T16 - __field imm8 16 +: 8 - __opcode '11011111 xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - imm32 = ZeroExtend(imm8, 32); - - __execute __conditional - AArch32.CheckForSVCTrap(imm32[15:0]); - AArch32.CallSupervisor(imm32[15:0]); - -__instruction aarch32_STMDB_A - __encoding aarch32_STMDB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - __opcode 'xxxx1001 00x0xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - n = UInt(Rn); registers = register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - - __encoding aarch32_STMDB_T1_A - __instruction_set T32 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field P 15 +: 1 - __field M 14 +: 1 - __field register_list 0 +: 14 - __opcode '11101001 00x0xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - n = UInt(Rn); registers = P:M:register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; - if wback && registers[n] == '1' then UNPREDICTABLE; - if registers[13] == '1' then UNPREDICTABLE; - if registers[15] == '1' then UNPREDICTABLE; - - __execute __conditional - address = R[n] - 4*BitCount(registers); - for i = 0 to 14 - if registers[i] == '1' then - if i == n && wback && i != LowestSetBit(registers) then - MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 - else - MemA[address,4] = R[i]; - address = address + 4; - if registers[15] == '1' then // Only possible for encoding A1 - MemA[address,4] = PCStoreValue(); - if wback then R[n] = R[n] - 4*BitCount(registers); - -__instruction aarch32_VMLA_s_A - __encoding aarch32_VMLA_s_T2A2_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0110 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); add = (op == '0'); floating_point = FALSE; long_destination = TRUE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = 1; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VMLA_s_T2A2_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0110 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); add = (op == '0'); floating_point = FALSE; long_destination = TRUE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = 1; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - op2 = Elem[Din[m],index,esize]; op2val = Int(op2, unsigned); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; op1val = Int(op1, unsigned); - if floating_point then - fp_addend = if add then FPMul(op1,op2,StandardFPSCRValue()) else FPNeg(FPMul(op1,op2,StandardFPSCRValue())); - Elem[D[d+r],e,esize] = FPAdd(Elem[Din[d+r],e,esize], fp_addend, StandardFPSCRValue()); - else - addend = if add then op1val*op2val else -op1val*op2val; - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend; - -__instruction aarch32_MCR_A - __encoding aarch32_MCR_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field opc1 21 +: 3 - __field CRn 16 +: 4 - __field Rt 12 +: 4 - __field coproc 8 +: 4 - __field opc2 5 +: 3 - __field CRm 0 +: 4 - __opcode 'xxxx1110 xxx0xxxx xxxx111x xxx1xxxx' - __guard cond != '1111' - __decode - t = UInt(Rt); cp = if coproc[0] == '0' then 14 else 15; - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_MCR_T1A1_A - __instruction_set T32 - __field opc1 21 +: 3 - __field CRn 16 +: 4 - __field Rt 12 +: 4 - __field coproc 8 +: 4 - __field opc2 5 +: 3 - __field CRm 0 +: 4 - __opcode '11101110 xxx0xxxx xxxx111x xxx1xxxx' - __guard TRUE - __decode - t = UInt(Rt); cp = if coproc[0] == '0' then 14 else 15; - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - AArch32.SysRegWrite(cp, ThisInstr(), R[t]); - -__instruction aarch32_VTRN_A - __encoding aarch32_VTRN_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0000 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VTRN_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0000 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - h = elements DIV 2; - - for r = 0 to regs-1 - if d == m then - D[d+r] = bits(64) UNKNOWN; - else - for e = 0 to h-1 - Elem[D[d+r],2*e+1,esize] = Elem[Din[m+r],2*e,esize]; - Elem[D[m+r],2*e,esize] = Elem[Din[d+r],2*e+1,esize]; - -__instruction aarch32_VLDM_A - __encoding aarch32_VLDM_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode 'xxxx110x xxx1xxxx xxxx1011 xxxxxxx0' - __guard cond != '1111' - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VLDR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see "FLDM*X". - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if imm8[0] == '1' && (d+regs) > 16 then UNPREDICTABLE; - - __encoding aarch32_VLDM_T2A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode 'xxxx110x xxx1xxxx xxxx1010 xxxxxxxx' - __guard cond != '1111' - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VLDR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); - imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; - - __encoding aarch32_VLDM_T1A1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode '1110110x xxx1xxxx xxxx1011 xxxxxxx0' - __guard TRUE - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VLDR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see "FLDM*X". - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if imm8[0] == '1' && (d+regs) > 16 then UNPREDICTABLE; - - __encoding aarch32_VLDM_T2A2_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode '1110110x xxx1xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VLDR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); - imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; - - __execute __conditional - CheckVFPEnabled(TRUE); - address = if add then R[n] else R[n]-imm32; - for r = 0 to regs-1 - if single_regs then - S[d+r] = MemA[address,4]; address = address+4; - else - word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; - // Combine the word-aligned words in the correct order for current endianness. - D[d+r] = if BigEndian() then word1:word2 else word2:word1; - if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; - -__instruction aarch32_AND_rr_A - __encoding aarch32_AND_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 000xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] AND shifted; - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_LDRD_i_A - __encoding aarch32_LDRD_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x0xxxx xxxxxxxx 1101xxxx' - __guard cond != '1111' - __decode - if Rn == '1111' then SEE "LDRD (literal)"; - if Rt[0] == '1' then UNPREDICTABLE; - t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if P == '0' && W == '1' then UNPREDICTABLE; - if wback && (n == t || n == t2) then UNPREDICTABLE; - if t2 == 15 then UNPREDICTABLE; - - __encoding aarch32_LDRD_i_T1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field imm8 0 +: 8 - __opcode '1110100x x1x1xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if P == '0' && W == '0' then SEE "Related encodings"; - if Rn == '1111' then SEE "LDRD (literal)"; - t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if wback && (n == t || n == t2) then UNPREDICTABLE; - if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - if address == Align(address, 8) then - data = MemA[address,8]; - if BigEndian() then - R[t] = data[63:32]; - R[t2] = data[31:0]; - else - R[t] = data[31:0]; - R[t2] = data[63:32]; - else - R[t] = MemA[address,4]; - R[t2] = MemA[address+4,4]; - if wback then R[n] = offset_addr; - -__instruction aarch32_PLD_l_A - __encoding aarch32_PLD_l_A1_A - __instruction_set A32 - __field U 23 +: 1 - __field imm12 0 +: 12 - __opcode '11110101 xx011111 xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 22 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - - __encoding aarch32_PLD_l_T1_A - __instruction_set T32 - __field U 23 +: 1 - __field imm12 0 +: 12 - __opcode '11111000 x0x11111 1111xxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 21 == '0' - __decode - imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - - __execute __conditional - address = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); - Hint_PreloadData(address); - -__instruction aarch32_VRINTA_asimd_A - __encoding aarch32_VRINTA_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0110 1xx0xxxx' - __guard TRUE - __decode - if op[2] != op[0] then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - // Rounding encoded differently from other VCVT and VRINT instructions - rounding = FPDecodeRM(op[2]:NOT(op[1])); exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRINTA_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0110 1xx0xxxx' - __guard TRUE - __decode - if op[2] != op[0] then SEE "Related encodings"; - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - // Rounding encoded differently from other VCVT and VRINT instructions - rounding = FPDecodeRM(op[2]:NOT(op[1])); exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[m+r],e,esize]; - result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact); - Elem[D[d+r],e,esize] = result; - -__instruction aarch32_STREX_A - __encoding aarch32_STREX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1000xxxx xxxxxx11 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t then UNPREDICTABLE; - - __encoding aarch32_STREX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11101000 0100xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - if d == n || d == t then UNPREDICTABLE; - - __execute __conditional - address = R[n] + imm32; - if AArch32.ExclusiveMonitorsPass(address,4) then - MemA[address,4] = R[t]; - R[d] = ZeroExtend('0'); - else - R[d] = ZeroExtend('1'); - -__instruction aarch32_SXTH_A - __encoding aarch32_SXTH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 10111111 xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SXTH_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - __opcode '10110010 00xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); rotation = 0; - - __encoding aarch32_SXTH_T2_A - __instruction_set T32 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 00001111 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d] = SignExtend(rotated[15:0], 32); - -__instruction aarch32_CMN_r_A - __encoding aarch32_CMN_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0111xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_CMN_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rn 16 +: 3 - __opcode '01000010 11xxxxxx 00000000 00000000' - __guard TRUE - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_CMN_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101011 0001xxxx xxxx1111 xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], shifted, '0'); - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_LDMDB_A - __encoding aarch32_LDMDB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - __opcode 'xxxx1001 00x1xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - n = UInt(Rn); registers = register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if wback && registers[n] == '1' then UNPREDICTABLE; - - __encoding aarch32_LDMDB_T1_A - __instruction_set T32 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field P 15 +: 1 - __field M 14 +: 1 - __field register_list 0 +: 14 - __opcode '11101001 00x1xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - n = UInt(Rn); registers = P:M:register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; - if wback && registers[n] == '1' then UNPREDICTABLE; - if registers[13] == '1' then UNPREDICTABLE; - if registers[15] == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - address = R[n] - 4*BitCount(registers); - for i = 0 to 14 - if registers[i] == '1' then - R[i] = MemA[address,4]; address = address + 4; - if registers[15] == '1' then - LoadWritePC(MemA[address,4]); - if wback && registers[n] == '0' then R[n] = R[n] - 4*BitCount(registers); - if wback && registers[n] == '1' then R[n] = bits(32) UNKNOWN; - -__instruction aarch32_LDRH_i_A - __encoding aarch32_LDRH_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x1xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __decode - if Rn == '1111' then SEE "LDRH (literal)"; - if P == '0' && W == '1' then SEE "LDRHT"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 || (wback && n == t) then UNPREDICTABLE; - - __encoding aarch32_LDRH_i_T1_A - __instruction_set T16 - __field imm5 22 +: 5 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '10001xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); - index = TRUE; add = TRUE; wback = FALSE; - - __encoding aarch32_LDRH_i_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 1011xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rt == '1111' then SEE "PLD (immediate)"; - if Rn == '1111' then SEE "LDRH (literal)"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = TRUE; add = TRUE; wback = FALSE; - // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_LDRH_i_T3_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field P 10 +: 1 - __field U 9 +: 1 - __field W 8 +: 1 - __field imm8 0 +: 8 - __opcode '11111000 0011xxxx xxxx1xxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "LDRH (literal)"; - if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "PLDW (immediate)"; - if P == '1' && U == '1' && W == '0' then SEE "LDRHT"; - if P == '0' && W == '0' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute - if CurrentInstrSet() == InstrSet_A32 then - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - data = MemU[address,2]; - if wback then R[n] = offset_addr; - R[t] = ZeroExtend(data, 32); - else - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - data = MemU[address,2]; - if wback then R[n] = offset_addr; - R[t] = ZeroExtend(data, 32); - -__instruction aarch32_VCVT_iv_A - __encoding aarch32_VCVT_iv_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field opc2 16 +: 3 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x11110x xxxx10xx 11x0xxxx' - __guard cond != '1111' - __decode - if opc2 != '000' && opc2 != '10x' then SEE "Related encodings"; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - to_integer = (opc2[2] == '1'); - if to_integer then - unsigned = (opc2[0] == '0'); - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - else - unsigned = (op == '0'); - rounding = FPRoundingMode(FPSCR); - m = UInt(Vm:M); - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __encoding aarch32_VCVT_iv_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field opc2 16 +: 3 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x11110x xxxx10xx 11x0xxxx' - __guard TRUE - __decode - if opc2 != '000' && opc2 != '10x' then SEE "Related encodings"; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - to_integer = (opc2[2] == '1'); - if to_integer then - unsigned = (opc2[0] == '0'); - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - else - unsigned = (op == '0'); - rounding = FPRoundingMode(FPSCR); - m = UInt(Vm:M); - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __execute __conditional - CheckVFPEnabled(TRUE); - if to_integer then - case esize of - when 16 - S[d] = FPToFixed(S[m][15:0], 0, unsigned, FPSCR, rounding); - when 32 - S[d] = FPToFixed(S[m], 0, unsigned, FPSCR, rounding); - when 64 - S[d] = FPToFixed(D[m], 0, unsigned, FPSCR, rounding); - else - case esize of - when 16 - bits(16) fp16 = FixedToFP(S[m], 0, unsigned, FPSCR, rounding); - S[d] = Zeros(16):fp16; - when 32 - S[d] = FixedToFP(S[m], 0, unsigned, FPSCR, rounding); - when 64 - D[d] = FixedToFP(S[m], 0, unsigned, FPSCR, rounding); - -__instruction aarch32_VTBL_A - __encoding aarch32_VTBL_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field len 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xxxx xxxx10xx xxx0xxxx' - __guard TRUE - __decode - is_vtbl = (op == '0'); length = UInt(len)+1; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - if n+length > 32 then UNPREDICTABLE; - - __encoding aarch32_VTBL_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field len 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xxxx xxxx10xx xxx0xxxx' - __guard TRUE - __decode - is_vtbl = (op == '0'); length = UInt(len)+1; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - if n+length > 32 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - - // Create 256-bit = 32-byte table variable, with zeros in entries that will not be used. - table3 = if length == 4 then D[n+3] else Zeros(64); - table2 = if length >= 3 then D[n+2] else Zeros(64); - table1 = if length >= 2 then D[n+1] else Zeros(64); - table = table3 : table2 : table1 : D[n]; - - for i = 0 to 7 - index = UInt(Elem[D[m],i,8]); - if index < 8*length then - Elem[D[d],i,8] = Elem[table,index,8]; - else - if is_vtbl then - Elem[D[d],i,8] = Zeros(8); - // else Elem[D[d],i,8] unchanged - -__instruction aarch32_VSRI_A - __encoding aarch32_VSRI_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1xxxxxxx xxxx0100 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSRI_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1xxxxxxx xxxx0100 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - mask = LSR(Ones(esize), shift_amount); - for r = 0 to regs-1 - for e = 0 to elements-1 - shifted_op = LSR(Elem[D[m+r],e,esize], shift_amount); - Elem[D[d+r],e,esize] = (Elem[D[d+r],e,esize] AND NOT(mask)) OR shifted_op; - -__instruction aarch32_TSB_A - __encoding aarch32_TSB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 00010010' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - if cond != '1110' then UNPREDICTABLE; // ESB must be encoded with AL condition - - __encoding aarch32_TSB_T1_A - __instruction_set T32 - __opcode '11110011 1010xxxx 10x0x000 00010010' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - if InITBlock() then UNPREDICTABLE; - - __execute __conditional - TraceSynchronizationBarrier(); - -__instruction aarch32_AND_r_A - __encoding aarch32_AND_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 000xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_AND_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rdn 16 +: 3 - __opcode '01000000 00xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_AND_r_T2_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101010 000xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - if Rd == '1111' && S == '1' then SEE "TST (register)"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if (d == 15 && !setflags) || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] AND shifted; - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_ADR_A - __encoding aarch32_ADR_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 10001111 xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); imm32 = A32ExpandImm(imm12); add = TRUE; - - __encoding aarch32_ADR_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 01001111 xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); imm32 = A32ExpandImm(imm12); add = FALSE; - - __encoding aarch32_ADR_T1_A - __instruction_set T16 - __field Rd 24 +: 3 - __field imm8 16 +: 8 - __opcode '10100xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); imm32 = ZeroExtend(imm8:'00', 32); add = TRUE; - - __encoding aarch32_ADR_T2_A - __instruction_set T32 - __field i 26 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x10 10101111 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); imm32 = ZeroExtend(i:imm3:imm8, 32); add = FALSE; - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_ADR_T3_A - __instruction_set T32 - __field i 26 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x10 00001111 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); imm32 = ZeroExtend(i:imm3:imm8, 32); add = TRUE; - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); - if d == 15 then // Can only occur for A32 encodings - ALUWritePC(result); - else - R[d] = result; - -__instruction aarch32_VZIP_A - __encoding aarch32_VZIP_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0001 1xx0xxxx' - __guard TRUE - __decode - if size == '11' || (Q == '0' && size == '10') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - quadword_operation = (Q == '1'); esize = 8 << UInt(size); - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VZIP_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0001 1xx0xxxx' - __guard TRUE - __decode - if size == '11' || (Q == '0' && size == '10') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - quadword_operation = (Q == '1'); esize = 8 << UInt(size); - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - if quadword_operation then - if d == m then - Q[d>>1] = bits(128) UNKNOWN; Q[m>>1] = bits(128) UNKNOWN; - else - bits(256) zipped_q; - for e = 0 to (128 DIV esize) - 1 - Elem[zipped_q,2*e,esize] = Elem[Q[d>>1],e,esize]; - Elem[zipped_q,2*e+1,esize] = Elem[Q[m>>1],e,esize]; - Q[d>>1] = zipped_q[127:0]; Q[m>>1] = zipped_q[255:128]; - else - if d == m then - D[d] = bits(64) UNKNOWN; D[m] = bits(64) UNKNOWN; - else - bits(128) zipped_d; - for e = 0 to (64 DIV esize) - 1 - Elem[zipped_d,2*e,esize] = Elem[D[d],e,esize]; - Elem[zipped_d,2*e+1,esize] = Elem[D[m],e,esize]; - D[d] = zipped_d[63:0]; D[m] = zipped_d[127:64]; - -__instruction aarch32_VREV16_A - __encoding aarch32_VREV16_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0001 0xx0xxxx' - __guard TRUE - __decode - if UInt(op)+UInt(size) >= 3 then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - - esize = 8 << UInt(size); - integer container_size; - case op of - when '10' container_size = 16; - when '01' container_size = 32; - when '00' container_size = 64; - integer containers = 64 DIV container_size; - integer elements_per_container = container_size DIV esize; - - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VREV16_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0001 0xx0xxxx' - __guard TRUE - __decode - if UInt(op)+UInt(size) >= 3 then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - - esize = 8 << UInt(size); - integer container_size; - case op of - when '10' container_size = 16; - when '01' container_size = 32; - when '00' container_size = 64; - integer containers = 64 DIV container_size; - integer elements_per_container = container_size DIV esize; - - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - - bits(64) result; - integer element; - integer rev_element; - for r = 0 to regs-1 - element = 0; - for c = 0 to containers-1 - rev_element = element + elements_per_container - 1; - for e = 0 to elements_per_container-1 - Elem[result, rev_element, esize] = Elem[D[m+r], element, esize]; - element = element + 1; - rev_element = rev_element - 1; - D[d+r] = result; - -__instruction aarch32_VDOT_bf16_A - __encoding aarch32_VDOT_bf16_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x00xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer regs = if Q == '1' then 2 else 1; - - __encoding aarch32_VDOT_bf16_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x00xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32BF16Ext() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer regs = if Q == '1' then 2 else 1; - - __execute - bits(64) operand1; - bits(64) operand2; - bits(64) result; - - CheckAdvSIMDEnabled(); - - for r = 0 to regs-1 - operand1 = Din[n+r]; - operand2 = Din[m+r]; - result = Din[d+r]; - for e = 0 to 1 - bits(16) elt1_a = Elem[operand1, 2 * e + 0, 16]; - bits(16) elt1_b = Elem[operand1, 2 * e + 1, 16]; - bits(16) elt2_a = Elem[operand2, 2 * e + 0, 16]; - bits(16) elt2_b = Elem[operand2, 2 * e + 1, 16]; - bits(32) sum = BFAdd(BFMul(elt1_a, elt2_a), BFMul(elt1_b, elt2_b)); - Elem[result, e, 32] = BFAdd(Elem[result, e, 32], sum); - D[d+r] = result; - -__instruction aarch32_VLD4_a_A - __encoding aarch32_VLD4_a_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx1111 xxxxxxxx' - __guard TRUE - __decode - if size == '11' && a == '0' then UNDEFINED; - if size == '11' then - ebytes = 4; alignment = 16; - else - ebytes = 1 << UInt(size); - if size == '10' then - alignment = if a == '0' then 1 else 8; - else - alignment = if a == '0' then 1 else 4*ebytes; - inc = if T == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD4_a_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx1111 xxxxxxxx' - __guard TRUE - __decode - if size == '11' && a == '0' then UNDEFINED; - if size == '11' then - ebytes = 4; alignment = 16; - else - ebytes = 1 << UInt(size); - if size == '10' then - alignment = if a == '0' then 1 else 8; - else - alignment = if a == '0' then 1 else 4*ebytes; - inc = if T == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - D[d] = Replicate(MemU[address,ebytes]); - D[d2] = Replicate(MemU[address+ebytes,ebytes]); - D[d3] = Replicate(MemU[address+2*ebytes,ebytes]); - D[d4] = Replicate(MemU[address+3*ebytes,ebytes]); - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 4*ebytes; - -__instruction aarch32_DOT_A - __encoding aarch32_DOT_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x00xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - boolean op1_unsigned = (U == '0'); - boolean op2_unsigned = (U == '1'); - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm); - integer i = UInt(M); - integer regs = if Q == '1' then 2 else 1; - - __encoding aarch32_DOT_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x00xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - boolean op1_unsigned = (U == '0'); - boolean op2_unsigned = (U == '1'); - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm); - integer i = UInt(M); - integer regs = if Q == '1' then 2 else 1; - - __execute - CheckAdvSIMDEnabled(); - bits(64) operand1; - bits(64) operand2; - bits(64) result; - - operand2 = Din[m]; - for r = 0 to regs-1 - operand1 = Din[n+r]; - result = Din[d+r]; - for e = 0 to 1 - bits(32) res = Elem[result, e, 32]; - for b = 0 to 3 - element1 = Int(Elem[operand1, 4 * e + b, 8], op1_unsigned); - element2 = Int(Elem[operand2, 4 * i + b, 8], op2_unsigned); - res = res + element1 * element2; - Elem[result, e, 32] = res; - D[d+r] = result; - -__instruction aarch32_ORN_r_A - __encoding aarch32_ORN_r_T1_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101010 011xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - if Rn == '1111' then SEE "MVN (register)"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] OR NOT(shifted); - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_UHSAX_A - __encoding aarch32_UHSAX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0111xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UHSAX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1110xxxx 1111xxxx 0110xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum = UInt(R[n][15:0]) + UInt(R[m][31:16]); - diff = UInt(R[n][31:16]) - UInt(R[m][15:0]); - R[d][15:0] = sum[16:1]; - R[d][31:16] = diff[16:1]; - -__instruction aarch32_SMMLS_A - __encoding aarch32_SMMLS_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field R 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0101xxxx xxxxxxxx 11x1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); round = (R == '1'); - if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE; - - __encoding aarch32_SMMLS_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field R 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0110xxxx xxxxxxxx 000xxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); round = (R == '1'); - if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = (SInt(R[a]) << 32) - SInt(R[n]) * SInt(R[m]); - if round then result = result + 0x80000000; - R[d] = result[63:32]; - -__instruction aarch32_SMMLA_A - __encoding aarch32_SMMLA_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field R 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0101xxxx xxxxxxxx 00x1xxxx' - __guard cond != '1111' - __decode - if Ra == '1111' then SEE "SMMUL"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); round = (R == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SMMLA_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field R 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0101xxxx xxxxxxxx 000xxxxx' - __guard TRUE - __decode - if Ra == '1111' then SEE "SMMUL"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); round = (R == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = (SInt(R[a]) << 32) + SInt(R[n]) * SInt(R[m]); - if round then result = result + 0x80000000; - R[d] = result[63:32]; - -__instruction aarch32_CMP_r_A - __encoding aarch32_CMP_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0101xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_CMP_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rn 16 +: 3 - __opcode '01000010 10xxxxxx 00000000 00000000' - __guard TRUE - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_CMP_r_T2_A - __instruction_set T16 - __field N 23 +: 1 - __field Rm 19 +: 4 - __field Rn 16 +: 3 - __opcode '01000101 xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - n = UInt(N:Rn); m = UInt(Rm); - (shift_t, shift_n) = (SRType_LSL, 0); - if n < 8 && m < 8 then UNPREDICTABLE; - if n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_CMP_r_T3_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101011 1011xxxx xxxx1111 xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], NOT(shifted), '1'); - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_AESIMC_A - __encoding aarch32_AESIMC_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0011 11x0xxxx' - __guard TRUE - __decode - if !HaveAESExt() then UNDEFINED; - if size != '00' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_AESIMC_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0011 11x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAESExt() then UNDEFINED; - if size != '00' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - Q[d>>1] = AESInvMixColumns(Q[m>>1]); - -__instruction aarch32_VMOVL_A - __encoding aarch32_VMOVL_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm3H 19 +: 3 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxx000 xxxx1010 00x1xxxx' - __guard TRUE - __decode - if imm3H == '000' then SEE "Related encodings"; - if imm3H != '001' && imm3H != '010' && imm3H != '100' then SEE "VSHLL"; - if Vd[0] == '1' then UNDEFINED; - esize = 8 * UInt(imm3H); - unsigned = (U == '1'); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VMOVL_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm3H 19 +: 3 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxx000 xxxx1010 00x1xxxx' - __guard TRUE - __decode - if imm3H == '000' then SEE "Related encodings"; - if imm3H != '001' && imm3H != '010' && imm3H != '100' then SEE "VSHLL"; - if Vd[0] == '1' then UNDEFINED; - esize = 8 * UInt(imm3H); - unsigned = (U == '1'); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - result = Int(Elem[Din[m],e,esize], unsigned); - Elem[Q[d>>1],e,2*esize] = result[2*esize-1:0]; - -__instruction aarch32_MLS_A - __encoding aarch32_MLS_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0000 0110xxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE; - - __encoding aarch32_MLS_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 0000xxxx xxxxxxxx 0001xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results - operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results - addend = SInt(R[a]); // addend = UInt(R[a]) produces the same final results - result = addend - operand1 * operand2; - R[d] = result[31:0]; - -__instruction aarch32_QSAX_A - __encoding aarch32_QSAX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0010xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QSAX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1110xxxx 1111xxxx 0001xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum = SInt(R[n][15:0]) + SInt(R[m][31:16]); - diff = SInt(R[n][31:16]) - SInt(R[m][15:0]); - R[d][15:0] = SignedSat(sum, 16); - R[d][31:16] = SignedSat(diff, 16); - -__instruction aarch32_VABD_i_A - __encoding aarch32_VABD_i_T2A2_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0111 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); long_destination = TRUE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __encoding aarch32_VABD_i_T2A2_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0111 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); long_destination = TRUE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; - op2 = Elem[Din[m+r],e,esize]; - absdiff = Abs(Int(op1,unsigned) - Int(op2,unsigned)); - if long_destination then - Elem[Q[d>>1],e,2*esize] = absdiff[2*esize-1:0]; - else - Elem[D[d+r],e,esize] = absdiff[esize-1:0]; - -__instruction aarch32_VRINTA_asimd_A - __encoding aarch32_VRINTA_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0100 0xx0xxxx' - __guard TRUE - __decode - if op[2] != op[0] then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - // Rounding encoded differently from other VCVT and VRINT instructions - rounding = FPDecodeRM(op[2]:NOT(op[1])); exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRINTA_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0100 0xx0xxxx' - __guard TRUE - __decode - if op[2] != op[0] then SEE "Related encodings"; - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - // Rounding encoded differently from other VCVT and VRINT instructions - rounding = FPDecodeRM(op[2]:NOT(op[1])); exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[m+r],e,esize]; - result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact); - Elem[D[d+r],e,esize] = result; - -__instruction aarch32_VCVTT_A - __encoding aarch32_VCVTT_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110011 xxxx1001 11x0xxxx' - __guard cond != '1111' - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - integer d = UInt(Vd:D); - integer m = UInt(Vm:M); - - __encoding aarch32_VCVTT_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110011 xxxx1001 11x0xxxx' - __guard TRUE - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - integer d = UInt(Vd:D); - integer m = UInt(Vm:M); - - __execute __conditional - CheckVFPEnabled(TRUE); - - S[d][31:16] = FPConvertBF(S[m], FPSCR); - -__instruction aarch32_VSTM_A - __encoding aarch32_VSTM_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode 'xxxx110x xxx0xxxx xxxx1011 xxxxxxx0' - __guard cond != '1111' - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VSTR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see "FSTMX". - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if imm8[0] == '1' && (d+regs) > 16 then UNPREDICTABLE; - - __encoding aarch32_VSTM_T2A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode 'xxxx110x xxx0xxxx xxxx1010 xxxxxxxx' - __guard cond != '1111' - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VSTR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); - imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; - - __encoding aarch32_VSTM_T1A1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode '1110110x xxx0xxxx xxxx1011 xxxxxxx0' - __guard TRUE - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VSTR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see "FSTMX". - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if imm8[0] == '1' && (d+regs) > 16 then UNPREDICTABLE; - - __encoding aarch32_VSTM_T2A2_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode '1110110x xxx0xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VSTR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); - imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; - - __execute __conditional - CheckVFPEnabled(TRUE); - address = if add then R[n] else R[n]-imm32; - for r = 0 to regs-1 - if single_regs then - MemA[address,4] = S[d+r]; address = address+4; - else - // Store as two word-aligned words in the correct order for current endianness. - MemA[address,4] = if BigEndian() then D[d+r][63:32] else D[d+r][31:0]; - MemA[address+4,4] = if BigEndian() then D[d+r][31:0] else D[d+r][63:32]; - address = address+8; - if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; - -__instruction aarch32_SMLSLD_A - __encoding aarch32_SMLSLD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field RdHi 16 +: 4 - __field RdLo 12 +: 4 - __field Rm 8 +: 4 - __field M 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0100xxxx xxxxxxxx 01x1xxxx' - __guard cond != '1111' - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if dHi == dLo then UNPREDICTABLE; - - __encoding aarch32_SMLSLD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field RdLo 12 +: 4 - __field RdHi 8 +: 4 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 1101xxxx xxxxxxxx 110xxxxx' - __guard TRUE - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UPREDICTABLE for R13 - if dHi == dLo then UNPREDICTABLE; - - __execute __conditional - operand2 = if m_swap then ROR(R[m],16) else R[m]; - product1 = SInt(R[n][15:0]) * SInt(operand2[15:0]); - product2 = SInt(R[n][31:16]) * SInt(operand2[31:16]); - result = product1 - product2 + SInt(R[dHi]:R[dLo]); - R[dHi] = result[63:32]; - R[dLo] = result[31:0]; - -__instruction aarch32_ADD_i_A - __encoding aarch32_ADD_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 100xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if Rn == '1111' && S == '0' then SEE "ADR"; - if Rn == '1101' then SEE "ADD (SP plus immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = A32ExpandImm(imm12); - - __encoding aarch32_ADD_i_T1_A - __instruction_set T16 - __field imm3 22 +: 3 - __field Rn 19 +: 3 - __field Rd 16 +: 3 - __opcode '0001110x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); - - __encoding aarch32_ADD_i_T2_A - __instruction_set T16 - __field Rdn 24 +: 3 - __field imm8 16 +: 8 - __opcode '00110xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); - - __encoding aarch32_ADD_i_T3_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x01 000xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rd == '1111' && S == '1' then SEE "CMN (immediate)"; - if Rn == '1101' then SEE "ADD (SP plus immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = T32ExpandImm(i:imm3:imm8); - if (d == 15 && !setflags) || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_ADD_i_T4_A - __instruction_set T32 - __field i 26 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x10 0000xxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "ADR"; - if Rn == '1101' then SEE "ADD (SP plus immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute - if CurrentInstrSet() == InstrSet_A32 then - (result, nzcv) = AddWithCarry(R[n], imm32, '0'); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - else - (result, nzcv) = AddWithCarry(R[n], imm32, '0'); - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_SUB_SP_r_A - __encoding aarch32_SUB_SP_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 010x1101 xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_SUB_SP_r_T1_A - __instruction_set T32 - __field S 20 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101011 101x1101 xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - if Rd == '1111' && S == '1' then SEE "CMP (register)"; - d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if (d == 15 && !setflags) || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(SP, NOT(shifted), '1'); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_LDAEXB_A - __encoding aarch32_LDAEXB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1101xxxx xxxxxx10 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDAEXB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 1100xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - AArch32.SetExclusiveMonitors(address, 1); - R[t] = ZeroExtend(MemO[address, 1], 32); - -__instruction aarch32_MOV_rr_A - __encoding aarch32_MOV_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 101xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __encoding aarch32_MOV_rr_T1_A - __instruction_set T16 - __field op 22 +: 4 - __field Rs 19 +: 3 - __field Rdm 16 +: 3 - __opcode '0100000x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - if !(op IN {'0010', '0011', '0100', '0111'}) then SEE "Related encodings"; - d = UInt(Rdm); m = UInt(Rdm); s = UInt(Rs); - setflags = !InITBlock(); shift_t = DecodeRegShift(op[2]:op[0]); - - __encoding aarch32_MOV_rr_T2_A - __instruction_set T32 - __field stype 21 +: 2 - __field S 20 +: 1 - __field Rm 16 +: 4 - __field Rd 8 +: 4 - __field Rs 0 +: 4 - __opcode '11111010 0xxxxxxx 1111xxxx 0000xxxx' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || m == 15 || s == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shift_n = UInt(R[s][7:0]); - (result, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_LDC_l_A - __encoding aarch32_LDC_l_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field imm8 0 +: 8 - __opcode 'xxxx110x x0x11111 01011110 xxxxxxxx' - __guard cond != '1111' - __decode - if P == '0' && U == '0' && W == '0' then UNDEFINED; - index = (P == '1'); add = (U == '1'); cp = 14; imm32 = ZeroExtend(imm8:'00', 32); - if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - - __encoding aarch32_LDC_l_T1A1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field imm8 0 +: 8 - __opcode '1110110x x0x11111 01011110 xxxxxxxx' - __guard TRUE - __decode - if P == '0' && U == '0' && W == '0' then UNDEFINED; - index = (P == '1'); add = (U == '1'); cp = 14; imm32 = ZeroExtend(imm8:'00', 32); - if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - - __execute __conditional - offset_addr = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); - address = if index then offset_addr else Align(PC,4); - - // System register write to DBGDTRTXint. - DBGDTR_EL0[] = MemA[address,4]; - -__instruction aarch32_PLI_i_A - __encoding aarch32_PLI_i_A1_A - __instruction_set A32 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - __opcode '11110100 x101xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - - __encoding aarch32_PLI_i_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - __opcode '11111001 1001xxxx 1111xxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "encoding T3"; - n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); add = TRUE; - - __encoding aarch32_PLI_i_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm8 0 +: 8 - __opcode '11111001 0001xxxx 11111100 xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "encoding T3"; - n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); add = FALSE; - - __encoding aarch32_PLI_i_T3_A - __instruction_set T32 - __field U 23 +: 1 - __field imm12 0 +: 12 - __opcode '11111001 x0011111 1111xxxx xxxxxxxx' - __guard TRUE - __decode - n = 15; imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - - __execute __conditional - base = if n == 15 then Align(PC,4) else R[n]; - address = if add then (base + imm32) else (base - imm32); - Hint_PreloadInstr(address); - -__instruction aarch32_ESB_A - __encoding aarch32_ESB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 00010000' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - if cond != '1110' then UNPREDICTABLE; // ESB must be encoded with AL condition - - __encoding aarch32_ESB_T1_A - __instruction_set T32 - __opcode '11110011 1010xxxx 10x0x000 00010000' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - if InITBlock() then UNPREDICTABLE; - - __execute __conditional - - SynchronizeErrors(); - AArch32.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch32.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - -__instruction aarch32_VMVN_i_A - __encoding aarch32_VMVN_i_T1A1_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx0xx0 0x11xxxx' - __guard TRUE - __decode - if (cmode[0] == '1' && cmode[3:2] != '11') || cmode[3:1] == '111' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMVN_i_T2A2_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx10x0 0x11xxxx' - __guard TRUE - __decode - if (cmode[0] == '1' && cmode[3:2] != '11') || cmode[3:1] == '111' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMVN_i_T3A3_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx110x 0x11xxxx' - __guard TRUE - __decode - if (cmode[0] == '1' && cmode[3:2] != '11') || cmode[3:1] == '111' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMVN_i_T1A1_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx0xx0 0x11xxxx' - __guard TRUE - __decode - if (cmode[0] == '1' && cmode[3:2] != '11') || cmode[3:1] == '111' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMVN_i_T2A2_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx10x0 0x11xxxx' - __guard TRUE - __decode - if (cmode[0] == '1' && cmode[3:2] != '11') || cmode[3:1] == '111' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMVN_i_T3A3_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx110x 0x11xxxx' - __guard TRUE - __decode - if (cmode[0] == '1' && cmode[3:2] != '11') || cmode[3:1] == '111' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - D[d+r] = NOT(imm64); - -__instruction aarch32_PLI_r_A - __encoding aarch32_PLI_r_A1_A - __instruction_set A32 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode '11110110 x101xxxx xxxxxxxx xxx0xxxx' - __guard TRUE - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - n = UInt(Rn); m = UInt(Rm); add = (U == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if m == 15 then UNPREDICTABLE; - - __encoding aarch32_PLI_r_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0001xxxx 11110000 00xxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "PLI (immediate, literal)"; - n = UInt(Rn); m = UInt(Rm); add = TRUE; - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - address = if add then (R[n] + offset) else (R[n] - offset); - Hint_PreloadInstr(address); - -__instruction aarch32_VRINTX_asimd_A - __encoding aarch32_VRINTX_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0100 1xx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPRounding_TIEEVEN; exact = TRUE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRINTX_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0100 1xx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPRounding_TIEEVEN; exact = TRUE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - if InITBlock() then UNPREDICTABLE; - - __execute - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[m+r],e,esize]; - result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact); - Elem[D[d+r],e,esize] = result; - -__instruction aarch32_ADC_r_A - __encoding aarch32_ADC_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 101xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_ADC_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rdn 16 +: 3 - __opcode '01000001 01xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_ADC_r_T2_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101011 010xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], shifted, PSTATE.C); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_SETPAN_A - __encoding aarch32_SETPAN_A1_A - __instruction_set A32 - __field imm1 9 +: 1 - __opcode '11110001 0001xxxx xxxxxxxx 0000xxxx' - __guard TRUE - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if !HavePANExt() then UNDEFINED; - value = imm1; - - __encoding aarch32_SETPAN_T1_A - __instruction_set T16 - __field imm1 19 +: 1 - __opcode '10110110 000xxxxx 00000000 00000000' - __guard TRUE - __unpredictable_unless 20 == '1' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - if InITBlock() then UNPREDICTABLE; - if !HavePANExt() then UNDEFINED; - value = imm1; - - __execute - if PSTATE.EL != EL0 then - PSTATE.PAN = value; - -__instruction aarch32_POP_A - __encoding aarch32_POP_T1_A - __instruction_set T16 - __field P 24 +: 1 - __field register_list 16 +: 8 - __opcode '1011110x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - registers = P:'0000000':register_list; UnalignedAllowed = FALSE; - if BitCount(registers) < 1 then UNPREDICTABLE; - if registers[15] == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - address = SP; - for i = 0 to 14 - if registers[i] == '1' then - R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; - address = address + 4; - if registers[15] == '1' then - if UnalignedAllowed then - if address[1:0] == '00' then - LoadWritePC(MemU[address,4]); - else - UNPREDICTABLE; - else - LoadWritePC(MemA[address,4]); - if registers[13] == '0' then SP = SP + 4*BitCount(registers); - if registers[13] == '1' then SP = bits(32) UNKNOWN; - -__instruction aarch32_LDAB_A - __encoding aarch32_LDAB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1101xxxx xxxxxx00 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDAB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 1000xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - R[t] = ZeroExtend(MemO[address, 1], 32); - -__instruction aarch32_AESE_A - __encoding aarch32_AESE_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0011 00x0xxxx' - __guard TRUE - __decode - if !HaveAESExt() then UNDEFINED; - if size != '00' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_AESE_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0011 00x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAESExt() then UNDEFINED; - if size != '00' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - op1 = Q[d>>1]; op2 = Q[m>>1]; - Q[d>>1] = AESSubBytes(AESShiftRows(op1 EOR op2)); - -__instruction aarch32_VCLS_A - __encoding aarch32_VCLS_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0100 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCLS_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0100 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = CountLeadingSignBits(Elem[D[m+r],e,esize])[esize-1:0]; - -__instruction aarch32_MSR_br_AS - __encoding aarch32_MSR_br_A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field R 22 +: 1 - __field M1 16 +: 4 - __field M 8 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0001 0x10xxxx xxxxxx1x 0000xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __decode - n = UInt(Rn); write_spsr = (R == '1'); - if n == 15 then UNPREDICTABLE; - SYSm = M:M1; - - __encoding aarch32_MSR_br_T1_AS - __instruction_set T32 - __field R 20 +: 1 - __field Rn 16 +: 4 - __field M1 8 +: 4 - __field M 4 +: 1 - __opcode '11110011 100xxxxx 10x0xxxx xx1xxxxx' - __guard TRUE - __unpredictable_unless 13 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - n = UInt(Rn); write_spsr = (R == '1'); - if n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - SYSm = M:M1; - - __execute __conditional - if PSTATE.EL == EL0 then - UNPREDICTABLE; - else - mode = PSTATE.M; - if write_spsr then - SPSRaccessValid(SYSm, mode); // Check for UNPREDICTABLE cases - case SYSm of - when '01110' SPSR_fiq = R[n]; - when '10000' SPSR_irq = R[n]; - when '10010' SPSR_svc = R[n]; - when '10100' SPSR_abt = R[n]; - when '10110' SPSR_und = R[n]; - when '11100' - if !ELUsingAArch32(EL3) then AArch64.MonitorModeTrap(); - SPSR_mon = R[n]; - when '11110' SPSR_hyp = R[n]; - else - BankedRegisterAccessValid(SYSm, mode); // Check for UNPREDICTABLE cases - case SYSm of - when '00xxx' // Access the User mode registers - m = UInt(SYSm[2:0]) + 8; - Rmode[m,M32_User] = R[n]; - when '01xxx' // Access the FIQ mode registers - m = UInt(SYSm[2:0]) + 8; - Rmode[m,M32_FIQ] = R[n]; - when '1000x' // Access the IRQ mode registers - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - Rmode[m,M32_IRQ] = R[n]; - when '1001x' // Access the Supervisor mode registers - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - Rmode[m,M32_Svc] = R[n]; - when '1010x' // Access the Abort mode registers - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - Rmode[m,M32_Abort] = R[n]; - when '1011x' // Access the Undefined mode registers - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - Rmode[m,M32_Undef] = R[n]; - when '1110x' // Access Monitor registers - if !ELUsingAArch32(EL3) then AArch64.MonitorModeTrap(); - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - Rmode[m,M32_Monitor] = R[n]; - when '11110' // Access ELR_hyp register - ELR_hyp = R[n]; - when '11111' // Access SP_hyp register - Rmode[13,M32_Hyp] = R[n]; - -__instruction aarch32_VRECPS_A - __encoding aarch32_VRECPS_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x0xxxxx xxxx1111 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRECPS_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x0xxxxx xxxx1111 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = FPRecipStep(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize]); - -__instruction aarch32_VFMAL_i_A - __encoding aarch32_VFMAL_i_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field S 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x00xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - - integer d = UInt(D:Vd); - integer n = if Q == '1' then UInt(N:Vn) else UInt(Vn:N); - integer m = if Q == '1' then UInt(Vm[2:0]) else UInt(Vm[2:0]:M); - - integer index = if Q == '1' then UInt(M:Vm[3]) else UInt(Vm[3]); - integer esize = 32; - integer regs = if Q=='1' then 2 else 1; - integer datasize = if Q=='1' then 64 else 32; - boolean sub_op = S=='1'; - - __encoding aarch32_VFMAL_i_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field S 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x00xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - - integer d = UInt(D:Vd); - integer n = if Q == '1' then UInt(N:Vn) else UInt(Vn:N); - integer m = if Q == '1' then UInt(Vm[2:0]) else UInt(Vm[2:0]:M); - - integer index = if Q == '1' then UInt(M:Vm[3]) else UInt(Vm[3]); - integer esize = 32; - integer regs = if Q=='1' then 2 else 1; - integer datasize = if Q=='1' then 64 else 32; - boolean sub_op = S=='1'; - - __execute - CheckAdvSIMDEnabled(); - bits(datasize) operand1 ; - bits(datasize) operand2 ; - bits(64) operand3; - bits(64) result; - bits(esize DIV 2) element1; - bits(esize DIV 2) element2; - - if Q=='0' then - operand1 = S[n][datasize-1:0]; - operand2 = S[m][datasize-1:0]; - else - operand1 = D[n][datasize-1:0]; - operand2 = D[m][datasize-1:0]; - element2 = Elem[operand2, index, esize DIV 2]; - for r = 0 to regs-1 - operand3 = D[d+r]; - for e = 0 to 1 - element1 = Elem[operand1, 2*r+e, esize DIV 2]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAddH(Elem[operand3, e, esize], element1, element2, StandardFPSCRValue()); - D[d+r] = result; - -__instruction aarch32_VMOVX_A - __encoding aarch32_VMOVX_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x110000 xxxx1010 01x0xxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - d = UInt(Vd:D); m = UInt(Vm:M); - - __encoding aarch32_VMOVX_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x110000 xxxx1010 01x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveFP16Ext() then UNDEFINED; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - d = UInt(Vd:D); m = UInt(Vm:M); - - __execute __conditional - CheckVFPEnabled(TRUE); - S[d] = Zeros(16) : S[m][31:16]; - -__instruction aarch32_VMUL_s_A - __encoding aarch32_VMUL_s_T2A2_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx1010 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); long_destination = TRUE; floating_point = FALSE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = 1; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VMUL_s_T2A2_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx1010 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); long_destination = TRUE; floating_point = FALSE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = 1; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - op2 = Elem[Din[m],index,esize]; op2val = Int(op2, unsigned); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; op1val = Int(op1, unsigned); - if floating_point then - Elem[D[d+r],e,esize] = FPMul(op1, op2, StandardFPSCRValue()); - else - if long_destination then - Elem[Q[d>>1],e,2*esize] = (op1val*op2val)[2*esize-1:0]; - else - Elem[D[d+r],e,esize] = (op1val*op2val)[esize-1:0]; - -__instruction aarch32_TST_r_A - __encoding aarch32_TST_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0001xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_TST_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rn 16 +: 3 - __opcode '01000010 00xxxxxx 00000000 00000000' - __guard TRUE - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_TST_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101010 0001xxxx xxxx1111 xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] AND shifted; - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VNMLA_A - __encoding aarch32_VNMLA_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 0x10xxxx xxxx10xx x1x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '01' && !HaveFP16Ext() then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - vtype = VFPNegMul_VNMUL; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VNMLA_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 0x10xxxx xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '01' && !HaveFP16Ext() then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - vtype = VFPNegMul_VNMUL; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - case esize of - when 16 - product16 = FPMul(S[n][15:0], S[m][15:0], FPSCR); - case vtype of - when VFPNegMul_VNMLA S[d] = Zeros(16) : FPAdd(FPNeg(S[d][15:0]), FPNeg(product16), FPSCR); - when VFPNegMul_VNMLS S[d] = Zeros(16) : FPAdd(FPNeg(S[d][15:0]), product16, FPSCR); - when VFPNegMul_VNMUL S[d] = Zeros(16) : FPNeg(product16); - when 32 - product32 = FPMul(S[n], S[m], FPSCR); - case vtype of - when VFPNegMul_VNMLA S[d] = FPAdd(FPNeg(S[d]), FPNeg(product32), FPSCR); - when VFPNegMul_VNMLS S[d] = FPAdd(FPNeg(S[d]), product32, FPSCR); - when VFPNegMul_VNMUL S[d] = FPNeg(product32); - when 64 - product64 = FPMul(D[n], D[m], FPSCR); - case vtype of - when VFPNegMul_VNMLA D[d] = FPAdd(FPNeg(D[d]), FPNeg(product64), FPSCR); - when VFPNegMul_VNMLS D[d] = FPAdd(FPNeg(D[d]), product64, FPSCR); - when VFPNegMul_VNMUL D[d] = FPNeg(product64); - -__instruction aarch32_VCVTA_asimd_A - __encoding aarch32_VCVTA_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field RM 8 +: 2 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx11 xxxx0011 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCVTA_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field RM 8 +: 2 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx11 xxxx0011 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - bits(esize) result; - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = FPToFixed(Elem[D[m+r],e,esize], 0, unsigned, - StandardFPSCRValue(), rounding); - -__instruction aarch32_UMULL_A - __encoding aarch32_UMULL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field RdHi 16 +: 4 - __field RdLo 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0000 100xxxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if dHi == dLo then UNPREDICTABLE; - - __encoding aarch32_UMULL_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field RdLo 12 +: 4 - __field RdHi 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 1010xxxx xxxxxxxx 0000xxxx' - __guard TRUE - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - if dHi == dLo then UNPREDICTABLE; - - __execute __conditional - result = UInt(R[n]) * UInt(R[m]); - R[dHi] = result[63:32]; - R[dLo] = result[31:0]; - if setflags then - PSTATE.N = result[63]; - PSTATE.Z = IsZeroBit(result[63:0]); - // PSTATE.C, PSTATE.V unchanged - -__instruction aarch32_UHSUB8_A - __encoding aarch32_UHSUB8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0111xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UHSUB8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1100xxxx 1111xxxx 0110xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = UInt(R[n][7:0]) - UInt(R[m][7:0]); - diff2 = UInt(R[n][15:8]) - UInt(R[m][15:8]); - diff3 = UInt(R[n][23:16]) - UInt(R[m][23:16]); - diff4 = UInt(R[n][31:24]) - UInt(R[m][31:24]); - R[d][7:0] = diff1[8:1]; - R[d][15:8] = diff2[8:1]; - R[d][23:16] = diff3[8:1]; - R[d][31:24] = diff4[8:1]; - -__instruction aarch32_LDM_e_AS - __encoding aarch32_LDM_e_A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 15 - __opcode 'xxxx100x x1x1xxxx 1xxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - n = UInt(Rn); registers = register_list; - wback = (W == '1'); increment = (U == '1'); wordhigher = (P == U); - if n == 15 then UNPREDICTABLE; - if wback && registers[n] == '1' then UNPREDICTABLE; - - __execute __conditional - if PSTATE.EL == EL2 then - UNDEFINED; - elsif PSTATE.M IN {M32_User,M32_System} then - UNPREDICTABLE; // UNDEFINED or NOP - else - length = 4*BitCount(registers) + 4; - address = if increment then R[n] else R[n]-length; - if wordhigher then address = address+4; - - for i = 0 to 14 - if registers[i] == '1' then - R[i] = MemA[address,4]; address = address + 4; - new_pc_value = MemA[address,4]; - - if wback && registers[n] == '0' then R[n] = if increment then R[n]+length else R[n]-length; - if wback && registers[n] == '1' then R[n] = bits(32) UNKNOWN; - - AArch32.ExceptionReturn(new_pc_value, SPSR[]); - -__instruction aarch32_VINS_A - __encoding aarch32_VINS_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x110000 xxxx1010 11x0xxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - d = UInt(Vd:D); m = UInt(Vm:M); - - __encoding aarch32_VINS_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x110000 xxxx1010 11x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveFP16Ext() then UNDEFINED; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - d = UInt(Vd:D); m = UInt(Vm:M); - - __execute __conditional - CheckVFPEnabled(TRUE); - S[d] = S[m][15:0] : S[d][15:0]; - -__instruction aarch32_VSHL_r_A - __encoding aarch32_VSHL_r_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0100 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSHL_r_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0100 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - shift = SInt(Elem[D[n+r],e,esize][7:0]); - result = Int(Elem[D[m+r],e,esize], unsigned) << shift; - Elem[D[d+r],e,esize] = result[esize-1:0]; - -__instruction aarch32_UXTAH_A - __encoding aarch32_UXTAH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1111xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if Rn == '1111' then SEE "UXTH"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UXTAH_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 0001xxxx 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - if Rn == '1111' then SEE "UXTH"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d] = R[n] + ZeroExtend(rotated[15:0], 32); - -__instruction aarch32_SHADD8_A - __encoding aarch32_SHADD8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0011xxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SHADD8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 0010xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = SInt(R[n][7:0]) + SInt(R[m][7:0]); - sum2 = SInt(R[n][15:8]) + SInt(R[m][15:8]); - sum3 = SInt(R[n][23:16]) + SInt(R[m][23:16]); - sum4 = SInt(R[n][31:24]) + SInt(R[m][31:24]); - R[d][7:0] = sum1[8:1]; - R[d][15:8] = sum2[8:1]; - R[d][23:16] = sum3[8:1]; - R[d][31:24] = sum4[8:1]; - -__instruction aarch32_LDAEXD_A - __encoding aarch32_LDAEXD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1011xxxx xxxxxx10 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); t2 = t + 1; n = UInt(Rn); - if Rt[0] == '1' || t2 == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDAEXD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 1111xxxx' - __guard TRUE - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); - if t == 15 || t2 == 15 || t == t2 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - AArch32.SetExclusiveMonitors(address, 8); - value = MemO[address, 8]; - // Extract words from 64-bit loaded value such that R[t] is - // loaded from address and R[t2] from address+4. - R[t] = if BigEndian() then value[63:32] else value[31:0]; - R[t2] = if BigEndian() then value[31:0] else value[63:32]; - -__instruction aarch32_STRD_r_A - __encoding aarch32_STRD_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx000x x0x0xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if Rt[0] == '1' then UNPREDICTABLE; - t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if P == '0' && W == '1' then UNPREDICTABLE; - if t2 == 15 || m == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; - - __execute __conditional - offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); - address = if index then offset_addr else R[n]; - if address == Align(address, 8) then - bits(64) data; - if BigEndian() then - data[63:32] = R[t]; - data[31:0] = R[t2]; - else - data[31:0] = R[t]; - data[63:32] = R[t2]; - MemA[address,8] = data; - else - MemA[address,4] = R[t]; - MemA[address+4,4] = R[t2]; - if wback then R[n] = offset_addr; - -__instruction aarch32_BKPT_A - __encoding aarch32_BKPT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field imm12 8 +: 12 - __field imm4 0 +: 4 - __opcode 'xxxx0001 0010xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __decode - imm16 = imm12:imm4; - if cond != '1110' then UNPREDICTABLE; // BKPT must be encoded with AL condition - - __encoding aarch32_BKPT_T1_A - __instruction_set T16 - __field imm8 16 +: 8 - __opcode '10111110 xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - imm16 = ZeroExtend(imm8, 16); - - __execute - AArch32.SoftwareBreakpoint(imm16); - -__instruction aarch32_VPMAX_i_A - __encoding aarch32_VPMAX_i_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field op 4 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx1010 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - maximum = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VPMAX_i_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field op 4 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx1010 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - maximum = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - bits(64) dest; - h = elements DIV 2; - - for e = 0 to h-1 - op1 = Int(Elem[D[n],2*e,esize], unsigned); - op2 = Int(Elem[D[n],2*e+1,esize], unsigned); - result = if maximum then Max(op1,op2) else Min(op1,op2); - Elem[dest,e,esize] = result[esize-1:0]; - op1 = Int(Elem[D[m],2*e,esize], unsigned); - op2 = Int(Elem[D[m],2*e+1,esize], unsigned); - result = if maximum then Max(op1,op2) else Min(op1,op2); - Elem[dest,e+h,esize] = result[esize-1:0]; - - D[d] = dest; - -__instruction aarch32_VSTR_A - __encoding aarch32_VSTR_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm8 0 +: 8 - __opcode 'xxxx1101 xx00xxxx xxxx10xx xxxxxxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - esize = 8 << UInt(size); add = (U == '1'); - imm32 = if esize == 16 then ZeroExtend(imm8:'0', 32) else ZeroExtend(imm8:'00', 32); - case size of - when '01' d = UInt(Vd:D); - when '10' d = UInt(Vd:D); - when '11' d = UInt(D:Vd); - n = UInt(Rn); - if n == 15 && CurrentInstrSet() != InstrSet_A32 then UNPREDICTABLE; - - __encoding aarch32_VSTR_T1_A - __instruction_set T32 - __field U 23 +: 1 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm8 0 +: 8 - __opcode '11101101 xx00xxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - esize = 8 << UInt(size); add = (U == '1'); - imm32 = if esize == 16 then ZeroExtend(imm8:'0', 32) else ZeroExtend(imm8:'00', 32); - case size of - when '01' d = UInt(Vd:D); - when '10' d = UInt(Vd:D); - when '11' d = UInt(D:Vd); - n = UInt(Rn); - if n == 15 && CurrentInstrSet() != InstrSet_A32 then UNPREDICTABLE; - - __execute __conditional - CheckVFPEnabled(TRUE); - address = if add then (R[n] + imm32) else (R[n] - imm32); - case esize of - when 16 - MemA[address,2] = S[d][15:0]; - when 32 - MemA[address,4] = S[d]; - when 64 - // Store as two word-aligned words in the correct order for current endianness. - MemA[address,4] = if BigEndian() then D[d][63:32] else D[d][31:0]; - MemA[address+4,4] = if BigEndian() then D[d][31:0] else D[d][63:32]; - -__instruction aarch32_LDMIB_A - __encoding aarch32_LDMIB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - __opcode 'xxxx1001 10x1xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - n = UInt(Rn); registers = register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if wback && registers[n] == '1' then UNPREDICTABLE; - - __execute __conditional - address = R[n] + 4; - for i = 0 to 14 - if registers[i] == '1' then - R[i] = MemA[address,4]; address = address + 4; - if registers[15] == '1' then - LoadWritePC(MemA[address,4]); - if wback && registers[n] == '0' then R[n] = R[n] + 4*BitCount(registers); - if wback && registers[n] == '1' then R[n] = bits(32) UNKNOWN; - -__instruction aarch32_UDIV_A - __encoding aarch32_UDIV_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0011xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - if d == 15 || n == 15 || m == 15 || a != 15 then UNPREDICTABLE; - - __encoding aarch32_UDIV_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 1011xxxx xxxxxxxx 1111xxxx' - __guard TRUE - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - if d == 15 || n == 15 || m == 15 || a != 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - if UInt(R[m]) == 0 then - result = 0; - else - result = RoundTowardsZero(Real(UInt(R[n])) / Real(UInt(R[m]))); - R[d] = result[31:0]; - -__instruction aarch32_SMC_AS - __encoding aarch32_SMC_A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field imm4 0 +: 4 - __opcode 'xxxx0001 0110xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // imm4 is for assembly/disassembly only and is ignored by hardware - - __encoding aarch32_SMC_T1_AS - __instruction_set T32 - __field imm4 16 +: 4 - __opcode '11110111 1111xxxx 1000xxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 4 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - // imm4 is for assembly/disassembly only and is ignored by hardware - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - - AArch32.CheckForSMCUndefOrTrap(); - - if !ELUsingAArch32(EL3) then - if SCR_EL3.SMD == '1' then - // SMC disabled. - UNDEFINED; - else - if SCR.SCD == '1' then - // SMC disabled - if IsSecure() then - // Executes either as a NOP or UNALLOCATED. - c = ConstrainUnpredictable(Unpredictable_SMD); - assert c IN {Constraint_NOP, Constraint_UNDEF}; - if c == Constraint_NOP then EndOfInstruction(); - UNDEFINED; - - if !ELUsingAArch32(EL3) then - AArch64.CallSecureMonitor(Zeros(16)); - else - AArch32.TakeSMCException(); - -__instruction aarch32_BX_A - __encoding aarch32_BX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0010xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - m = UInt(Rm); - - __encoding aarch32_BX_T1_A - __instruction_set T16 - __field Rm 19 +: 4 - __opcode '01000111 0xxxxxxx 00000000 00000000' - __guard TRUE - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - m = UInt(Rm); - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - BXWritePC(R[m], BranchType_INDIR); - -__instruction aarch32_SMULBB_A - __encoding aarch32_SMULBB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Rm 8 +: 4 - __field M 6 +: 1 - __field N 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0001 0110xxxx xxxxxxxx 1xx0xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - n_high = (N == '1'); m_high = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SMULBB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field N 5 +: 1 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0001xxxx 1111xxxx 00xxxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - n_high = (N == '1'); m_high = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand1 = if n_high then R[n][31:16] else R[n][15:0]; - operand2 = if m_high then R[m][31:16] else R[m][15:0]; - result = SInt(operand1) * SInt(operand2); - R[d] = result[31:0]; - // Signed overflow cannot occur - -__instruction aarch32_LDRD_r_A - __encoding aarch32_LDRD_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx000x x0x0xxxx xxxxxxxx 1101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if Rt[0] == '1' then UNPREDICTABLE; - t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if P == '0' && W == '1' then UNPREDICTABLE; - if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; - if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; - - __execute __conditional - offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); - address = if index then offset_addr else R[n]; - if address == Align(address, 8) then - data = MemA[address,8]; - if BigEndian() then - R[t] = data[63:32]; - R[t2] = data[31:0]; - else - R[t] = data[31:0]; - R[t2] = data[63:32]; - else - R[t] = MemA[address,4]; - R[t2] = MemA[address+4,4]; - - if wback then R[n] = offset_addr; - -__instruction aarch32_VCGE_r_A - __encoding aarch32_VCGE_r_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0011 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - vtype = if U == '1' then VCGEtype_unsigned else VCGEtype_signed; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCGE_r_A2_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x0xxxxx xxxx1110 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - vtype = VCGEtype_fp; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCGE_r_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0011 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - vtype = if U == '1' then VCGEtype_unsigned else VCGEtype_signed; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCGE_r_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x0xxxxx xxxx1110 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - vtype = VCGEtype_fp; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[n+r],e,esize]; op2 = Elem[D[m+r],e,esize]; - case vtype of - when VCGEtype_signed test_passed = (SInt(op1) >= SInt(op2)); - when VCGEtype_unsigned test_passed = (UInt(op1) >= UInt(op2)); - when VCGEtype_fp test_passed = FPCompareGE(op1, op2, StandardFPSCRValue()); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_UXTB_A - __encoding aarch32_UXTB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 11101111 xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UXTB_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - __opcode '10110010 11xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); rotation = 0; - - __encoding aarch32_UXTB_T2_A - __instruction_set T32 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 01011111 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d] = ZeroExtend(rotated[7:0], 32); - -__instruction aarch32_VMOV_h_A - __encoding aarch32_VMOV_h_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field op 20 +: 1 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - __opcode 'xxxx1110 000xxxxx xxxx1001 xxx1xxxx' - __guard cond != '1111' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if !HaveFP16Ext() then UNDEFINED; - if cond != '1110' then UNPREDICTABLE; - to_arm_register = (op == '1'); t = UInt(Rt); n = UInt(Vn:N); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_VMOV_h_T1_A - __instruction_set T32 - __field op 20 +: 1 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - __opcode '11101110 000xxxxx xxxx1001 xxx1xxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if !HaveFP16Ext() then UNDEFINED; - if InITBlock() then UNPREDICTABLE; - to_arm_register = (op == '1'); t = UInt(Rt); n = UInt(Vn:N); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - CheckVFPEnabled(TRUE); - if to_arm_register then - R[t] = Zeros(16) : S[n][15:0]; - else - S[n] = Zeros(16) : R[t][15:0]; - -__instruction aarch32_SUB_r_A - __encoding aarch32_SUB_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 010xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if Rn == '1101' then SEE "SUB (SP minus register)"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_SUB_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rd 16 +: 3 - __opcode '0001101x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_SUB_r_T2_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101011 101xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - if Rd == '1111' && S == '1' then SEE "CMP (register)"; - if Rn == '1101' then SEE "SUB (SP minus register)"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if (d == 15 && !setflags) || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], NOT(shifted), '1'); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_SB_A - __encoding aarch32_SB_A1_A - __instruction_set A32 - __opcode '11110101 0111xxxx xxxxxxxx 0111xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - // No additional decoding required - - __encoding aarch32_SB_T1_A - __instruction_set T32 - __opcode '11110011 1011xxxx 10x0xxxx 0111xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if InITBlock() then UNPREDICTABLE; - - __execute __conditional - SpeculationBarrier(); - -__instruction aarch32_DMB_A - __encoding aarch32_DMB_A1_A - __instruction_set A32 - __field option 0 +: 4 - __opcode '11110101 0111xxxx xxxxxxxx 0101xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_DMB_T1_A - __instruction_set T32 - __field option 0 +: 4 - __opcode '11110011 1011xxxx 10x0xxxx 0101xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - // No additional decoding required - - __execute __conditional - case option of - when '0001' domain = MBReqDomain_OuterShareable; types = MBReqTypes_Reads; - when '0010' domain = MBReqDomain_OuterShareable; types = MBReqTypes_Writes; - when '0011' domain = MBReqDomain_OuterShareable; types = MBReqTypes_All; - when '0101' domain = MBReqDomain_Nonshareable; types = MBReqTypes_Reads; - when '0110' domain = MBReqDomain_Nonshareable; types = MBReqTypes_Writes; - when '0111' domain = MBReqDomain_Nonshareable; types = MBReqTypes_All; - when '1001' domain = MBReqDomain_InnerShareable; types = MBReqTypes_Reads; - when '1010' domain = MBReqDomain_InnerShareable; types = MBReqTypes_Writes; - when '1011' domain = MBReqDomain_InnerShareable; types = MBReqTypes_All; - when '1101' domain = MBReqDomain_FullSystem; types = MBReqTypes_Reads; - when '1110' domain = MBReqDomain_FullSystem; types = MBReqTypes_Writes; - otherwise domain = MBReqDomain_FullSystem; types = MBReqTypes_All; - - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then - if HCR.BSU == '11' then - domain = MBReqDomain_FullSystem; - if HCR.BSU == '10' && domain != MBReqDomain_FullSystem then - domain = MBReqDomain_OuterShareable; - if HCR.BSU == '01' && domain == MBReqDomain_Nonshareable then - domain = MBReqDomain_InnerShareable; - - DataMemoryBarrier(domain, types); - -__instruction aarch32_DCPS2_A - __encoding aarch32_DCPS2_T1_A - __instruction_set T32 - __opcode '11110111 10001111 10000000 00000010' - __guard TRUE - __decode - if !HaveEL(EL2) then UNDEFINED; - - __execute - if !Halted() || IsSecure() then UNDEFINED; - - if ELUsingAArch32(EL2) then - AArch32.WriteMode(M32_Hyp); - PSTATE.E = HSCTLR.EE; - - ELR_hyp = bits(32) UNKNOWN; - HSR = bits(32) UNKNOWN; - SPSR_hyp = bits(32) UNKNOWN; - - DLR = bits(32) UNKNOWN; - DSPSR = bits(32) UNKNOWN; - else // Targeting EL2 using AArch64 - AArch64.MaybeZeroRegisterUppers(); - MaybeZeroSVEUppers(EL2); - PSTATE.nRW = '0'; - PSTATE.SP = '1'; - PSTATE.EL = EL2; - if HavePANExt() && SCTLR_EL2.SPAN == '0' && HCR_EL2.E2H == '1' && HCR_EL2.TGE == '1' then - PSTATE.PAN = '1'; - if HaveUAOExt() then PSTATE.UAO = '0'; - - ELR_EL2 = bits(64) UNKNOWN; - ESR_EL2 = bits(32) UNKNOWN; - SPSR_EL2 = bits(32) UNKNOWN; - - DLR_EL0 = bits(64) UNKNOWN; - DSPSR_EL0 = bits(32) UNKNOWN; - - // SCTLR_EL2.IESB might be ignored in Debug state. - if HaveIESB() && SCTLR_EL2.IESB == '1' && !ConstrainUnpredictableBool(Unpredictable_IESBinDebug) then - SynchronizeErrors(); - - UpdateEDSCRFields(); // Update EDSCR PE state flags - -__instruction aarch32_VRINTA_asimd_A - __encoding aarch32_VRINTA_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0111 1xx0xxxx' - __guard TRUE - __decode - if op[2] != op[0] then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - // Rounding encoded differently from other VCVT and VRINT instructions - rounding = FPDecodeRM(op[2]:NOT(op[1])); exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRINTA_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0111 1xx0xxxx' - __guard TRUE - __decode - if op[2] != op[0] then SEE "Related encodings"; - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - // Rounding encoded differently from other VCVT and VRINT instructions - rounding = FPDecodeRM(op[2]:NOT(op[1])); exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[m+r],e,esize]; - result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact); - Elem[D[d+r],e,esize] = result; - -__instruction aarch32_VMLA_f_A - __encoding aarch32_VMLA_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x1xxxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - advsimd = TRUE; add = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMLA_f_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 0x00xxxx xxxx10xx x1x0xxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - advsimd = FALSE; add = (op == '0'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VMLA_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x1xxxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - advsimd = TRUE; add = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMLA_f_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 0x00xxxx xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - advsimd = FALSE; add = (op == '0'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - product = FPMul(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize], StandardFPSCRValue()); - addend = if add then product else FPNeg(product); - Elem[D[d+r],e,esize] = FPAdd(Elem[D[d+r],e,esize], addend, StandardFPSCRValue()); - else // VFP instruction - case esize of - when 16 - addend16 = if add then FPMul(S[n][15:0], S[m][15:0], FPSCR) else FPNeg(FPMul(S[n][15:0], S[m][15:0], FPSCR)); - S[d] = Zeros(16) : FPAdd(S[d][15:0], addend16, FPSCR); - when 32 - addend32 = if add then FPMul(S[n], S[m], FPSCR) else FPNeg(FPMul(S[n], S[m], FPSCR)); - S[d] = FPAdd(S[d], addend32, FPSCR); - when 64 - addend64 = if add then FPMul(D[n], D[m], FPSCR) else FPNeg(FPMul(D[n], D[m], FPSCR)); - D[d] = FPAdd(D[d], addend64, FPSCR); - -__instruction aarch32_VMRS_AS - __encoding aarch32_VMRS_T1A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field reg 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx1110 1111xxxx xxxx1010 xxx1xxxx' - __guard cond != '1111' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - t = UInt(Rt); - if !(reg IN {'000x', '0101', '011x', '1000'}) then UNPREDICTABLE; - if t == 15 && reg != '0001' then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_VMRS_T1A1_AS - __instruction_set T32 - __field reg 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101110 1111xxxx xxxx1010 xxx1xxxx' - __guard TRUE - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - t = UInt(Rt); - if !(reg IN {'000x', '0101', '011x', '1000'}) then UNPREDICTABLE; - if t == 15 && reg != '0001' then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - if reg == '0001' then // FPSCR - CheckVFPEnabled(TRUE); - if t == 15 then - PSTATE.[N,Z,C,V] = FPSR.[N,Z,C,V]; - else - R[t] = FPSCR; - elsif PSTATE.EL == EL0 then - UNDEFINED; // Non-FPSCR registers accessible only at PL1 or above - else - CheckVFPEnabled(FALSE); // Non-FPSCR registers are not affected by FPEXC.EN - AArch32.CheckAdvSIMDOrFPRegisterTraps(reg); - case reg of - when '0000' R[t] = FPSID; - when '0101' R[t] = MVFR2; - when '0110' R[t] = MVFR1; - when '0111' R[t] = MVFR0; - when '1000' R[t] = FPEXC; - otherwise Unreachable(); // Dealt with above or in encoding-specific pseudocode - -__instruction aarch32_VCVT_hs_A - __encoding aarch32_VCVT_hs_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx011x 00x0xxxx' - __guard TRUE - __decode - if size != '01' then UNDEFINED; - half_to_single = (op == '1'); - if half_to_single && Vd[0] == '1' then UNDEFINED; - if !half_to_single && Vm[0] == '1' then UNDEFINED; - esize = 16; elements = 4; - m = UInt(M:Vm); d = UInt(D:Vd); - - __encoding aarch32_VCVT_hs_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx011x 00x0xxxx' - __guard TRUE - __decode - if size != '01' then UNDEFINED; - half_to_single = (op == '1'); - if half_to_single && Vd[0] == '1' then UNDEFINED; - if !half_to_single && Vm[0] == '1' then UNDEFINED; - esize = 16; elements = 4; - m = UInt(M:Vm); d = UInt(D:Vd); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - if half_to_single then - Elem[Q[d>>1],e,32] = FPConvert(Elem[Din[m],e,16], StandardFPSCRValue()); - else - Elem[D[d],e,16] = FPConvert(Elem[Qin[m>>1],e,32], StandardFPSCRValue()); - -__instruction aarch32_MOV_r_A - __encoding aarch32_MOV_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 101xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_MOV_r_T1_A - __instruction_set T16 - __field D 23 +: 1 - __field Rm 19 +: 4 - __field Rd 16 +: 3 - __opcode '01000110 xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(D:Rd); m = UInt(Rm); setflags = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - if d == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __encoding aarch32_MOV_r_T2_A - __instruction_set T16 - __field op 27 +: 2 - __field imm5 22 +: 5 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - __opcode '000xxxxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = DecodeImmShift(op, imm5); - if op == '00' && imm5 == '00000' && InITBlock() then UNPREDICTABLE; - - __encoding aarch32_MOV_r_T3_A - __instruction_set T32 - __field S 20 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101010 010x1111 xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = shifted; - if d == 15 then - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_RSC_i_A - __encoding aarch32_RSC_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 111xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = A32ExpandImm(imm12); - - __execute __conditional - (result, nzcv) = AddWithCarry(NOT(R[n]), imm32, PSTATE.C); - if d == 15 then - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_STREXB_A - __encoding aarch32_STREXB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1100xxxx xxxxxx11 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t then UNPREDICTABLE; - - __encoding aarch32_STREXB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rd 0 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 0100xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - if d == n || d == t then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - if AArch32.ExclusiveMonitorsPass(address,1) then - MemA[address,1] = R[t][7:0]; - R[d] = ZeroExtend('0'); - else - R[d] = ZeroExtend('1'); - -__instruction aarch32_SADD16_A - __encoding aarch32_SADD16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0001xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SADD16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 0000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = SInt(R[n][15:0]) + SInt(R[m][15:0]); - sum2 = SInt(R[n][31:16]) + SInt(R[m][31:16]); - R[d][15:0] = sum1[15:0]; - R[d][31:16] = sum2[15:0]; - PSTATE.GE[1:0] = if sum1 >= 0 then '11' else '00'; - PSTATE.GE[3:2] = if sum2 >= 0 then '11' else '00'; - -__instruction aarch32_REVSH_A - __encoding aarch32_REVSH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1111xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); m = UInt(Rm); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_REVSH_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - __opcode '10111010 11xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); - - __encoding aarch32_REVSH_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 1011xxxx' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); n = UInt(Rn); - if m != n || d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - bits(32) result; - result[31:8] = SignExtend(R[m][7:0], 24); - result[7:0] = R[m][15:8]; - R[d] = result; - -__instruction aarch32_VRSQRTE_A - __encoding aarch32_VRSQRTE_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 8 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx11 xxxx010x 1xx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - floating_point = (F == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRSQRTE_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 8 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx11 xxxx010x 1xx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - floating_point = (F == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - if floating_point then - Elem[D[d+r],e,esize] = FPRSqrtEstimate(Elem[D[m+r],e,esize], StandardFPSCRValue()); - else - Elem[D[d+r],e,esize] = UnsignedRSqrtEstimate(Elem[D[m+r],e,esize]); - -__instruction aarch32_VMUL_i_A - __encoding aarch32_VMUL_i_A2_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx11x0 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - unsigned = (U == '1'); polynomial = (op == '1'); long_destination = TRUE; - esize = 8 << UInt(size); elements = 64 DIV esize; - if polynomial then - if U == '1' || size == '01' then UNDEFINED; - if size == '10' then // .p64 - if !HaveBit128PMULLExt() then UNDEFINED; - esize = 64; elements = 1; - if Vd[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __encoding aarch32_VMUL_i_T2_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx11x0 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - unsigned = (U == '1'); polynomial = (op == '1'); long_destination = TRUE; - esize = 8 << UInt(size); elements = 64 DIV esize; - if polynomial then - if U == '1' || size == '01' then UNDEFINED; - if size == '10' then // .p64 - if InITBlock() then UNPREDICTABLE; - if !HaveBit128PMULLExt() then UNDEFINED; - esize = 64; elements = 1; - if Vd[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; op1val = Int(op1, unsigned); - op2 = Elem[Din[m+r],e,esize]; op2val = Int(op2, unsigned); - if polynomial then - product = PolynomialMult(op1,op2); - else - product = (op1val*op2val)[2*esize-1:0]; - if long_destination then - Elem[Q[d>>1],e,2*esize] = product; - else - Elem[D[d+r],e,esize] = product[esize-1:0]; - -__instruction aarch32_VFNMA_A - __encoding aarch32_VFNMA_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x01xxxx xxxx10xx x0x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - op1_neg = (op == '1'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VFNMA_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x01xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - op1_neg = (op == '1'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - case esize of - when 16 - op16 = if op1_neg then FPNeg(S[n][15:0]) else S[n][15:0]; - S[d] = Zeros(16) : FPMulAdd(FPNeg(S[d][15:0]), op16, S[m][15:0], FPSCR); - when 32 - op32 = if op1_neg then FPNeg(S[n]) else S[n]; - S[d] = FPMulAdd(FPNeg(S[d]), op32, S[m], FPSCR); - when 64 - op64 = if op1_neg then FPNeg(D[n]) else D[n]; - D[d] = FPMulAdd(FPNeg(D[d]), op64, D[m], FPSCR); - -__instruction aarch32_EOR_r_A - __encoding aarch32_EOR_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 001xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_EOR_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rdn 16 +: 3 - __opcode '01000000 01xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_EOR_r_T2_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101010 100xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - if Rd == '1111' && S == '1' then SEE "TEQ (register)"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if (d == 15 && !setflags) || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] EOR shifted; - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VSEL_A - __encoding aarch32_VSEL_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field cc 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0xxxxxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - cond = cc:(cc[1] EOR cc[0]):'0'; - - __encoding aarch32_VSEL_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field cc 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0xxxxxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - cond = cc:(cc[1] EOR cc[0]):'0'; - - __execute - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = Zeros(16) : (if ConditionHolds(cond) then S[n] else S[m])[15:0]; - when 32 - S[d] = if ConditionHolds(cond) then S[n] else S[m]; - when 64 - D[d] = if ConditionHolds(cond) then D[n] else D[m]; - -__instruction aarch32_VRSHRN_A - __encoding aarch32_VRSHRN_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx1000 01x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if Vm[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '01xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '1xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VRSHRN_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx1000 01x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if Vm[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '01xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '1xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - round_const = 1 << (shift_amount-1); - for e = 0 to elements-1 - result = LSR(Elem[Qin[m>>1],e,2*esize] + round_const, shift_amount); - Elem[D[d],e,esize] = result[esize-1:0]; - -__instruction aarch32_DBG_A - __encoding aarch32_DBG_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field option 0 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // DBG executes as a NOP. The 'option' field is ignored - - __encoding aarch32_DBG_T1_A - __instruction_set T32 - __field option 0 +: 4 - __opcode '11110011 1010xxxx 10x0x000 1111xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - // DBG executes as a NOP. The 'option' field is ignored - - __execute __conditional - -__instruction aarch32_VSHLL_A - __encoding aarch32_VSHLL_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx1010 00x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = UInt(imm6) - 8; - when '01xxxx' esize = 16; elements = 4; shift_amount = UInt(imm6) - 16; - when '1xxxxx' esize = 32; elements = 2; shift_amount = UInt(imm6) - 32; - if shift_amount == 0 then SEE "VMOVL"; - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VSHLL_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0011 00x0xxxx' - __guard TRUE - __decode - if size == '11' || Vd[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; shift_amount = esize; - unsigned = FALSE; // Or TRUE without change of functionality - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VSHLL_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx1010 00x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = UInt(imm6) - 8; - when '01xxxx' esize = 16; elements = 4; shift_amount = UInt(imm6) - 16; - when '1xxxxx' esize = 32; elements = 2; shift_amount = UInt(imm6) - 32; - if shift_amount == 0 then SEE "VMOVL"; - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VSHLL_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0011 00x0xxxx' - __guard TRUE - __decode - if size == '11' || Vd[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; shift_amount = esize; - unsigned = FALSE; // Or TRUE without change of functionality - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - result = Int(Elem[Din[m],e,esize], unsigned) << shift_amount; - Elem[Q[d>>1],e,2*esize] = result[2*esize-1:0]; - -__instruction aarch32_QASX_A - __encoding aarch32_QASX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0010xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QASX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1010xxxx 1111xxxx 0001xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff = SInt(R[n][15:0]) - SInt(R[m][31:16]); - sum = SInt(R[n][31:16]) + SInt(R[m][15:0]); - R[d][15:0] = SignedSat(diff, 16); - R[d][31:16] = SignedSat(sum, 16); - -__instruction aarch32_VQABS_A - __encoding aarch32_VQABS_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0111 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQABS_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0111 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - result = Abs(SInt(Elem[D[m+r],e,esize])); - (Elem[D[d+r],e,esize], sat) = SignedSatQ(result, esize); - if sat then FPSCR.QC = '1'; - -__instruction aarch32_SMLALD_A - __encoding aarch32_SMLALD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field RdHi 16 +: 4 - __field RdLo 12 +: 4 - __field Rm 8 +: 4 - __field M 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0100xxxx xxxxxxxx 00x1xxxx' - __guard cond != '1111' - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if dHi == dLo then UNPREDICTABLE; - - __encoding aarch32_SMLALD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field RdLo 12 +: 4 - __field RdHi 8 +: 4 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 1100xxxx xxxxxxxx 110xxxxx' - __guard TRUE - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - if dHi == dLo then UNPREDICTABLE; - - __execute __conditional - operand2 = if m_swap then ROR(R[m],16) else R[m]; - product1 = SInt(R[n][15:0]) * SInt(operand2[15:0]); - product2 = SInt(R[n][31:16]) * SInt(operand2[31:16]); - result = product1 + product2 + SInt(R[dHi]:R[dLo]); - R[dHi] = result[63:32]; - R[dLo] = result[31:0]; - -__instruction aarch32_LDRSH_i_A - __encoding aarch32_LDRSH_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x1xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __decode - if Rn == '1111' then SEE "LDRSH (literal)"; - if P == '0' && W == '1' then SEE "LDRSHT"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 || (wback && n == t) then UNPREDICTABLE; - - __encoding aarch32_LDRSH_i_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111001 1011xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "LDRSH (literal)"; - if Rt == '1111' then SEE "Related instructions"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = TRUE; add = TRUE; wback = FALSE; - // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_LDRSH_i_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field P 10 +: 1 - __field U 9 +: 1 - __field W 8 +: 1 - __field imm8 0 +: 8 - __opcode '11111001 0011xxxx xxxx1xxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "LDRSH (literal)"; - if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Related instructions"; - if P == '1' && U == '1' && W == '0' then SEE "LDRSHT"; - if P == '0' && W == '0' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - data = MemU[address,2]; - if wback then R[n] = offset_addr; - R[t] = SignExtend(data, 32); - -__instruction aarch32_SETEND_A - __encoding aarch32_SETEND_A1_A - __instruction_set A32 - __field E 9 +: 1 - __opcode '11110001 0000xxx1 xxxxxxxx 0000xxxx' - __guard TRUE - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - set_bigend = (E == '1'); - - __encoding aarch32_SETEND_T1_A - __instruction_set T16 - __field E 19 +: 1 - __opcode '10110110 010xxxxx 00000000 00000000' - __guard TRUE - __unpredictable_unless 20 == '1' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - set_bigend = (E == '1'); - if InITBlock() then UNPREDICTABLE; - - __execute - AArch32.CheckSETENDEnabled(); - PSTATE.E = if set_bigend then '1' else '0'; - -__instruction aarch32_VST4_1_A - __encoding aarch32_VST4_1_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx1011 xxxx1111' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if size != '10' then SEE "Related encodings"; - if index_align[1:0] == '11' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - alignment = if index_align[1:0] == '00' then 1 else 4 << UInt(index_align[1:0]); - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = TRUE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - MemU[address, ebytes] = Elem[D[d], index]; - MemU[address+ebytes, ebytes] = Elem[D[d2],index]; - MemU[address+2*ebytes,ebytes] = Elem[D[d3],index]; - MemU[address+3*ebytes,ebytes] = Elem[D[d4],index]; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 4*ebytes; - -__instruction aarch32_UQADD8_A - __encoding aarch32_UQADD8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0110xxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UQADD8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 0101xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = UInt(R[n][7:0]) + UInt(R[m][7:0]); - sum2 = UInt(R[n][15:8]) + UInt(R[m][15:8]); - sum3 = UInt(R[n][23:16]) + UInt(R[m][23:16]); - sum4 = UInt(R[n][31:24]) + UInt(R[m][31:24]); - R[d][7:0] = UnsignedSat(sum1, 8); - R[d][15:8] = UnsignedSat(sum2, 8); - R[d][23:16] = UnsignedSat(sum3, 8); - R[d][31:24] = UnsignedSat(sum4, 8); - -__instruction aarch32_STREXD_A - __encoding aarch32_STREXD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1010xxxx xxxxxx11 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); t2 = t+1; n = UInt(Rn); - if d == 15 || Rt[0] == '1' || t2 == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t || d == t2 then UNPREDICTABLE; - - __encoding aarch32_STREXD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field Rd 0 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 0111xxxx' - __guard TRUE - __decode - d = UInt(Rd); t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); - if d == 15 || t == 15 || t2 == 15 || n == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - if d == n || d == t || d == t2 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - // Create doubleword to store such that R[t] will be stored at address and R[t2] at address+4. - value = if BigEndian() then R[t]:R[t2] else R[t2]:R[t]; - if AArch32.ExclusiveMonitorsPass(address,8) then - MemA[address,8] = value; R[d] = ZeroExtend('0'); - else - R[d] = ZeroExtend('1'); - -__instruction aarch32_STR_r_A - __encoding aarch32_STR_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx011x x0x0xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "STRT"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if m == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_STR_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '0101000x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_STR_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111000 0100xxxx xxxx0000 00xxxxxx' - __guard TRUE - __decode - if Rn == '1111' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if t == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if index then offset_addr else R[n]; - if t == 15 then // Only possible for encoding A1 - data = PCStoreValue(); - else - data = R[t]; - MemU[address,4] = data; - if wback then R[n] = offset_addr; - -__instruction aarch32_STMIB_A - __encoding aarch32_STMIB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - __opcode 'xxxx1001 10x0xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - n = UInt(Rn); registers = register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - - __execute __conditional - address = R[n] + 4; - for i = 0 to 14 - if registers[i] == '1' then - if i == n && wback && i != LowestSetBit(registers) then - MemA[address,4] = bits(32) UNKNOWN; - else - MemA[address,4] = R[i]; - address = address + 4; - if registers[15] == '1' then - MemA[address,4] = PCStoreValue(); - if wback then R[n] = R[n] + 4*BitCount(registers); - -__instruction aarch32_VDIV_A - __encoding aarch32_VDIV_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x00xxxx xxxx10xx x0x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VDIV_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x00xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if size == '01' && InITBlock() then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = Zeros(16) : FPDiv(S[n][15:0], S[m][15:0], FPSCR); - when 32 - S[d] = FPDiv(S[n], S[m], FPSCR); - when 64 - D[d] = FPDiv(D[n], D[m], FPSCR); - -__instruction aarch32_LDRBT_A - __encoding aarch32_LDRBT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0100 x111xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); postindex = TRUE; add = (U == '1'); - register_form = FALSE; imm32 = ZeroExtend(imm12, 32); - if t == 15 || n == 15 || n == t then UNPREDICTABLE; - - __encoding aarch32_LDRBT_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 x111xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); postindex = TRUE; add = (U == '1'); - register_form = TRUE; (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE; - - __encoding aarch32_LDRBT_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - __opcode '11111000 0001xxxx xxxx1110 xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - if Rn == '1111' then SEE "LDRB (literal)"; - t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; - register_form = FALSE; imm32 = ZeroExtend(imm8, 32); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = if register_form then Shift(R[m], shift_t, shift_n, PSTATE.C) else imm32; - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if postindex then R[n] else offset_addr; - R[t] = ZeroExtend(MemU_unpriv[address,1],32); - if postindex then R[n] = offset_addr; - -__instruction aarch32_VEOR_A - __encoding aarch32_VEOR_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x00xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VEOR_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x00xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - D[d+r] = D[n+r] EOR D[m+r]; - -__instruction aarch32_LDRSB_r_A - __encoding aarch32_LDRSB_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx000x x0x1xxxx xxxxxxxx 1101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if P == '0' && W == '1' then SEE "LDRSBT"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - (shift_t, shift_n) = (SRType_LSL, 0); - if t == 15 || m == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_LDRSB_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '0101011x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_LDRSB_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0001xxxx xxxx0000 00xxxxxx' - __guard TRUE - __decode - if Rt == '1111' then SEE "PLI"; - if Rn == '1111' then SEE "LDRSB (literal)"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if index then offset_addr else R[n]; - R[t] = SignExtend(MemU[address,1], 32); - if wback then R[n] = offset_addr; - -__instruction aarch32_UADD8_A - __encoding aarch32_UADD8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0101xxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UADD8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 0100xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = UInt(R[n][7:0]) + UInt(R[m][7:0]); - sum2 = UInt(R[n][15:8]) + UInt(R[m][15:8]); - sum3 = UInt(R[n][23:16]) + UInt(R[m][23:16]); - sum4 = UInt(R[n][31:24]) + UInt(R[m][31:24]); - R[d][7:0] = sum1[7:0]; - R[d][15:8] = sum2[7:0]; - R[d][23:16] = sum3[7:0]; - R[d][31:24] = sum4[7:0]; - PSTATE.GE[0] = if sum1 >= 0x100 then '1' else '0'; - PSTATE.GE[1] = if sum2 >= 0x100 then '1' else '0'; - PSTATE.GE[2] = if sum3 >= 0x100 then '1' else '0'; - PSTATE.GE[3] = if sum4 >= 0x100 then '1' else '0'; - -__instruction aarch32_LDR_i_A - __encoding aarch32_LDR_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx010x x0x1xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if Rn == '1111' then SEE "LDR (literal)"; - if P == '0' && W == '1' then SEE "LDRT"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if wback && n == t then UNPREDICTABLE; - - __encoding aarch32_LDR_i_T1_A - __instruction_set T16 - __field imm5 22 +: 5 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '01101xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); - index = TRUE; add = TRUE; wback = FALSE; - - __encoding aarch32_LDR_i_T2_A - __instruction_set T16 - __field Rt 24 +: 3 - __field imm8 16 +: 8 - __opcode '10011xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); - index = TRUE; add = TRUE; wback = FALSE; - - __encoding aarch32_LDR_i_T3_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 1101xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "LDR (literal)"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); index = TRUE; add = TRUE; - wback = FALSE; if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __encoding aarch32_LDR_i_T4_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field P 10 +: 1 - __field U 9 +: 1 - __field W 8 +: 1 - __field imm8 0 +: 8 - __opcode '11111000 0101xxxx xxxx1xxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "LDR (literal)"; - if P == '1' && U == '1' && W == '0' then SEE "LDRT"; - if P == '0' && W == '0' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); - imm32 = ZeroExtend(imm8, 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; - - __execute - if CurrentInstrSet() == InstrSet_A32 then - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - data = MemU[address,4]; - if wback then R[n] = offset_addr; - if t == 15 then - if address[1:0] == '00' then - LoadWritePC(data); - else - UNPREDICTABLE; - else - R[t] = data; - else - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - data = MemU[address,4]; - if wback then R[n] = offset_addr; - if t == 15 then - if address[1:0] == '00' then - LoadWritePC(data); - else - UNPREDICTABLE; - else - R[t] = data; - -__instruction aarch32_SUB_i_A - __encoding aarch32_SUB_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 010xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if Rn == '1111' && S == '0' then SEE "ADR"; - if Rn == '1101' then SEE "SUB (SP minus immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = A32ExpandImm(imm12); - - __encoding aarch32_SUB_i_T1_A - __instruction_set T16 - __field imm3 22 +: 3 - __field Rn 19 +: 3 - __field Rd 16 +: 3 - __opcode '0001111x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); - - __encoding aarch32_SUB_i_T2_A - __instruction_set T16 - __field Rdn 24 +: 3 - __field imm8 16 +: 8 - __opcode '00111xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); - - __encoding aarch32_SUB_i_T3_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x01 101xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rd == '1111' && S == '1' then SEE "CMP (immediate)"; - if Rn == '1101' then SEE "SUB (SP minus immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = T32ExpandImm(i:imm3:imm8); - if (d == 15 && !setflags) || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_SUB_i_T4_A - __instruction_set T32 - __field i 26 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x10 1010xxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "ADR"; - if Rn == '1101' then SEE "SUB (SP minus immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_SUB_i_T5_AS - __instruction_set T32 - __field Rn 16 +: 4 - __field imm8 0 +: 8 - __opcode '11110011 1101xxxx 10x0xxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - if Rn == '1110' && IsZero(imm8) then SEE "ERET"; - d = 15; n = UInt(Rn); setflags = TRUE; imm32 = ZeroExtend(imm8, 32); - if n != 14 then UNPREDICTABLE; - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - (result, nzcv) = AddWithCarry(R[n], NOT(imm32), '1'); - if d == 15 then - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VQSHRN_A - __encoding aarch32_VQSHRN_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx100x 00x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if U == '0' && op == '0' then SEE "VSHRN"; - if Vm[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '01xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '1xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - src_unsigned = (U == '1' && op == '1'); dest_unsigned = (U == '1'); - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VQSHRN_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx100x 00x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if U == '0' && op == '0' then SEE "VSHRN"; - if Vm[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '01xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '1xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - src_unsigned = (U == '1' && op == '1'); dest_unsigned = (U == '1'); - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - operand = Int(Elem[Qin[m>>1],e,2*esize], src_unsigned); - (result, sat) = SatQ(operand >> shift_amount, esize, dest_unsigned); - Elem[D[d],e,esize] = result; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_VNMLA_A - __encoding aarch32_VNMLA_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 0x01xxxx xxxx10xx x1x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - vtype = if op == '1' then VFPNegMul_VNMLA else VFPNegMul_VNMLS; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VNMLA_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 0x01xxxx xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - vtype = if op == '1' then VFPNegMul_VNMLA else VFPNegMul_VNMLS; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - case esize of - when 16 - product16 = FPMul(S[n][15:0], S[m][15:0], FPSCR); - case vtype of - when VFPNegMul_VNMLA S[d] = Zeros(16) : FPAdd(FPNeg(S[d][15:0]), FPNeg(product16), FPSCR); - when VFPNegMul_VNMLS S[d] = Zeros(16) : FPAdd(FPNeg(S[d][15:0]), product16, FPSCR); - when VFPNegMul_VNMUL S[d] = Zeros(16) : FPNeg(product16); - when 32 - product32 = FPMul(S[n], S[m], FPSCR); - case vtype of - when VFPNegMul_VNMLA S[d] = FPAdd(FPNeg(S[d]), FPNeg(product32), FPSCR); - when VFPNegMul_VNMLS S[d] = FPAdd(FPNeg(S[d]), product32, FPSCR); - when VFPNegMul_VNMUL S[d] = FPNeg(product32); - when 64 - product64 = FPMul(D[n], D[m], FPSCR); - case vtype of - when VFPNegMul_VNMLA D[d] = FPAdd(FPNeg(D[d]), FPNeg(product64), FPSCR); - when VFPNegMul_VNMLS D[d] = FPAdd(FPNeg(D[d]), product64, FPSCR); - when VFPNegMul_VNMUL D[d] = FPNeg(product64); - -__instruction aarch32_UMAAL_A - __encoding aarch32_UMAAL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field RdHi 16 +: 4 - __field RdLo 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0000 0100xxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if dHi == dLo then UNPREDICTABLE; - - __encoding aarch32_UMAAL_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field RdLo 12 +: 4 - __field RdHi 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 1110xxxx xxxxxxxx 0110xxxx' - __guard TRUE - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - if dHi == dLo then UNPREDICTABLE; - - __execute __conditional - result = UInt(R[n]) * UInt(R[m]) + UInt(R[dHi]) + UInt(R[dLo]); - R[dHi] = result[63:32]; - R[dLo] = result[31:0]; - -__instruction aarch32_QADD8_A - __encoding aarch32_QADD8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0010xxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QADD8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 0001xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = SInt(R[n][7:0]) + SInt(R[m][7:0]); - sum2 = SInt(R[n][15:8]) + SInt(R[m][15:8]); - sum3 = SInt(R[n][23:16]) + SInt(R[m][23:16]); - sum4 = SInt(R[n][31:24]) + SInt(R[m][31:24]); - R[d][7:0] = SignedSat(sum1, 8); - R[d][15:8] = SignedSat(sum2, 8); - R[d][23:16] = SignedSat(sum3, 8); - R[d][31:24] = SignedSat(sum4, 8); - -__instruction aarch32_QSUB8_A - __encoding aarch32_QSUB8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0010xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QSUB8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1100xxxx 1111xxxx 0001xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = SInt(R[n][7:0]) - SInt(R[m][7:0]); - diff2 = SInt(R[n][15:8]) - SInt(R[m][15:8]); - diff3 = SInt(R[n][23:16]) - SInt(R[m][23:16]); - diff4 = SInt(R[n][31:24]) - SInt(R[m][31:24]); - R[d][7:0] = SignedSat(diff1, 8); - R[d][15:8] = SignedSat(diff2, 8); - R[d][23:16] = SignedSat(diff3, 8); - R[d][31:24] = SignedSat(diff4, 8); - -__instruction aarch32_VLD2_1_A - __encoding aarch32_VLD2_1_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx0001 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD2 (single 2-element structure to all lanes)"; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - alignment = if index_align[0] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD2_1_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx0101 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD2 (single 2-element structure to all lanes)"; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 4; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD2_1_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx1001 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD2 (single 2-element structure to all lanes)"; - if index_align[1] != '0' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 8; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD2_1_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx0001 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD2 (single 2-element structure to all lanes)"; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - alignment = if index_align[0] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD2_1_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx0101 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD2 (single 2-element structure to all lanes)"; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 4; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD2_1_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx1001 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD2 (single 2-element structure to all lanes)"; - if index_align[1] != '0' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 8; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - Elem[D[d], index] = MemU[address,ebytes]; - Elem[D[d2],index] = MemU[address+ebytes,ebytes]; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 2*ebytes; - -__instruction aarch32_VCGT_r_A - __encoding aarch32_VCGT_r_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0011 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - vtype = if U == '1' then VCGTtype_unsigned else VCGTtype_signed; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCGT_r_A2_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x1xxxxx xxxx1110 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - vtype = VCGTtype_fp; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCGT_r_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0011 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - vtype = if U == '1' then VCGTtype_unsigned else VCGTtype_signed; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCGT_r_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x1xxxxx xxxx1110 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - vtype = VCGTtype_fp; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[n+r],e,esize]; op2 = Elem[D[m+r],e,esize]; - case vtype of - when VCGTtype_signed test_passed = (SInt(op1) > SInt(op2)); - when VCGTtype_unsigned test_passed = (UInt(op1) > UInt(op2)); - when VCGTtype_fp test_passed = FPCompareGT(op1, op2, StandardFPSCRValue()); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_VSTM_A - __encoding aarch32_VSTM_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode 'xxxx110x xxx0xxxx xxxx1011 xxxxxxx1' - __guard cond != '1111' - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VSTR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see "FSTMX". - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if imm8[0] == '1' && (d+regs) > 16 then UNPREDICTABLE; - - __encoding aarch32_VSTM_T1A1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode '1110110x xxx0xxxx xxxx1011 xxxxxxx1' - __guard TRUE - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VSTR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see "FSTMX". - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if imm8[0] == '1' && (d+regs) > 16 then UNPREDICTABLE; - - __execute __conditional - CheckVFPEnabled(TRUE); - address = if add then R[n] else R[n]-imm32; - for r = 0 to regs-1 - if single_regs then - MemA[address,4] = S[d+r]; address = address+4; - else - // Store as two word-aligned words in the correct order for current endianness. - MemA[address,4] = if BigEndian() then D[d+r][63:32] else D[d+r][31:0]; - MemA[address+4,4] = if BigEndian() then D[d+r][31:0] else D[d+r][63:32]; - address = address+8; - if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; - -__instruction aarch32_VLDR_A - __encoding aarch32_VLDR_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm8 0 +: 8 - __opcode 'xxxx1101 xx01xxxx xxxx10xx xxxxxxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - esize = 8 << UInt(size); add = (U == '1'); - imm32 = if esize == 16 then ZeroExtend(imm8:'0', 32) else ZeroExtend(imm8:'00', 32); - case size of - when '01' d = UInt(Vd:D); - when '10' d = UInt(Vd:D); - when '11' d = UInt(D:Vd); - n = UInt(Rn); - - __encoding aarch32_VLDR_T1_A - __instruction_set T32 - __field U 23 +: 1 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm8 0 +: 8 - __opcode '11101101 xx01xxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - esize = 8 << UInt(size); add = (U == '1'); - imm32 = if esize == 16 then ZeroExtend(imm8:'0', 32) else ZeroExtend(imm8:'00', 32); - case size of - when '01' d = UInt(Vd:D); - when '10' d = UInt(Vd:D); - when '11' d = UInt(D:Vd); - n = UInt(Rn); - - __execute __conditional - CheckVFPEnabled(TRUE); - base = if n == 15 then Align(PC,4) else R[n]; - address = if add then (base + imm32) else (base - imm32); - case esize of - when 16 - S[d] = Zeros(16) : MemA[address,2]; - when 32 - S[d] = MemA[address,4]; - when 64 - word1 = MemA[address,4]; word2 = MemA[address+4,4]; - // Combine the word-aligned words in the correct order for current endianness. - D[d] = if BigEndian() then word1:word2 else word2:word1; - -__instruction aarch32_LDAH_A - __encoding aarch32_LDAH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1111xxxx xxxxxx00 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDAH_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 1001xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - R[t] = ZeroExtend(MemO[address, 2], 32); - -__instruction aarch32_SMMUL_A - __encoding aarch32_SMMUL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Rm 8 +: 4 - __field R 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0101xxxx 1111xxxx 00x1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); round = (R == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SMMUL_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field R 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0101xxxx 1111xxxx 000xxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); round = (R == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = SInt(R[n]) * SInt(R[m]); - if round then result = result + 0x80000000; - R[d] = result[63:32]; - -__instruction aarch32_STLH_A - __encoding aarch32_STLH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1110xxxx xxxxxx00 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_STLH_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 1001xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - MemO[address, 2] = R[t][15:0]; - -__instruction aarch32_VQNEG_A - __encoding aarch32_VQNEG_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0111 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQNEG_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0111 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - result = -SInt(Elem[D[m+r],e,esize]); - (Elem[D[d+r],e,esize], sat) = SignedSatQ(result, esize); - if sat then FPSCR.QC = '1'; - -__instruction aarch32_RBIT_A - __encoding aarch32_RBIT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1111xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); m = UInt(Rm); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_RBIT_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 1010xxxx' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); n = UInt(Rn); - if m != n || d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - bits(32) result; - for i = 0 to 31 - result[31-i] = R[m][i]; - R[d] = result; - -__instruction aarch32_VLD2_a_A - __encoding aarch32_VLD2_a_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx1101 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - ebytes = 1 << UInt(size); - alignment = if a == '0' then 1 else 2*ebytes; - inc = if T == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD2_a_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx1101 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - ebytes = 1 << UInt(size); - alignment = if a == '0' then 1 else 2*ebytes; - inc = if T == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - D[d] = Replicate(MemU[address,ebytes]); - D[d2] = Replicate(MemU[address+ebytes,ebytes]); - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 2*ebytes; - -__instruction aarch32_SHA1H_A - __encoding aarch32_SHA1H_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx01 xxxx0010 11x0xxxx' - __guard TRUE - __decode - if !HaveSHA1Ext() then UNDEFINED; - if size != '10' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_SHA1H_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx01 xxxx0010 11x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA1Ext() then UNDEFINED; - if size != '10' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - Q[d>>1] = ZeroExtend(ROL(Q[m>>1][31:0], 30), 128); - -__instruction aarch32_LDA_A - __encoding aarch32_LDA_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1001xxxx xxxxxx00 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDA_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 1010xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - R[t] = MemO[address, 4]; - -__instruction aarch32_VST2_m_A - __encoding aarch32_VST2_m_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x00xxxx xxxx100x xxxxxxxx' - __guard TRUE - __decode - regs = 1; if align == '11' then UNDEFINED; - if size == '11' then UNDEFINED; - inc = if itype == '1001' then 2 else 1; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST2_m_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x00xxxx xxxx0011 xxxxxxxx' - __guard TRUE - __decode - regs = 2; inc = 2; - if size == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST2_m_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x00xxxx xxxx100x xxxxxxxx' - __guard TRUE - __decode - regs = 1; if align == '11' then UNDEFINED; - if size == '11' then UNDEFINED; - inc = if itype == '1001' then 2 else 1; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST2_m_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x00xxxx xxxx0011 xxxxxxxx' - __guard TRUE - __decode - regs = 2; inc = 2; - if size == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2+regs > 32 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = TRUE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - for r = 0 to regs-1 - for e = 0 to elements-1 - MemU[address, ebytes] = Elem[D[d+r], e]; - MemU[address+ebytes,ebytes] = Elem[D[d2+r],e]; - address = address + 2*ebytes; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 16*regs; - -__instruction aarch32_SHA1C_A - __encoding aarch32_SHA1C_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x00xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if !HaveSHA1Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_SHA1C_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x00xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA1Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - X = Q[d>>1]; - Y = Q[n>>1][31:0]; // Note: 32 bits wide - W = Q[m>>1]; - for e = 0 to 3 - t = SHAchoose(X[63:32], X[95:64], X[127:96]); - Y = Y + ROL(X[31:0], 5) + t + Elem[W, e, 32]; - X[63:32] = ROL(X[63:32], 30); - [Y, X] = ROL(Y:X, 32); - Q[d>>1] = X; - -__instruction aarch32_STLEXH_A - __encoding aarch32_STLEXH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1110xxxx xxxxxx10 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t then UNPREDICTABLE; - - __encoding aarch32_STLEXH_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rd 0 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 1101xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - if AArch32.ExclusiveMonitorsPass(address,2) then - MemO[address, 2] = R[t][15:0]; - R[d] = ZeroExtend('0'); - else - R[d] = ZeroExtend('1'); - -__instruction aarch32_VMLA_i_A - __encoding aarch32_VMLA_i_T2A2_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx1010 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - add = (op == '0'); long_destination = TRUE; unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __encoding aarch32_VMLA_i_T2A2_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx1010 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - add = (op == '0'); long_destination = TRUE; unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - product = Int(Elem[Din[n+r],e,esize],unsigned) * Int(Elem[Din[m+r],e,esize],unsigned); - addend = if add then product else -product; - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend; - -__instruction aarch32_SMLAD_A - __encoding aarch32_SMLAD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field M 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0000xxxx xxxxxxxx 00x1xxxx' - __guard cond != '1111' - __decode - if Ra == '1111' then SEE "SMUAD"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - m_swap = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SMLAD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0010xxxx xxxxxxxx 000xxxxx' - __guard TRUE - __decode - if Ra == '1111' then SEE "SMUAD"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - m_swap = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand2 = if m_swap then ROR(R[m],16) else R[m]; - product1 = SInt(R[n][15:0]) * SInt(operand2[15:0]); - product2 = SInt(R[n][31:16]) * SInt(operand2[31:16]); - result = product1 + product2 + SInt(R[a]); - R[d] = result[31:0]; - if result != SInt(result[31:0]) then // Signed overflow - PSTATE.Q = '1'; - -__instruction aarch32_DCPS1_A - __encoding aarch32_DCPS1_T1_A - __instruction_set T32 - __opcode '11110111 10001111 10000000 00000001' - __guard TRUE - __decode - // No additional decoding required. - - __execute - if !Halted() then UNDEFINED; - - if EL2Enabled() && PSTATE.EL == EL0 then - tge = if ELUsingAArch32(EL2) then HCR.TGE else HCR_EL2.TGE; - if tge == '1' then UNDEFINED; - - if PSTATE.EL != EL0 || ELUsingAArch32(EL1) then - if PSTATE.M == M32_Monitor then SCR.NS = '0'; - if PSTATE.EL != EL2 then - AArch32.WriteMode(M32_Svc); - PSTATE.E = SCTLR.EE; - if HavePANExt() && SCTLR.SPAN == '0' then PSTATE.PAN = '1'; - LR_svc = bits(32) UNKNOWN; - SPSR_svc = bits(32) UNKNOWN; - else - PSTATE.E = HSCTLR.EE; - ELR_hyp = bits(32) UNKNOWN; - HSR = bits(32) UNKNOWN; - SPSR_hyp = bits(32) UNKNOWN; - - DLR = bits(32) UNKNOWN; - DSPSR = bits(32) UNKNOWN; - else // Targeting EL1 using AArch64 - AArch64.MaybeZeroRegisterUppers(); - MaybeZeroSVEUppers(EL1); - PSTATE.nRW = '0'; - PSTATE.SP = '1'; - PSTATE.EL = EL1; - if HavePANExt() && SCTLR_EL1.SPAN == '0' then PSTATE.PAN = '1'; - if HaveUAOExt() then PSTATE.UAO = '0'; - - ELR_EL1 = bits(64) UNKNOWN; - ESR_EL1 = bits(32) UNKNOWN; - SPSR_EL1 = bits(32) UNKNOWN; - - DLR_EL0 = bits(64) UNKNOWN; - DSPSR_EL0 = bits(32) UNKNOWN; - - // SCTLR_EL1.IESB might be ignored in Debug state. - if HaveIESB() && SCTLR_EL1.IESB == '1' && !ConstrainUnpredictableBool(Unpredictable_IESBinDebug) then - SynchronizeErrors(); - - UpdateEDSCRFields(); // Update EDSCR PE state flags - -__instruction aarch32_LDRSHT_A - __encoding aarch32_LDRSHT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx0000 x111xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); postindex = TRUE; add = (U == '1'); - register_form = FALSE; imm32 = ZeroExtend(imm4H:imm4L, 32); - if t == 15 || n == 15 || n == t then UNPREDICTABLE; - - __encoding aarch32_LDRSHT_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0000 x011xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); postindex = TRUE; add = (U == '1'); - register_form = TRUE; - if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE; - - __encoding aarch32_LDRSHT_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - __opcode '11111001 0011xxxx xxxx1110 xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - if Rn == '1111' then SEE "LDRSH (literal)"; - t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; - register_form = FALSE; imm32 = ZeroExtend(imm8, 32); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = if register_form then R[m] else imm32; - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if postindex then R[n] else offset_addr; - data = MemU_unpriv[address,2]; - if postindex then R[n] = offset_addr; - R[t] = SignExtend(data, 32); - -__instruction aarch32_VCVT_is_A - __encoding aarch32_VCVT_is_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx11 xxxx011x xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - to_integer = (op[1] == '1'); unsigned = (op[0] == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCVT_is_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx11 xxxx011x xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - to_integer = (op[1] == '1'); unsigned = (op[0] == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - bits(esize) result; - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[m+r],e,esize]; - if to_integer then - result = FPToFixed(op1, 0, unsigned, StandardFPSCRValue(), FPRounding_ZERO); - else - result = FixedToFP(op1, 0, unsigned, StandardFPSCRValue(), FPRounding_TIEEVEN); - Elem[D[d+r],e,esize] = result; - -__instruction aarch32_AESD_A - __encoding aarch32_AESD_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0011 01x0xxxx' - __guard TRUE - __decode - if !HaveAESExt() then UNDEFINED; - if size != '00' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_AESD_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0011 01x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAESExt() then UNDEFINED; - if size != '00' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - op1 = Q[d>>1]; op2 = Q[m>>1]; - Q[d>>1] = AESInvSubBytes(AESInvShiftRows(op1 EOR op2)); - -__instruction aarch32_VLD4_1_A - __encoding aarch32_VLD4_1_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx0011 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD4 (single 4-element structure to all lanes)"; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - alignment = if index_align[0] == '0' then 1 else 4; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD4_1_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx0111 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD4 (single 4-element structure to all lanes)"; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 8; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD4_1_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx1011 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD4 (single 4-element structure to all lanes)"; - if index_align[1:0] == '11' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - alignment = if index_align[1:0] == '00' then 1 else 4 << UInt(index_align[1:0]); - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD4_1_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx0011 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD4 (single 4-element structure to all lanes)"; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - alignment = if index_align[0] == '0' then 1 else 4; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD4_1_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx0111 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD4 (single 4-element structure to all lanes)"; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 8; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD4_1_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx1011 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD4 (single 4-element structure to all lanes)"; - if index_align[1:0] == '11' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - alignment = if index_align[1:0] == '00' then 1 else 4 << UInt(index_align[1:0]); - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - Elem[D[d], index] = MemU[address,ebytes]; - Elem[D[d2],index] = MemU[address+ebytes,ebytes]; - Elem[D[d3],index] = MemU[address+2*ebytes,ebytes]; - Elem[D[d4],index] = MemU[address+3*ebytes,ebytes]; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 4*ebytes; - -__instruction aarch32_VDOT_s_A - __encoding aarch32_VDOT_s_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x10xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if !HaveDOTPExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - boolean signed = (U=='0'); - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm[3:0]); - integer index = UInt(M); - integer esize = 32; - integer regs = if Q == '1' then 2 else 1; - - __encoding aarch32_VDOT_s_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x10xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveDOTPExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - boolean signed = (U=='0'); - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm[3:0]); - integer index = UInt(M); - integer esize = 32; - integer regs = if Q == '1' then 2 else 1; - - __execute - bits(64) operand1; - bits(64) operand2 = D[m]; - bits(64) result; - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - operand1 = D[n+r]; - result = D[d+r]; - integer element1, element2; - for e = 0 to 1 - integer res = 0; - for i = 0 to 3 - if signed then - element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = SInt(Elem[operand2, 4 * index + i, esize DIV 4]); - else - element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = UInt(Elem[operand2, 4 * index + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = Elem[result, e, esize] + res; - D[d+r] = result; - -__instruction aarch32_SMUAD_A - __encoding aarch32_SMUAD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Rm 8 +: 4 - __field M 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0000xxxx 1111xxxx 00x1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SMUAD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0010xxxx 1111xxxx 000xxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand2 = if m_swap then ROR(R[m],16) else R[m]; - product1 = SInt(R[n][15:0]) * SInt(operand2[15:0]); - product2 = SInt(R[n][31:16]) * SInt(operand2[31:16]); - result = product1 + product2; - R[d] = result[31:0]; - if result != SInt(result[31:0]) then // Signed overflow - PSTATE.Q = '1'; - -__instruction aarch32_VMAX_i_A - __encoding aarch32_VMAX_i_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field op 4 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0110 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - maximum = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMAX_i_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field op 4 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0110 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - maximum = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Int(Elem[D[n+r],e,esize], unsigned); - op2 = Int(Elem[D[m+r],e,esize], unsigned); - result = if maximum then Max(op1,op2) else Min(op1,op2); - Elem[D[d+r],e,esize] = result[esize-1:0]; - -__instruction aarch32_LDRSH_l_A - __encoding aarch32_LDRSH_l_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x11111 xxxxxxxx 1111xxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "LDRSHT"; - t = UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); - add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 || wback then UNPREDICTABLE; - - __encoding aarch32_LDRSH_l_T1_A - __instruction_set T32 - __field U 23 +: 1 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111001 x0111111 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rt == '1111' then SEE "Related instructions"; - t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - base = Align(PC,4); - address = if add then (base + imm32) else (base - imm32); - data = MemU[address,2]; - R[t] = SignExtend(data, 32); - -__instruction aarch32_VQMOVN_A - __encoding aarch32_VQMOVN_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 6 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0010 xxx0xxxx' - __guard TRUE - __decode - if op == '00' then SEE "VMOVN"; - if size == '11' || Vm[0] == '1' then UNDEFINED; - src_unsigned = (op == '11'); dest_unsigned = (op[0] == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VQMOVN_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 6 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0010 xxx0xxxx' - __guard TRUE - __decode - if op == '00' then SEE "VMOVN"; - if size == '11' || Vm[0] == '1' then UNDEFINED; - src_unsigned = (op == '11'); dest_unsigned = (op[0] == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - operand = Int(Elem[Qin[m>>1],e,2*esize], src_unsigned); - (Elem[D[d],e,esize], sat) = SatQ(operand, esize, dest_unsigned); - if sat then FPSCR.QC = '1'; - -__instruction aarch32_UQASX_A - __encoding aarch32_UQASX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0110xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UQASX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1010xxxx 1111xxxx 0101xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff = UInt(R[n][15:0]) - UInt(R[m][31:16]); - sum = UInt(R[n][31:16]) + UInt(R[m][15:0]); - R[d][15:0] = UnsignedSat(diff, 16); - R[d][31:16] = UnsignedSat(sum, 16); - -__instruction aarch32_VNEG_A - __encoding aarch32_VNEG_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx01 xxxx0x11 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - advsimd = TRUE; floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VNEG_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110001 xxxx10xx 01x0xxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - advsimd = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VNEG_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx01 xxxx0x11 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - advsimd = TRUE; floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VNEG_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110001 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - advsimd = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - if floating_point then - Elem[D[d+r],e,esize] = FPNeg(Elem[D[m+r],e,esize]); - else - result = -SInt(Elem[D[m+r],e,esize]); - Elem[D[d+r],e,esize] = result[esize-1:0]; - else // VFP instruction - case esize of - when 16 S[d] = Zeros(16) : FPNeg(S[m][15:0]); - when 32 S[d] = FPNeg(S[m]); - when 64 D[d] = FPNeg(D[m]); - -__instruction aarch32_VCVT_ds_A - __encoding aarch32_VCVT_ds_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110111 xxxx101x 11x0xxxx' - __guard cond != '1111' - __decode - double_to_single = (size == '11'); - d = if double_to_single then UInt(Vd:D) else UInt(D:Vd); - m = if double_to_single then UInt(M:Vm) else UInt(Vm:M); - - __encoding aarch32_VCVT_ds_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110111 xxxx101x 11x0xxxx' - __guard TRUE - __decode - double_to_single = (size == '11'); - d = if double_to_single then UInt(Vd:D) else UInt(D:Vd); - m = if double_to_single then UInt(M:Vm) else UInt(Vm:M); - - __execute __conditional - CheckVFPEnabled(TRUE); - if double_to_single then - S[d] = FPConvert(D[m], FPSCR); - else - D[d] = FPConvert(S[m], FPSCR); - -__instruction aarch32_SSAT_A - __encoding aarch32_SSAT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field sat_imm 16 +: 5 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field sh 6 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0110 101xxxxx xxxxxxxx xx01xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm)+1; - (shift_t, shift_n) = DecodeImmShift(sh:'0', imm5); - if d == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_SSAT_T1_A - __instruction_set T32 - __field sh 21 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field sat_imm 0 +: 5 - __opcode '11110x11 00x0xxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 26 == '0' - __unpredictable_unless 5 == '0' - __decode - if sh == '1' && (imm3:imm2) == '00000' then SEE "SSAT16"; - d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm)+1; - (shift_t, shift_n) = DecodeImmShift(sh:'0', imm3:imm2); - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand = Shift(R[n], shift_t, shift_n, PSTATE.C); // PSTATE.C ignored - (result, sat) = SignedSatQ(SInt(operand), saturate_to); - R[d] = SignExtend(result, 32); - if sat then - PSTATE.Q = '1'; - -__instruction aarch32_STMDA_A - __encoding aarch32_STMDA_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - __opcode 'xxxx1000 00x0xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - n = UInt(Rn); registers = register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - - __execute __conditional - address = R[n] - 4*BitCount(registers) + 4; - for i = 0 to 14 - if registers[i] == '1' then - if i == n && wback && i != LowestSetBit(registers) then - MemA[address,4] = bits(32) UNKNOWN; - else - MemA[address,4] = R[i]; - address = address + 4; - if registers[15] == '1' then - MemA[address,4] = PCStoreValue(); - if wback then R[n] = R[n] - 4*BitCount(registers); - -__instruction aarch32_RSB_i_A - __encoding aarch32_RSB_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 011xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = A32ExpandImm(imm12); - - __encoding aarch32_RSB_i_T1_A - __instruction_set T16 - __field Rn 19 +: 3 - __field Rd 16 +: 3 - __opcode '01000010 01xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = Zeros(32); // immediate = #0 - - __encoding aarch32_RSB_i_T2_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x01 110xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = T32ExpandImm(i:imm3:imm8); - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (result, nzcv) = AddWithCarry(NOT(R[n]), imm32, '1'); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VRSHL_A - __encoding aarch32_VRSHL_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRSHL_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - shift = SInt(Elem[D[n+r],e,esize][7:0]); - round_const = 1 << (-shift-1); // 0 for left shift, 2^(n-1) for right shift - result = (Int(Elem[D[m+r],e,esize], unsigned) + round_const) << shift; - Elem[D[d+r],e,esize] = result[esize-1:0]; - -__instruction aarch32_TEQ_r_A - __encoding aarch32_TEQ_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0011xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_TEQ_r_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101010 1001xxxx xxxx1111 xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] EOR shifted; - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_ORR_i_A - __encoding aarch32_ORR_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 100xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); - (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C); - - __encoding aarch32_ORR_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x00 010xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "MOV (immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); - (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = R[n] OR imm32; - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_SHA256H_A - __encoding aarch32_SHA256H_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x00xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if !HaveSHA256Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_SHA256H_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x00xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA256Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - X = Q[d>>1]; Y = Q[n>>1]; W = Q[m>>1]; part1 = TRUE; - Q[d>>1] = SHA256hash(X, Y, W, part1); - -__instruction aarch32_VTST_A - __encoding aarch32_VTST_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0xxxxxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VTST_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0xxxxxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - if !IsZero(Elem[D[n+r],e,esize] AND Elem[D[m+r],e,esize]) then - Elem[D[d+r],e,esize] = Ones(esize); - else - Elem[D[d+r],e,esize] = Zeros(esize); - -__instruction aarch32_MMLA_A - __encoding aarch32_MMLA_A1_A - __instruction_set A32 - __field B 23 +: 1 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x10xxxx xxxx1100 x1x0xxxx' - __guard TRUE - __decode - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - case B:U of - when '00' op1_unsigned = FALSE; op2_unsigned = FALSE; - when '01' op1_unsigned = TRUE; op2_unsigned = TRUE; - when '10' op1_unsigned = TRUE; op2_unsigned = FALSE; - when '11' UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - - __encoding aarch32_MMLA_T1_A - __instruction_set T32 - __field B 23 +: 1 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x10xxxx xxxx1100 x1x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - case B:U of - when '00' op1_unsigned = FALSE; op2_unsigned = FALSE; - when '01' op1_unsigned = TRUE; op2_unsigned = TRUE; - when '10' op1_unsigned = TRUE; op2_unsigned = FALSE; - when '11' UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - - __execute - CheckAdvSIMDEnabled(); - bits(128) operand1 = Q[n>>1]; - bits(128) operand2 = Q[m>>1]; - bits(128) addend = Q[d>>1]; - - Q[d>>1] = MatMulAdd(addend, operand1, operand2, op1_unsigned, op2_unsigned); - -__instruction aarch32_VORN_r_A - __encoding aarch32_VORN_r_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x11xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VORN_r_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x11xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - D[d+r] = D[n+r] OR NOT(D[m+r]); - -__instruction aarch32_VRINTA_vfp_A - __encoding aarch32_VRINTA_vfp_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111000 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VRINTA_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111000 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = Zeros(16) : FPRoundInt(S[m][15:0], FPSCR, rounding, exact); - when 32 - S[d] = FPRoundInt(S[m], FPSCR, rounding, exact); - when 64 - D[d] = FPRoundInt(D[m], FPSCR, rounding, exact); - -__instruction aarch32_LDR_r_A - __encoding aarch32_LDR_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx011x x0x1xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "LDRT"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if m == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_LDR_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '0101100x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_LDR_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111000 0101xxxx xxxx0000 00xxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "LDR (literal)"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute - if CurrentInstrSet() == InstrSet_A32 then - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if index then offset_addr else R[n]; - data = MemU[address,4]; - if wback then R[n] = offset_addr; - if t == 15 then - if address[1:0] == '00' then - LoadWritePC(data); - else - UNPREDICTABLE; - else - R[t] = data; - else - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - offset_addr = (R[n] + offset); - address = offset_addr; - data = MemU[address,4]; - if t == 15 then - if address[1:0] == '00' then - LoadWritePC(data); - else - UNPREDICTABLE; - else - R[t] = data; - -__instruction aarch32_BIC_r_A - __encoding aarch32_BIC_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 110xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_BIC_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rdn 16 +: 3 - __opcode '01000011 10xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_BIC_r_T2_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101010 001xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] AND NOT(shifted); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VREV16_A - __encoding aarch32_VREV16_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0000 1xx0xxxx' - __guard TRUE - __decode - if UInt(op)+UInt(size) >= 3 then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - - esize = 8 << UInt(size); - integer container_size; - case op of - when '10' container_size = 16; - when '01' container_size = 32; - when '00' container_size = 64; - integer containers = 64 DIV container_size; - integer elements_per_container = container_size DIV esize; - - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VREV16_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0000 1xx0xxxx' - __guard TRUE - __decode - if UInt(op)+UInt(size) >= 3 then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - - esize = 8 << UInt(size); - integer container_size; - case op of - when '10' container_size = 16; - when '01' container_size = 32; - when '00' container_size = 64; - integer containers = 64 DIV container_size; - integer elements_per_container = container_size DIV esize; - - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - - bits(64) result; - integer element; - integer rev_element; - for r = 0 to regs-1 - element = 0; - for c = 0 to containers-1 - rev_element = element + elements_per_container - 1; - for e = 0 to elements_per_container-1 - Elem[result, rev_element, esize] = Elem[D[m+r], element, esize]; - element = element + 1; - rev_element = rev_element - 1; - D[d+r] = result; - -__instruction aarch32_SUB_rr_A - __encoding aarch32_SUB_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 010xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], NOT(shifted), '1'); - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VSWP_A - __encoding aarch32_VSWP_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x110010 xxxx0000 0xx0xxxx' - __guard TRUE - __decode - if size != '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSWP_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x110010 xxxx0000 0xx0xxxx' - __guard TRUE - __decode - if size != '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - if d == m then - D[d+r] = bits(64) UNKNOWN; - else - D[d+r] = Din[m+r]; - D[m+r] = Din[d+r]; - -__instruction aarch32_ADC_i_A - __encoding aarch32_ADC_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 101xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = A32ExpandImm(imm12); - - __encoding aarch32_ADC_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x01 010xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = T32ExpandImm(i:imm3:imm8); - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (result, nzcv) = AddWithCarry(R[n], imm32, PSTATE.C); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_STRD_i_A - __encoding aarch32_STRD_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x0xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __decode - if Rt[0] == '1' then UNPREDICTABLE; - t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if P == '0' && W == '1' then UNPREDICTABLE; - if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; - if t2 == 15 then UNPREDICTABLE; - - __encoding aarch32_STRD_i_T1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field imm8 0 +: 8 - __opcode '1110100x x1x0xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if P == '0' && W == '0' then SEE "Related encodings"; - t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if wback && (n == t || n == t2) then UNPREDICTABLE; - if n == 15 || t == 15 || t2 == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - if address == Align(address, 8) then - bits(64) data; - if BigEndian() then - data[63:32] = R[t]; - data[31:0] = R[t2]; - else - data[31:0] = R[t]; - data[63:32] = R[t2]; - MemA[address,8] = data; - else - MemA[address,4] = R[t]; - MemA[address+4,4] = R[t2]; - if wback then R[n] = offset_addr; - -__instruction aarch32_VSLI_A - __encoding aarch32_VSLI_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1xxxxxxx xxxx0101 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = UInt(imm6) - 8; - when '001xxxx' esize = 16; elements = 4; shift_amount = UInt(imm6) - 16; - when '01xxxxx' esize = 32; elements = 2; shift_amount = UInt(imm6) - 32; - when '1xxxxxx' esize = 64; elements = 1; shift_amount = UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSLI_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1xxxxxxx xxxx0101 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = UInt(imm6) - 8; - when '001xxxx' esize = 16; elements = 4; shift_amount = UInt(imm6) - 16; - when '01xxxxx' esize = 32; elements = 2; shift_amount = UInt(imm6) - 32; - when '1xxxxxx' esize = 64; elements = 1; shift_amount = UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - mask = LSL(Ones(esize), shift_amount); - for r = 0 to regs-1 - for e = 0 to elements-1 - shifted_op = LSL(Elem[D[m+r],e,esize], shift_amount); - Elem[D[d+r],e,esize] = (Elem[D[d+r],e,esize] AND NOT(mask)) OR shifted_op; - -__instruction aarch32_VRSHR_A - __encoding aarch32_VRSHR_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0010 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRSHR_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0010 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - round_const = 1 << (shift_amount - 1); - for r = 0 to regs-1 - for e = 0 to elements-1 - result = (Int(Elem[D[m+r],e,esize], unsigned) + round_const) >> shift_amount; - Elem[D[d+r],e,esize] = result[esize-1:0]; - -__instruction aarch32_LDRD_l_A - __encoding aarch32_LDRD_l_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x01111 xxxxxxxx 1101xxxx' - __guard cond != '1111' - __unpredictable_unless 24 == '1' - __unpredictable_unless 21 == '0' - __decode - if Rt[0] == '1' then UNPREDICTABLE; - t = UInt(Rt); t2 = t+1; imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); - if t2 == 15 then UNPREDICTABLE; - - __encoding aarch32_LDRD_l_T1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field imm8 0 +: 8 - __opcode '1110100x x1x11111 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if P == '0' && W == '0' then SEE "Related encodings"; - t = UInt(Rt); t2 = UInt(Rt2); - imm32 = ZeroExtend(imm8:'00', 32); add = (U == '1'); - if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - if W == '1' then UNPREDICTABLE; - - __execute __conditional - address = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); - if address == Align(address, 8) then - data = MemA[address,8]; - if BigEndian() then - R[t] = data[63:32]; - R[t2] = data[31:0]; - else - R[t] = data[31:0]; - R[t2] = data[63:32]; - else - R[t] = MemA[address,4]; - R[t2] = MemA[address+4,4]; - -__instruction aarch32_MSR_r_AS - __encoding aarch32_MSR_r_A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field R 22 +: 1 - __field mask 16 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0001 0x10xxxx xxxxxx0x 0000xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 8 == '0' - __decode - n = UInt(Rn); write_spsr = (R == '1'); - if mask == '0000' then UNPREDICTABLE; - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_MSR_r_T1_AS - __instruction_set T32 - __field R 20 +: 1 - __field Rn 16 +: 4 - __field mask 8 +: 4 - __opcode '11110011 100xxxxx 10x0xxxx xx0xxxxx' - __guard TRUE - __unpredictable_unless 13 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 4 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - n = UInt(Rn); write_spsr = (R == '1'); - if mask == '0000' then UNPREDICTABLE; - if n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - if write_spsr then - if PSTATE.M IN {M32_User,M32_System} then - UNPREDICTABLE; - else - SPSRWriteByInstr(R[n], mask); - else - // Attempts to change to an illegal mode will invoke the Illegal Execution state mechanism - CPSRWriteByInstr(R[n], mask); - -__instruction aarch32_VST1_1_A - __encoding aarch32_VST1_1_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx0000 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[0] != '0' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); alignment = 1; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VST1_1_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx0100 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[1] != '0' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - alignment = if index_align[0] == '0' then 1 else 2; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VST1_1_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx1000 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[2] != '0' then UNDEFINED; - if index_align[1:0] != '00' && index_align[1:0] != '11' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - alignment = if index_align[1:0] == '00' then 1 else 4; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VST1_1_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx0000 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[0] != '0' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); alignment = 1; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VST1_1_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx0100 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[1] != '0' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - alignment = if index_align[0] == '0' then 1 else 2; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VST1_1_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx1000 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[2] != '0' then UNDEFINED; - if index_align[1:0] != '00' && index_align[1:0] != '11' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - alignment = if index_align[1:0] == '00' then 1 else 4; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = TRUE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - MemU[address,ebytes] = Elem[D[d],index]; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + ebytes; - -__instruction aarch32_VFMA_bf_A - __encoding aarch32_VFMA_bf_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x11xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer elements = 128 DIV 32; - integer sel = UInt(Q); - - __encoding aarch32_VFMA_bf_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x11xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32BF16Ext() then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer elements = 128 DIV 32; - integer sel = UInt(Q); - - __execute - CheckAdvSIMDEnabled(); - bits(128) operand1 = Q[n>>1]; - bits(128) operand2 = Q[m>>1]; - bits(128) operand3 = Q[d>>1]; - bits(128) result; - - for e = 0 to elements-1 - bits(32) element1 = Elem[operand1, 2 * e + sel, 16] : Zeros(16); - bits(32) element2 = Elem[operand2, 2 * e + sel, 16] : Zeros(16); - bits(32) addend = Elem[operand3, e, 32]; - Elem[result, e, 32] = FPMulAdd(addend, element1, element2, - StandardFPSCRValue()); - - Q[d>>1] = result; - -__instruction aarch32_DCPS3_A - __encoding aarch32_DCPS3_T1_A - __instruction_set T32 - __opcode '11110111 10001111 10000000 00000011' - __guard TRUE - __decode - if !HaveEL(EL3) then UNDEFINED; - - __execute - if !Halted() || EDSCR.SDD == '1' then UNDEFINED; - - if ELUsingAArch32(EL3) then - from_secure = IsSecure(); - if PSTATE.M == M32_Monitor then SCR.NS = '0'; - AArch32.WriteMode(M32_Monitor); - if HavePANExt() then - if !from_secure then - PSTATE.PAN = '0'; - elsif SCTLR.SPAN == '0' then - PSTATE.PAN = '1'; - PSTATE.E = SCTLR.EE; - - LR_mon = bits(32) UNKNOWN; - SPSR_mon = bits(32) UNKNOWN; - - DLR = bits(32) UNKNOWN; - DSPSR = bits(32) UNKNOWN; - else // Targeting EL3 using AArch64 - AArch64.MaybeZeroRegisterUppers(); - MaybeZeroSVEUppers(EL3); - PSTATE.nRW = '0'; - PSTATE.SP = '1'; - PSTATE.EL = EL3; - if HaveUAOExt() then PSTATE.UAO = '0'; - - ELR_EL3 = bits(64) UNKNOWN; - ESR_EL3 = bits(32) UNKNOWN; - SPSR_EL3 = bits(32) UNKNOWN; - - DLR_EL0 = bits(64) UNKNOWN; - DSPSR_EL0 = bits(32) UNKNOWN; - - sync_errors = HaveIESB() && SCTLR_EL3.IESB == '1'; - if HaveDoubleFaultExt() && SCR_EL3.EA == '1' && SCR_EL3.NMEA == '1' then - sync_errors = TRUE; - // SCTLR_EL3.IESB might be ignored in Debug state. - if !ConstrainUnpredictableBool(Unpredictable_IESBinDebug) then - sync_errors = FALSE; - if sync_errors then SynchronizeErrors(); - - UpdateEDSCRFields(); // Update EDSCR PE state flags - -__instruction aarch32_BFI_A - __encoding aarch32_BFI_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field msb 16 +: 5 - __field Rd 12 +: 4 - __field lsb 7 +: 5 - __field Rn 0 +: 4 - __opcode 'xxxx0111 110xxxxx xxxxxxxx x001xxxx' - __guard cond != '1111' - __decode - if Rn == '1111' then SEE "BFC"; - d = UInt(Rd); n = UInt(Rn); msbit = UInt(msb); lsbit = UInt(lsb); - if d == 15 then UNPREDICTABLE; - - __encoding aarch32_BFI_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field msb 0 +: 5 - __opcode '11110x11 0110xxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 26 == '0' - __unpredictable_unless 5 == '0' - __decode - if Rn == '1111' then SEE "BFC"; - d = UInt(Rd); n = UInt(Rn); msbit = UInt(msb); lsbit = UInt(imm3:imm2); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - if msbit >= lsbit then - R[d][msbit:lsbit] = R[n][(msbit-lsbit):0]; - // Other bits of R[d] are unchanged - else - UNPREDICTABLE; - -__instruction aarch32_VREV16_A - __encoding aarch32_VREV16_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0000 0xx0xxxx' - __guard TRUE - __decode - if UInt(op)+UInt(size) >= 3 then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - - esize = 8 << UInt(size); - integer container_size; - case op of - when '10' container_size = 16; - when '01' container_size = 32; - when '00' container_size = 64; - integer containers = 64 DIV container_size; - integer elements_per_container = container_size DIV esize; - - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VREV16_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0000 0xx0xxxx' - __guard TRUE - __decode - if UInt(op)+UInt(size) >= 3 then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - - esize = 8 << UInt(size); - integer container_size; - case op of - when '10' container_size = 16; - when '01' container_size = 32; - when '00' container_size = 64; - integer containers = 64 DIV container_size; - integer elements_per_container = container_size DIV esize; - - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - - bits(64) result; - integer element; - integer rev_element; - for r = 0 to regs-1 - element = 0; - for c = 0 to containers-1 - rev_element = element + elements_per_container - 1; - for e = 0 to elements_per_container-1 - Elem[result, rev_element, esize] = Elem[D[m+r], element, esize]; - element = element + 1; - rev_element = rev_element - 1; - D[d+r] = result; - -__instruction aarch32_VDUP_s_A - __encoding aarch32_VDUP_s_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field imm4 16 +: 4 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xxxx xxxx1100 0xx0xxxx' - __guard TRUE - __decode - if imm4 == 'x000' then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - case imm4 of - when 'xxx1' esize = 8; elements = 8; index = UInt(imm4[3:1]); - when 'xx10' esize = 16; elements = 4; index = UInt(imm4[3:2]); - when 'x100' esize = 32; elements = 2; index = UInt(imm4[3]); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VDUP_s_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field imm4 16 +: 4 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xxxx xxxx1100 0xx0xxxx' - __guard TRUE - __decode - if imm4 == 'x000' then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - case imm4 of - when 'xxx1' esize = 8; elements = 8; index = UInt(imm4[3:1]); - when 'xx10' esize = 16; elements = 4; index = UInt(imm4[3:2]); - when 'x100' esize = 32; elements = 2; index = UInt(imm4[3]); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - scalar = Elem[D[m],index,esize]; - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = scalar; - -__instruction aarch32_ORR_r_A - __encoding aarch32_ORR_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 100xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_ORR_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rdn 16 +: 3 - __opcode '01000011 00xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_ORR_r_T2_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101010 010xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - if Rn == '1111' then SEE "Related encodings"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] OR shifted; - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VMAXNM_A - __encoding aarch32_VMAXNM_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x1xxxxx xxxx1111 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - maximum = (op == '0'); - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMAXNM_A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x00xxxx xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - advsimd = FALSE; - maximum = (op == '0'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VMAXNM_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x1xxxxx xxxx1111 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - maximum = (op == '0'); - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMAXNM_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x00xxxx xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - advsimd = FALSE; - maximum = (op == '0'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[n+r], e, esize]; op2 = Elem[D[m+r], e, esize]; - if maximum then - Elem[D[d+r], e, esize] = FPMaxNum(op1, op2, StandardFPSCRValue()); - else - Elem[D[d+r], e, esize] = FPMinNum(op1, op2, StandardFPSCRValue()); - else // VFP instruction - case esize of - when 16 - if maximum then - S[d] = Zeros(16) : FPMaxNum(S[n][15:0], S[m][15:0], FPSCR); - else - S[d] = Zeros(16) : FPMinNum(S[n][15:0], S[m][15:0], FPSCR); - when 32 - if maximum then - S[d] = FPMaxNum(S[n], S[m], FPSCR); - else - S[d] = FPMinNum(S[n], S[m], FPSCR); - when 64 - if maximum then - D[d] = FPMaxNum(D[n], D[m], FPSCR); - else - D[d] = FPMinNum(D[n], D[m], FPSCR); - -__instruction aarch32_MOV_i_A - __encoding aarch32_MOV_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 101xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C); - - __encoding aarch32_MOV_i_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field imm4 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 0000xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); - if d == 15 then UNPREDICTABLE; - - __encoding aarch32_MOV_i_T1_A - __instruction_set T16 - __field Rd 24 +: 3 - __field imm8 16 +: 8 - __opcode '00100xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); carry = PSTATE.C; - - __encoding aarch32_MOV_i_T2_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x00 010x1111 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_MOV_i_T3_A - __instruction_set T32 - __field i 26 +: 1 - __field imm4 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x10 0100xxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = imm32; - if d == 15 then // Can only occur for encoding A1 - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VLDM_A - __encoding aarch32_VLDM_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode 'xxxx110x xxx1xxxx xxxx1011 xxxxxxx1' - __guard cond != '1111' - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VLDR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see "FLDM*X". - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if imm8[0] == '1' && (d+regs) > 16 then UNPREDICTABLE; - - __encoding aarch32_VLDM_T1A1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field D 22 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field imm8 0 +: 8 - __opcode '1110110x xxx1xxxx xxxx1011 xxxxxxx1' - __guard TRUE - __decode - if P == '0' && U == '0' && W == '0' then SEE "Related encodings"; - if P == '1' && W == '0' then SEE "VLDR"; - if P == U && W == '1' then UNDEFINED; - // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - single_regs = FALSE; add = (U == '1'); wback = (W == '1'); - d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see "FLDM*X". - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; - if imm8[0] == '1' && (d+regs) > 16 then UNPREDICTABLE; - - __execute __conditional - CheckVFPEnabled(TRUE); - address = if add then R[n] else R[n]-imm32; - for r = 0 to regs-1 - if single_regs then - S[d+r] = MemA[address,4]; address = address+4; - else - word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; - // Combine the word-aligned words in the correct order for current endianness. - D[d+r] = if BigEndian() then word1:word2 else word2:word1; - if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; - -__instruction aarch32_VMAXNM_A - __encoding aarch32_VMAXNM_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x0xxxxx xxxx1111 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - maximum = (op == '0'); - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMAXNM_A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x00xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - advsimd = FALSE; - maximum = (op == '0'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VMAXNM_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x0xxxxx xxxx1111 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - maximum = (op == '0'); - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMAXNM_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x00xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - advsimd = FALSE; - maximum = (op == '0'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[n+r], e, esize]; op2 = Elem[D[m+r], e, esize]; - if maximum then - Elem[D[d+r], e, esize] = FPMaxNum(op1, op2, StandardFPSCRValue()); - else - Elem[D[d+r], e, esize] = FPMinNum(op1, op2, StandardFPSCRValue()); - else // VFP instruction - case esize of - when 16 - if maximum then - S[d] = Zeros(16) : FPMaxNum(S[n][15:0], S[m][15:0], FPSCR); - else - S[d] = Zeros(16) : FPMinNum(S[n][15:0], S[m][15:0], FPSCR); - when 32 - if maximum then - S[d] = FPMaxNum(S[n], S[m], FPSCR); - else - S[d] = FPMinNum(S[n], S[m], FPSCR); - when 64 - if maximum then - D[d] = FPMaxNum(D[n], D[m], FPSCR); - else - D[d] = FPMinNum(D[n], D[m], FPSCR); - -__instruction aarch32_VPMAX_i_A - __encoding aarch32_VPMAX_i_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field op 4 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx1010 x0x1xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - maximum = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VPMAX_i_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field op 4 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx1010 x0x1xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - maximum = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - bits(64) dest; - h = elements DIV 2; - - for e = 0 to h-1 - op1 = Int(Elem[D[n],2*e,esize], unsigned); - op2 = Int(Elem[D[n],2*e+1,esize], unsigned); - result = if maximum then Max(op1,op2) else Min(op1,op2); - Elem[dest,e,esize] = result[esize-1:0]; - op1 = Int(Elem[D[m],2*e,esize], unsigned); - op2 = Int(Elem[D[m],2*e+1,esize], unsigned); - result = if maximum then Max(op1,op2) else Min(op1,op2); - Elem[dest,e+h,esize] = result[esize-1:0]; - - D[d] = dest; - -__instruction aarch32_VPADD_f_A - __encoding aarch32_VPADD_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x0xxxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VPADD_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x0xxxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - bits(64) dest; - h = elements DIV 2; - - for e = 0 to h-1 - Elem[dest,e,esize] = FPAdd(Elem[D[n],2*e,esize], Elem[D[n],2*e+1,esize], StandardFPSCRValue()); - Elem[dest,e+h,esize] = FPAdd(Elem[D[m],2*e,esize], Elem[D[m],2*e+1,esize], StandardFPSCRValue()); - - D[d] = dest; - -__instruction aarch32_UHSUB16_A - __encoding aarch32_UHSUB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0111xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UHSUB16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1101xxxx 1111xxxx 0110xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = UInt(R[n][15:0]) - UInt(R[m][15:0]); - diff2 = UInt(R[n][31:16]) - UInt(R[m][31:16]); - R[d][15:0] = diff1[16:1]; - R[d][31:16] = diff2[16:1]; - -__instruction aarch32_HLT_A - __encoding aarch32_HLT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field imm12 8 +: 12 - __field imm4 0 +: 4 - __opcode 'xxxx0001 0000xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __decode - if EDSCR.HDE == '0' || !HaltingAllowed() then UNDEFINED; - if cond != '1110' then UNPREDICTABLE; // HLT must be encoded with AL condition - - __encoding aarch32_HLT_T1_A - __instruction_set T16 - __field imm6 16 +: 6 - __opcode '10111010 10xxxxxx 00000000 00000000' - __guard TRUE - __decode - if EDSCR.HDE == '0' || !HaltingAllowed() then UNDEFINED; - - __execute - Halt(DebugHalt_HaltInstruction); - -__instruction aarch32_VMOV_sr_A - __encoding aarch32_VMOV_sr_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field opc1 21 +: 2 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - __field opc2 5 +: 2 - __opcode 'xxxx1110 xxx1xxxx xxxx1011 xxx1xxxx' - __guard cond != '1111' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - case U:opc1:opc2 of - when 'x1xxx' advsimd = TRUE; esize = 8; index = UInt(opc1[0]:opc2); - when 'x0xx1' advsimd = TRUE; esize = 16; index = UInt(opc1[0]:opc2[1]); - when '00x00' advsimd = FALSE; esize = 32; index = UInt(opc1[0]); - when '10x00' UNDEFINED; - when 'x0x10' UNDEFINED; - t = UInt(Rt); n = UInt(N:Vn); unsigned = (U == '1'); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_VMOV_sr_T1A1_A - __instruction_set T32 - __field U 23 +: 1 - __field opc1 21 +: 2 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - __field opc2 5 +: 2 - __opcode '11101110 xxx1xxxx xxxx1011 xxx1xxxx' - __guard TRUE - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - case U:opc1:opc2 of - when 'x1xxx' advsimd = TRUE; esize = 8; index = UInt(opc1[0]:opc2); - when 'x0xx1' advsimd = TRUE; esize = 16; index = UInt(opc1[0]:opc2[1]); - when '00x00' advsimd = FALSE; esize = 32; index = UInt(opc1[0]); - when '10x00' UNDEFINED; - when 'x0x10' UNDEFINED; - t = UInt(Rt); n = UInt(N:Vn); unsigned = (U == '1'); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if unsigned then - R[t] = ZeroExtend(Elem[D[n],index,esize], 32); - else - R[t] = SignExtend(Elem[D[n],index,esize], 32); - -__instruction aarch32_BIC_rr_A - __encoding aarch32_BIC_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 110xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] AND NOT(shifted); - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_CMP_i_A - __encoding aarch32_CMP_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 0101xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); imm32 = A32ExpandImm(imm12); - - __encoding aarch32_CMP_i_T1_A - __instruction_set T16 - __field Rn 24 +: 3 - __field imm8 16 +: 8 - __opcode '00101xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - - __encoding aarch32_CMP_i_T2_A - __instruction_set T32 - __field i 26 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field imm8 0 +: 8 - __opcode '11110x01 1011xxxx 0xxx1111 xxxxxxxx' - __guard TRUE - __decode - n = UInt(Rn); imm32 = T32ExpandImm(i:imm3:imm8); - if n == 15 then UNPREDICTABLE; - - __execute __conditional - (result, nzcv) = AddWithCarry(R[n], NOT(imm32), '1'); - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_BFC_A - __encoding aarch32_BFC_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field msb 16 +: 5 - __field Rd 12 +: 4 - __field lsb 7 +: 5 - __opcode 'xxxx0111 110xxxxx xxxxxxxx x0011111' - __guard cond != '1111' - __decode - d = UInt(Rd); msbit = UInt(msb); lsbit = UInt(lsb); - if d == 15 then UNPREDICTABLE; - - __encoding aarch32_BFC_T1_A - __instruction_set T32 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field msb 0 +: 5 - __opcode '11110x11 01101111 0xxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 26 == '0' - __unpredictable_unless 5 == '0' - __decode - d = UInt(Rd); msbit = UInt(msb); lsbit = UInt(imm3:imm2); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - if msbit >= lsbit then - R[d][msbit:lsbit] = Replicate('0', msbit-lsbit+1); - // Other bits of R[d] are unchanged - else - UNPREDICTABLE; - -__instruction aarch32_SHA256H2_A - __encoding aarch32_SHA256H2_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x01xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if !HaveSHA256Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_SHA256H2_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x01xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA256Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - X = Q[n>>1]; Y = Q[d>>1]; W = Q[m>>1]; part1 = FALSE; - Q[d>>1] = SHA256hash(X, Y, W, part1); - -__instruction aarch32_TEQ_rr_A - __encoding aarch32_TEQ_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0011xxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - shift_t = DecodeRegShift(stype); - if n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] EOR shifted; - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VQDMULH_A - __encoding aarch32_VQDMULH_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0xxxxxxx xxxx1011 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '00' || size == '11' then UNDEFINED; - scalar_form = FALSE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQDMULH_T2A2_A - __instruction_set A32 - __field Q 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx1100 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VQDMULH_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0xxxxxxx xxxx1011 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '00' || size == '11' then UNDEFINED; - scalar_form = FALSE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQDMULH_T2A2_A - __instruction_set T32 - __field Q 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx1100 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - if scalar_form then op2 = SInt(Elem[D[m],index,esize]); - for r = 0 to regs-1 - for e = 0 to elements-1 - if !scalar_form then op2 = SInt(Elem[D[m+r],e,esize]); - op1 = SInt(Elem[D[n+r],e,esize]); - // The following only saturates if both op1 and op2 equal -(2^(esize-1)) - (result, sat) = SignedSatQ((2*op1*op2) >> esize, esize); - Elem[D[d+r],e,esize] = result; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_B_A - __encoding aarch32_B_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field imm24 0 +: 24 - __opcode 'xxxx1010 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - imm32 = SignExtend(imm24:'00', 32); - - __encoding aarch32_B_T1_A - __instruction_set T16 - __field cond 24 +: 4 - __field imm8 16 +: 8 - __opcode '1101xxxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - if cond == '1110' then SEE "UDF"; - if cond == '1111' then SEE "SVC"; - imm32 = SignExtend(imm8:'0', 32); - if InITBlock() then UNPREDICTABLE; - - __encoding aarch32_B_T2_A - __instruction_set T16 - __field imm11 16 +: 11 - __opcode '11100xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - imm32 = SignExtend(imm11:'0', 32); - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __encoding aarch32_B_T3_A - __instruction_set T32 - __field S 26 +: 1 - __field cond 22 +: 4 - __field imm6 16 +: 6 - __field J1 13 +: 1 - __field J2 11 +: 1 - __field imm11 0 +: 11 - __opcode '11110xxx xxxxxxxx 10x0xxxx xxxxxxxx' - __guard TRUE - __decode - if cond[3:1] == '111' then SEE "Related encodings"; - imm32 = SignExtend(S:J2:J1:imm6:imm11:'0', 32); - if InITBlock() then UNPREDICTABLE; - - __encoding aarch32_B_T4_A - __instruction_set T32 - __field S 26 +: 1 - __field imm10 16 +: 10 - __field J1 13 +: 1 - __field J2 11 +: 1 - __field imm11 0 +: 11 - __opcode '11110xxx xxxxxxxx 10x1xxxx xxxxxxxx' - __guard TRUE - __decode - I1 = NOT(J1 EOR S); I2 = NOT(J2 EOR S); imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - BranchWritePC(PC + imm32, BranchType_DIR); - -__instruction aarch32_SSBB_A - __encoding aarch32_SSBB_A1_A - __instruction_set A32 - __opcode '11110101 0111xxxx xxxxxxxx 01000000' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_SSBB_T1_A - __instruction_set T32 - __opcode '11110011 1011xxxx 10x0xxxx 01000000' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - if InITBlock() then UNPREDICTABLE; - - __execute __conditional - SpeculativeStoreBypassBarrierToVA(); - -__instruction aarch32_STM_A - __encoding aarch32_STM_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - __opcode 'xxxx1000 10x0xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - n = UInt(Rn); registers = register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - - __encoding aarch32_STM_T1_A - __instruction_set T16 - __field Rn 24 +: 3 - __field register_list 16 +: 8 - __opcode '11000xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; - if BitCount(registers) < 1 then UNPREDICTABLE; - - __encoding aarch32_STM_T2_A - __instruction_set T32 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field P 15 +: 1 - __field M 14 +: 1 - __field register_list 0 +: 14 - __opcode '11101000 10x0xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - n = UInt(Rn); registers = P:M:register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; - if wback && registers[n] == '1' then UNPREDICTABLE; - if registers[13] == '1' then UNPREDICTABLE; - if registers[15] == '1' then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - for i = 0 to 14 - if registers[i] == '1' then - if i == n && wback && i != LowestSetBit(registers) then - MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 - else - MemA[address,4] = R[i]; - address = address + 4; - if registers[15] == '1' then // Only possible for encoding A1 - MemA[address,4] = PCStoreValue(); - if wback then R[n] = R[n] + 4*BitCount(registers); - -__instruction aarch32_LDRT_A - __encoding aarch32_LDRT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0100 x011xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); postindex = TRUE; add = (U == '1'); - register_form = FALSE; imm32 = ZeroExtend(imm12, 32); - if t == 15 || n == 15 || n == t then UNPREDICTABLE; - - __encoding aarch32_LDRT_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 x011xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); postindex = TRUE; add = (U == '1'); - register_form = TRUE; (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE; - - __encoding aarch32_LDRT_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - __opcode '11111000 0101xxxx xxxx1110 xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - if Rn == '1111' then SEE "LDR (literal)"; - t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; - register_form = FALSE; imm32 = ZeroExtend(imm8, 32); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = if register_form then Shift(R[m], shift_t, shift_n, PSTATE.C) else imm32; - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if postindex then R[n] else offset_addr; - data = MemU_unpriv[address,4]; - if postindex then R[n] = offset_addr; - R[t] = data; - -__instruction aarch32_UQSUB8_A - __encoding aarch32_UQSUB8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0110xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UQSUB8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1100xxxx 1111xxxx 0101xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = UInt(R[n][7:0]) - UInt(R[m][7:0]); - diff2 = UInt(R[n][15:8]) - UInt(R[m][15:8]); - diff3 = UInt(R[n][23:16]) - UInt(R[m][23:16]); - diff4 = UInt(R[n][31:24]) - UInt(R[m][31:24]); - R[d][7:0] = UnsignedSat(diff1, 8); - R[d][15:8] = UnsignedSat(diff2, 8); - R[d][23:16] = UnsignedSat(diff3, 8); - R[d][31:24] = UnsignedSat(diff4, 8); - -__instruction aarch32_CBNZ_A - __encoding aarch32_CBNZ_T1_A - __instruction_set T16 - __field op 27 +: 1 - __field i 25 +: 1 - __field imm5 19 +: 5 - __field Rn 16 +: 3 - __opcode '1011x0x1 xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - n = UInt(Rn); imm32 = ZeroExtend(i:imm5:'0', 32); nonzero = (op == '1'); - if InITBlock() then UNPREDICTABLE; - - __execute - if nonzero != IsZero(R[n]) then - BranchWritePC(PC + imm32, BranchType_DIR); - -__instruction aarch32_WFI_A - __encoding aarch32_WFI_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 00000011' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_WFI_T1_A - __instruction_set T16 - __opcode '10111111 00110000 00000000 00000000' - __guard TRUE - __decode - // No additional decoding required - - __encoding aarch32_WFI_T2_A - __instruction_set T32 - __opcode '11110011 1010xxxx 10x0x000 00000011' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - // No additional decoding required - - __execute __conditional - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch32.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch32.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.M != M32_Monitor then - // Check for traps described by the Secure Monitor. - AArch32.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - -__instruction aarch32_MOVT_A - __encoding aarch32_MOVT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field imm4 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 0100xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); imm16 = imm4:imm12; - if d == 15 then UNPREDICTABLE; - - __encoding aarch32_MOVT_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field imm4 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x10 1100xxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); imm16 = imm4:i:imm3:imm8; - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - R[d][31:16] = imm16; - // R[d][15:0] unchanged - -__instruction aarch32_VCNT_A - __encoding aarch32_VCNT_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0101 0xx0xxxx' - __guard TRUE - __decode - if size != '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8; elements = 8; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCNT_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0101 0xx0xxxx' - __guard TRUE - __decode - if size != '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8; elements = 8; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = BitCount(Elem[D[m+r],e,esize])[esize-1:0]; - -__instruction aarch32_VSRA_A - __encoding aarch32_VSRA_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSRA_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - result = Int(Elem[D[m+r],e,esize], unsigned) >> shift_amount; - Elem[D[d+r],e,esize] = Elem[D[d+r],e,esize] + result; - -__instruction aarch32_QSUB_A - __encoding aarch32_QSUB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0010xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QSUB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 1010xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (R[d], sat) = SignedSatQ(SInt(R[m]) - SInt(R[n]), 32); - if sat then - PSTATE.Q = '1'; - -__instruction aarch32_CLZ_A - __encoding aarch32_CLZ_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0110xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); m = UInt(Rm); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_CLZ_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1011xxxx 1111xxxx 1000xxxx' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); n = UInt(Rn); - if m != n || d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = CountLeadingZeroBits(R[m]); - R[d] = result[31:0]; - -__instruction aarch32_VBIC_i_A - __encoding aarch32_VBIC_i_T1A1_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx0xx1 0x11xxxx' - __guard TRUE - __decode - if cmode[0] == '0' || cmode[3:2] == '11' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VBIC_i_T2A2_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx10x1 0x11xxxx' - __guard TRUE - __decode - if cmode[0] == '0' || cmode[3:2] == '11' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VBIC_i_T1A1_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx0xx1 0x11xxxx' - __guard TRUE - __decode - if cmode[0] == '0' || cmode[3:2] == '11' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VBIC_i_T2A2_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx10x1 0x11xxxx' - __guard TRUE - __decode - if cmode[0] == '0' || cmode[3:2] == '11' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - imm64 = AdvSIMDExpandImm('1', cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - D[d+r] = D[d+r] AND NOT(imm64); - -__instruction aarch32_VPADAL_A - __encoding aarch32_VPADAL_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0110 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (op == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VPADAL_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0110 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (op == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - h = elements DIV 2; - - for r = 0 to regs-1 - for e = 0 to h-1 - op1 = Elem[D[m+r],2*e,esize]; op2 = Elem[D[m+r],2*e+1,esize]; - result = Int(op1, unsigned) + Int(op2, unsigned); - Elem[D[d+r],e,2*esize] = Elem[D[d+r],e,2*esize] + result; - -__instruction aarch32_VRSQRTS_A - __encoding aarch32_VRSQRTS_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x1xxxxx xxxx1111 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRSQRTS_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x1xxxxx xxxx1111 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = FPRSqrtStep(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize]); - -__instruction aarch32_VACGE_A - __encoding aarch32_VACGE_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x1xxxxx xxxx1110 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - or_equal = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VACGE_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x1xxxxx xxxx1110 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - or_equal = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = FPAbs(Elem[D[n+r],e,esize]); op2 = FPAbs(Elem[D[m+r],e,esize]); - if or_equal then - test_passed = FPCompareGE(op1, op2, StandardFPSCRValue()); - else - test_passed = FPCompareGT(op1, op2, StandardFPSCRValue()); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_VMOV_s_A - __encoding aarch32_VMOV_s_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field op 20 +: 1 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - __opcode 'xxxx1110 000xxxxx xxxx1010 xxx1xxxx' - __guard cond != '1111' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - to_arm_register = (op == '1'); t = UInt(Rt); n = UInt(Vn:N); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_VMOV_s_T1_A - __instruction_set T32 - __field op 20 +: 1 - __field Vn 16 +: 4 - __field Rt 12 +: 4 - __field N 7 +: 1 - __opcode '11101110 000xxxxx xxxx1010 xxx1xxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - to_arm_register = (op == '1'); t = UInt(Rt); n = UInt(Vn:N); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - CheckVFPEnabled(TRUE); - if to_arm_register then - R[t] = S[n]; - else - S[n] = R[t]; - -__instruction aarch32_VST3_m_A - __encoding aarch32_VST3_m_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x00xxxx xxxx010x xxxxxxxx' - __guard TRUE - __decode - if size == '11' || align[1] == '1' then UNDEFINED; - case itype of - when '0100' - inc = 1; - when '0101' - inc = 2; - otherwise - SEE "Related encodings"; - alignment = if align[0] == '0' then 1 else 8; - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST3_m_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x00xxxx xxxx010x xxxxxxxx' - __guard TRUE - __decode - if size == '11' || align[1] == '1' then UNDEFINED; - case itype of - when '0100' - inc = 1; - when '0101' - inc = 2; - otherwise - SEE "Related encodings"; - alignment = if align[0] == '0' then 1 else 8; - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = TRUE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - for e = 0 to elements-1 - MemU[address, ebytes] = Elem[D[d], e]; - MemU[address+ebytes, ebytes] = Elem[D[d2],e]; - MemU[address+2*ebytes,ebytes] = Elem[D[d3],e]; - address = address + 3*ebytes; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 24; - -__instruction aarch32_VCMLA_idx_A - __encoding aarch32_VCMLA_idx_A1_A - __instruction_set A32 - __field S 23 +: 1 - __field D 22 +: 1 - __field rot 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 xxxxxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if !HaveFCADDExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); - m = if S=='1' then UInt(M:Vm) else UInt(Vm); - esize = 16 << UInt(S); - if !HaveFP16Ext() && esize == 16 then UNDEFINED; - elements = 64 DIV esize; - regs = if Q == '0' then 1 else 2; - index = if S=='1' then 0 else UInt(M); - - __encoding aarch32_VCMLA_idx_T1_A - __instruction_set T32 - __field S 23 +: 1 - __field D 22 +: 1 - __field rot 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 xxxxxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveFCADDExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); - m = if S=='1' then UInt(M:Vm) else UInt(Vm); - esize = 16 << UInt(S); - if !HaveFP16Ext() && esize == 16 then UNDEFINED; - elements = 64 DIV esize; - regs = if Q == '0' then 1 else 2; - index = if S=='1' then 0 else UInt(M); - - __execute - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - operand1 = D[n+r]; - operand2 = Din[m]; - operand3 = D[d+r]; - for e = 0 to (elements DIV 2)-1 - case rot of - when '00' - element1 = Elem[operand2,index*2,esize]; - element2 = Elem[operand1,e*2,esize]; - element3 = Elem[operand2,index*2+1,esize]; - element4 = Elem[operand1,e*2,esize]; - when '01' - element1 = FPNeg(Elem[operand2,index*2+1,esize]); - element2 = Elem[operand1,e*2+1,esize]; - element3 = Elem[operand2,index*2,esize]; - element4 = Elem[operand1,e*2+1,esize]; - when '10' - element1 = FPNeg(Elem[operand2,index*2,esize]); - element2 = Elem[operand1,e*2,esize]; - element3 = FPNeg(Elem[operand2,index*2+1,esize]); - element4 = Elem[operand1,e*2,esize]; - when '11' - element1 = Elem[operand2,index*2+1,esize]; - element2 = Elem[operand1,e*2+1,esize]; - element3 = FPNeg(Elem[operand2,index*2,esize]); - element4 = Elem[operand1,e*2+1,esize]; - result1 = FPMulAdd(Elem[operand3,e*2,esize],element2,element1, StandardFPSCRValue()); - result2 = FPMulAdd(Elem[operand3,e*2+1,esize],element4,element3,StandardFPSCRValue()); - Elem[D[d+r],e*2,esize] = result1; - Elem[D[d+r],e*2+1,esize] = result2; - -__instruction aarch32_SHSAX_A - __encoding aarch32_SHSAX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0011xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SHSAX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1110xxxx 1111xxxx 0010xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum = SInt(R[n][15:0]) + SInt(R[m][31:16]); - diff = SInt(R[n][31:16]) - SInt(R[m][15:0]); - R[d][15:0] = sum[16:1]; - R[d][31:16] = diff[16:1]; - -__instruction aarch32_SMLALBB_A - __encoding aarch32_SMLALBB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field RdHi 16 +: 4 - __field RdLo 12 +: 4 - __field Rm 8 +: 4 - __field M 6 +: 1 - __field N 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0001 0100xxxx xxxxxxxx 1xx0xxxx' - __guard cond != '1111' - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); - n_high = (N == '1'); m_high = (M == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if dHi == dLo then UNPREDICTABLE; - - __encoding aarch32_SMLALBB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field RdLo 12 +: 4 - __field RdHi 8 +: 4 - __field N 5 +: 1 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 1100xxxx xxxxxxxx 10xxxxxx' - __guard TRUE - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); - n_high = (N == '1'); m_high = (M == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - if dHi == dLo then UNPREDICTABLE; - - __execute __conditional - operand1 = if n_high then R[n][31:16] else R[n][15:0]; - operand2 = if m_high then R[m][31:16] else R[m][15:0]; - result = SInt(operand1) * SInt(operand2) + SInt(R[dHi]:R[dLo]); - R[dHi] = result[63:32]; - R[dLo] = result[31:0]; - -__instruction aarch32_VCMLA_A - __encoding aarch32_VCMLA_A1_A - __instruction_set A32 - __field rot 23 +: 2 - __field D 22 +: 1 - __field S 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111110x xx1xxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if !HaveFCADDExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 16 << UInt(S); - if !HaveFP16Ext() && esize == 16 then UNDEFINED; - elements = 64 DIV esize; - regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCMLA_T1_A - __instruction_set T32 - __field rot 23 +: 2 - __field D 22 +: 1 - __field S 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111110x xx1xxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveFCADDExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 16 << UInt(S); - if !HaveFP16Ext() && esize == 16 then UNDEFINED; - elements = 64 DIV esize; - regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - operand1 = D[n+r]; - operand2 = D[m+r]; - operand3 = D[d+r]; - for e = 0 to (elements DIV 2)-1 - case rot of - when '00' - element1 = Elem[operand2,e*2,esize]; - element2 = Elem[operand1,e*2,esize]; - element3 = Elem[operand2,e*2+1,esize]; - element4 = Elem[operand1,e*2,esize]; - when '01' - element1 = FPNeg(Elem[operand2,e*2+1,esize]); - element2 = Elem[operand1,e*2+1,esize]; - element3 = Elem[operand2,e*2,esize]; - element4 = Elem[operand1,e*2+1,esize]; - when '10' - element1 = FPNeg(Elem[operand2,e*2,esize]); - element2 = Elem[operand1,e*2,esize]; - element3 = FPNeg(Elem[operand2,e*2+1,esize]); - element4 = Elem[operand1,e*2,esize]; - when '11' - element1 = Elem[operand2,e*2+1,esize]; - element2 = Elem[operand1,e*2+1,esize]; - element3 = FPNeg(Elem[operand2,e*2,esize]); - element4 = Elem[operand1,e*2+1,esize]; - result1 = FPMulAdd(Elem[operand3,e*2,esize],element2,element1, StandardFPSCRValue()); - result2 = FPMulAdd(Elem[operand3,e*2+1,esize],element4,element3, StandardFPSCRValue()); - Elem[D[d+r],e*2,esize] = result1; - Elem[D[d+r],e*2+1,esize] = result2; - -__instruction aarch32_LDM_A - __encoding aarch32_LDM_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - __opcode 'xxxx1000 10x1xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - n = UInt(Rn); registers = register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if wback && registers[n] == '1' then UNPREDICTABLE; - - __encoding aarch32_LDM_T1_A - __instruction_set T16 - __field Rn 24 +: 3 - __field register_list 16 +: 8 - __opcode '11001xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - n = UInt(Rn); registers = '00000000':register_list; wback = (registers[n] == '0'); - if BitCount(registers) < 1 then UNPREDICTABLE; - - __encoding aarch32_LDM_T2_A - __instruction_set T32 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field P 15 +: 1 - __field M 14 +: 1 - __field register_list 0 +: 14 - __opcode '11101000 10x1xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - n = UInt(Rn); registers = P:M:register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; - if wback && registers[n] == '1' then UNPREDICTABLE; - if registers[13] == '1' then UNPREDICTABLE; - if registers[15] == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - for i = 0 to 14 - if registers[i] == '1' then - R[i] = MemA[address,4]; address = address + 4; - if registers[15] == '1' then - LoadWritePC(MemA[address,4]); - if wback && registers[n] == '0' then R[n] = R[n] + 4*BitCount(registers); - if wback && registers[n] == '1' then R[n] = bits(32) UNKNOWN; - -__instruction aarch32_VMAX_f_A - __encoding aarch32_VMAX_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x0xxxxx xxxx1111 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - maximum = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMAX_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x0xxxxx xxxx1111 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - maximum = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[n+r],e,esize]; op2 = Elem[D[m+r],e,esize]; - if maximum then - Elem[D[d+r],e,esize] = FPMax(op1, op2, StandardFPSCRValue()); - else - Elem[D[d+r],e,esize] = FPMin(op1, op2, StandardFPSCRValue()); - -__instruction aarch32_SMULL_A - __encoding aarch32_SMULL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field RdHi 16 +: 4 - __field RdLo 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0000 110xxxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if dHi == dLo then UNPREDICTABLE; - - __encoding aarch32_SMULL_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field RdLo 12 +: 4 - __field RdHi 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 1000xxxx xxxxxxxx 0000xxxx' - __guard TRUE - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - if dHi == dLo then UNPREDICTABLE; - - __execute __conditional - result = SInt(R[n]) * SInt(R[m]); - R[dHi] = result[63:32]; - R[dLo] = result[31:0]; - if setflags then - PSTATE.N = result[63]; - PSTATE.Z = IsZeroBit(result[63:0]); - // PSTATE.C, PSTATE.V unchanged - -__instruction aarch32_BIC_i_A - __encoding aarch32_BIC_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 110xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); - (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C); - - __encoding aarch32_BIC_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x00 001xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); - (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C); - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = R[n] AND NOT(imm32); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_SHA1SU1_A - __encoding aarch32_SHA1SU1_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0011 10x0xxxx' - __guard TRUE - __decode - if !HaveSHA1Ext() then UNDEFINED; - if size != '10' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_SHA1SU1_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0011 10x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA1Ext() then UNDEFINED; - if size != '10' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - X = Q[d>>1]; Y = Q[m>>1]; - T = X EOR LSR(Y, 32); - W0 = ROL(T[31:0], 1); - W1 = ROL(T[63:32], 1); - W2 = ROL(T[95:64], 1); - W3 = ROL(T[127:96], 1) EOR ROL(T[31:0], 2); - Q[d>>1] = W3:W2:W1:W0; - -__instruction aarch32_QADD16_A - __encoding aarch32_QADD16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0010xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QADD16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 0001xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = SInt(R[n][15:0]) + SInt(R[m][15:0]); - sum2 = SInt(R[n][31:16]) + SInt(R[m][31:16]); - R[d][15:0] = SignedSat(sum1, 16); - R[d][31:16] = SignedSat(sum2, 16); - -__instruction aarch32_VSUBL_A - __encoding aarch32_VSUBL_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0010 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' || (op == '1' && Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; is_vsubw = (op == '1'); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VSUBL_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0010 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' || (op == '1' && Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; is_vsubw = (op == '1'); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - if is_vsubw then - op1 = Int(Elem[Qin[n>>1],e,2*esize], unsigned); - else - op1 = Int(Elem[Din[n],e,esize], unsigned); - result = op1 - Int(Elem[Din[m],e,esize], unsigned); - Elem[Q[d>>1],e,2*esize] = result[2*esize-1:0]; - -__instruction aarch32_VCGT_i_A - __encoding aarch32_VCGT_i_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx01 xxxx0x00 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCGT_i_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx01 xxxx0x00 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - if floating_point then - bits(esize) zero = FPZero('0'); - test_passed = FPCompareGT(Elem[D[m+r],e,esize], zero, StandardFPSCRValue()); - else - test_passed = (SInt(Elem[D[m+r],e,esize]) > 0); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_QADD_A - __encoding aarch32_QADD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0000xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QADD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 1000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (R[d], sat) = SignedSatQ(SInt(R[m]) + SInt(R[n]), 32); - if sat then - PSTATE.Q = '1'; - -__instruction aarch32_UADD16_A - __encoding aarch32_UADD16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0101xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UADD16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 0100xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = UInt(R[n][15:0]) + UInt(R[m][15:0]); - sum2 = UInt(R[n][31:16]) + UInt(R[m][31:16]); - R[d][15:0] = sum1[15:0]; - R[d][31:16] = sum2[15:0]; - PSTATE.GE[1:0] = if sum1 >= 0x10000 then '11' else '00'; - PSTATE.GE[3:2] = if sum2 >= 0x10000 then '11' else '00'; - -__instruction aarch32_SSUB16_A - __encoding aarch32_SSUB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0001xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SSUB16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1101xxxx 1111xxxx 0000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = SInt(R[n][15:0]) - SInt(R[m][15:0]); - diff2 = SInt(R[n][31:16]) - SInt(R[m][31:16]); - R[d][15:0] = diff1[15:0]; - R[d][31:16] = diff2[15:0]; - PSTATE.GE[1:0] = if diff1 >= 0 then '11' else '00'; - PSTATE.GE[3:2] = if diff2 >= 0 then '11' else '00'; - -__instruction aarch32_TST_rr_A - __encoding aarch32_TST_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0001xxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - shift_t = DecodeRegShift(stype); - if n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] AND shifted; - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_SHA256SU1_A - __encoding aarch32_SHA256SU1_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x10xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if !HaveSHA256Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_SHA256SU1_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x10xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA256Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - bits(128) result; - X = Q[d>>1]; Y = Q[n>>1]; Z = Q[m>>1]; - T0 = Z[31:0] : Y[127:32]; - - T1 = Z[127:64]; - for e = 0 to 1 - elt = Elem[T1, e, 32]; - elt = ROR(elt, 17) EOR ROR(elt, 19) EOR LSR(elt, 10); - elt = elt + Elem[X, e, 32] + Elem[T0, e, 32]; - Elem[result, e, 32] = elt; - - T1 = result[63:0]; - for e = 2 to 3 - elt = Elem[T1, e - 2, 32]; - elt = ROR(elt, 17) EOR ROR(elt, 19) EOR LSR(elt, 10); - elt = elt + Elem[X, e, 32] + Elem[T0, e, 32]; - Elem[result, e, 32] = elt; - - Q[d>>1] = result; - -__instruction aarch32_VFMA_bfs_A - __encoding aarch32_VFMA_bfs_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x11xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm[2:0]); - integer i = UInt(M:Vm[3]); - integer elements = 128 DIV 32; - integer sel = UInt(Q); - - __encoding aarch32_VFMA_bfs_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x11xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32BF16Ext() then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm[2:0]); - integer i = UInt(M:Vm[3]); - integer elements = 128 DIV 32; - integer sel = UInt(Q); - - __execute - CheckAdvSIMDEnabled(); - bits(128) operand1 = Q[n>>1]; - bits(64) operand2 = D[m]; - bits(128) operand3 = Q[d>>1]; - bits(128) result; - - bits(32) element2 = Elem[operand2, i, 16] : Zeros(16); - - for e = 0 to elements-1 - bits(32) element1 = Elem[operand1, 2 * e + sel, 16] : Zeros(16); - bits(32) addend = Elem[operand3, e, 32]; - Elem[result, e, 32] = FPMulAdd(addend, element1, element2, - StandardFPSCRValue()); - - Q[d>>1] = result; - -__instruction aarch32_PLD_r_A - __encoding aarch32_PLD_r_A1_A - __instruction_set A32 - __field U 23 +: 1 - __field R 22 +: 1 - __field Rn 16 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode '11110111 xx01xxxx xxxxxxxx xxx0xxxx' - __guard TRUE - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - n = UInt(Rn); m = UInt(Rm); add = (U == '1'); is_pldw = (R == '0'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if m == 15 || (n == 15 && is_pldw) then UNPREDICTABLE; - - __encoding aarch32_PLD_r_T1_A - __instruction_set T32 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111000 00x1xxxx 11110000 00xxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "PLD (literal)"; - n = UInt(Rn); m = UInt(Rm); add = TRUE; is_pldw = (W == '1'); - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - address = if add then (R[n] + offset) else (R[n] - offset); - if is_pldw then - Hint_PreloadDataForWrite(address); - else - Hint_PreloadData(address); - -__instruction aarch32_SSAX_A - __encoding aarch32_SSAX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0001xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SSAX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1110xxxx 1111xxxx 0000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum = SInt(R[n][15:0]) + SInt(R[m][31:16]); - diff = SInt(R[n][31:16]) - SInt(R[m][15:0]); - R[d][15:0] = sum[15:0]; - R[d][31:16] = diff[15:0]; - PSTATE.GE[1:0] = if sum >= 0 then '11' else '00'; - PSTATE.GE[3:2] = if diff >= 0 then '11' else '00'; - -__instruction aarch32_VRSUBHN_A - __encoding aarch32_VRSUBHN_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1xxxxxxx xxxx0110 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VRSUBHN_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1xxxxxxx xxxx0110 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - round_const = 1 << (esize-1); - for e = 0 to elements-1 - result = Elem[Qin[n>>1],e,2*esize] - Elem[Qin[m>>1],e,2*esize] + round_const; - Elem[D[d],e,esize] = result[2*esize-1:esize]; - -__instruction aarch32_VCGE_i_A - __encoding aarch32_VCGE_i_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx01 xxxx0x00 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCGE_i_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx01 xxxx0x00 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - if floating_point then - bits(esize) zero = FPZero('0'); - test_passed = FPCompareGE(Elem[D[m+r],e,esize], zero, StandardFPSCRValue()); - else - test_passed = (SInt(Elem[D[m+r],e,esize]) >= 0); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_RSC_r_A - __encoding aarch32_RSC_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 111xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(NOT(R[n]), shifted, PSTATE.C); - if d == 15 then - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_SMLSD_A - __encoding aarch32_SMLSD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field M 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0111 0000xxxx xxxxxxxx 01x1xxxx' - __guard cond != '1111' - __decode - if Ra == '1111' then SEE "SMUSD"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_swap = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SMLSD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0100xxxx xxxxxxxx 000xxxxx' - __guard TRUE - __decode - if Ra == '1111' then SEE "SMUSD"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_swap = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand2 = if m_swap then ROR(R[m],16) else R[m]; - product1 = SInt(R[n][15:0]) * SInt(operand2[15:0]); - product2 = SInt(R[n][31:16]) * SInt(operand2[31:16]); - result = product1 - product2 + SInt(R[a]); - R[d] = result[31:0]; - if result != SInt(result[31:0]) then // Signed overflow - PSTATE.Q = '1'; - -__instruction aarch32_LDRH_l_A - __encoding aarch32_LDRH_l_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x11111 xxxxxxxx 1011xxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "LDRHT"; - t = UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); - add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 || wback then UNPREDICTABLE; - - __encoding aarch32_LDRH_l_T1_A - __instruction_set T32 - __field U 23 +: 1 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 x0111111 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rt == '1111' then SEE "PLD (literal)"; - t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - base = Align(PC,4); - address = if add then (base + imm32) else (base - imm32); - data = MemU[address,2]; - R[t] = ZeroExtend(data, 32); - -__instruction aarch32_SEV_A - __encoding aarch32_SEV_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 00000100' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_SEV_T1_A - __instruction_set T16 - __opcode '10111111 01000000 00000000 00000000' - __guard TRUE - __decode - // No additional decoding required - - __encoding aarch32_SEV_T2_A - __instruction_set T32 - __opcode '11110011 1010xxxx 10x0x000 00000100' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - // No additional decoding required - - __execute __conditional - SendEvent(); - -__instruction aarch32_SMLAL_A - __encoding aarch32_SMLAL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field RdHi 16 +: 4 - __field RdLo 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0000 111xxxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if dHi == dLo then UNPREDICTABLE; - - __encoding aarch32_SMLAL_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field RdLo 12 +: 4 - __field RdHi 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 1100xxxx xxxxxxxx 0000xxxx' - __guard TRUE - __decode - dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; - if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - if dHi == dLo then UNPREDICTABLE; - - __execute __conditional - result = SInt(R[n]) * SInt(R[m]) + SInt(R[dHi]:R[dLo]); - R[dHi] = result[63:32]; - R[dLo] = result[31:0]; - if setflags then - PSTATE.N = result[63]; - PSTATE.Z = IsZeroBit(result[63:0]); - // PSTATE.C, PSTATE.V unchanged - -__instruction aarch32_UQSUB16_A - __encoding aarch32_UQSUB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0110xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UQSUB16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1101xxxx 1111xxxx 0101xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = UInt(R[n][15:0]) - UInt(R[m][15:0]); - diff2 = UInt(R[n][31:16]) - UInt(R[m][31:16]); - R[d][15:0] = UnsignedSat(diff1, 16); - R[d][31:16] = UnsignedSat(diff2, 16); - -__instruction aarch32_STC_A - __encoding aarch32_STC_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field imm8 0 +: 8 - __opcode 'xxxx110x x0x0xxxx 01011110 xxxxxxxx' - __guard cond != '1111' - __decode - if P == '0' && U == '0' && W == '0' then UNDEFINED; - n = UInt(Rn); cp = 14; - imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - - __encoding aarch32_STC_T1A1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field imm8 0 +: 8 - __opcode '1110110x x0x0xxxx 01011110 xxxxxxxx' - __guard TRUE - __decode - if P == '0' && U == '0' && W == '0' then UNDEFINED; - n = UInt(Rn); cp = 14; - imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE; - - __execute __conditional - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - - // System register read from DBGDTRRXint. - MemA[address,4] = DBGDTR_EL0[]; - - if wback then R[n] = offset_addr; - -__instruction aarch32_VMUL_s_A - __encoding aarch32_VMUL_s_A1_A - __instruction_set A32 - __field Q 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field F 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx100x x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || (F == '1' && size == '01' && !HaveFP16Ext()) then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - floating_point = (F == '1'); long_destination = FALSE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VMUL_s_T1_A - __instruction_set T32 - __field Q 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field F 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx100x x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if size == '00' || (F == '1' && size == '01' && !HaveFP16Ext()) then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - floating_point = (F == '1'); long_destination = FALSE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - op2 = Elem[Din[m],index,esize]; op2val = Int(op2, unsigned); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; op1val = Int(op1, unsigned); - if floating_point then - Elem[D[d+r],e,esize] = FPMul(op1, op2, StandardFPSCRValue()); - else - if long_destination then - Elem[Q[d>>1],e,2*esize] = (op1val*op2val)[2*esize-1:0]; - else - Elem[D[d+r],e,esize] = (op1val*op2val)[esize-1:0]; - -__instruction aarch32_MMLA_A - __encoding aarch32_MMLA_A1_A - __instruction_set A32 - __field B 23 +: 1 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 1x10xxxx xxxx1100 x1x0xxxx' - __guard TRUE - __decode - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - case B:U of - when '00' op1_unsigned = FALSE; op2_unsigned = FALSE; - when '01' op1_unsigned = TRUE; op2_unsigned = TRUE; - when '10' op1_unsigned = TRUE; op2_unsigned = FALSE; - when '11' UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - - __encoding aarch32_MMLA_T1_A - __instruction_set T32 - __field B 23 +: 1 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 1x10xxxx xxxx1100 x1x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - case B:U of - when '00' op1_unsigned = FALSE; op2_unsigned = FALSE; - when '01' op1_unsigned = TRUE; op2_unsigned = TRUE; - when '10' op1_unsigned = TRUE; op2_unsigned = FALSE; - when '11' UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - - __execute - CheckAdvSIMDEnabled(); - bits(128) operand1 = Q[n>>1]; - bits(128) operand2 = Q[m>>1]; - bits(128) addend = Q[d>>1]; - - Q[d>>1] = MatMulAdd(addend, operand1, operand2, op1_unsigned, op2_unsigned); - -__instruction aarch32_VLD1_m_A - __encoding aarch32_VLD1_m_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x10xxxx xxxx0111 xxxxxxxx' - __guard TRUE - __decode - regs = 1; if align[1] == '1' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD1_m_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x10xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - regs = 2; if align == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD1_m_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x10xxxx xxxx0110 xxxxxxxx' - __guard TRUE - __decode - regs = 3; if align[1] == '1' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD1_m_T4A4_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x10xxxx xxxx0010 xxxxxxxx' - __guard TRUE - __decode - regs = 4; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD1_m_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x10xxxx xxxx0111 xxxxxxxx' - __guard TRUE - __decode - regs = 1; if align[1] == '1' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD1_m_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x10xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - regs = 2; if align == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD1_m_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x10xxxx xxxx0110 xxxxxxxx' - __guard TRUE - __decode - regs = 3; if align[1] == '1' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD1_m_T4A4_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x10xxxx xxxx0010 xxxxxxxx' - __guard TRUE - __decode - regs = 4; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - for r = 0 to regs-1 - for e = 0 to elements-1 - bits(ebytes*8) data; - if ebytes != 8 then - data = MemU[address,ebytes]; - else - - = AArch32.CheckAlignment(address, ebytes, AccType_NORMAL, iswrite); - data[31:0] = if BigEndian() then MemU[address+4,4] else MemU[address,4]; - data[63:32] = if BigEndian() then MemU[address,4] else MemU[address+4,4]; - Elem[D[d+r],e] = data; - address = address + ebytes; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 8*regs; - -__instruction aarch32_ADD_r_A - __encoding aarch32_ADD_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 100xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if Rn == '1101' then SEE "ADD (SP plus register)"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_ADD_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rd 16 +: 3 - __opcode '0001100x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_ADD_r_T2_A - __instruction_set T16 - __field DN 23 +: 1 - __field Rm 19 +: 4 - __field Rdn 16 +: 3 - __opcode '01000100 xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - if (DN:Rdn) == '1101' || Rm == '1101' then SEE "ADD (SP plus register)"; - d = UInt(DN:Rdn); n = d; m = UInt(Rm); setflags = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); - if n == 15 && m == 15 then UNPREDICTABLE; - if d == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __encoding aarch32_ADD_r_T3_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101011 000xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - if Rd == '1111' && S == '1' then SEE "CMN (register)"; - if Rn == '1101' then SEE "ADD (SP plus register)"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if (d == 15 && !setflags) || n == 15 || m == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], shifted, '0'); - if d == 15 then - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VPADDL_A - __encoding aarch32_VPADDL_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0010 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (op == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VPADDL_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0010 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (op == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - h = elements DIV 2; - - for r = 0 to regs-1 - for e = 0 to h-1 - op1 = Elem[D[m+r],2*e,esize]; op2 = Elem[D[m+r],2*e+1,esize]; - result = Int(op1, unsigned) + Int(op2, unsigned); - Elem[D[d+r],e,2*esize] = result[2*esize-1:0]; - -__instruction aarch32_SBC_rr_A - __encoding aarch32_SBC_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 110xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], NOT(shifted), PSTATE.C); - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VCMP_A - __encoding aarch32_VCMP_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field E 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110100 xxxx10xx 11x0xxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - quiet_nan_exc = (E == '1'); with_zero = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VCMP_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field E 7 +: 1 - __opcode 'xxxx1110 1x110101 xxxx10xx 11x0xxxx' - __guard cond != '1111' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - quiet_nan_exc = (E == '1'); with_zero = TRUE; - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __encoding aarch32_VCMP_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field E 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110100 xxxx10xx 11x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - quiet_nan_exc = (E == '1'); with_zero = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VCMP_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field E 7 +: 1 - __opcode '11101110 1x110101 xxxx10xx 11x0xxxx' - __guard TRUE - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - quiet_nan_exc = (E == '1'); with_zero = TRUE; - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __execute __conditional - CheckVFPEnabled(TRUE); - bits(4) nzcv; - case esize of - when 16 - bits(16) op16 = if with_zero then FPZero('0') else S[m][15:0]; - nzcv = FPCompare(S[d][15:0], op16, quiet_nan_exc, FPSCR); - when 32 - bits(32) op32 = if with_zero then FPZero('0') else S[m]; - nzcv = FPCompare(S[d], op32, quiet_nan_exc, FPSCR); - when 64 - bits(64) op64 = if with_zero then FPZero('0') else D[m]; - nzcv = FPCompare(D[d], op64, quiet_nan_exc, FPSCR); - - FPSCR.[N,Z,C,V] = nzcv; - -__instruction aarch32_SADD8_A - __encoding aarch32_SADD8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0001xxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SADD8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 0000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = SInt(R[n][7:0]) + SInt(R[m][7:0]); - sum2 = SInt(R[n][15:8]) + SInt(R[m][15:8]); - sum3 = SInt(R[n][23:16]) + SInt(R[m][23:16]); - sum4 = SInt(R[n][31:24]) + SInt(R[m][31:24]); - R[d][7:0] = sum1[7:0]; - R[d][15:8] = sum2[7:0]; - R[d][23:16] = sum3[7:0]; - R[d][31:24] = sum4[7:0]; - PSTATE.GE[0] = if sum1 >= 0 then '1' else '0'; - PSTATE.GE[1] = if sum2 >= 0 then '1' else '0'; - PSTATE.GE[2] = if sum3 >= 0 then '1' else '0'; - PSTATE.GE[3] = if sum4 >= 0 then '1' else '0'; - -__instruction aarch32_VCVT_xs_A - __encoding aarch32_VCVT_xs_A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field op 8 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx11xx 0xx1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if op[1] == '0' && !HaveFP16Ext() then UNDEFINED; - if op[1] == '0' && imm6 == '10xxxx' then UNDEFINED; - if imm6 == '0xxxxx' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - to_fixed = (op[0] == '1'); frac_bits = 64 - UInt(imm6); - unsigned = (U == '1'); - case op[1] of - when '0' esize = 16; elements = 4; - when '1' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCVT_xs_T1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field op 8 +: 2 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx11xx 0xx1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if op[1] == '0' && !HaveFP16Ext() then UNDEFINED; - if op[1] == '0' && imm6 == '10xxxx' then UNDEFINED; - if imm6 == '0xxxxx' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - to_fixed = (op[0] == '1'); frac_bits = 64 - UInt(imm6); - unsigned = (U == '1'); - case op[1] of - when '0' esize = 16; elements = 4; - when '1' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - bits(esize) result; - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[m+r],e,esize]; - if to_fixed then - result = FPToFixed(op1, frac_bits, unsigned, StandardFPSCRValue(), - FPRounding_ZERO); - else - result = FixedToFP(op1, frac_bits, unsigned, StandardFPSCRValue(), - FPRounding_TIEEVEN); - Elem[D[d+r],e,esize] = result; - -__instruction aarch32_VABA_A - __encoding aarch32_VABA_T2A2_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0101 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); long_destination = TRUE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __encoding aarch32_VABA_T2A2_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0101 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); long_destination = TRUE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; - op2 = Elem[Din[m+r],e,esize]; - absdiff = Abs(Int(op1,unsigned) - Int(op2,unsigned)); - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + absdiff; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + absdiff; - -__instruction aarch32_SXTAB_A - __encoding aarch32_SXTAB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1010xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if Rn == '1111' then SEE "SXTB"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SXTAB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 0100xxxx 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - if Rn == '1111' then SEE "SXTB"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d] = R[n] + SignExtend(rotated[7:0], 32); - -__instruction aarch32_VLD4_m_A - __encoding aarch32_VLD4_m_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x10xxxx xxxx000x xxxxxxxx' - __guard TRUE - __decode - case itype of - when '0000' - inc = 1; - when '0001' - inc = 2; - otherwise - SEE "Related encodings"; - if size == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD4_m_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x10xxxx xxxx000x xxxxxxxx' - __guard TRUE - __decode - case itype of - when '0000' - inc = 1; - when '0001' - inc = 2; - otherwise - SEE "Related encodings"; - if size == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d4 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - for e = 0 to elements-1 - Elem[D[d], e] = MemU[address,ebytes]; - Elem[D[d2],e] = MemU[address+ebytes,ebytes]; - Elem[D[d3],e] = MemU[address+2*ebytes,ebytes]; - Elem[D[d4],e] = MemU[address+3*ebytes,ebytes]; - address = address + 4*ebytes; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 32; - -__instruction aarch32_VLD1_1_A - __encoding aarch32_VLD1_1_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx0000 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD1 (single element to all lanes)"; - if index_align[0] != '0' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); alignment = 1; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VLD1_1_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx0100 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD1 (single element to all lanes)"; - if index_align[1] != '0' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - alignment = if index_align[0] == '0' then 1 else 2; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VLD1_1_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx1000 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD1 (single element to all lanes)"; - if index_align[2] != '0' then UNDEFINED; - if index_align[1:0] != '00' && index_align[1:0] != '11' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - alignment = if index_align[1:0] == '00' then 1 else 4; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VLD1_1_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx0000 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD1 (single element to all lanes)"; - if index_align[0] != '0' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); alignment = 1; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VLD1_1_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx0100 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD1 (single element to all lanes)"; - if index_align[1] != '0' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - alignment = if index_align[0] == '0' then 1 else 2; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_VLD1_1_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx1000 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then SEE "VLD1 (single element to all lanes)"; - if index_align[2] != '0' then UNDEFINED; - if index_align[1:0] != '00' && index_align[1:0] != '11' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - alignment = if index_align[1:0] == '00' then 1 else 4; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - Elem[D[d],index] = MemU[address,ebytes]; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + ebytes; - -__instruction aarch32_SMULWB_A - __encoding aarch32_SMULWB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Rm 8 +: 4 - __field M 6 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0001 0010xxxx xxxxxxxx 1x10xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_high = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SMULWB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0011xxxx 1111xxxx 000xxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_high = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand2 = if m_high then R[m][31:16] else R[m][15:0]; - product = SInt(R[n]) * SInt(operand2); - R[d] = product[47:16]; - // Signed overflow cannot occur - -__instruction aarch32_VQRDMLAH_A - __encoding aarch32_VQRDMLAH_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0xxxxxxx xxxx1011 xxx1xxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '00' || size == '11' then UNDEFINED; - add = TRUE; scalar_form = FALSE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQRDMLAH_A2_A - __instruction_set A32 - __field Q 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx1110 x1x0xxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - if size == '11' then SEE "Related encodings"; - if size == '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - add = TRUE; scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VQRDMLAH_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0xxxxxxx xxxx1011 xxx1xxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '00' || size == '11' then UNDEFINED; - add = TRUE; scalar_form = FALSE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQRDMLAH_T2_A - __instruction_set T32 - __field Q 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx1110 x1x0xxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - if InITBlock() then UNPREDICTABLE; - if size == '11' then SEE "Related encodings"; - if size == '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - add = TRUE; scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute - CheckAdvSIMDEnabled(); - round_const = 1 << (esize-1); - if scalar_form then op2 = SInt(Elem[D[m],index,esize]); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = SInt(Elem[D[n+r],e,esize]); - op3 = SInt(Elem[D[d+r],e,esize]) << esize; - if !scalar_form then op2 = SInt(Elem[D[m+r],e,esize]); - (result, sat) = SignedSatQ((op3 + 2*(op1*op2) + round_const) >> esize, esize); - Elem[D[d+r],e,esize] = result; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_UHADD16_A - __encoding aarch32_UHADD16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0111xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UHADD16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 0110xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = UInt(R[n][15:0]) + UInt(R[m][15:0]); - sum2 = UInt(R[n][31:16]) + UInt(R[m][31:16]); - R[d][15:0] = sum1[16:1]; - R[d][31:16] = sum2[16:1]; - -__instruction aarch32_VCVTB_A - __encoding aarch32_VCVTB_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field op 16 +: 1 - __field Vd 12 +: 4 - __field sz 8 +: 1 - __field T 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x11001x xxxx101x 11x0xxxx' - __guard cond != '1111' - __decode - uses_double = (sz == '1'); convert_from_half = (op == '0'); - lowbit = (if T == '1' then 16 else 0); - if uses_double then - if convert_from_half then - d = UInt(D:Vd); m = UInt(Vm:M); - else - d = UInt(Vd:D); m = UInt(M:Vm); - else - d = UInt(Vd:D); m = UInt(Vm:M); - - __encoding aarch32_VCVTB_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 16 +: 1 - __field Vd 12 +: 4 - __field sz 8 +: 1 - __field T 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x11001x xxxx101x 11x0xxxx' - __guard TRUE - __decode - uses_double = (sz == '1'); convert_from_half = (op == '0'); - lowbit = (if T == '1' then 16 else 0); - if uses_double then - if convert_from_half then - d = UInt(D:Vd); m = UInt(Vm:M); - else - d = UInt(Vd:D); m = UInt(M:Vm); - else - d = UInt(Vd:D); m = UInt(Vm:M); - - __execute __conditional - CheckVFPEnabled(TRUE); - bits(16) hp; - if convert_from_half then - hp = S[m][lowbit+15:lowbit]; - if uses_double then - D[d] = FPConvert(hp, FPSCR); - else - S[d] = FPConvert(hp, FPSCR); - else - if uses_double then - hp = FPConvert(D[m], FPSCR); - else - hp = FPConvert(S[m], FPSCR); - S[d][lowbit+15:lowbit] = hp; - -__instruction aarch32_VSHL_i_A - __encoding aarch32_VSHL_i_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx0101 xxx1xxxx' - __guard TRUE - __decode - if L:imm6 == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = UInt(imm6) - 8; - when '001xxxx' esize = 16; elements = 4; shift_amount = UInt(imm6) - 16; - when '01xxxxx' esize = 32; elements = 2; shift_amount = UInt(imm6) - 32; - when '1xxxxxx' esize = 64; elements = 1; shift_amount = UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSHL_i_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx0101 xxx1xxxx' - __guard TRUE - __decode - if L:imm6 == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = UInt(imm6) - 8; - when '001xxxx' esize = 16; elements = 4; shift_amount = UInt(imm6) - 16; - when '01xxxxx' esize = 32; elements = 2; shift_amount = UInt(imm6) - 32; - when '1xxxxxx' esize = 64; elements = 1; shift_amount = UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = LSL(Elem[D[m+r],e,esize], shift_amount); - -__instruction aarch32_STREXH_A - __encoding aarch32_STREXH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1110xxxx xxxxxx11 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t then UNPREDICTABLE; - - __encoding aarch32_STREXH_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rd 0 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 0101xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - if d == n || d == t then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - if AArch32.ExclusiveMonitorsPass(address,2) then - MemA[address,2] = R[t][15:0]; - R[d] = ZeroExtend('0'); - else - R[d] = ZeroExtend('1'); - -__instruction aarch32_SBFX_A - __encoding aarch32_SBFX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field widthm1 16 +: 5 - __field Rd 12 +: 4 - __field lsb 7 +: 5 - __field Rn 0 +: 4 - __opcode 'xxxx0111 101xxxxx xxxxxxxx x101xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); - lsbit = UInt(lsb); widthminus1 = UInt(widthm1); - if d == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_SBFX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field widthm1 0 +: 5 - __opcode '11110x11 0100xxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 26 == '0' - __unpredictable_unless 5 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); - lsbit = UInt(imm3:imm2); widthminus1 = UInt(widthm1); - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - msbit = lsbit + widthminus1; - if msbit <= 31 then - R[d] = SignExtend(R[n][msbit:lsbit], 32); - else - UNPREDICTABLE; - -__instruction aarch32_ADD_SP_r_A - __encoding aarch32_ADD_SP_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 100x1101 xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_ADD_SP_r_T1_A - __instruction_set T16 - __field DM 23 +: 1 - __field Rdm 16 +: 3 - __opcode '01000100 x1101xxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(DM:Rdm); m = UInt(DM:Rdm); setflags = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - if d == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __encoding aarch32_ADD_SP_r_T2_A - __instruction_set T16 - __field Rm 19 +: 4 - __opcode '01000100 1xxxx101 00000000 00000000' - __guard TRUE - __decode - if Rm == '1101' then SEE "encoding T1"; - d = 13; m = UInt(Rm); setflags = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_ADD_SP_r_T3_A - __instruction_set T32 - __field S 20 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101011 000x1101 xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - if Rd == '1111' && S == '1' then SEE "CMN (register)"; - d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if (d == 15 && !setflags) || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(SP, shifted, '0'); - if d == 15 then - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_LDC_i_A - __encoding aarch32_LDC_i_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field imm8 0 +: 8 - __opcode 'xxxx110x x0x1xxxx 01011110 xxxxxxxx' - __guard cond != '1111' - __decode - if Rn == '1111' then SEE "LDC (literal)"; - if P == '0' && U == '0' && W == '0' then UNDEFINED; - n = UInt(Rn); cp = 14; - imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); - - __encoding aarch32_LDC_i_T1A1_A - __instruction_set T32 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field imm8 0 +: 8 - __opcode '1110110x x0x1xxxx 01011110 xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "LDC (literal)"; - if P == '0' && U == '0' && W == '0' then UNDEFINED; - n = UInt(Rn); cp = 14; - imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); - - __execute __conditional - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - - // System register write to DBGDTRTXint. - DBGDTR_EL0[] = MemA[address,4]; - - if wback then R[n] = offset_addr; - -__instruction aarch32_LDRSB_i_A - __encoding aarch32_LDRSB_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x1xxxx xxxxxxxx 1101xxxx' - __guard cond != '1111' - __decode - if Rn == '1111' then SEE "LDRSB (literal)"; - if P == '0' && W == '1' then SEE "LDRSBT"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 || (wback && n == t) then UNPREDICTABLE; - - __encoding aarch32_LDRSB_i_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111001 1001xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rt == '1111' then SEE "PLI"; - if Rn == '1111' then SEE "LDRSB (literal)"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = TRUE; add = TRUE; wback = FALSE; - // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_LDRSB_i_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field P 10 +: 1 - __field U 9 +: 1 - __field W 8 +: 1 - __field imm8 0 +: 8 - __opcode '11111001 0001xxxx xxxx1xxx xxxxxxxx' - __guard TRUE - __decode - if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "PLI"; - if Rn == '1111' then SEE "LDRSB (literal)"; - if P == '1' && U == '1' && W == '0' then SEE "LDRSBT"; - if P == '0' && W == '0' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - R[t] = SignExtend(MemU[address,1], 32); - if wback then R[n] = offset_addr; - -__instruction aarch32_LDR_l_A - __encoding aarch32_LDR_l_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx010x x0x11111 xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "LDRT"; - t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); - add = (U == '1'); wback = (P == '0') || (W == '1'); - if wback then UNPREDICTABLE; - - __encoding aarch32_LDR_l_T1_A - __instruction_set T16 - __field Rt 24 +: 3 - __field imm8 16 +: 8 - __opcode '01001xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); imm32 = ZeroExtend(imm8:'00', 32); add = TRUE; - - __encoding aarch32_LDR_l_T2_A - __instruction_set T32 - __field U 23 +: 1 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 x1011111 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); - if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - base = Align(PC,4); - address = if add then (base + imm32) else (base - imm32); - data = MemU[address,4]; - if t == 15 then - if address[1:0] == '00' then - LoadWritePC(data); - else - UNPREDICTABLE; - else - R[t] = data; - -__instruction aarch32_PUSH_A - __encoding aarch32_PUSH_T1_A - __instruction_set T16 - __field M 24 +: 1 - __field register_list 16 +: 8 - __opcode '1011010x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - registers = '0':M:'000000':register_list; UnalignedAllowed = FALSE; - if BitCount(registers) < 1 then UNPREDICTABLE; - - __execute __conditional - address = SP - 4*BitCount(registers); - for i = 0 to 14 - if registers[i] == '1' then - if i == 13 && i != LowestSetBit(registers) then // Only possible for encoding A1 - MemA[address,4] = bits(32) UNKNOWN; - else - if UnalignedAllowed then - MemU[address,4] = R[i]; - else - MemA[address,4] = R[i]; - address = address + 4; - if registers[15] == '1' then // Only possible for encoding A1 or A2 - if UnalignedAllowed then - MemU[address,4] = PCStoreValue(); - else - MemA[address,4] = PCStoreValue(); - SP = SP - 4*BitCount(registers); - -__instruction aarch32_STRHT_A - __encoding aarch32_STRHT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx0000 x110xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); postindex = TRUE; add = (U == '1'); - register_form = FALSE; imm32 = ZeroExtend(imm4H:imm4L, 32); - if t == 15 || n == 15 || n == t then UNPREDICTABLE; - - __encoding aarch32_STRHT_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0000 x010xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); postindex = TRUE; add = (U == '1'); - register_form = TRUE; - if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE; - - __encoding aarch32_STRHT_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - __opcode '11111000 0010xxxx xxxx1110 xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - if Rn == '1111' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; - register_form = FALSE; imm32 = ZeroExtend(imm8, 32); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = if register_form then R[m] else imm32; - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if postindex then R[n] else offset_addr; - MemU_unpriv[address,2] = R[t][15:0]; - if postindex then R[n] = offset_addr; - -__instruction aarch32_TEQ_i_A - __encoding aarch32_TEQ_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 0011xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); - (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C); - - __encoding aarch32_TEQ_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field imm8 0 +: 8 - __opcode '11110x00 1001xxxx 0xxx1111 xxxxxxxx' - __guard TRUE - __decode - n = UInt(Rn); - (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C); - if n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = R[n] EOR imm32; - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_LDAEXH_A - __encoding aarch32_LDAEXH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1111xxxx xxxxxx10 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDAEXH_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 1101xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - AArch32.SetExclusiveMonitors(address, 2); - R[t] = ZeroExtend(MemO[address, 2], 32); - -__instruction aarch32_VABS_A - __encoding aarch32_VABS_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx01 xxxx0x11 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - advsimd = TRUE; floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VABS_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110000 xxxx10xx 11x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - advsimd = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VABS_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx01 xxxx0x11 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - advsimd = TRUE; floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VABS_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110000 xxxx10xx 11x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - advsimd = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - if floating_point then - Elem[D[d+r],e,esize] = FPAbs(Elem[D[m+r],e,esize]); - else - result = Abs(SInt(Elem[D[m+r],e,esize])); - Elem[D[d+r],e,esize] = result[esize-1:0]; - else // VFP instruction - case esize of - when 16 S[d] = Zeros(16) : FPAbs(S[m][15:0]); - when 32 S[d] = FPAbs(S[m]); - when 64 D[d] = FPAbs(D[m]); - -__instruction aarch32_VRADDHN_A - __encoding aarch32_VRADDHN_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1xxxxxxx xxxx0100 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VRADDHN_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1xxxxxxx xxxx0100 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - round_const = 1 << (esize-1); - for e = 0 to elements-1 - result = Elem[Qin[n>>1],e,2*esize] + Elem[Qin[m>>1],e,2*esize] + round_const; - Elem[D[d],e,esize] = result[2*esize-1:esize]; - -__instruction aarch32_LDRHT_A - __encoding aarch32_LDRHT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx0000 x111xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); postindex = TRUE; add = (U == '1'); - register_form = FALSE; imm32 = ZeroExtend(imm4H:imm4L, 32); - if t == 15 || n == 15 || n == t then UNPREDICTABLE; - - __encoding aarch32_LDRHT_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0000 x011xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); postindex = TRUE; add = (U == '1'); - register_form = TRUE; - if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE; - - __encoding aarch32_LDRHT_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - __opcode '11111000 0011xxxx xxxx1110 xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - if Rn == '1111' then SEE "LDRH (literal)"; - t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; - register_form = FALSE; imm32 = ZeroExtend(imm8, 32); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = if register_form then R[m] else imm32; - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if postindex then R[n] else offset_addr; - data = MemU_unpriv[address,2]; - if postindex then R[n] = offset_addr; - R[t] = ZeroExtend(data, 32); - -__instruction aarch32_VCLZ_A - __encoding aarch32_VCLZ_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx00 xxxx0100 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCLZ_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx00 xxxx0100 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = CountLeadingZeroBits(Elem[D[m+r],e,esize])[esize-1:0]; - -__instruction aarch32_ORN_i_A - __encoding aarch32_ORN_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x00 011xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "MVN (immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); - (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = R[n] OR NOT(imm32); - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VMOV_rs_A - __encoding aarch32_VMOV_rs_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field opc1 21 +: 2 - __field Vd 16 +: 4 - __field Rt 12 +: 4 - __field D 7 +: 1 - __field opc2 5 +: 2 - __opcode 'xxxx1110 0xx0xxxx xxxx1011 xxx1xxxx' - __guard cond != '1111' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - case opc1:opc2 of - when '1xxx' advsimd = TRUE; esize = 8; index = UInt(opc1[0]:opc2); - when '0xx1' advsimd = TRUE; esize = 16; index = UInt(opc1[0]:opc2[1]); - when '0x00' advsimd = FALSE; esize = 32; index = UInt(opc1[0]); - when '0x10' UNDEFINED; - d = UInt(D:Vd); t = UInt(Rt); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_VMOV_rs_T1A1_A - __instruction_set T32 - __field opc1 21 +: 2 - __field Vd 16 +: 4 - __field Rt 12 +: 4 - __field D 7 +: 1 - __field opc2 5 +: 2 - __opcode '11101110 0xx0xxxx xxxx1011 xxx1xxxx' - __guard TRUE - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - case opc1:opc2 of - when '1xxx' advsimd = TRUE; esize = 8; index = UInt(opc1[0]:opc2); - when '0xx1' advsimd = TRUE; esize = 16; index = UInt(opc1[0]:opc2[1]); - when '0x00' advsimd = FALSE; esize = 32; index = UInt(opc1[0]); - when '0x10' UNDEFINED; - d = UInt(D:Vd); t = UInt(Rt); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - Elem[D[d],index,esize] = R[t][esize-1:0]; - -__instruction aarch32_USUB16_A - __encoding aarch32_USUB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0101xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_USUB16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1101xxxx 1111xxxx 0100xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = UInt(R[n][15:0]) - UInt(R[m][15:0]); - diff2 = UInt(R[n][31:16]) - UInt(R[m][31:16]); - R[d][15:0] = diff1[15:0]; - R[d][31:16] = diff2[15:0]; - PSTATE.GE[1:0] = if diff1 >= 0 then '11' else '00'; - PSTATE.GE[3:2] = if diff2 >= 0 then '11' else '00'; - -__instruction aarch32_VDOT_s_A - __encoding aarch32_VDOT_s_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x10xxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if !HaveDOTPExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - boolean signed = (U=='0'); - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm[3:0]); - integer index = UInt(M); - integer esize = 32; - integer regs = if Q == '1' then 2 else 1; - - __encoding aarch32_VDOT_s_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x10xxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveDOTPExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - boolean signed = (U=='0'); - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm[3:0]); - integer index = UInt(M); - integer esize = 32; - integer regs = if Q == '1' then 2 else 1; - - __execute - bits(64) operand1; - bits(64) operand2 = D[m]; - bits(64) result; - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - operand1 = D[n+r]; - result = D[d+r]; - integer element1, element2; - for e = 0 to 1 - integer res = 0; - for i = 0 to 3 - if signed then - element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = SInt(Elem[operand2, 4 * index + i, esize DIV 4]); - else - element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = UInt(Elem[operand2, 4 * index + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = Elem[result, e, esize] + res; - D[d+r] = result; - -__instruction aarch32_UBFX_A - __encoding aarch32_UBFX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field widthm1 16 +: 5 - __field Rd 12 +: 4 - __field lsb 7 +: 5 - __field Rn 0 +: 4 - __opcode 'xxxx0111 111xxxxx xxxxxxxx x101xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); - lsbit = UInt(lsb); widthminus1 = UInt(widthm1); - if d == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_UBFX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field widthm1 0 +: 5 - __opcode '11110x11 1100xxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 26 == '0' - __unpredictable_unless 5 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); - lsbit = UInt(imm3:imm2); widthminus1 = UInt(widthm1); - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - msbit = lsbit + widthminus1; - if msbit <= 31 then - R[d] = ZeroExtend(R[n][msbit:lsbit], 32); - else - UNPREDICTABLE; - -__instruction aarch32_VADDL_A - __encoding aarch32_VADDL_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0000 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' || (op == '1' && Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; is_vaddw = (op == '1'); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VADDL_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0000 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' || (op == '1' && Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; is_vaddw = (op == '1'); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - if is_vaddw then - op1 = Int(Elem[Qin[n>>1],e,2*esize], unsigned); - else - op1 = Int(Elem[Din[n],e,esize], unsigned); - result = op1 + Int(Elem[Din[m],e,esize],unsigned); - Elem[Q[d>>1],e,2*esize] = result[2*esize-1:0]; - -__instruction aarch32_LDREX_A - __encoding aarch32_LDREX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1001xxxx xxxxxx11 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDREX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - __opcode '11101000 0101xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); - if t == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - address = R[n] + imm32; - AArch32.SetExclusiveMonitors(address,4); - R[t] = MemA[address,4]; - -__instruction aarch32_MRC_A - __encoding aarch32_MRC_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field opc1 21 +: 3 - __field CRn 16 +: 4 - __field Rt 12 +: 4 - __field coproc 8 +: 4 - __field opc2 5 +: 3 - __field CRm 0 +: 4 - __opcode 'xxxx1110 xxx1xxxx xxxx111x xxx1xxxx' - __guard cond != '1111' - __decode - t = UInt(Rt); cp = if coproc[0] == '0' then 14 else 15; - // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_MRC_T1A1_A - __instruction_set T32 - __field opc1 21 +: 3 - __field CRn 16 +: 4 - __field Rt 12 +: 4 - __field coproc 8 +: 4 - __field opc2 5 +: 3 - __field CRm 0 +: 4 - __opcode '11101110 xxx1xxxx xxxx111x xxx1xxxx' - __guard TRUE - __decode - t = UInt(Rt); cp = if coproc[0] == '0' then 14 else 15; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - bits(32) value = AArch32.SysRegRead(cp, ThisInstr()); - if t != 15 then - R[t] = value; - elsif AArch32.SysRegReadCanWriteAPSR(cp, ThisInstr()) then - PSTATE.[N,Z,C,V] = value[31:28]; - // value[27:0] are not used. - else - PSTATE.[N,Z,C,V] = bits(4) UNKNOWN; - -__instruction aarch32_VRINTZ_vfp_A - __encoding aarch32_VRINTZ_vfp_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110110 xxxx10xx 11x0xxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VRINTZ_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110110 xxxx10xx 11x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = Zeros(16) : FPRoundInt(S[m][15:0], FPSCR, rounding, exact); - when 32 - S[d] = FPRoundInt(S[m], FPSCR, rounding, exact); - when 64 - D[d] = FPRoundInt(D[m], FPSCR, rounding, exact); - -__instruction aarch32_UDF_A - __encoding aarch32_UDF_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field imm12 8 +: 12 - __field imm4 0 +: 4 - __opcode '11100111 1111xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __decode - imm32 = ZeroExtend(imm12:imm4, 32); - // imm32 is for assembly and disassembly only, and is ignored by hardware. - - __encoding aarch32_UDF_T1_A - __instruction_set T16 - __field imm8 16 +: 8 - __opcode '11011110 xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - imm32 = ZeroExtend(imm8, 32); - // imm32 is for assembly and disassembly only, and is ignored by hardware. - - __encoding aarch32_UDF_T2_A - __instruction_set T32 - __field imm4 16 +: 4 - __field imm12 0 +: 12 - __opcode '11110111 1111xxxx 1010xxxx xxxxxxxx' - __guard TRUE - __decode - imm32 = ZeroExtend(imm4:imm12, 32); - // imm32 is for assembly and disassembly only, and is ignored by hardware. - - __execute __conditional - UNDEFINED; - -__instruction aarch32_SXTB_A - __encoding aarch32_SXTB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 10101111 xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SXTB_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - __opcode '10110010 01xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); rotation = 0; - - __encoding aarch32_SXTB_T2_A - __instruction_set T32 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 01001111 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d] = SignExtend(rotated[7:0], 32); - -__instruction aarch32_SSAT16_A - __encoding aarch32_SSAT16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field sat_imm 16 +: 4 - __field Rd 12 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0110 1010xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm)+1; - if d == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_SSAT16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field sat_imm 0 +: 4 - __opcode '11110x11 0010xxxx 0000xxxx 00xxxxxx' - __guard TRUE - __unpredictable_unless 26 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 4 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm)+1; - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (result1, sat1) = SignedSatQ(SInt(R[n][15:0]), saturate_to); - (result2, sat2) = SignedSatQ(SInt(R[n][31:16]), saturate_to); - R[d][15:0] = SignExtend(result1, 16); - R[d][31:16] = SignExtend(result2, 16); - if sat1 || sat2 then - PSTATE.Q = '1'; - -__instruction aarch32_VMOVN_A - __encoding aarch32_VMOVN_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0010 00x0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VMOVN_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0010 00x0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - Elem[D[d],e,esize] = Elem[Qin[m>>1],e,2*esize][esize-1:0]; - -__instruction aarch32_VMOV_i_A - __encoding aarch32_VMOV_i_T1A1_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx0xx0 0x01xxxx' - __guard TRUE - __decode - if op == '0' && cmode[0] == '1' && cmode[3:2] != '11' then SEE "VORR (immediate)"; - if op == '1' && cmode != '1110' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - single_register = FALSE; advsimd = TRUE; imm64 = AdvSIMDExpandImm(op, cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMOV_i_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field imm4H 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm4L 0 +: 4 - __opcode 'xxxx1110 1x11xxxx xxxx10xx x0x0xxxx' - __guard cond != '1111' - __unpredictable_unless 7 == '0' - __unpredictable_unless 5 == '0' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - single_register = (size != '11'); advsimd = FALSE; - bits(16) imm16; - bits(32) imm32; - bits(64) imm64; - case size of - when '01' d = UInt(Vd:D); imm16 = VFPExpandImm(imm4H:imm4L); imm32 = Zeros(16) : imm16; - when '10' d = UInt(Vd:D); imm32 = VFPExpandImm(imm4H:imm4L); - when '11' d = UInt(D:Vd); imm64 = VFPExpandImm(imm4H:imm4L); regs = 1; - - __encoding aarch32_VMOV_i_T3A3_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx10x0 0x01xxxx' - __guard TRUE - __decode - if op == '0' && cmode[0] == '1' && cmode[3:2] != '11' then SEE "VORR (immediate)"; - if op == '1' && cmode != '1110' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - single_register = FALSE; advsimd = TRUE; imm64 = AdvSIMDExpandImm(op, cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMOV_i_T4A4_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx11xx 0x01xxxx' - __guard TRUE - __decode - if op == '0' && cmode[0] == '1' && cmode[3:2] != '11' then SEE "VORR (immediate)"; - if op == '1' && cmode != '1110' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - single_register = FALSE; advsimd = TRUE; imm64 = AdvSIMDExpandImm(op, cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMOV_i_T5A5_A - __instruction_set A32 - __field i 24 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - __opcode '1111001x 1x000xxx xxxx1110 0x11xxxx' - __guard TRUE - __decode - if op == '0' && cmode[0] == '1' && cmode[3:2] != '11' then SEE "VORR (immediate)"; - if op == '1' && cmode != '1110' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - single_register = FALSE; advsimd = TRUE; imm64 = AdvSIMDExpandImm(op, cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMOV_i_T1A1_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx0xx0 0x01xxxx' - __guard TRUE - __decode - if op == '0' && cmode[0] == '1' && cmode[3:2] != '11' then SEE "VORR (immediate)"; - if op == '1' && cmode != '1110' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - single_register = FALSE; advsimd = TRUE; imm64 = AdvSIMDExpandImm(op, cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMOV_i_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field imm4H 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm4L 0 +: 4 - __opcode '11101110 1x11xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __unpredictable_unless 7 == '0' - __unpredictable_unless 5 == '0' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - single_register = (size != '11'); advsimd = FALSE; - bits(16) imm16; - bits(32) imm32; - bits(64) imm64; - case size of - when '01' d = UInt(Vd:D); imm16 = VFPExpandImm(imm4H:imm4L); imm32 = Zeros(16) : imm16; - when '10' d = UInt(Vd:D); imm32 = VFPExpandImm(imm4H:imm4L); - when '11' d = UInt(D:Vd); imm64 = VFPExpandImm(imm4H:imm4L); regs = 1; - - __encoding aarch32_VMOV_i_T3A3_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx10x0 0x01xxxx' - __guard TRUE - __decode - if op == '0' && cmode[0] == '1' && cmode[3:2] != '11' then SEE "VORR (immediate)"; - if op == '1' && cmode != '1110' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - single_register = FALSE; advsimd = TRUE; imm64 = AdvSIMDExpandImm(op, cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMOV_i_T4A4_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx11xx 0x01xxxx' - __guard TRUE - __decode - if op == '0' && cmode[0] == '1' && cmode[3:2] != '11' then SEE "VORR (immediate)"; - if op == '1' && cmode != '1110' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - single_register = FALSE; advsimd = TRUE; imm64 = AdvSIMDExpandImm(op, cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMOV_i_T5A5_A - __instruction_set T32 - __field i 28 +: 1 - __field D 22 +: 1 - __field imm3 16 +: 3 - __field Vd 12 +: 4 - __field cmode 8 +: 4 - __field Q 6 +: 1 - __field op 5 +: 1 - __field imm4 0 +: 4 - __opcode '111x1111 1x000xxx xxxx1110 0x11xxxx' - __guard TRUE - __decode - if op == '0' && cmode[0] == '1' && cmode[3:2] != '11' then SEE "VORR (immediate)"; - if op == '1' && cmode != '1110' then SEE "Related encodings"; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - single_register = FALSE; advsimd = TRUE; imm64 = AdvSIMDExpandImm(op, cmode, i:imm3:imm4); - d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if single_register then - S[d] = imm32; - else - for r = 0 to regs-1 - D[d+r] = imm64; - -__instruction aarch32_STRH_i_A - __encoding aarch32_STRH_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx000x x1x0xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "STRHT"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_STRH_i_T1_A - __instruction_set T16 - __field imm5 22 +: 5 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '10000xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); - index = TRUE; add = TRUE; wback = FALSE; - - __encoding aarch32_STRH_i_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 1010xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = TRUE; add = TRUE; wback = FALSE; - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_STRH_i_T3_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field P 10 +: 1 - __field U 9 +: 1 - __field W 8 +: 1 - __field imm8 0 +: 8 - __opcode '11111000 0010xxxx xxxx1xxx xxxxxxxx' - __guard TRUE - __decode - if P == '1' && U == '1' && W == '0' then SEE "STRHT"; - if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if t == 15 || (wback && n == t) then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute - if CurrentInstrSet() == InstrSet_A32 then - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - MemU[address,2] = R[t][15:0]; - if wback then R[n] = offset_addr; - else - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - MemU[address,2] = R[t][15:0]; - if wback then R[n] = offset_addr; - -__instruction aarch32_VLD3_a_A - __encoding aarch32_VLD3_a_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - __opcode '11110100 1x10xxxx xxxx1110 xxx0xxxx' - __guard TRUE - __decode - if size == '11' || a == '1' then UNDEFINED; - ebytes = 1 << UInt(size); - inc = if T == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD3_a_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field T 5 +: 1 - __field a 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111001 1x10xxxx xxxx1110 xxx0xxxx' - __guard TRUE - __decode - if size == '11' || a == '1' then UNDEFINED; - ebytes = 1 << UInt(size); - inc = if T == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; - D[d] = Replicate(MemU[address,ebytes]); - D[d2] = Replicate(MemU[address+ebytes,ebytes]); - D[d3] = Replicate(MemU[address+2*ebytes,ebytes]); - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 3*ebytes; - -__instruction aarch32_VRINTA_vfp_A - __encoding aarch32_VRINTA_vfp_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111001 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VRINTA_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111001 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = Zeros(16) : FPRoundInt(S[m][15:0], FPSCR, rounding, exact); - when 32 - S[d] = FPRoundInt(S[m], FPSCR, rounding, exact); - when 64 - D[d] = FPRoundInt(D[m], FPSCR, rounding, exact); - -__instruction aarch32_SHSUB8_A - __encoding aarch32_SHSUB8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0011xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SHSUB8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1100xxxx 1111xxxx 0010xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = SInt(R[n][7:0]) - SInt(R[m][7:0]); - diff2 = SInt(R[n][15:8]) - SInt(R[m][15:8]); - diff3 = SInt(R[n][23:16]) - SInt(R[m][23:16]); - diff4 = SInt(R[n][31:24]) - SInt(R[m][31:24]); - R[d][7:0] = diff1[8:1]; - R[d][15:8] = diff2[8:1]; - R[d][23:16] = diff3[8:1]; - R[d][31:24] = diff4[8:1]; - -__instruction aarch32_LDREXH_A - __encoding aarch32_LDREXH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1111xxxx xxxxxx11 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDREXH_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 0101xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - address = R[n]; - AArch32.SetExclusiveMonitors(address,2); - R[t] = ZeroExtend(MemA[address,2], 32); - -__instruction aarch32_DSB_A - __encoding aarch32_DSB_A1_A - __instruction_set A32 - __field option 0 +: 4 - __opcode '11110101 0111xxxx xxxxxxxx 0100xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_DSB_T1_A - __instruction_set T32 - __field option 0 +: 4 - __opcode '11110011 1011xxxx 10x0xxxx 0100xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - // No additional decoding required - - __execute __conditional - case option of - when '0001' domain = MBReqDomain_OuterShareable; types = MBReqTypes_Reads; - when '0010' domain = MBReqDomain_OuterShareable; types = MBReqTypes_Writes; - when '0011' domain = MBReqDomain_OuterShareable; types = MBReqTypes_All; - when '0101' domain = MBReqDomain_Nonshareable; types = MBReqTypes_Reads; - when '0110' domain = MBReqDomain_Nonshareable; types = MBReqTypes_Writes; - when '0111' domain = MBReqDomain_Nonshareable; types = MBReqTypes_All; - when '1001' domain = MBReqDomain_InnerShareable; types = MBReqTypes_Reads; - when '1010' domain = MBReqDomain_InnerShareable; types = MBReqTypes_Writes; - when '1011' domain = MBReqDomain_InnerShareable; types = MBReqTypes_All; - when '1101' domain = MBReqDomain_FullSystem; types = MBReqTypes_Reads; - when '1110' domain = MBReqDomain_FullSystem; types = MBReqTypes_Writes; - otherwise - if option == '0000' then SEE "SSBB"; - elsif option == '0100' then SEE "PSSBB"; - else domain = MBReqDomain_FullSystem; types = MBReqTypes_All; - - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then - if HCR.BSU == '11' then - domain = MBReqDomain_FullSystem; - if HCR.BSU == '10' && domain != MBReqDomain_FullSystem then - domain = MBReqDomain_OuterShareable; - if HCR.BSU == '01' && domain == MBReqDomain_Nonshareable then - domain = MBReqDomain_InnerShareable; - - DataSynchronizationBarrier(domain, types); - -__instruction aarch32_REV_A - __encoding aarch32_REV_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1011xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); m = UInt(Rm); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_REV_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - __opcode '10111010 00xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); - - __encoding aarch32_REV_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 1000xxxx' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); n = UInt(Rn); - if m != n || d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - bits(32) result; - result[31:24] = R[m][7:0]; - result[23:16] = R[m][15:8]; - result[15:8] = R[m][23:16]; - result[7:0] = R[m][31:24]; - R[d] = result; - -__instruction aarch32_VORR_r_A - __encoding aarch32_VORR_r_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x10xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VORR_r_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x10xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - D[d+r] = D[n+r] OR D[m+r]; - -__instruction aarch32_VQRSHL_A - __encoding aarch32_VQRSHL_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0101 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQRSHL_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0101 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - shift = SInt(Elem[D[n+r],e,esize][7:0]); - round_const = 1 << (-1-shift); // 0 for left shift, 2^(n-1) for right shift - operand = Int(Elem[D[m+r],e,esize], unsigned); - (result, sat) = SatQ((operand + round_const) << shift, esize, unsigned); - Elem[D[d+r],e,esize] = result; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_STRH_r_A - __encoding aarch32_STRH_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx000x x0x0xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if P == '0' && W == '1' then SEE "STRHT"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - (shift_t, shift_n) = (SRType_LSL, 0); - if t == 15 || m == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_STRH_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '0101001x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_STRH_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111000 0010xxxx xxxx0000 00xxxxxx' - __guard TRUE - __decode - if Rn == '1111' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if t == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if index then offset_addr else R[n]; - MemU[address,2] = R[t][15:0]; - if wback then R[n] = offset_addr; - -__instruction aarch32_VAND_r_A - __encoding aarch32_VAND_r_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x00xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VAND_r_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x00xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - D[d+r] = D[n+r] AND D[m+r]; - -__instruction aarch32_STL_A - __encoding aarch32_STL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1000xxxx xxxxxx00 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_STL_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 1010xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - MemO[address, 4] = R[t]; - -__instruction aarch32_VQADD_A - __encoding aarch32_VQADD_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0000 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQADD_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0000 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - sum = Int(Elem[D[n+r],e,esize], unsigned) + Int(Elem[D[m+r],e,esize], unsigned); - (Elem[D[d+r],e,esize], sat) = SatQ(sum, esize, unsigned); - if sat then FPSCR.QC = '1'; - -__instruction aarch32_QSUB16_A - __encoding aarch32_QSUB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0010xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QSUB16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1101xxxx 1111xxxx 0001xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = SInt(R[n][15:0]) - SInt(R[m][15:0]); - diff2 = SInt(R[n][31:16]) - SInt(R[m][31:16]); - R[d][15:0] = SignedSat(diff1, 16); - R[d][31:16] = SignedSat(diff2, 16); - -__instruction aarch32_VRSRA_A - __encoding aarch32_VRSRA_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0011 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRSRA_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0011 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - round_const = 1 << (shift_amount - 1); - for r = 0 to regs-1 - for e = 0 to elements-1 - result = (Int(Elem[D[m+r],e,esize], unsigned) + round_const) >> shift_amount; - Elem[D[d+r],e,esize] = Elem[D[d+r],e,esize] + result; - -__instruction aarch32_VMLA_s_A - __encoding aarch32_VMLA_s_T2A2_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0010 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); add = (op == '0'); floating_point = FALSE; long_destination = TRUE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = 1; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VMLA_s_T2A2_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0010 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - unsigned = (U == '1'); add = (op == '0'); floating_point = FALSE; long_destination = TRUE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = 1; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - op2 = Elem[Din[m],index,esize]; op2val = Int(op2, unsigned); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; op1val = Int(op1, unsigned); - if floating_point then - fp_addend = if add then FPMul(op1,op2,StandardFPSCRValue()) else FPNeg(FPMul(op1,op2,StandardFPSCRValue())); - Elem[D[d+r],e,esize] = FPAdd(Elem[Din[d+r],e,esize], fp_addend, StandardFPSCRValue()); - else - addend = if add then op1val*op2val else -op1val*op2val; - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend; - -__instruction aarch32_LDRSH_r_A - __encoding aarch32_LDRSH_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx000x x0x1xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if P == '0' && W == '1' then SEE "LDRSHT"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - (shift_t, shift_n) = (SRType_LSL, 0); - if t == 15 || m == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_LDRSH_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '0101111x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_LDRSH_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0011xxxx xxxx0000 00xxxxxx' - __guard TRUE - __decode - if Rn == '1111' then SEE "LDRSH (literal)"; - if Rt == '1111' then SEE "Related instructions"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if index then offset_addr else R[n]; - data = MemU[address,2]; - if wback then R[n] = offset_addr; - R[t] = SignExtend(data, 32); - -__instruction aarch32_RSB_rr_A - __encoding aarch32_RSB_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 011xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(NOT(R[n]), shifted, '1'); - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_NOP_A - __encoding aarch32_NOP_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 00000000' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_NOP_T1_A - __instruction_set T16 - __opcode '10111111 00000000 00000000 00000000' - __guard TRUE - __decode - // No additional decoding required - - __encoding aarch32_NOP_T2_A - __instruction_set T32 - __opcode '11110011 1010xxxx 10x0x000 00000000' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - // No additional decoding required - - __execute __conditional - // Do nothing - -__instruction aarch32_VCVT_iv_A - __encoding aarch32_VCVT_iv_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field opc2 16 +: 3 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x111000 xxxx10xx x1x0xxxx' - __guard cond != '1111' - __decode - if opc2 != '000' && opc2 != '10x' then SEE "Related encodings"; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - to_integer = (opc2[2] == '1'); - if to_integer then - unsigned = (opc2[0] == '0'); - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - else - unsigned = (op == '0'); - rounding = FPRoundingMode(FPSCR); - m = UInt(Vm:M); - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __encoding aarch32_VCVT_iv_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field opc2 16 +: 3 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x111000 xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if opc2 != '000' && opc2 != '10x' then SEE "Related encodings"; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - to_integer = (opc2[2] == '1'); - if to_integer then - unsigned = (opc2[0] == '0'); - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - else - unsigned = (op == '0'); - rounding = FPRoundingMode(FPSCR); - m = UInt(Vm:M); - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __execute __conditional - CheckVFPEnabled(TRUE); - if to_integer then - case esize of - when 16 - S[d] = FPToFixed(S[m][15:0], 0, unsigned, FPSCR, rounding); - when 32 - S[d] = FPToFixed(S[m], 0, unsigned, FPSCR, rounding); - when 64 - S[d] = FPToFixed(D[m], 0, unsigned, FPSCR, rounding); - else - case esize of - when 16 - bits(16) fp16 = FixedToFP(S[m], 0, unsigned, FPSCR, rounding); - S[d] = Zeros(16):fp16; - when 32 - S[d] = FixedToFP(S[m], 0, unsigned, FPSCR, rounding); - when 64 - D[d] = FixedToFP(S[m], 0, unsigned, FPSCR, rounding); - -__instruction aarch32_SUB_SP_i_A - __encoding aarch32_SUB_SP_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 010x1101 xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); setflags = (S == '1'); imm32 = A32ExpandImm(imm12); - - __encoding aarch32_SUB_SP_i_T1_A - __instruction_set T16 - __field imm7 16 +: 7 - __opcode '10110000 1xxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); - - __encoding aarch32_SUB_SP_i_T2_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x01 101x1101 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rd == '1111' && S == '1' then SEE "CMP (immediate)"; - d = UInt(Rd); setflags = (S == '1'); imm32 = T32ExpandImm(i:imm3:imm8); - if d == 15 && !setflags then UNPREDICTABLE; - - __encoding aarch32_SUB_SP_i_T3_A - __instruction_set T32 - __field i 26 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x10 10101101 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); - if d == 15 then UNPREDICTABLE; - - __execute __conditional - (result, nzcv) = AddWithCarry(SP, NOT(imm32), '1'); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VSUB_i_A - __encoding aarch32_VSUB_i_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0xxxxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSUB_i_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0xxxxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = Elem[D[n+r],e,esize] - Elem[D[m+r],e,esize]; - -__instruction aarch32_SHASX_A - __encoding aarch32_SHASX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0011xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SHASX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1010xxxx 1111xxxx 0010xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff = SInt(R[n][15:0]) - SInt(R[m][31:16]); - sum = SInt(R[n][31:16]) + SInt(R[m][15:0]); - R[d][15:0] = diff[16:1]; - R[d][31:16] = sum[16:1]; - -__instruction aarch32_SHA1M_A - __encoding aarch32_SHA1M_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x10xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if !HaveSHA1Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_SHA1M_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x10xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA1Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - X = Q[d>>1]; - Y = Q[n>>1][31:0]; // Note: 32 bits wide - W = Q[m>>1]; - for e = 0 to 3 - t = SHAmajority(X[63:32], X[95:64], X[127:96]); - Y = Y + ROL(X[31:0], 5) + t + Elem[W, e, 32]; - X[63:32] = ROL(X[63:32], 30); - [Y, X] = ROL(Y:X, 32); - Q[d>>1] = X; - -__instruction aarch32_SMLABB_A - __encoding aarch32_SMLABB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field M 6 +: 1 - __field N 5 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0001 0000xxxx xxxxxxxx 1xx0xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - n_high = (N == '1'); m_high = (M == '1'); - if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE; - - __encoding aarch32_SMLABB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field N 5 +: 1 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0001xxxx xxxxxxxx 00xxxxxx' - __guard TRUE - __decode - if Ra == '1111' then SEE "SMULBB, SMULBT, SMULTB, SMULTT"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - n_high = (N == '1'); m_high = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand1 = if n_high then R[n][31:16] else R[n][15:0]; - operand2 = if m_high then R[m][31:16] else R[m][15:0]; - result = SInt(operand1) * SInt(operand2) + SInt(R[a]); - R[d] = result[31:0]; - if result != SInt(result[31:0]) then // Signed overflow - PSTATE.Q = '1'; - -__instruction aarch32_VCEQ_r_A - __encoding aarch32_VCEQ_r_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0xxxxxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - int_operation = TRUE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCEQ_r_A2_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x0xxxxx xxxx1110 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - int_operation = FALSE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCEQ_r_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0xxxxxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - int_operation = TRUE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCEQ_r_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x0xxxxx xxxx1110 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - int_operation = FALSE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[n+r],e,esize]; op2 = Elem[D[m+r],e,esize]; - if int_operation then - test_passed = (op1 == op2); - else - test_passed = FPCompareEQ(op1, op2, StandardFPSCRValue()); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_SBC_i_A - __encoding aarch32_SBC_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 110xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = A32ExpandImm(imm12); - - __encoding aarch32_SBC_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x01 011xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = T32ExpandImm(i:imm3:imm8); - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (result, nzcv) = AddWithCarry(R[n], NOT(imm32), PSTATE.C); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VRINTZ_asimd_A - __encoding aarch32_VRINTZ_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0101 1xx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPRounding_ZERO; exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRINTZ_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0101 1xx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPRounding_ZERO; exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - if InITBlock() then UNPREDICTABLE; - - __execute - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[m+r],e,esize]; - result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact); - Elem[D[d+r],e,esize] = result; - -__instruction aarch32_UASX_A - __encoding aarch32_UASX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0101xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UASX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1010xxxx 1111xxxx 0100xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff = UInt(R[n][15:0]) - UInt(R[m][31:16]); - sum = UInt(R[n][31:16]) + UInt(R[m][15:0]); - R[d][15:0] = diff[15:0]; - R[d][31:16] = sum[15:0]; - PSTATE.GE[1:0] = if diff >= 0 then '11' else '00'; - PSTATE.GE[3:2] = if sum >= 0x10000 then '11' else '00'; - -__instruction aarch32_STLEXD_A - __encoding aarch32_STLEXD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1010xxxx xxxxxx10 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); t2 = t+1; n = UInt(Rn); - if d == 15 || Rt[0] == '1' || t2 == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t || d == t2 then UNPREDICTABLE; - - __encoding aarch32_STLEXD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __field Rd 0 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 1111xxxx' - __guard TRUE - __decode - d = UInt(Rd); t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); - if d == 15 || t == 15 || t2 == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t || d == t2 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - // Create doubleword to store such that R[t] will be stored at address and R[t2] at address+4. - value = if BigEndian() then R[t]:R[t2] else R[t2]:R[t]; - if AArch32.ExclusiveMonitorsPass(address, 8) then - MemO[address, 8] = value; - R[d] = ZeroExtend('0'); - else - R[d] = ZeroExtend('1'); - -__instruction aarch32_VACGE_A - __encoding aarch32_VACGE_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x0xxxxx xxxx1110 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - or_equal = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VACGE_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x0xxxxx xxxx1110 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - or_equal = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = FPAbs(Elem[D[n+r],e,esize]); op2 = FPAbs(Elem[D[m+r],e,esize]); - if or_equal then - test_passed = FPCompareGE(op1, op2, StandardFPSCRValue()); - else - test_passed = FPCompareGT(op1, op2, StandardFPSCRValue()); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_VRHADD_A - __encoding aarch32_VRHADD_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0001 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRHADD_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0001 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Int(Elem[D[n+r],e,esize], unsigned); - op2 = Int(Elem[D[m+r],e,esize], unsigned); - result = op1 + op2 + 1; - Elem[D[d+r],e,esize] = result[esize:1]; - -__instruction aarch32_SASX_A - __encoding aarch32_SASX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0001xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SASX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1010xxxx 1111xxxx 0000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff = SInt(R[n][15:0]) - SInt(R[m][31:16]); - sum = SInt(R[n][31:16]) + SInt(R[m][15:0]); - R[d][15:0] = diff[15:0]; - R[d][31:16] = sum[15:0]; - PSTATE.GE[1:0] = if diff >= 0 then '11' else '00'; - PSTATE.GE[3:2] = if sum >= 0 then '11' else '00'; - -__instruction aarch32_ADD_rr_A - __encoding aarch32_ADD_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 100xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], shifted, '0'); - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VSHR_A - __encoding aarch32_VSHR_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0000 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VSHR_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field L 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0000 xxx1xxxx' - __guard TRUE - __decode - if (L:imm6) == '0000xxx' then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - case L:imm6 of - when '0001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '001xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '01xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - when '1xxxxxx' esize = 64; elements = 1; shift_amount = 64 - UInt(imm6); - unsigned = (U == '1'); d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - result = Int(Elem[D[m+r],e,esize], unsigned) >> shift_amount; - Elem[D[d+r],e,esize] = result[esize-1:0]; - -__instruction aarch32_STRBT_A - __encoding aarch32_STRBT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0100 x110xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); postindex = TRUE; add = (U == '1'); - register_form = FALSE; imm32 = ZeroExtend(imm12, 32); - if t == 15 || n == 15 || n == t then UNPREDICTABLE; - - __encoding aarch32_STRBT_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 x110xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); postindex = TRUE; add = (U == '1'); - register_form = TRUE; (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE; - - __encoding aarch32_STRBT_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - __opcode '11111000 0000xxxx xxxx1110 xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - if Rn == '1111' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; - register_form = FALSE; imm32 = ZeroExtend(imm8, 32); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = if register_form then Shift(R[m], shift_t, shift_n, PSTATE.C) else imm32; - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if postindex then R[n] else offset_addr; - MemU_unpriv[address,1] = R[t][7:0]; - if postindex then R[n] = offset_addr; - -__instruction aarch32_UQSAX_A - __encoding aarch32_UQSAX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0110xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UQSAX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1110xxxx 1111xxxx 0101xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum = UInt(R[n][15:0]) + UInt(R[m][31:16]); - diff = UInt(R[n][31:16]) - UInt(R[m][15:0]); - R[d][15:0] = UnsignedSat(sum, 16); - R[d][31:16] = UnsignedSat(diff, 16); - -__instruction aarch32_VCVTA_asimd_A - __encoding aarch32_VCVTA_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field RM 8 +: 2 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx11 xxxx0001 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCVTA_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field RM 8 +: 2 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx11 xxxx0001 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - bits(esize) result; - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = FPToFixed(Elem[D[m+r],e,esize], 0, unsigned, - StandardFPSCRValue(), rounding); - -__instruction aarch32_LDREXD_A - __encoding aarch32_LDREXD_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1011xxxx xxxxxx11 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); t2 = t + 1; n = UInt(Rn); - if Rt[0] == '1' || t2 == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDREXD_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rt2 8 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 0111xxxx' - __guard TRUE - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); - if t == 15 || t2 == 15 || t == t2 || n == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - address = R[n]; - AArch32.SetExclusiveMonitors(address,8); - value = MemA[address,8]; - // Extract words from 64-bit loaded value such that R[t] is - // loaded from address and R[t2] from address+4. - R[t] = if BigEndian() then value[63:32] else value[31:0]; - R[t2] = if BigEndian() then value[31:0] else value[63:32]; - -__instruction aarch32_VUSDOT_A - __encoding aarch32_VUSDOT_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 1x10xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer regs = if Q == '1' then 2 else 1; - - __encoding aarch32_VUSDOT_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 1x10xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer regs = if Q == '1' then 2 else 1; - - __execute - CheckAdvSIMDEnabled(); - bits(64) operand1; - bits(64) operand2; - bits(64) result; - - for r = 0 to regs-1 - operand1 = Din[n+r]; - operand2 = Din[m+r]; - result = Din[d+r]; - for e = 0 to 1 - bits(32) res = Elem[result, e, 32]; - for b = 0 to 3 - element1 = UInt(Elem[operand1, 4 * e + b, 8]); - element2 = SInt(Elem[operand2, 4 * e + b, 8]); - res = res + element1 * element2; - Elem[result, e, 32] = res; - D[d+r] = result; - -__instruction aarch32_VDOT_A - __encoding aarch32_VDOT_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x10xxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if !HaveDOTPExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - boolean signed = U=='0'; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer esize = 32; - integer regs = if Q == '1' then 2 else 1; - - __encoding aarch32_VDOT_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x10xxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveDOTPExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - boolean signed = U=='0'; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer esize = 32; - integer regs = if Q == '1' then 2 else 1; - - __execute - bits(64) operand1; - bits(64) operand2; - bits(64) result; - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - operand1 = D[n+r]; - operand2 = D[m+r]; - result = D[d+r]; - integer element1, element2; - for e = 0 to 1 - integer res = 0; - for i = 0 to 3 - if signed then - element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = SInt(Elem[operand2, 4 * e + i, esize DIV 4]); - else - element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = UInt(Elem[operand2, 4 * e + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = Elem[result, e, esize] + res; - D[d+r] = result; - -__instruction aarch32_VCVT_A - __encoding aarch32_VCVT_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x110110 xxxx0110 01x0xxxx' - __guard TRUE - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - if Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer m = UInt(M:Vm); - - __encoding aarch32_VCVT_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x110110 xxxx0110 01x0xxxx' - __guard TRUE - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - if Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - bits(128) operand; - bits(64) result; - operand = Q[m>>1]; - for e = 0 to 3 - bits(32) op = Elem[operand, e, 32]; - Elem[result, e, 16] = FPConvertBF(op, StandardFPSCRValue()); - D[d] = result; - -__instruction aarch32_UXTB16_A - __encoding aarch32_UXTB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 11001111 xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UXTB16_T1_A - __instruction_set T32 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 00111111 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d][15:0] = ZeroExtend(rotated[7:0], 16); - R[d][31:16] = ZeroExtend(rotated[23:16], 16); - -__instruction aarch32_VRECPE_A - __encoding aarch32_VRECPE_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 8 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx11 xxxx010x 0xx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - floating_point = (F == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRECPE_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 8 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx11 xxxx010x 0xx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - floating_point = (F == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - if floating_point then - Elem[D[d+r],e,esize] = FPRecipEstimate(Elem[D[m+r],e,esize], StandardFPSCRValue()); - else - Elem[D[d+r],e,esize] = UnsignedRecipEstimate(Elem[D[m+r],e,esize]); - -__instruction aarch32_VMOV_r_A - __encoding aarch32_VMOV_r_T2A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110000 xxxx101x 01x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - single_register = (size == '10'); advsimd = FALSE; - if single_register then - d = UInt(Vd:D); m = UInt(Vm:M); - else - d = UInt(D:Vd); m = UInt(M:Vm); regs = 1; - - __encoding aarch32_VMOV_r_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110000 xxxx101x 01x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - single_register = (size == '10'); advsimd = FALSE; - if single_register then - d = UInt(Vd:D); m = UInt(Vm:M); - else - d = UInt(D:Vd); m = UInt(M:Vm); regs = 1; - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if single_register then - S[d] = S[m]; - else - for r = 0 to regs-1 - D[d+r] = D[m+r]; - -__instruction aarch32_PSSBB_A - __encoding aarch32_PSSBB_A1_A - __instruction_set A32 - __opcode '11110101 0111xxxx xxxxxxxx 01000100' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_PSSBB_T1_A - __instruction_set T32 - __opcode '11110011 1011xxxx 10x0xxxx 01000100' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - if InITBlock() then UNPREDICTABLE; - - __execute __conditional - SpeculativeStoreBypassBarrierToPA(); - -__instruction aarch32_VJCVT_A - __encoding aarch32_VJCVT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x111001 xxxx1011 11x0xxxx' - __guard cond != '1111' - __decode - if !HaveFJCVTZSExt() then UNDEFINED; - if cond != '1110' then UNPREDICTABLE; - d = UInt(Vd:D); m = UInt(M:Vm); - - __encoding aarch32_VJCVT_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x111001 xxxx1011 11x0xxxx' - __guard TRUE - __decode - if !HaveFJCVTZSExt() then UNDEFINED; - if InITBlock() then UNPREDICTABLE; - d = UInt(Vd:D); m = UInt(M:Vm); - - __execute - CheckVFPEnabled(TRUE); - bits(64) fltval = D[m]; - bits(32) intval; - bit Z; - (intval, Z) = FPToFixedJS(fltval, FPSCR, FALSE); - FPSCR[31:28] = '0':Z:'00'; - S[d] = intval; - -__instruction aarch32_VRINTX_vfp_A - __encoding aarch32_VRINTX_vfp_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110111 xxxx10xx 01x0xxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - exact = TRUE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VRINTX_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110111 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - exact = TRUE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - rounding = FPRoundingMode(FPSCR); - case esize of - when 16 - S[d] = Zeros(16) : FPRoundInt(S[m][15:0], FPSCR, rounding, exact); - when 32 - S[d] = FPRoundInt(S[m], FPSCR, rounding, exact); - when 64 - D[d] = FPRoundInt(D[m], FPSCR, rounding, exact); - -__instruction aarch32_VCMP_A - __encoding aarch32_VCMP_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field E 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110100 xxxx10xx 01x0xxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - quiet_nan_exc = (E == '1'); with_zero = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VCMP_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field E 7 +: 1 - __opcode 'xxxx1110 1x110101 xxxx10xx 01x0xxxx' - __guard cond != '1111' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - quiet_nan_exc = (E == '1'); with_zero = TRUE; - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __encoding aarch32_VCMP_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field E 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110100 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - quiet_nan_exc = (E == '1'); with_zero = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VCMP_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field E 7 +: 1 - __opcode '11101110 1x110101 xxxx10xx 01x0xxxx' - __guard TRUE - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - quiet_nan_exc = (E == '1'); with_zero = TRUE; - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __execute __conditional - CheckVFPEnabled(TRUE); - bits(4) nzcv; - case esize of - when 16 - bits(16) op16 = if with_zero then FPZero('0') else S[m][15:0]; - nzcv = FPCompare(S[d][15:0], op16, quiet_nan_exc, FPSCR); - when 32 - bits(32) op32 = if with_zero then FPZero('0') else S[m]; - nzcv = FPCompare(S[d], op32, quiet_nan_exc, FPSCR); - when 64 - bits(64) op64 = if with_zero then FPZero('0') else D[m]; - nzcv = FPCompare(D[d], op64, quiet_nan_exc, FPSCR); - - FPSCR.[N,Z,C,V] = nzcv; - -__instruction aarch32_TST_i_A - __encoding aarch32_TST_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 0001xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); - (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C); - - __encoding aarch32_TST_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field imm8 0 +: 8 - __opcode '11110x00 0001xxxx 0xxx1111 xxxxxxxx' - __guard TRUE - __decode - n = UInt(Rn); - (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C); - if n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = R[n] AND imm32; - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_LDAEX_A - __encoding aarch32_LDAEX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1001xxxx xxxxxx10 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDAEX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 1110xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - AArch32.SetExclusiveMonitors(address, 4); - R[t] = MemO[address, 4]; - -__instruction aarch32_MVN_i_A - __encoding aarch32_MVN_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 111xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - d = UInt(Rd); setflags = (S == '1'); - (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C); - - __encoding aarch32_MVN_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x00 011x1111 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); setflags = (S == '1'); - (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = NOT(imm32); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VFMA_A - __encoding aarch32_VFMA_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x0xxxxx xxxx1100 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - advsimd = TRUE; op1_neg = (op == '1'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VFMA_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x10xxxx xxxx10xx x0x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - advsimd = FALSE; op1_neg = (op == '1'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VFMA_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x0xxxxx xxxx1100 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - advsimd = TRUE; op1_neg = (op == '1'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VFMA_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x10xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - advsimd = FALSE; op1_neg = (op == '1'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - bits(esize) op1 = Elem[D[n+r],e,esize]; - if op1_neg then op1 = FPNeg(op1); - Elem[D[d+r],e,esize] = FPMulAdd(Elem[D[d+r],e,esize], - op1, Elem[D[m+r],e,esize], StandardFPSCRValue()); - - else // VFP instruction - case esize of - when 16 - op16 = if op1_neg then FPNeg(S[n][15:0]) else S[n][15:0]; - S[d] = Zeros(16) : FPMulAdd(S[d][15:0], op16, S[m][15:0], FPSCR); - when 32 - op32 = if op1_neg then FPNeg(S[n]) else S[n]; - S[d] = FPMulAdd(S[d], op32, S[m], FPSCR); - when 64 - op64 = if op1_neg then FPNeg(D[n]) else D[n]; - D[d] = FPMulAdd(D[d], op64, D[m], FPSCR); - -__instruction aarch32_WFE_A - __encoding aarch32_WFE_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 00000010' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_WFE_T1_A - __instruction_set T16 - __opcode '10111111 00100000 00000000 00000000' - __guard TRUE - __decode - // No additional decoding required - - __encoding aarch32_WFE_T2_A - __instruction_set T32 - __opcode '11110011 1010xxxx 10x0x000 00000010' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - // No additional decoding required - - __execute __conditional - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch32.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch32.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.M != M32_Monitor then - // Check for traps described by the Secure Monitor. - AArch32.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - -__instruction aarch32_VQRDMULH_A - __encoding aarch32_VQRDMULH_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0xxxxxxx xxxx1011 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '00' || size == '11' then UNDEFINED; - scalar_form = FALSE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQRDMULH_T2A2_A - __instruction_set A32 - __field Q 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx1101 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VQRDMULH_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0xxxxxxx xxxx1011 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '00' || size == '11' then UNDEFINED; - scalar_form = FALSE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQRDMULH_T2A2_A - __instruction_set T32 - __field Q 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx1101 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - round_const = 1 << (esize-1); - if scalar_form then op2 = SInt(Elem[D[m],index,esize]); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = SInt(Elem[D[n+r],e,esize]); - if !scalar_form then op2 = SInt(Elem[D[m+r],e,esize]); - (result, sat) = SignedSatQ((2*op1*op2 + round_const) >> esize, esize); - Elem[D[d+r],e,esize] = result; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_UHASX_A - __encoding aarch32_UHASX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0111xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UHASX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1010xxxx 1111xxxx 0110xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff = UInt(R[n][15:0]) - UInt(R[m][31:16]); - sum = UInt(R[n][31:16]) + UInt(R[m][15:0]); - R[d][15:0] = diff[16:1]; - R[d][31:16] = sum[16:1]; - -__instruction aarch32_RSC_rr_A - __encoding aarch32_RSC_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 111xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(NOT(R[n]), shifted, PSTATE.C); - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VCVT_iv_A - __encoding aarch32_VCVT_iv_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field opc2 16 +: 3 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x11110x xxxx10xx 01x0xxxx' - __guard cond != '1111' - __decode - if opc2 != '000' && opc2 != '10x' then SEE "Related encodings"; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - to_integer = (opc2[2] == '1'); - if to_integer then - unsigned = (opc2[0] == '0'); - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - else - unsigned = (op == '0'); - rounding = FPRoundingMode(FPSCR); - m = UInt(Vm:M); - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __encoding aarch32_VCVT_iv_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field opc2 16 +: 3 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x11110x xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if opc2 != '000' && opc2 != '10x' then SEE "Related encodings"; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - to_integer = (opc2[2] == '1'); - if to_integer then - unsigned = (opc2[0] == '0'); - rounding = if op == '1' then FPRounding_ZERO else FPRoundingMode(FPSCR); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - else - unsigned = (op == '0'); - rounding = FPRoundingMode(FPSCR); - m = UInt(Vm:M); - case size of - when '01' esize = 16; d = UInt(Vd:D); - when '10' esize = 32; d = UInt(Vd:D); - when '11' esize = 64; d = UInt(D:Vd); - - __execute __conditional - CheckVFPEnabled(TRUE); - if to_integer then - case esize of - when 16 - S[d] = FPToFixed(S[m][15:0], 0, unsigned, FPSCR, rounding); - when 32 - S[d] = FPToFixed(S[m], 0, unsigned, FPSCR, rounding); - when 64 - S[d] = FPToFixed(D[m], 0, unsigned, FPSCR, rounding); - else - case esize of - when 16 - bits(16) fp16 = FixedToFP(S[m], 0, unsigned, FPSCR, rounding); - S[d] = Zeros(16):fp16; - when 32 - S[d] = FixedToFP(S[m], 0, unsigned, FPSCR, rounding); - when 64 - D[d] = FixedToFP(S[m], 0, unsigned, FPSCR, rounding); - -__instruction aarch32_VST1_m_A - __encoding aarch32_VST1_m_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x00xxxx xxxx0111 xxxxxxxx' - __guard TRUE - __decode - regs = 1; if align[1] == '1' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST1_m_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x00xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - regs = 2; if align == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST1_m_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x00xxxx xxxx0110 xxxxxxxx' - __guard TRUE - __decode - regs = 3; if align[1] == '1' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST1_m_T4A4_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x00xxxx xxxx0010 xxxxxxxx' - __guard TRUE - __decode - regs = 4; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST1_m_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x00xxxx xxxx0111 xxxxxxxx' - __guard TRUE - __decode - regs = 1; if align[1] == '1' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST1_m_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x00xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - regs = 2; if align == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST1_m_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x00xxxx xxxx0110 xxxxxxxx' - __guard TRUE - __decode - regs = 3; if align[1] == '1' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VST1_m_T4A4_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x00xxxx xxxx0010 xxxxxxxx' - __guard TRUE - __decode - regs = 4; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d+regs > 32 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = TRUE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - for r = 0 to regs-1 - for e = 0 to elements-1 - if ebytes != 8 then - MemU[address,ebytes] = Elem[D[d+r],e]; - else - - = AArch32.CheckAlignment(address, ebytes, AccType_NORMAL, iswrite); - bits(64) data = Elem[D[d+r],e]; - MemU[address,4] = if BigEndian() then data[63:32] else data[31:0]; - MemU[address+4,4] = if BigEndian() then data[31:0] else data[63:32]; - address = address + ebytes; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 8*regs; - -__instruction aarch32_LDMDA_A - __encoding aarch32_LDMDA_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - __opcode 'xxxx1000 00x1xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - n = UInt(Rn); registers = register_list; wback = (W == '1'); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - if wback && registers[n] == '1' then UNPREDICTABLE; - - __execute __conditional - address = R[n] - 4*BitCount(registers) + 4; - for i = 0 to 14 - if registers[i] == '1' then - R[i] = MemA[address,4]; address = address + 4; - if registers[15] == '1' then - LoadWritePC(MemA[address,4]); - if wback && registers[n] == '0' then R[n] = R[n] - 4*BitCount(registers); - if wback && registers[n] == '1' then R[n] = bits(32) UNKNOWN; - -__instruction aarch32_VMUL_f_A - __encoding aarch32_VMUL_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x0xxxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMUL_f_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 0x10xxxx xxxx10xx x0x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - advsimd = FALSE; - - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VMUL_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x0xxxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if sz == '1' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMUL_f_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 0x10xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if size == '01' && InITBlock() then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - advsimd = FALSE; - - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = FPMul(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize], StandardFPSCRValue()); - else // VFP instruction - case esize of - when 16 - S[d] = Zeros(16) : FPMul(S[n][15:0], S[m][15:0], FPSCR); - when 32 - S[d] = FPMul(S[n], S[m], FPSCR); - when 64 - D[d] = FPMul(D[n], D[m], FPSCR); - -__instruction aarch32_VMLA_f_A - __encoding aarch32_VMLA_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x0xxxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - advsimd = TRUE; add = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMLA_f_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 0x00xxxx xxxx10xx x0x0xxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - advsimd = FALSE; add = (op == '0'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VMLA_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x0xxxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - advsimd = TRUE; add = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMLA_f_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 0x00xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - advsimd = FALSE; add = (op == '0'); - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - product = FPMul(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize], StandardFPSCRValue()); - addend = if add then product else FPNeg(product); - Elem[D[d+r],e,esize] = FPAdd(Elem[D[d+r],e,esize], addend, StandardFPSCRValue()); - else // VFP instruction - case esize of - when 16 - addend16 = if add then FPMul(S[n][15:0], S[m][15:0], FPSCR) else FPNeg(FPMul(S[n][15:0], S[m][15:0], FPSCR)); - S[d] = Zeros(16) : FPAdd(S[d][15:0], addend16, FPSCR); - when 32 - addend32 = if add then FPMul(S[n], S[m], FPSCR) else FPNeg(FPMul(S[n], S[m], FPSCR)); - S[d] = FPAdd(S[d], addend32, FPSCR); - when 64 - addend64 = if add then FPMul(D[n], D[m], FPSCR) else FPNeg(FPMul(D[n], D[m], FPSCR)); - D[d] = FPAdd(D[d], addend64, FPSCR); - -__instruction aarch32_VMMLA_A - __encoding aarch32_VMMLA_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x00xxxx xxxx1100 x1x0xxxx' - __guard TRUE - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer regs = 2; - - __encoding aarch32_VMMLA_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x00xxxx xxxx1100 x1x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32BF16Ext() then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(M:Vm); - integer regs = 2; - - __execute - CheckAdvSIMDEnabled(); - - bits(128) op1 = Q[n>>1]; - bits(128) op2 = Q[m>>1]; - bits(128) acc = Q[d>>1]; - - Q[d>>1] = BFMatMulAdd(acc, op1, op2); - -__instruction aarch32_HVC_AS - __encoding aarch32_HVC_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field imm12 8 +: 12 - __field imm4 0 +: 4 - __opcode 'xxxx0001 0100xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __decode - if cond != '1110' then UNPREDICTABLE; - imm16 = imm12:imm4; - - __encoding aarch32_HVC_T1_A - __instruction_set T32 - __field imm4 16 +: 4 - __field imm12 0 +: 12 - __opcode '11110111 1110xxxx 1000xxxx xxxxxxxx' - __guard TRUE - __decode - imm16 = imm4:imm12; - if InITBlock() then UNPREDICTABLE; - - __execute - if !HaveEL(EL2) || PSTATE.EL == EL0 || (IsSecure() && !IsSecureEL2Enabled()) then - UNDEFINED; - - if HaveEL(EL3) then - if ELUsingAArch32(EL3) && SCR.HCE == '0' && PSTATE.EL == EL2 then - UNPREDICTABLE; - else - hvc_enable = SCR_GEN[].HCE; - else - hvc_enable = if ELUsingAArch32(EL2) then NOT(HCR.HCD) else NOT(HCR_EL2.HCD); - - if hvc_enable == '0' then - UNDEFINED; - else - AArch32.CallHypervisor(imm16); - -__instruction aarch32_UXTAB16_A - __encoding aarch32_UXTAB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1100xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if Rn == '1111' then SEE "UXTB16"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UXTAB16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 0011xxxx 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - if Rn == '1111' then SEE "UXTB16"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d][15:0] = R[n][15:0] + ZeroExtend(rotated[7:0], 16); - R[d][31:16] = R[n][31:16] + ZeroExtend(rotated[23:16], 16); - -__instruction aarch32_SHSUB16_A - __encoding aarch32_SHSUB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0011xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SHSUB16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1101xxxx 1111xxxx 0010xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = SInt(R[n][15:0]) - SInt(R[m][15:0]); - diff2 = SInt(R[n][31:16]) - SInt(R[m][31:16]); - R[d][15:0] = diff1[16:1]; - R[d][31:16] = diff2[16:1]; - -__instruction aarch32_ISB_A - __encoding aarch32_ISB_A1_A - __instruction_set A32 - __field option 0 +: 4 - __opcode '11110101 0111xxxx xxxxxxxx 0110xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - // No additional decoding required - - __encoding aarch32_ISB_T1_A - __instruction_set T32 - __field option 0 +: 4 - __opcode '11110011 1011xxxx 10x0xxxx 0110xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - // No additional decoding required - - __execute __conditional - InstructionSynchronizationBarrier(); - -__instruction aarch32_VLD3_m_A - __encoding aarch32_VLD3_m_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x10xxxx xxxx010x xxxxxxxx' - __guard TRUE - __decode - case itype of - when '0100' - inc = 1; - when '0101' - inc = 2; - otherwise - SEE "Related encodings"; - if size == '11' || align[1] == '1' then UNDEFINED; - alignment = if align[0] == '0' then 1 else 8; - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VLD3_m_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x10xxxx xxxx010x xxxxxxxx' - __guard TRUE - __decode - case itype of - when '0100' - inc = 1; - when '0101' - inc = 2; - otherwise - SEE "Related encodings"; - if size == '11' || align[1] == '1' then UNDEFINED; - alignment = if align[0] == '0' then 1 else 8; - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - for e = 0 to elements-1 - Elem[D[d], e] = MemU[address,ebytes]; - Elem[D[d2],e] = MemU[address+ebytes,ebytes]; - Elem[D[d3],e] = MemU[address+2*ebytes,ebytes]; - address = address + 3*ebytes; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 24; - -__instruction aarch32_TBB_A - __encoding aarch32_TBB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field H 4 +: 1 - __field Rm 0 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 000xxxxx' - __guard TRUE - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); is_tbh = (H == '1'); - if m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - if is_tbh then - halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); - else - halfwords = UInt(MemU[R[n]+R[m], 1]); - BranchWritePC(PC + 2*halfwords, BranchType_INDIR); - -__instruction aarch32_MRS_AS - __encoding aarch32_MRS_A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field R 22 +: 1 - __field Rd 12 +: 4 - __opcode 'xxxx0001 0x00xxxx xxxxxx0x 0000xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - d = UInt(Rd); read_spsr = (R == '1'); - if d == 15 then UNPREDICTABLE; - - __encoding aarch32_MRS_T1_AS - __instruction_set T32 - __field R 20 +: 1 - __field Rd 8 +: 4 - __opcode '11110011 111xxxxx 10x0xxxx xx0xxxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 4 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - d = UInt(Rd); read_spsr = (R == '1'); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - if read_spsr then - if PSTATE.M IN {M32_User,M32_System} then - UNPREDICTABLE; - else - R[d] = SPSR[]; - else - // CPSR has same bit assignments as SPSR, but with the IT, J, SS, IL, and T bits masked out. - bits(32) mask = '11111000 00001111 00000011 11011111'; - if HavePANExt() then - mask[22] = '1'; - - if HaveDITExt() then - mask[21] = '1'; - psr_val = GetPSRFromPSTATE() AND mask; - if PSTATE.EL == EL0 then - // If accessed from User mode return UNKNOWN values for E, A, I, F bits, bits[9:6], - // and for the M field, bits[4:0] - psr_val[22] = bits(1) UNKNOWN; - psr_val[9:6] = bits(4) UNKNOWN; - psr_val[4:0] = bits(5) UNKNOWN; - R[d] = psr_val; - -__instruction aarch32_MCRR_A - __encoding aarch32_MCRR_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field coproc 8 +: 4 - __field opc1 4 +: 4 - __field CRm 0 +: 4 - __opcode 'xxxx1100 0100xxxx xxxx111x xxxxxxxx' - __guard cond != '1111' - __decode - t = UInt(Rt); t2 = UInt(Rt2); cp = if coproc[0] == '0' then 14 else 15; - if t == 15 || t2 == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_MCRR_T1A1_A - __instruction_set T32 - __field Rt2 16 +: 4 - __field Rt 12 +: 4 - __field coproc 8 +: 4 - __field opc1 4 +: 4 - __field CRm 0 +: 4 - __opcode '11101100 0100xxxx xxxx111x xxxxxxxx' - __guard TRUE - __decode - t = UInt(Rt); t2 = UInt(Rt2); cp = if coproc[0] == '0' then 14 else 15; - if t == 15 || t2 == 15 then UNPREDICTABLE; - // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - value = R[t2]:R[t]; - AArch32.SysRegWrite64(cp, ThisInstr(), value); - -__instruction aarch32_STRB_i_A - __encoding aarch32_STRB_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx010x x1x0xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "STRBT"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if t == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_STRB_i_T1_A - __instruction_set T16 - __field imm5 22 +: 5 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '01110xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); - index = TRUE; add = TRUE; wback = FALSE; - - __encoding aarch32_STRB_i_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 1000xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = TRUE; add = TRUE; wback = FALSE; - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_STRB_i_T3_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field P 10 +: 1 - __field U 9 +: 1 - __field W 8 +: 1 - __field imm8 0 +: 8 - __opcode '11111000 0000xxxx xxxx1xxx xxxxxxxx' - __guard TRUE - __decode - if P == '1' && U == '1' && W == '0' then SEE "STRBT"; - if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if t == 15 || (wback && n == t) then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute - if CurrentInstrSet() == InstrSet_A32 then - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - MemU[address,1] = R[t][7:0]; - if wback then R[n] = offset_addr; - else - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - MemU[address,1] = R[t][7:0]; - if wback then R[n] = offset_addr; - -__instruction aarch32_DOT_A - __encoding aarch32_DOT_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x00xxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - boolean op1_unsigned = (U == '0'); - boolean op2_unsigned = (U == '1'); - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm); - integer i = UInt(M); - integer regs = if Q == '1' then 2 else 1; - - __encoding aarch32_DOT_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field U 4 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x00xxxx xxxx1101 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32Int8MatMulExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - boolean op1_unsigned = (U == '0'); - boolean op2_unsigned = (U == '1'); - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm); - integer i = UInt(M); - integer regs = if Q == '1' then 2 else 1; - - __execute - CheckAdvSIMDEnabled(); - bits(64) operand1; - bits(64) operand2; - bits(64) result; - - operand2 = Din[m]; - for r = 0 to regs-1 - operand1 = Din[n+r]; - result = Din[d+r]; - for e = 0 to 1 - bits(32) res = Elem[result, e, 32]; - for b = 0 to 3 - element1 = Int(Elem[operand1, 4 * e + b, 8], op1_unsigned); - element2 = Int(Elem[operand2, 4 * i + b, 8], op2_unsigned); - res = res + element1 * element2; - Elem[result, e, 32] = res; - D[d+r] = result; - -__instruction aarch32_MVN_rr_A - __encoding aarch32_MVN_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 111xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = NOT(shifted); - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_STM_u_AS - __encoding aarch32_STM_u_A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 16 - __opcode 'xxxx100x x1x0xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __unpredictable_unless 21 == '0' - __decode - n = UInt(Rn); registers = register_list; increment = (U == '1'); wordhigher = (P == U); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - - __execute __conditional - if PSTATE.EL == EL2 then - UNDEFINED; - elsif PSTATE.M IN {M32_User,M32_System} then - UNPREDICTABLE; - else - length = 4*BitCount(registers); - address = if increment then R[n] else R[n]-length; - if wordhigher then address = address+4; - for i = 0 to 14 - if registers[i] == '1' then // Store User mode register - MemA[address,4] = Rmode[i, M32_User]; - address = address + 4; - if registers[15] == '1' then - MemA[address,4] = PCStoreValue(); - -__instruction aarch32_USUB8_A - __encoding aarch32_USUB8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0101xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_USUB8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1100xxxx 1111xxxx 0100xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = UInt(R[n][7:0]) - UInt(R[m][7:0]); - diff2 = UInt(R[n][15:8]) - UInt(R[m][15:8]); - diff3 = UInt(R[n][23:16]) - UInt(R[m][23:16]); - diff4 = UInt(R[n][31:24]) - UInt(R[m][31:24]); - R[d][7:0] = diff1[7:0]; - R[d][15:8] = diff2[7:0]; - R[d][23:16] = diff3[7:0]; - R[d][31:24] = diff4[7:0]; - PSTATE.GE[0] = if diff1 >= 0 then '1' else '0'; - PSTATE.GE[1] = if diff2 >= 0 then '1' else '0'; - PSTATE.GE[2] = if diff3 >= 0 then '1' else '0'; - PSTATE.GE[3] = if diff4 >= 0 then '1' else '0'; - -__instruction aarch32_LDRSBT_A - __encoding aarch32_LDRSBT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm4H 8 +: 4 - __field imm4L 0 +: 4 - __opcode 'xxxx0000 x111xxxx xxxxxxxx 1101xxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); postindex = TRUE; add = (U == '1'); - register_form = FALSE; imm32 = ZeroExtend(imm4H:imm4L, 32); - if t == 15 || n == 15 || n == t then UNPREDICTABLE; - - __encoding aarch32_LDRSBT_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0000 x011xxxx xxxxxxxx 1101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); postindex = TRUE; add = (U == '1'); - register_form = TRUE; - if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE; - - __encoding aarch32_LDRSBT_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - __opcode '11111001 0001xxxx xxxx1110 xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - if Rn == '1111' then SEE "LDRSB (literal)"; - t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; - register_form = FALSE; imm32 = ZeroExtend(imm8, 32); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = if register_form then R[m] else imm32; - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if postindex then R[n] else offset_addr; - R[t] = SignExtend(MemU_unpriv[address,1], 32); - if postindex then R[n] = offset_addr; - -__instruction aarch32_VCVTB_bf16_A - __encoding aarch32_VCVTB_bf16_T1A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110011 xxxx1001 01x0xxxx' - __guard cond != '1111' - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - integer d = UInt(Vd:D); - integer m = UInt(Vm:M); - - __encoding aarch32_VCVTB_bf16_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110011 xxxx1001 01x0xxxx' - __guard TRUE - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - integer d = UInt(Vd:D); - integer m = UInt(Vm:M); - - __execute __conditional - CheckVFPEnabled(TRUE); - - S[d][15:0] = FPConvertBF(S[m], FPSCR); - -__instruction aarch32_VFMAL_A - __encoding aarch32_VFMAL_A1_A - __instruction_set A32 - __field S 23 +: 1 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 1x10xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - - integer d = UInt(D:Vd); - integer n = if Q == '1' then UInt(N:Vn) else UInt(Vn:N); - integer m = if Q == '1' then UInt(M:Vm) else UInt(Vm:M); - integer esize = 32; - integer regs = if Q=='1' then 2 else 1; - integer datasize = if Q=='1' then 64 else 32; - boolean sub_op = S=='1'; - - __encoding aarch32_VFMAL_T1_A - __instruction_set T32 - __field S 23 +: 1 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 1x10xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - - integer d = UInt(D:Vd); - integer n = if Q == '1' then UInt(N:Vn) else UInt(Vn:N); - integer m = if Q == '1' then UInt(M:Vm) else UInt(Vm:M); - integer esize = 32; - integer regs = if Q=='1' then 2 else 1; - integer datasize = if Q=='1' then 64 else 32; - boolean sub_op = S=='1'; - - __execute - CheckAdvSIMDEnabled(); - bits(datasize) operand1 ; - bits(datasize) operand2 ; - bits(64) operand3; - bits(64) result; - bits(esize DIV 2) element1; - bits(esize DIV 2) element2; - - if Q=='0' then - operand1 = S[n][datasize-1:0]; - operand2 = S[m][datasize-1:0]; - else - operand1 = D[n][datasize-1:0]; - operand2 = D[m][datasize-1:0]; - for r = 0 to regs-1 - operand3 = D[d+r]; - for e = 0 to 1 - element1 = Elem[operand1, 2*r+e, esize DIV 2]; - element2 = Elem[operand2, 2*r+e, esize DIV 2]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAddH(Elem[operand3, e, esize], element1, element2, StandardFPSCRValue()); - D[d+r] = result; - -__instruction aarch32_EOR_rr_A - __encoding aarch32_EOR_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 001xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = R[n] EOR shifted; - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_ADD_SP_i_A - __encoding aarch32_ADD_SP_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 100x1101 xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); setflags = (S == '1'); imm32 = A32ExpandImm(imm12); - - __encoding aarch32_ADD_SP_i_T1_A - __instruction_set T16 - __field Rd 24 +: 3 - __field imm8 16 +: 8 - __opcode '10101xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); - - __encoding aarch32_ADD_SP_i_T2_A - __instruction_set T16 - __field imm7 16 +: 7 - __opcode '10110000 0xxxxxxx 00000000 00000000' - __guard TRUE - __decode - d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); - - __encoding aarch32_ADD_SP_i_T3_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x01 000x1101 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rd == '1111' && S == '1' then SEE "CMN (immediate)"; - d = UInt(Rd); setflags = (S == '1'); imm32 = T32ExpandImm(i:imm3:imm8); - if d == 15 && !setflags then UNPREDICTABLE; - - __encoding aarch32_ADD_SP_i_T4_A - __instruction_set T32 - __field i 26 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x10 00001101 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); - if d == 15 then UNPREDICTABLE; - - __execute __conditional - (result, nzcv) = AddWithCarry(SP, imm32, '0'); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_SSUB8_A - __encoding aarch32_SSUB8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0001xxxx xxxxxxxx 1111xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SSUB8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1100xxxx 1111xxxx 0000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - diff1 = SInt(R[n][7:0]) - SInt(R[m][7:0]); - diff2 = SInt(R[n][15:8]) - SInt(R[m][15:8]); - diff3 = SInt(R[n][23:16]) - SInt(R[m][23:16]); - diff4 = SInt(R[n][31:24]) - SInt(R[m][31:24]); - R[d][7:0] = diff1[7:0]; - R[d][15:8] = diff2[7:0]; - R[d][23:16] = diff3[7:0]; - R[d][31:24] = diff4[7:0]; - PSTATE.GE[0] = if diff1 >= 0 then '1' else '0'; - PSTATE.GE[1] = if diff2 >= 0 then '1' else '0'; - PSTATE.GE[2] = if diff3 >= 0 then '1' else '0'; - PSTATE.GE[3] = if diff4 >= 0 then '1' else '0'; - -__instruction aarch32_LDM_u_AS - __encoding aarch32_LDM_u_A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field register_list 0 +: 15 - __opcode 'xxxx100x x1x1xxxx 0xxxxxxx xxxxxxxx' - __guard cond != '1111' - __unpredictable_unless 21 == '0' - __decode - n = UInt(Rn); registers = register_list; increment = (U == '1'); wordhigher = (P == U); - if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; - - __execute __conditional - if PSTATE.EL == EL2 then UNDEFINED; - elsif PSTATE.M IN {M32_User,M32_System} then UNPREDICTABLE; - else - length = 4*BitCount(registers); - address = if increment then R[n] else R[n]-length; - if wordhigher then address = address+4; - for i = 0 to 14 - if registers[i] == '1' then // Load User mode register - Rmode[i, M32_User] = MemA[address,4]; address = address + 4; - -__instruction aarch32_MSR_i_AS - __encoding aarch32_MSR_i_A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field R 22 +: 1 - __field mask 16 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0011 0x10xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __decode - if mask == '0000' && R == '0' then SEE "Related encodings"; - imm32 = A32ExpandImm(imm12); write_spsr = (R == '1'); - if mask == '0000' then UNPREDICTABLE; - - __execute __conditional - if write_spsr then - if PSTATE.M IN {M32_User,M32_System} then - UNPREDICTABLE; - else - SPSRWriteByInstr(imm32, mask); - else - // Attempts to change to an illegal mode will invoke the Illegal Execution state mechanism - CPSRWriteByInstr(imm32, mask); - -__instruction aarch32_USAT16_A - __encoding aarch32_USAT16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field sat_imm 16 +: 4 - __field Rd 12 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0110 1110xxxx xxxxxxxx 0011xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm); - if d == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_USAT16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field sat_imm 0 +: 4 - __opcode '11110x11 1010xxxx 0000xxxx 00xxxxxx' - __guard TRUE - __unpredictable_unless 26 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 4 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm); - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (result1, sat1) = UnsignedSatQ(SInt(R[n][15:0]), saturate_to); - (result2, sat2) = UnsignedSatQ(SInt(R[n][31:16]), saturate_to); - R[d][15:0] = ZeroExtend(result1, 16); - R[d][31:16] = ZeroExtend(result2, 16); - if sat1 || sat2 then - PSTATE.Q = '1'; - -__instruction aarch32_VLD2_m_A - __encoding aarch32_VLD2_m_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x10xxxx xxxx100x xxxxxxxx' - __guard TRUE - __decode - regs = 1; if align == '11' then UNDEFINED; - if size == '11' then UNDEFINED; - inc = if itype == '1001' then 2 else 1; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD2_m_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11110100 0x10xxxx xxxx0011 xxxxxxxx' - __guard TRUE - __decode - regs = 2; inc = 2; - if size == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD2_m_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field itype 8 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x10xxxx xxxx100x xxxxxxxx' - __guard TRUE - __decode - regs = 1; if align == '11' then UNDEFINED; - if size == '11' then UNDEFINED; - inc = if itype == '1001' then 2 else 1; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2+regs > 32 then UNPREDICTABLE; - - __encoding aarch32_VLD2_m_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 6 +: 2 - __field align 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111001 0x10xxxx xxxx0011 xxxxxxxx' - __guard TRUE - __decode - regs = 2; inc = 2; - if size == '11' then UNDEFINED; - alignment = if align == '00' then 1 else 4 << UInt(align); - ebytes = 1 << UInt(size); elements = 8 DIV ebytes; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2+regs > 32 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = FALSE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r], e] = MemU[address,ebytes]; - Elem[D[d2+r],e] = MemU[address+ebytes,ebytes]; - address = address + 2*ebytes; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 16*regs; - -__instruction aarch32_VCEQ_i_A - __encoding aarch32_VCEQ_i_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx01 xxxx0x01 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCEQ_i_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx01 xxxx0x01 0xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - if floating_point then - bits(esize) zero = FPZero('0'); - test_passed = FPCompareEQ(Elem[D[m+r],e,esize], zero, StandardFPSCRValue()); - else - test_passed = (Elem[D[m+r],e,esize] == Zeros(esize)); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_USADA8_A - __encoding aarch32_USADA8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0111 1000xxxx xxxxxxxx 0001xxxx' - __guard cond != '1111' - __decode - if Ra == '1111' then SEE "USAD8"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_USADA8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 0111xxxx xxxxxxxx 0000xxxx' - __guard TRUE - __decode - if Ra == '1111' then SEE "USAD8"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - absdiff1 = Abs(UInt(R[n][7:0]) - UInt(R[m][7:0])); - absdiff2 = Abs(UInt(R[n][15:8]) - UInt(R[m][15:8])); - absdiff3 = Abs(UInt(R[n][23:16]) - UInt(R[m][23:16])); - absdiff4 = Abs(UInt(R[n][31:24]) - UInt(R[m][31:24])); - result = UInt(R[a]) + absdiff1 + absdiff2 + absdiff3 + absdiff4; - R[d] = result[31:0]; - -__instruction aarch32_VMLA_i_A - __encoding aarch32_VMLA_i_T1A1_A - __instruction_set A32 - __field op 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0xxxxxxx xxxx1001 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - add = (op == '0'); long_destination = FALSE; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMLA_i_T1A1_A - __instruction_set T32 - __field op 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0xxxxxxx xxxx1001 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - add = (op == '0'); long_destination = FALSE; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - product = Int(Elem[Din[n+r],e,esize],unsigned) * Int(Elem[Din[m+r],e,esize],unsigned); - addend = if add then product else -product; - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend; - -__instruction aarch32_SMLAWB_A - __encoding aarch32_SMLAWB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field M 6 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0001 0010xxxx xxxxxxxx 1x00xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_high = (M == '1'); - if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE; - - __encoding aarch32_SMLAWB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field M 4 +: 1 - __field Rm 0 +: 4 - __opcode '11111011 0011xxxx xxxxxxxx 000xxxxx' - __guard TRUE - __decode - if Ra == '1111' then SEE "SMULWB, SMULWT"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_high = (M == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand2 = if m_high then R[m][31:16] else R[m][15:0]; - result = SInt(R[n]) * SInt(operand2) + (SInt(R[a]) << 16); - R[d] = result[47:16]; - if (result >> 16) != SInt(R[d]) then // Signed overflow - PSTATE.Q = '1'; - -__instruction aarch32_VSQRT_A - __encoding aarch32_VSQRT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 1x110001 xxxx10xx 11x0xxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VSQRT_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 1x110001 xxxx10xx 11x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - case esize of - when 16 S[d] = Zeros(16) : FPSqrt(S[m][15:0], FPSCR); - when 32 S[d] = FPSqrt(S[m], FPSCR); - when 64 D[d] = FPSqrt(D[m], FPSCR); - -__instruction aarch32_STR_i_A - __encoding aarch32_STR_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx010x x0x0xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "STRT"; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_STR_i_T1_A - __instruction_set T16 - __field imm5 22 +: 5 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '01100xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); - index = TRUE; add = TRUE; wback = FALSE; - - __encoding aarch32_STR_i_T2_A - __instruction_set T16 - __field Rt 24 +: 3 - __field imm8 16 +: 8 - __opcode '10010xxx xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); - index = TRUE; add = TRUE; wback = FALSE; - - __encoding aarch32_STR_i_T3_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode '11111000 1100xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rn == '1111' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - index = TRUE; add = TRUE; wback = FALSE; - if t == 15 then UNPREDICTABLE; - - __encoding aarch32_STR_i_T4_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field P 10 +: 1 - __field U 9 +: 1 - __field W 8 +: 1 - __field imm8 0 +: 8 - __opcode '11111000 0100xxxx xxxx1xxx xxxxxxxx' - __guard TRUE - __decode - if P == '1' && U == '1' && W == '0' then SEE "STRT"; - if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); - index = (P == '1'); add = (U == '1'); wback = (W == '1'); - if t == 15 || (wback && n == t) then UNPREDICTABLE; - - __execute - if CurrentInstrSet() == InstrSet_A32 then - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; - if wback then R[n] = offset_addr; - else - offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); - address = if index then offset_addr else R[n]; - MemU[address,4] = R[t]; - if wback then R[n] = offset_addr; - -__instruction aarch32_LDRB_r_A - __encoding aarch32_LDRB_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx011x x1x1xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if P == '0' && W == '1' then SEE "LDRBT"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if t == 15 || m == 15 then UNPREDICTABLE; - if wback && (n == 15 || n == t) then UNPREDICTABLE; - - __encoding aarch32_LDRB_r_T1_A - __instruction_set T16 - __field Rm 22 +: 3 - __field Rn 19 +: 3 - __field Rt 16 +: 3 - __opcode '0101110x xxxxxxxx 00000000 00000000' - __guard TRUE - __decode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_LDRB_r_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm2 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111000 0001xxxx xxxx0000 00xxxxxx' - __guard TRUE - __decode - if Rt == '1111' then SEE "PLD"; - if Rn == '1111' then SEE "LDRB (literal)"; - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); - index = TRUE; add = TRUE; wback = FALSE; - (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); - if m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = Shift(R[m], shift_t, shift_n, PSTATE.C); - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if index then offset_addr else R[n]; - R[t] = ZeroExtend(MemU[address,1],32); - if wback then R[n] = offset_addr; - -__instruction aarch32_MRS_br_AS - __encoding aarch32_MRS_br_A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field R 22 +: 1 - __field M1 16 +: 4 - __field Rd 12 +: 4 - __field M 8 +: 1 - __opcode 'xxxx0001 0x00xxxx xxxxxx1x 0000xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - d = UInt(Rd); read_spsr = (R == '1'); - if d == 15 then UNPREDICTABLE; - SYSm = M:M1; - - __encoding aarch32_MRS_br_T1_AS - __instruction_set T32 - __field R 20 +: 1 - __field M1 16 +: 4 - __field Rd 8 +: 4 - __field M 4 +: 1 - __opcode '11110011 111xxxxx 10x0xxxx xx1xxxxx' - __guard TRUE - __unpredictable_unless 13 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - d = UInt(Rd); read_spsr = (R == '1'); - if d == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - SYSm = M:M1; - - __execute __conditional - if PSTATE.EL == EL0 then - UNPREDICTABLE; - else - mode = PSTATE.M; - if read_spsr then - SPSRaccessValid(SYSm, mode); // Check for UNPREDICTABLE cases - case SYSm of - when '01110' R[d] = SPSR_fiq; - when '10000' R[d] = SPSR_irq; - when '10010' R[d] = SPSR_svc; - when '10100' R[d] = SPSR_abt; - when '10110' R[d] = SPSR_und; - when '11100' - if !ELUsingAArch32(EL3) then AArch64.MonitorModeTrap(); - R[d] = SPSR_mon; - when '11110' R[d] = SPSR_hyp; - else - BankedRegisterAccessValid(SYSm, mode); // Check for UNPREDICTABLE cases - case SYSm of - when '00xxx' // Access the User mode registers - m = UInt(SYSm[2:0]) + 8; - R[d] = Rmode[m,M32_User]; - when '01xxx' // Access the FIQ mode registers - m = UInt(SYSm[2:0]) + 8; - R[d] = Rmode[m,M32_FIQ]; - when '1000x' // Access the IRQ mode registers - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - R[d] = Rmode[m,M32_IRQ]; - when '1001x' // Access the Supervisor mode registers - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - R[d] = Rmode[m,M32_Svc]; - when '1010x' // Access the Abort mode registers - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - R[d] = Rmode[m,M32_Abort]; - when '1011x' // Access the Undefined mode registers - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - R[d] = Rmode[m,M32_Undef]; - when '1110x' // Access Monitor registers - if !ELUsingAArch32(EL3) then AArch64.MonitorModeTrap(); - m = 14 - UInt(SYSm[0]); // LR when SYSm[0] == 0, otherwise SP - R[d] = Rmode[m,M32_Monitor]; - when '11110' // Access ELR_hyp register - R[d] = ELR_hyp; - when '11111' // Access SP_hyp register - R[d] = Rmode[13,M32_Hyp]; - -__instruction aarch32_VMUL_i_A - __encoding aarch32_VMUL_i_T1A1_A - __instruction_set A32 - __field op 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx1001 xxx1xxxx' - __guard TRUE - __decode - if size == '11' || (op == '1' && size != '00') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - polynomial = (op == '1'); long_destination = FALSE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMUL_i_T1A1_A - __instruction_set T32 - __field op 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx1001 xxx1xxxx' - __guard TRUE - __decode - if size == '11' || (op == '1' && size != '00') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - polynomial = (op == '1'); long_destination = FALSE; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; op1val = Int(op1, unsigned); - op2 = Elem[Din[m+r],e,esize]; op2val = Int(op2, unsigned); - if polynomial then - product = PolynomialMult(op1,op2); - else - product = (op1val*op2val)[2*esize-1:0]; - if long_destination then - Elem[Q[d>>1],e,2*esize] = product; - else - Elem[D[d+r],e,esize] = product[esize-1:0]; - -__instruction aarch32_VBIC_r_A - __encoding aarch32_VBIC_r_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x01xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VBIC_r_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x01xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - D[d+r] = D[n+r] AND NOT(D[m+r]); - -__instruction aarch32_SHA256SU0_A - __encoding aarch32_SHA256SU0_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0011 11x0xxxx' - __guard TRUE - __decode - if !HaveSHA256Ext() then UNDEFINED; - if size != '10' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_SHA256SU0_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0011 11x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA256Ext() then UNDEFINED; - if size != '10' then UNDEFINED; - if Vd[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - bits(128) result; - X = Q[d>>1]; Y = Q[m>>1]; - T = Y[31:0] : X[127:32]; - for e = 0 to 3 - elt = Elem[T, e, 32]; - elt = ROR(elt, 7) EOR ROR(elt, 18) EOR LSR(elt, 3); - Elem[result, e, 32] = elt + Elem[X, e, 32]; - Q[d>>1] = result; - -__instruction aarch32_VMSR_AS - __encoding aarch32_VMSR_T1A1_AS - __instruction_set A32 - __field cond 28 +: 4 - __field reg 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx1110 1110xxxx xxxx1010 xxx1xxxx' - __guard cond != '1111' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - t = UInt(Rt); - if reg != '000x' && reg != '1000' then UNPREDICTABLE; - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __encoding aarch32_VMSR_T1A1_AS - __instruction_set T32 - __field reg 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101110 1110xxxx xxxx1010 xxx1xxxx' - __guard TRUE - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - t = UInt(Rt); - if reg != '000x' && reg != '1000' then UNPREDICTABLE; - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - if reg == '0001' then // FPSCR - CheckVFPEnabled(TRUE); - FPSCR = R[t]; - elsif PSTATE.EL == EL0 then - UNDEFINED; // Non-FPSCR registers accessible only at PL1 or above - else - CheckVFPEnabled(FALSE); // Non-FPSCR registers are not affected by FPEXC.EN - case reg of - when '0000' // VMSR access to FPSID is ignored - when '1000' FPEXC = R[t]; - otherwise Unreachable(); // Dealt with above or in encoding-specific pseudocode - -__instruction aarch32_VPMAX_f_A - __encoding aarch32_VPMAX_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x1xxxxx xxxx1111 x0x0xxxx' - __guard TRUE - __decode - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - maximum = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VPMAX_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x1xxxxx xxxx1111 x0x0xxxx' - __guard TRUE - __decode - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - maximum = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - bits(64) dest; - h = elements DIV 2; - - for e = 0 to h-1 - op1 = Elem[D[n],2*e,esize]; op2 = Elem[D[n],2*e+1,esize]; - Elem[dest,e,esize] = if maximum then FPMax(op1,op2,StandardFPSCRValue()) else FPMin(op1,op2,StandardFPSCRValue()); - op1 = Elem[D[m],2*e,esize]; op2 = Elem[D[m],2*e+1,esize]; - Elem[dest,e+h,esize] = if maximum then FPMax(op1,op2,StandardFPSCRValue()) else FPMin(op1,op2,StandardFPSCRValue()); - - D[d] = dest; - -__instruction aarch32_CSDB_A - __encoding aarch32_CSDB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __opcode 'xxxx0011 00100000 xxxxxxxx 00010100' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if cond != '1110' then UNPREDICTABLE; // CSDB must be encoded with AL condition - - __encoding aarch32_CSDB_T1_A - __instruction_set T32 - __opcode '11110011 1010xxxx 10x0x000 00010100' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '0' - __decode - if InITBlock() then UNPREDICTABLE; - - __execute __conditional - - ConsumptionOfSpeculativeDataBarrier(); - -__instruction aarch32_MUL_A - __encoding aarch32_MUL_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 16 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0000 000xxxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_MUL_T1_A - __instruction_set T16 - __field Rn 19 +: 3 - __field Rdm 16 +: 3 - __opcode '01000011 01xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); - - __encoding aarch32_MUL_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 0000xxxx 1111xxxx 0000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results - operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results - result = operand1 * operand2; - R[d] = result[31:0]; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result[31:0]); - // PSTATE.C, PSTATE.V unchanged - -__instruction aarch32_VPADD_i_A - __encoding aarch32_VPADD_i_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0xxxxxxx xxxx1011 xxx1xxxx' - __guard TRUE - __decode - if size == '11' || Q == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VPADD_i_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0xxxxxxx xxxx1011 xxx1xxxx' - __guard TRUE - __decode - if size == '11' || Q == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - bits(64) dest; - h = elements DIV 2; - - for e = 0 to h-1 - Elem[dest,e,esize] = Elem[D[n],2*e,esize] + Elem[D[n],2*e+1,esize]; - Elem[dest,e+h,esize] = Elem[D[m],2*e,esize] + Elem[D[m],2*e+1,esize]; - - D[d] = dest; - -__instruction aarch32_VQDMLSL_A - __encoding aarch32_VQDMLSL_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx1011 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - add = (op == '0'); - scalar_form = FALSE; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 8 << UInt(size); elements = 64 DIV esize; - - __encoding aarch32_VQDMLSL_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx0111 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - add = (op == '0'); - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VQDMLSL_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx1011 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - add = (op == '0'); - scalar_form = FALSE; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 8 << UInt(size); elements = 64 DIV esize; - - __encoding aarch32_VQDMLSL_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx0111 x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || Vd[0] == '1' then UNDEFINED; - add = (op == '0'); - scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - if scalar_form then op2 = SInt(Elem[Din[m],index,esize]); - for e = 0 to elements-1 - if !scalar_form then op2 = SInt(Elem[Din[m],e,esize]); - op1 = SInt(Elem[Din[n],e,esize]); - // The following only saturates if both op1 and op2 equal -(2^(esize-1)) - (product, sat1) = SignedSatQ(2*op1*op2, 2*esize); - if add then - result = SInt(Elem[Qin[d>>1],e,2*esize]) + SInt(product); - else - result = SInt(Elem[Qin[d>>1],e,2*esize]) - SInt(product); - (Elem[Q[d>>1],e,2*esize], sat2) = SignedSatQ(result, 2*esize); - if sat1 || sat2 then FPSCR.QC = '1'; - -__instruction aarch32_STRT_A - __encoding aarch32_STRT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0100 x010xxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); postindex = TRUE; add = (U == '1'); - register_form = FALSE; imm32 = ZeroExtend(imm12, 32); - if n == 15 || n == t then UNPREDICTABLE; - - __encoding aarch32_STRT_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 x010xxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); postindex = TRUE; add = (U == '1'); - register_form = TRUE; (shift_t, shift_n) = DecodeImmShift(stype, imm5); - if n == 15 || n == t || m == 15 then UNPREDICTABLE; - - __encoding aarch32_STRT_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field imm8 0 +: 8 - __opcode '11111000 0100xxxx xxxx1110 xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL2 then UNPREDICTABLE; // Hyp mode - if Rn == '1111' then UNDEFINED; - t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; - register_form = FALSE; imm32 = ZeroExtend(imm8, 32); - if t == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - offset = if register_form then Shift(R[m], shift_t, shift_n, PSTATE.C) else imm32; - offset_addr = if add then (R[n] + offset) else (R[n] - offset); - address = if postindex then R[n] else offset_addr; - if t == 15 then // Only possible for encodings A1 and A2 - data = PCStoreValue(); - else - data = R[t]; - MemU_unpriv[address,4] = data; - if postindex then R[n] = offset_addr; - -__instruction aarch32_VSHRN_A - __encoding aarch32_VSHRN_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx1000 00x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if Vm[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '01xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '1xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VSHRN_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field imm6 16 +: 6 - __field Vd 12 +: 4 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx1000 00x1xxxx' - __guard TRUE - __decode - if imm6 == '000xxx' then SEE "Related encodings"; - if Vm[0] == '1' then UNDEFINED; - case imm6 of - when '001xxx' esize = 8; elements = 8; shift_amount = 16 - UInt(imm6); - when '01xxxx' esize = 16; elements = 4; shift_amount = 32 - UInt(imm6); - when '1xxxxx' esize = 32; elements = 2; shift_amount = 64 - UInt(imm6); - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - result = LSR(Elem[Qin[m>>1],e,2*esize], shift_amount); - Elem[D[d],e,esize] = result[esize-1:0]; - -__instruction aarch32_STLEX_A - __encoding aarch32_STLEX_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1000xxxx xxxxxx10 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t then UNPREDICTABLE; - - __encoding aarch32_STLEX_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __field Rd 0 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 1110xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); - if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; - if d == n || d == t then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - if AArch32.ExclusiveMonitorsPass(address,4) then - MemO[address, 4] = R[t]; - R[d] = ZeroExtend('0'); - else - R[d] = ZeroExtend('1'); - -__instruction aarch32_UXTH_A - __encoding aarch32_UXTH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 11111111 xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UXTH_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - __opcode '10110010 10xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); rotation = 0; - - __encoding aarch32_UXTH_T2_A - __instruction_set T32 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 00011111 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d] = ZeroExtend(rotated[15:0], 32); - -__instruction aarch32_MVN_r_A - __encoding aarch32_MVN_r_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 111xxxxx xxxxxxxx xxx0xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '0' - __unpredictable_unless 18 == '0' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm5); - - __encoding aarch32_MVN_r_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - __opcode '01000011 11xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); setflags = !InITBlock(); - (shift_t, shift_n) = (SRType_LSL, 0); - - __encoding aarch32_MVN_r_T2_A - __instruction_set T32 - __field S 20 +: 1 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field stype 4 +: 2 - __field Rm 0 +: 4 - __opcode '11101010 011x1111 xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); - (shift_t, shift_n) = DecodeImmShift(stype, imm3:imm2); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, PSTATE.C); - result = NOT(shifted); - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_BL_i_A - __encoding aarch32_BL_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field imm24 0 +: 24 - __opcode 'xxxx1011 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - imm32 = SignExtend(imm24:'00', 32); targetInstrSet = InstrSet_A32; - - __encoding aarch32_BL_i_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field H 24 +: 1 - __field imm24 0 +: 24 - __opcode '1111101x xxxxxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - imm32 = SignExtend(imm24:H:'0', 32); targetInstrSet = InstrSet_T32; - - __encoding aarch32_BL_i_T1_A - __instruction_set T32 - __field S 26 +: 1 - __field imm10 16 +: 10 - __field J1 13 +: 1 - __field J2 11 +: 1 - __field imm11 0 +: 11 - __opcode '11110xxx xxxxxxxx 11x1xxxx xxxxxxxx' - __guard TRUE - __decode - I1 = NOT(J1 EOR S); I2 = NOT(J2 EOR S); imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); - targetInstrSet = InstrSet_T32; - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __encoding aarch32_BL_i_T2_A - __instruction_set T32 - __field S 26 +: 1 - __field imm10H 16 +: 10 - __field J1 13 +: 1 - __field J2 11 +: 1 - __field imm10L 1 +: 10 - __field H 0 +: 1 - __opcode '11110xxx xxxxxxxx 11x0xxxx xxxxxxxx' - __guard TRUE - __decode - if H == '1' then UNDEFINED; - I1 = NOT(J1 EOR S); I2 = NOT(J2 EOR S); imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32); - targetInstrSet = InstrSet_A32; - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - if CurrentInstrSet() == InstrSet_A32 then - LR = PC - 4; - else - LR = PC[31:1] : '1'; - if targetInstrSet == InstrSet_A32 then - targetAddress = Align(PC,4) + imm32; - else - targetAddress = PC + imm32; - SelectInstrSet(targetInstrSet); - BranchWritePC(targetAddress, BranchType_DIRCALL); - -__instruction aarch32_VSUBL_A - __encoding aarch32_VSUBL_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx0011 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' || (op == '1' && Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; is_vsubw = (op == '1'); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VSUBL_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx0011 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' || (op == '1' && Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; is_vsubw = (op == '1'); - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - if is_vsubw then - op1 = Int(Elem[Qin[n>>1],e,2*esize], unsigned); - else - op1 = Int(Elem[Din[n],e,esize], unsigned); - result = op1 - Int(Elem[Din[m],e,esize], unsigned); - Elem[Q[d>>1],e,2*esize] = result[2*esize-1:0]; - -__instruction aarch32_VCVTA_vfp_A - __encoding aarch32_VCVTA_vfp_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111111 xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '0'); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - - __encoding aarch32_VCVTA_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field op 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111111 xxxx10xx x1x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '0'); - d = UInt(Vd:D); - case size of - when '01' esize = 16; m = UInt(Vm:M); - when '10' esize = 32; m = UInt(Vm:M); - when '11' esize = 64; m = UInt(M:Vm); - - __execute - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = FPToFixed(S[m][15:0], 0, unsigned, FPSCR, rounding); - when 32 - S[d] = FPToFixed(S[m], 0, unsigned, FPSCR, rounding); - when 64 - S[d] = FPToFixed(D[m], 0, unsigned, FPSCR, rounding); - -__instruction aarch32_VRINTA_asimd_A - __encoding aarch32_VRINTA_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0101 0xx0xxxx' - __guard TRUE - __decode - if op[2] != op[0] then SEE "Related encodings"; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - // Rounding encoded differently from other VCVT and VRINT instructions - rounding = FPDecodeRM(op[2]:NOT(op[1])); exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VRINTA_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field op 7 +: 3 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0101 0xx0xxxx' - __guard TRUE - __decode - if op[2] != op[0] then SEE "Related encodings"; - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - // Rounding encoded differently from other VCVT and VRINT instructions - rounding = FPDecodeRM(op[2]:NOT(op[1])); exact = FALSE; - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[m+r],e,esize]; - result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact); - Elem[D[d+r],e,esize] = result; - -__instruction aarch32_VNMLA_A - __encoding aarch32_VNMLA_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 0x01xxxx xxxx10xx x0x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - vtype = if op == '1' then VFPNegMul_VNMLA else VFPNegMul_VNMLS; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VNMLA_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field op 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 0x01xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - vtype = if op == '1' then VFPNegMul_VNMLA else VFPNegMul_VNMLS; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckVFPEnabled(TRUE); - case esize of - when 16 - product16 = FPMul(S[n][15:0], S[m][15:0], FPSCR); - case vtype of - when VFPNegMul_VNMLA S[d] = Zeros(16) : FPAdd(FPNeg(S[d][15:0]), FPNeg(product16), FPSCR); - when VFPNegMul_VNMLS S[d] = Zeros(16) : FPAdd(FPNeg(S[d][15:0]), product16, FPSCR); - when VFPNegMul_VNMUL S[d] = Zeros(16) : FPNeg(product16); - when 32 - product32 = FPMul(S[n], S[m], FPSCR); - case vtype of - when VFPNegMul_VNMLA S[d] = FPAdd(FPNeg(S[d]), FPNeg(product32), FPSCR); - when VFPNegMul_VNMLS S[d] = FPAdd(FPNeg(S[d]), product32, FPSCR); - when VFPNegMul_VNMUL S[d] = FPNeg(product32); - when 64 - product64 = FPMul(D[n], D[m], FPSCR); - case vtype of - when VFPNegMul_VNMLA D[d] = FPAdd(FPNeg(D[d]), FPNeg(product64), FPSCR); - when VFPNegMul_VNMLS D[d] = FPAdd(FPNeg(D[d]), product64, FPSCR); - when VFPNegMul_VNMUL D[d] = FPNeg(product64); - -__instruction aarch32_REV16_A - __encoding aarch32_REV16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1011xxxx xxxxxxxx 1011xxxx' - __guard cond != '1111' - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); m = UInt(Rm); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_REV16_T1_A - __instruction_set T16 - __field Rm 19 +: 3 - __field Rd 16 +: 3 - __opcode '10111010 01xxxxxx 00000000 00000000' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); - - __encoding aarch32_REV16_T2_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1001xxxx 1111xxxx 1001xxxx' - __guard TRUE - __decode - d = UInt(Rd); m = UInt(Rm); n = UInt(Rn); - if m != n || d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - bits(32) result; - result[31:24] = R[m][23:16]; - result[23:16] = R[m][31:24]; - result[15:8] = R[m][7:0]; - result[7:0] = R[m][15:8]; - R[d] = result; - -__instruction aarch32_SXTAB16_A - __encoding aarch32_SXTAB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1000xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if Rn == '1111' then SEE "SXTB16"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SXTAB16_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 0010xxxx 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - if Rn == '1111' then SEE "SXTB16"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d][15:0] = R[n][15:0] + SignExtend(rotated[7:0], 16); - R[d][31:16] = R[n][31:16] + SignExtend(rotated[23:16], 16); - -__instruction aarch32_VST2_1_A - __encoding aarch32_VST2_1_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx0001 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - alignment = if index_align[0] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST2_1_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx0101 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 4; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST2_1_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx1001 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[1] != '0' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 8; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST2_1_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx0001 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - alignment = if index_align[0] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST2_1_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx0101 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 4; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST2_1_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx1001 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[1] != '0' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - alignment = if index_align[0] == '0' then 1 else 8; - d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d2 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; iswrite = TRUE; - - = AArch32.CheckAlignment(address, alignment, AccType_VEC, iswrite); - MemU[address, ebytes] = Elem[D[d], index]; - MemU[address+ebytes,ebytes] = Elem[D[d2],index]; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 2*ebytes; - -__instruction aarch32_VRINTA_vfp_A - __encoding aarch32_VRINTA_vfp_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111011 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VRINTA_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111011 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = Zeros(16) : FPRoundInt(S[m][15:0], FPSCR, rounding, exact); - when 32 - S[d] = FPRoundInt(S[m], FPSCR, rounding, exact); - when 64 - D[d] = FPRoundInt(D[m], FPSCR, rounding, exact); - -__instruction aarch32_SRS_AS - __encoding aarch32_SRS_A1_AS - __instruction_set A32 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field mode 0 +: 5 - __opcode '1111100x x1x0xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '1' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __decode - wback = (W == '1'); increment = (U == '1'); wordhigher = (P == U); - - __encoding aarch32_SRS_T1_AS - __instruction_set T32 - __field W 21 +: 1 - __field mode 0 +: 5 - __opcode '11101000 00x0xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __decode - wback = (W == '1'); increment = FALSE; wordhigher = FALSE; - - __encoding aarch32_SRS_T2_AS - __instruction_set T32 - __field W 21 +: 1 - __field mode 0 +: 5 - __opcode '11101001 10x0xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '0' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __decode - wback = (W == '1'); increment = TRUE; wordhigher = FALSE; - - __execute - if CurrentInstrSet() == InstrSet_A32 then - if PSTATE.EL == EL2 then // UNDEFINED at EL2 - UNDEFINED; - - // Check for UNPREDICTABLE cases. The definition of UNPREDICTABLE does not permit these - // to be security holes - if PSTATE.M IN {M32_User,M32_System} then - UNPREDICTABLE; - elsif mode == M32_Hyp then // Check for attempt to access Hyp mode SP - UNPREDICTABLE; - elsif mode == M32_Monitor then // Check for attempt to access Monitor mode SP - if !HaveEL(EL3) || !IsSecure() then - UNPREDICTABLE; - elsif !ELUsingAArch32(EL3) then - AArch64.MonitorModeTrap(); - elsif BadMode(mode) then - UNPREDICTABLE; - - base = Rmode[13,mode]; - address = if increment then base else base-8; - if wordhigher then address = address+4; - MemA[address,4] = LR; - MemA[address+4,4] = SPSR[]; - if wback then Rmode[13,mode] = if increment then base+8 else base-8; - else - if PSTATE.EL == EL2 then // UNDEFINED at EL2 - UNDEFINED; - - // Check for UNPREDICTABLE cases. The definition of UNPREDICTABLE does not permit these - // to be security holes - if PSTATE.M IN {M32_User,M32_System} then - UNPREDICTABLE; - elsif mode == M32_Hyp then // Check for attempt to access Hyp mode SP - UNPREDICTABLE; - elsif mode == M32_Monitor then // Check for attempt to access Monitor mode SP - if !HaveEL(EL3) || !IsSecure() then - UNPREDICTABLE; - elsif !ELUsingAArch32(EL3) then - AArch64.MonitorModeTrap(); - elsif BadMode(mode) then - UNPREDICTABLE; - - base = Rmode[13,mode]; - address = if increment then base else base-8; - if wordhigher then address = address+4; - MemA[address,4] = LR; - MemA[address+4,4] = SPSR[]; - if wback then Rmode[13,mode] = if increment then base+8 else base-8; - -__instruction aarch32_USAD8_A - __encoding aarch32_USAD8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 16 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0111 1000xxxx 1111xxxx 0001xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_USAD8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 0111xxxx 1111xxxx 0000xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - absdiff1 = Abs(UInt(R[n][7:0]) - UInt(R[m][7:0])); - absdiff2 = Abs(UInt(R[n][15:8]) - UInt(R[m][15:8])); - absdiff3 = Abs(UInt(R[n][23:16]) - UInt(R[m][23:16])); - absdiff4 = Abs(UInt(R[n][31:24]) - UInt(R[m][31:24])); - result = absdiff1 + absdiff2 + absdiff3 + absdiff4; - R[d] = result[31:0]; - -__instruction aarch32_VUZP_A - __encoding aarch32_VUZP_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx10 xxxx0001 0xx0xxxx' - __guard TRUE - __decode - if size == '11' || (Q == '0' && size == '10') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - quadword_operation = (Q == '1'); esize = 8 << UInt(size); - d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VUZP_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx10 xxxx0001 0xx0xxxx' - __guard TRUE - __decode - if size == '11' || (Q == '0' && size == '10') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - quadword_operation = (Q == '1'); esize = 8 << UInt(size); - d = UInt(D:Vd); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - if quadword_operation then - if d == m then - Q[d>>1] = bits(128) UNKNOWN; Q[m>>1] = bits(128) UNKNOWN; - else - zipped_q = Q[m>>1]:Q[d>>1]; - for e = 0 to (128 DIV esize) - 1 - Elem[Q[d>>1],e,esize] = Elem[zipped_q,2*e,esize]; - Elem[Q[m>>1],e,esize] = Elem[zipped_q,2*e+1,esize]; - else - if d == m then - D[d] = bits(64) UNKNOWN; D[m] = bits(64) UNKNOWN; - else - zipped_d = D[m]:D[d]; - for e = 0 to (64 DIV esize) - 1 - Elem[D[d],e,esize] = Elem[zipped_d,2*e,esize]; - Elem[D[m],e,esize] = Elem[zipped_d,2*e+1,esize]; - -__instruction aarch32_UXTAB_A - __encoding aarch32_UXTAB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1110xxxx xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - if Rn == '1111' then SEE "UXTB"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UXTAB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 0101xxxx 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - if Rn == '1111' then SEE "UXTB"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d] = R[n] + ZeroExtend(rotated[7:0], 32); - -__instruction aarch32_VMLA_i_A - __encoding aarch32_VMLA_i_T1A1_A - __instruction_set A32 - __field op 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0xxxxxxx xxxx1001 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - add = (op == '0'); long_destination = FALSE; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMLA_i_T1A1_A - __instruction_set T32 - __field op 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0xxxxxxx xxxx1001 xxx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - add = (op == '0'); long_destination = FALSE; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - product = Int(Elem[Din[n+r],e,esize],unsigned) * Int(Elem[Din[m+r],e,esize],unsigned); - addend = if add then product else -product; - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend; - -__instruction aarch32_AND_i_A - __encoding aarch32_AND_i_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm12 0 +: 12 - __opcode 'xxxx0010 000xxxxx xxxxxxxx xxxxxxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); - (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C); - - __encoding aarch32_AND_i_T1_A - __instruction_set T32 - __field i 26 +: 1 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm8 0 +: 8 - __opcode '11110x00 000xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if Rd == '1111' && S == '1' then SEE "TST (immediate)"; - d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); - (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C); - if (d == 15 && !setflags) || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - result = R[n] AND imm32; - if d == 15 then // Can only occur for A32 encoding - if setflags then - ALUExceptionReturn(result); - else - ALUWritePC(result); - else - R[d] = result; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result); - PSTATE.C = carry; - // PSTATE.V unchanged - -__instruction aarch32_VMLA_i_A - __encoding aarch32_VMLA_i_T2A2_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx1000 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - add = (op == '0'); long_destination = TRUE; unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __encoding aarch32_VMLA_i_T2A2_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 9 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx1000 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vd[0] == '1' then UNDEFINED; - add = (op == '0'); long_destination = TRUE; unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - product = Int(Elem[Din[n+r],e,esize],unsigned) * Int(Elem[Din[m+r],e,esize],unsigned); - addend = if add then product else -product; - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend; - -__instruction aarch32_USAT_A - __encoding aarch32_USAT_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field sat_imm 16 +: 5 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field sh 6 +: 1 - __field Rn 0 +: 4 - __opcode 'xxxx0110 111xxxxx xxxxxxxx xx01xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm); - (shift_t, shift_n) = DecodeImmShift(sh:'0', imm5); - if d == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_USAT_T1_A - __instruction_set T32 - __field sh 21 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field sat_imm 0 +: 5 - __opcode '11110x11 10x0xxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 26 == '0' - __unpredictable_unless 5 == '0' - __decode - if sh == '1' && (imm3:imm2) == '00000' then SEE "USAT16"; - d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm); - (shift_t, shift_n) = DecodeImmShift(sh:'0', imm3:imm2); - if d == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand = Shift(R[n], shift_t, shift_n, PSTATE.C); // PSTATE.C ignored - (result, sat) = UnsignedSatQ(SInt(operand), saturate_to); - R[d] = ZeroExtend(result, 32); - if sat then - PSTATE.Q = '1'; - -__instruction aarch32_VQRDMLSH_A - __encoding aarch32_VQRDMLSH_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0xxxxxxx xxxx1100 xxx1xxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '00' || size == '11' then UNDEFINED; - add = FALSE; scalar_form = FALSE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQRDMLSH_A2_A - __instruction_set A32 - __field Q 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx1111 x1x0xxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - if size == '11' then SEE "Related encodings"; - if size == '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - add = FALSE; scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VQRDMLSH_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0xxxxxxx xxxx1100 xxx1xxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '00' || size == '11' then UNDEFINED; - add = FALSE; scalar_form = FALSE; esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQRDMLSH_T2_A - __instruction_set T32 - __field Q 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx1111 x1x0xxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - if InITBlock() then UNPREDICTABLE; - if size == '11' then SEE "Related encodings"; - if size == '00' then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - add = FALSE; scalar_form = TRUE; d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute - CheckAdvSIMDEnabled(); - round_const = 1 << (esize-1); - if scalar_form then op2 = SInt(Elem[D[m],index,esize]); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = SInt(Elem[D[n+r],e,esize]); - op3 = SInt(Elem[D[d+r],e,esize]) << esize; - if !scalar_form then op2 = SInt(Elem[D[m+r],e,esize]); - (result, sat) = SignedSatQ((op3 - 2*(op1*op2) + round_const) >> esize, esize); - Elem[D[d+r],e,esize] = result; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_VMLA_s_A - __encoding aarch32_VMLA_s_A1_A - __instruction_set A32 - __field Q 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field F 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 1xxxxxxx xxxx010x x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || (F == '1' && size == '01' && !HaveFP16Ext()) then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - add = (op == '0'); floating_point = (F == '1'); long_destination = FALSE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __encoding aarch32_VMLA_s_T1_A - __instruction_set T32 - __field Q 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field op 10 +: 1 - __field F 8 +: 1 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 1xxxxxxx xxxx010x x1x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if size == '00' || (F == '1' && size == '01' && !HaveFP16Ext()) then UNDEFINED; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = FALSE; // "Don't care" value: TRUE produces same functionality - add = (op == '0'); floating_point = (F == '1'); long_destination = FALSE; - d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - if size == '01' then esize = 16; elements = 4; m = UInt(Vm[2:0]); index = UInt(M:Vm[3]); - if size == '10' then esize = 32; elements = 2; m = UInt(Vm); index = UInt(M); - - __execute __conditional - CheckAdvSIMDEnabled(); - op2 = Elem[Din[m],index,esize]; op2val = Int(op2, unsigned); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[Din[n+r],e,esize]; op1val = Int(op1, unsigned); - if floating_point then - fp_addend = if add then FPMul(op1,op2,StandardFPSCRValue()) else FPNeg(FPMul(op1,op2,StandardFPSCRValue())); - Elem[D[d+r],e,esize] = FPAdd(Elem[Din[d+r],e,esize], fp_addend, StandardFPSCRValue()); - else - addend = if add then op1val*op2val else -op1val*op2val; - if long_destination then - Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend; - else - Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend; - -__instruction aarch32_VRINTA_vfp_A - __encoding aarch32_VRINTA_vfp_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111010 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __encoding aarch32_VRINTA_vfp_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field RM 16 +: 2 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 1x111010 xxxx10xx 01x0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - rounding = FPDecodeRM(RM); exact = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); m = UInt(M:Vm); - - __execute - CheckVFPEnabled(TRUE); - case esize of - when 16 - S[d] = Zeros(16) : FPRoundInt(S[m][15:0], FPSCR, rounding, exact); - when 32 - S[d] = FPRoundInt(S[m], FPSCR, rounding, exact); - when 64 - D[d] = FPRoundInt(D[m], FPSCR, rounding, exact); - -__instruction aarch32_STLB_A - __encoding aarch32_STLB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 0 +: 4 - __opcode 'xxxx0001 1100xxxx xxxxxx00 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_STLB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1100xxxx xxxxxxxx 1000xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __execute __conditional - address = R[n]; - MemO[address, 1] = R[t][7:0]; - -__instruction aarch32_CMN_rr_A - __encoding aarch32_CMN_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0111xxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __decode - n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - shift_t = DecodeRegShift(stype); - if n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], shifted, '0'); - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_VCADD_A - __encoding aarch32_VCADD_A1_A - __instruction_set A32 - __field rot 24 +: 1 - __field D 22 +: 1 - __field S 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111110x 1x0xxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if !HaveFCADDExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 16 << UInt(S); - if !HaveFP16Ext() && esize == 16 then UNDEFINED; - elements = 64 DIV esize; - regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCADD_T1_A - __instruction_set T32 - __field rot 24 +: 1 - __field D 22 +: 1 - __field S 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111110x 1x0xxxxx xxxx1000 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveFCADDExt() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - esize = 16 << UInt(S); - if !HaveFP16Ext() && esize == 16 then UNDEFINED; - elements = 64 DIV esize; - regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - operand1 = D[n+r]; - operand2 = D[m+r]; - operand3 = D[d+r]; - for e = 0 to (elements DIV 2)-1 - case rot of - when '0' - element1 = FPNeg(Elem[operand2,e*2+1,esize]); - element3 = Elem[operand2,e*2,esize]; - when '1' - element1 = Elem[operand2,e*2+1,esize]; - element3 = FPNeg(Elem[operand2,e*2,esize]); - result1 = FPAdd(Elem[operand1,e*2,esize],element1,StandardFPSCRValue()); - result2 = FPAdd(Elem[operand1,e*2+1,esize],element3,StandardFPSCRValue()); - Elem[D[d+r],e*2,esize] = result1; - Elem[D[d+r],e*2+1,esize] = result2; - -__instruction aarch32_VCLE_i_A - __encoding aarch32_VCLE_i_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx01 xxxx0x01 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCLE_i_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field F 10 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx01 xxxx0x01 1xx0xxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if F == '1' && ((size == '01' && !HaveFP16Ext()) || size == '00') then UNDEFINED; - if F == '1' && size == '01' && InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - floating_point = (F == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - if floating_point then - bits(esize) zero = FPZero('0'); - test_passed = FPCompareGE(zero, Elem[D[m+r],e,esize], StandardFPSCRValue()); - else - test_passed = (SInt(Elem[D[m+r],e,esize]) <= 0); - Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize); - -__instruction aarch32_VABD_f_A - __encoding aarch32_VABD_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x1xxxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VABD_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x1xxxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Elem[D[n+r],e,esize]; op2 = Elem[D[m+r],e,esize]; - Elem[D[d+r],e,esize] = FPAbs(FPSub(op1,op2,StandardFPSCRValue())); - -__instruction aarch32_MLA_A - __encoding aarch32_MLA_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rd 16 +: 4 - __field Ra 12 +: 4 - __field Rm 8 +: 4 - __field Rn 0 +: 4 - __opcode 'xxxx0000 001xxxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); setflags = (S == '1'); - if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE; - - __encoding aarch32_MLA_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Ra 12 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111011 0000xxxx xxxxxxxx 0000xxxx' - __guard TRUE - __decode - if Ra == '1111' then SEE "MUL"; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); setflags = FALSE; - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results - operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results - addend = SInt(R[a]); // addend = UInt(R[a]) produces the same final results - result = operand1 * operand2 + addend; - R[d] = result[31:0]; - if setflags then - PSTATE.N = result[31]; - PSTATE.Z = IsZeroBit(result[31:0]); - // PSTATE.C, PSTATE.V unchanged - -__instruction aarch32_SHA1P_A - __encoding aarch32_SHA1P_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x01xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if !HaveSHA1Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_SHA1P_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x01xxxx xxxx1100 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveSHA1Ext() then UNDEFINED; - if Q != '1' then UNDEFINED; - if Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckCryptoEnabled32(); - X = Q[d>>1]; - Y = Q[n>>1][31:0]; // Note: 32 bits wide - W = Q[m>>1]; - for e = 0 to 3 - t = SHAparity(X[63:32], X[95:64], X[127:96]); - Y = Y + ROL(X[31:0], 5) + t + Elem[W, e, 32]; - X[63:32] = ROL(X[63:32], 30); - [Y, X] = ROL(Y:X, 32); - Q[d>>1] = X; - -__instruction aarch32_QDSUB_A - __encoding aarch32_QDSUB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0110xxxx xxxxxxxx 0101xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_QDSUB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 1011xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - (doubled, sat1) = SignedSatQ(2 * SInt(R[n]), 32); - (R[d], sat2) = SignedSatQ(SInt(R[m]) - SInt(doubled), 32); - if sat1 || sat2 then - PSTATE.Q = '1'; - -__instruction aarch32_VDOT_bf16_i_A - __encoding aarch32_VDOT_bf16_i_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x00xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if !HaveAArch32BF16Ext() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm); - integer i = UInt(M); - integer regs = if Q == '1' then 2 else 1; - - __encoding aarch32_VDOT_bf16_i_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111110 0x00xxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveAArch32BF16Ext() then UNDEFINED; - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1') then UNDEFINED; - integer d = UInt(D:Vd); - integer n = UInt(N:Vn); - integer m = UInt(Vm); - integer i = UInt(M); - integer regs = if Q == '1' then 2 else 1; - - __execute - bits(64) operand1; - bits(64) operand2; - bits(64) result; - - CheckAdvSIMDEnabled(); - - operand2 = Din[m]; - for r = 0 to regs-1 - operand1 = Din[n+r]; - result = Din[d+r]; - for e = 0 to 1 - bits(16) elt1_a = Elem[operand1, 2 * e + 0, 16]; - bits(16) elt1_b = Elem[operand1, 2 * e + 1, 16]; - bits(16) elt2_a = Elem[operand2, 2 * i + 0, 16]; - bits(16) elt2_b = Elem[operand2, 2 * i + 1, 16]; - bits(32) sum = BFAdd(BFMul(elt1_a, elt2_a), BFMul(elt1_b, elt2_b)); - Elem[result, e, 32] = BFAdd(Elem[result, e, 32], sum); - D[d+r] = result; - -__instruction aarch32_VQSHL_r_A - __encoding aarch32_VQSHL_r_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0100 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VQSHL_r_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0100 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1' || Vn[0] == '1') then UNDEFINED; - unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - shift = SInt(Elem[D[n+r],e,esize][7:0]); - operand = Int(Elem[D[m+r],e,esize], unsigned); - (result,sat) = SatQ(operand << shift, esize, unsigned); - Elem[D[d+r],e,esize] = result; - if sat then FPSCR.QC = '1'; - -__instruction aarch32_VBIF_A - __encoding aarch32_VBIF_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x11xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if op == '00' then SEE "VEOR"; - if op == '01' then operation = VBitOps_VBSL; - if op == '10' then operation = VBitOps_VBIT; - if op == '11' then operation = VBitOps_VBIF; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VBIF_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x11xxxx xxxx0001 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if op == '00' then SEE "VEOR"; - if op == '01' then operation = VBitOps_VBSL; - if op == '10' then operation = VBitOps_VBIT; - if op == '11' then operation = VBitOps_VBIF; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - case operation of - when VBitOps_VBIF D[d+r] = (D[d+r] AND D[m+r]) OR (D[n+r] AND NOT(D[m+r])); - when VBitOps_VBIT D[d+r] = (D[n+r] AND D[m+r]) OR (D[d+r] AND NOT(D[m+r])); - when VBitOps_VBSL D[d+r] = (D[n+r] AND D[d+r]) OR (D[m+r] AND NOT(D[d+r])); - -__instruction aarch32_VPMAX_f_A - __encoding aarch32_VPMAX_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 0x0xxxxx xxxx1111 x0x0xxxx' - __guard TRUE - __decode - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - maximum = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VPMAX_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field op 21 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 0x0xxxxx xxxx1111 x0x0xxxx' - __guard TRUE - __decode - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - maximum = (op == '0'); - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - bits(64) dest; - h = elements DIV 2; - - for e = 0 to h-1 - op1 = Elem[D[n],2*e,esize]; op2 = Elem[D[n],2*e+1,esize]; - Elem[dest,e,esize] = if maximum then FPMax(op1,op2,StandardFPSCRValue()) else FPMin(op1,op2,StandardFPSCRValue()); - op1 = Elem[D[m],2*e,esize]; op2 = Elem[D[m],2*e+1,esize]; - Elem[dest,e+h,esize] = if maximum then FPMax(op1,op2,StandardFPSCRValue()) else FPMin(op1,op2,StandardFPSCRValue()); - - D[d] = dest; - -__instruction aarch32_VLDR_A - __encoding aarch32_VLDR_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field U 23 +: 1 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm8 0 +: 8 - __opcode 'xxxx1101 xx011111 xxxx10xx xxxxxxxx' - __guard cond != '1111' - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - esize = 8 << UInt(size); add = (U == '1'); - imm32 = if esize == 16 then ZeroExtend(imm8:'0', 32) else ZeroExtend(imm8:'00', 32); - case size of - when '01' d = UInt(Vd:D); - when '10' d = UInt(Vd:D); - when '11' d = UInt(D:Vd); - n = UInt(Rn); - - __encoding aarch32_VLDR_T1_A - __instruction_set T32 - __field U 23 +: 1 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field imm8 0 +: 8 - __opcode '11101101 xx011111 xxxx10xx xxxxxxxx' - __guard TRUE - __decode - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - esize = 8 << UInt(size); add = (U == '1'); - imm32 = if esize == 16 then ZeroExtend(imm8:'0', 32) else ZeroExtend(imm8:'00', 32); - case size of - when '01' d = UInt(Vd:D); - when '10' d = UInt(Vd:D); - when '11' d = UInt(D:Vd); - n = UInt(Rn); - - __execute __conditional - CheckVFPEnabled(TRUE); - base = if n == 15 then Align(PC,4) else R[n]; - address = if add then (base + imm32) else (base - imm32); - case esize of - when 16 - S[d] = Zeros(16) : MemA[address,2]; - when 32 - S[d] = MemA[address,4]; - when 64 - word1 = MemA[address,4]; word2 = MemA[address+4,4]; - // Combine the word-aligned words in the correct order for current endianness. - D[d] = if BigEndian() then word1:word2 else word2:word1; - -__instruction aarch32_VST3_1_A - __encoding aarch32_VST3_1_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx0010 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[0] != '0' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST3_1_T2A2_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx0110 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[0] != '0' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST3_1_T3A3_A - __instruction_set A32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11110100 1x00xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[1:0] != '00' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST3_1_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx0010 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[0] != '0' then UNDEFINED; - ebytes = 1; index = UInt(index_align[3:1]); inc = 1; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST3_1_T2A2_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx0110 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[0] != '0' then UNDEFINED; - ebytes = 2; index = UInt(index_align[3:2]); - inc = if index_align[1] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __encoding aarch32_VST3_1_T3A3_A - __instruction_set T32 - __field D 22 +: 1 - __field Rn 16 +: 4 - __field Vd 12 +: 4 - __field size 10 +: 2 - __field index_align 4 +: 4 - __field Rm 0 +: 4 - __opcode '11111001 1x00xxxx xxxx1010 xxxxxxxx' - __guard TRUE - __decode - if size == '11' then UNDEFINED; - if index_align[1:0] != '00' then UNDEFINED; - ebytes = 4; index = UInt(index_align[3]); - inc = if index_align[2] == '0' then 1 else 2; - d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); - wback = (m != 15); register_index = (m != 15 && m != 13); - if n == 15 || d3 > 31 then UNPREDICTABLE; - - __execute __conditional - CheckAdvSIMDEnabled(); - address = R[n]; - MemU[address, ebytes] = Elem[D[d], index]; - MemU[address+ebytes, ebytes] = Elem[D[d2],index]; - MemU[address+2*ebytes,ebytes] = Elem[D[d3],index]; - if wback then - if register_index then - R[n] = R[n] + R[m]; - else - R[n] = R[n] + 3*ebytes; - -__instruction aarch32_ADC_rr_A - __encoding aarch32_ADC_rr_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rs 8 +: 4 - __field stype 5 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0000 101xxxxx xxxxxxxx 0xx1xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); - setflags = (S == '1'); shift_t = DecodeRegShift(stype); - if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; - - __execute __conditional - shift_n = UInt(R[s][7:0]); - shifted = Shift(R[m], shift_t, shift_n, PSTATE.C); - (result, nzcv) = AddWithCarry(R[n], shifted, PSTATE.C); - R[d] = result; - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - -__instruction aarch32_LDREXB_A - __encoding aarch32_LDREXB_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode 'xxxx0001 1101xxxx xxxxxx11 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; - - __encoding aarch32_LDREXB_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rt 12 +: 4 - __opcode '11101000 1101xxxx xxxxxxxx 0100xxxx' - __guard TRUE - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - t = UInt(Rt); n = UInt(Rn); - if t == 15 || n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - address = R[n]; - AArch32.SetExclusiveMonitors(address,1); - R[t] = ZeroExtend(MemA[address,1], 32); - -__instruction aarch32_CLREX_A - __encoding aarch32_CLREX_A1_A - __instruction_set A32 - __opcode '11110101 0111xxxx xxxxxxxx 0001xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '1' - __unpredictable_unless 12 == '1' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - // No additional decoding required - - __encoding aarch32_CLREX_T1_A - __instruction_set T32 - __opcode '11110011 1011xxxx 10x0xxxx 0010xxxx' - __guard TRUE - __unpredictable_unless 19 == '1' - __unpredictable_unless 18 == '1' - __unpredictable_unless 17 == '1' - __unpredictable_unless 16 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __unpredictable_unless 3 == '1' - __unpredictable_unless 2 == '1' - __unpredictable_unless 1 == '1' - __unpredictable_unless 0 == '1' - __decode - // No additional decoding required - - __execute __conditional - ClearExclusiveLocal(ProcessorID()); - -__instruction aarch32_VADDHN_A - __encoding aarch32_VADDHN_T1A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 1xxxxxxx xxxx0100 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VADDHN_T1A1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 1xxxxxxx xxxx0100 x0x0xxxx' - __guard TRUE - __decode - if size == '11' then SEE "Related encodings"; - if Vn[0] == '1' || Vm[0] == '1' then UNDEFINED; - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDEnabled(); - for e = 0 to elements-1 - result = Elem[Qin[n>>1],e,2*esize] + Elem[Qin[m>>1],e,2*esize]; - Elem[D[d],e,esize] = result[2*esize-1:esize]; - -__instruction aarch32_PKH_A - __encoding aarch32_PKH_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field imm5 7 +: 5 - __field tb 6 +: 1 - __field Rm 0 +: 4 - __opcode 'xxxx0110 1000xxxx xxxxxxxx xx01xxxx' - __guard cond != '1111' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); tbform = (tb == '1'); - (shift_t, shift_n) = DecodeImmShift(tb:'0', imm5); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_PKH_T1_A - __instruction_set T32 - __field S 20 +: 1 - __field Rn 16 +: 4 - __field imm3 12 +: 3 - __field Rd 8 +: 4 - __field imm2 6 +: 2 - __field tb 5 +: 1 - __field T 4 +: 1 - __field Rm 0 +: 4 - __opcode '11101010 1100xxxx xxxxxxxx xxx0xxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __decode - if S == '1' || T == '1' then UNDEFINED; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); tbform = (tb == '1'); - (shift_t, shift_n) = DecodeImmShift(tb:'0', imm3:imm2); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - operand2 = Shift(R[m], shift_t, shift_n, PSTATE.C); // PSTATE.C ignored - R[d][15:0] = if tbform then operand2[15:0] else R[n][15:0]; - R[d][31:16] = if tbform then R[n][31:16] else operand2[31:16]; - -__instruction aarch32_RFE_AS - __encoding aarch32_RFE_A1_AS - __instruction_set A32 - __field P 24 +: 1 - __field U 23 +: 1 - __field W 21 +: 1 - __field Rn 16 +: 4 - __opcode '1111100x x0x1xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '0' - __unpredictable_unless 14 == '0' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 4 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - n = UInt(Rn); - wback = (W == '1'); increment = (U == '1'); wordhigher = (P == U); - if n == 15 then UNPREDICTABLE; - - __encoding aarch32_RFE_T1_AS - __instruction_set T32 - __field W 21 +: 1 - __field Rn 16 +: 4 - __opcode '11101000 00x1xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 4 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; - if n == 15 then UNPREDICTABLE; - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __encoding aarch32_RFE_T2_AS - __instruction_set T32 - __field W 21 +: 1 - __field Rn 16 +: 4 - __opcode '11101001 10x1xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __unpredictable_unless 15 == '1' - __unpredictable_unless 14 == '1' - __unpredictable_unless 13 == '0' - __unpredictable_unless 12 == '0' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __unpredictable_unless 7 == '0' - __unpredictable_unless 6 == '0' - __unpredictable_unless 5 == '0' - __unpredictable_unless 4 == '0' - __unpredictable_unless 3 == '0' - __unpredictable_unless 2 == '0' - __unpredictable_unless 1 == '0' - __unpredictable_unless 0 == '0' - __decode - n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; - if n == 15 then UNPREDICTABLE; - if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - __execute __conditional - if PSTATE.EL == EL2 then - UNDEFINED; - elsif PSTATE.EL == EL0 then - UNPREDICTABLE; // UNDEFINED or NOP - else - address = if increment then R[n] else R[n]-8; - if wordhigher then address = address+4; - new_pc_value = MemA[address,4]; - spsr = MemA[address+4,4]; - if wback then R[n] = if increment then R[n]+8 else R[n]-8; - AArch32.ExceptionReturn(new_pc_value, spsr); - -__instruction aarch32_VCVTA_asimd_A - __encoding aarch32_VCVTA_asimd_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field RM 8 +: 2 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110011 1x11xx11 xxxx0000 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VCVTA_asimd_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field size 18 +: 2 - __field Vd 12 +: 4 - __field RM 8 +: 2 - __field op 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111111 1x11xx11 xxxx0000 xxx0xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if Q == '1' && (Vd[0] == '1' || Vm[0] == '1') then UNDEFINED; - if (size == '01' && !HaveFP16Ext()) || size IN {'00', '11'} then UNDEFINED; - rounding = FPDecodeRM(RM); unsigned = (op == '1'); - case size of - when '01' esize = 16; elements = 4; - when '10' esize = 32; elements = 2; - d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute - CheckAdvSIMDEnabled(); - bits(esize) result; - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = FPToFixed(Elem[D[m+r],e,esize], 0, unsigned, - StandardFPSCRValue(), rounding); - -__instruction aarch32_VADD_f_A - __encoding aarch32_VADD_f_A1_A - __instruction_set A32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11110010 0x0xxxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VADD_f_A2_A - __instruction_set A32 - __field cond 28 +: 4 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode 'xxxx1110 0x11xxxx xxxx10xx x0x0xxxx' - __guard cond != '1111' - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && cond != '1110' then UNPREDICTABLE; - advsimd = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __encoding aarch32_VADD_f_T1_A - __instruction_set T32 - __field D 22 +: 1 - __field sz 20 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101111 0x0xxxxx xxxx1101 xxx0xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if sz == '1' && !HaveFP16Ext() then UNDEFINED; - if sz == '1' && InITBlock() then UNPREDICTABLE; - advsimd = TRUE; - case sz of - when '0' esize = 32; elements = 2; - when '1' esize = 16; elements = 4; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VADD_f_T2_A - __instruction_set T32 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field size 8 +: 2 - __field N 7 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11101110 0x11xxxx xxxx10xx x0x0xxxx' - __guard TRUE - __decode - if FPSCR.Len != '000' || FPSCR.Stride != '00' then UNDEFINED; - if size == '00' || (size == '01' && !HaveFP16Ext()) then UNDEFINED; - if size == '01' && InITBlock() then UNPREDICTABLE; - advsimd = FALSE; - case size of - when '01' esize = 16; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '10' esize = 32; d = UInt(Vd:D); n = UInt(Vn:N); m = UInt(Vm:M); - when '11' esize = 64; d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); - - __execute __conditional - CheckAdvSIMDOrVFPEnabled(TRUE, advsimd); - if advsimd then // Advanced SIMD instruction - for r = 0 to regs-1 - for e = 0 to elements-1 - Elem[D[d+r],e,esize] = FPAdd(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize], - StandardFPSCRValue()); - else // VFP instruction - case esize of - when 16 - S[d] = Zeros(16) : FPAdd(S[n][15:0], S[m][15:0], FPSCR); - when 32 - S[d] = FPAdd(S[n], S[m], FPSCR); - when 64 - D[d] = FPAdd(D[n], D[m], FPSCR); - -__instruction aarch32_SXTB16_A - __encoding aarch32_SXTB16_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rd 12 +: 4 - __field rotate 10 +: 2 - __field Rm 0 +: 4 - __opcode 'xxxx0110 10001111 xxxxxxxx 0111xxxx' - __guard cond != '1111' - __unpredictable_unless 9 == '0' - __unpredictable_unless 8 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_SXTB16_T1_A - __instruction_set T32 - __field Rd 8 +: 4 - __field rotate 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 00101111 1111xxxx 1xxxxxxx' - __guard TRUE - __unpredictable_unless 6 == '0' - __decode - d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); - if d == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - rotated = ROR(R[m], rotation); - R[d][15:0] = SignExtend(rotated[7:0], 16); - R[d][31:16] = SignExtend(rotated[23:16], 16); - -__instruction aarch32_VFMAL_A - __encoding aarch32_VFMAL_A1_A - __instruction_set A32 - __field S 23 +: 1 - __field D 22 +: 1 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x10xxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - - integer d = UInt(D:Vd); - integer n = if Q == '1' then UInt(N:Vn) else UInt(Vn:N); - integer m = if Q == '1' then UInt(M:Vm) else UInt(Vm:M); - integer esize = 32; - integer regs = if Q=='1' then 2 else 1; - integer datasize = if Q=='1' then 64 else 32; - boolean sub_op = S=='1'; - - __encoding aarch32_VFMAL_T1_A - __instruction_set T32 - __field S 23 +: 1 - __field D 22 +: 1 - __field op2 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field Vm 0 +: 4 - __opcode '11111100 0x1xxxxx xxxx1000 xxx1xxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - if Q == '1' && Vd[0] == '1' then UNDEFINED; - - integer d = UInt(D:Vd); - integer n = if Q == '1' then UInt(N:Vn) else UInt(Vn:N); - integer m = if Q == '1' then UInt(M:Vm) else UInt(Vm:M); - integer esize = 32; - integer regs = if Q=='1' then 2 else 1; - integer datasize = if Q=='1' then 64 else 32; - boolean sub_op = S=='1'; - - __execute - CheckAdvSIMDEnabled(); - bits(datasize) operand1 ; - bits(datasize) operand2 ; - bits(64) operand3; - bits(64) result; - bits(esize DIV 2) element1; - bits(esize DIV 2) element2; - - if Q=='0' then - operand1 = S[n][datasize-1:0]; - operand2 = S[m][datasize-1:0]; - else - operand1 = D[n][datasize-1:0]; - operand2 = D[m][datasize-1:0]; - for r = 0 to regs-1 - operand3 = D[d+r]; - for e = 0 to 1 - element1 = Elem[operand1, 2*r+e, esize DIV 2]; - element2 = Elem[operand2, 2*r+e, esize DIV 2]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAddH(Elem[operand3, e, esize], element1, element2, StandardFPSCRValue()); - D[d+r] = result; - -__instruction aarch32_UHADD8_A - __encoding aarch32_UHADD8_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field Rm 0 +: 4 - __opcode 'xxxx0110 0111xxxx xxxxxxxx 1001xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '1' - __unpredictable_unless 10 == '1' - __unpredictable_unless 9 == '1' - __unpredictable_unless 8 == '1' - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - - __encoding aarch32_UHADD8_T1_A - __instruction_set T32 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field Rm 0 +: 4 - __opcode '11111010 1000xxxx 1111xxxx 0110xxxx' - __guard TRUE - __decode - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 - - __execute __conditional - sum1 = UInt(R[n][7:0]) + UInt(R[m][7:0]); - sum2 = UInt(R[n][15:8]) + UInt(R[m][15:8]); - sum3 = UInt(R[n][23:16]) + UInt(R[m][23:16]); - sum4 = UInt(R[n][31:24]) + UInt(R[m][31:24]); - R[d][7:0] = sum1[8:1]; - R[d][15:8] = sum2[8:1]; - R[d][23:16] = sum3[8:1]; - R[d][31:24] = sum4[8:1]; - -__instruction aarch32_VMAX_i_A - __encoding aarch32_VMAX_i_T1A1_A - __instruction_set A32 - __field U 24 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field op 4 +: 1 - __field Vm 0 +: 4 - __opcode '1111001x 0xxxxxxx xxxx0110 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - maximum = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __encoding aarch32_VMAX_i_T1A1_A - __instruction_set T32 - __field U 28 +: 1 - __field D 22 +: 1 - __field size 20 +: 2 - __field Vn 16 +: 4 - __field Vd 12 +: 4 - __field N 7 +: 1 - __field Q 6 +: 1 - __field M 5 +: 1 - __field op 4 +: 1 - __field Vm 0 +: 4 - __opcode '111x1111 0xxxxxxx xxxx0110 xxx1xxxx' - __guard TRUE - __decode - if Q == '1' && (Vd[0] == '1' || Vn[0] == '1' || Vm[0] == '1') then UNDEFINED; - if size == '11' then UNDEFINED; - maximum = (op == '0'); unsigned = (U == '1'); - esize = 8 << UInt(size); elements = 64 DIV esize; - d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; - - __execute __conditional - CheckAdvSIMDEnabled(); - for r = 0 to regs-1 - for e = 0 to elements-1 - op1 = Int(Elem[D[n+r],e,esize], unsigned); - op2 = Int(Elem[D[m+r],e,esize], unsigned); - result = if maximum then Max(op1,op2) else Min(op1,op2); - Elem[D[d+r],e,esize] = result[esize-1:0]; - -__instruction aarch32_CRC32_A - __encoding aarch32_CRC32_A1_A - __instruction_set A32 - __field cond 28 +: 4 - __field sz 21 +: 2 - __field Rn 16 +: 4 - __field Rd 12 +: 4 - __field C 9 +: 1 - __field Rm 0 +: 4 - __opcode 'xxxx0001 0xx0xxxx xxxxxx1x 0100xxxx' - __guard cond != '1111' - __unpredictable_unless 11 == '0' - __unpredictable_unless 10 == '0' - __unpredictable_unless 8 == '0' - __decode - if ! HaveCRCExt() then UNDEFINED; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - size = 8 << UInt(sz); - crc32c = (C == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if size == 64 then UNPREDICTABLE; - if cond != '1110' then UNPREDICTABLE; - - __encoding aarch32_CRC32_T1_A - __instruction_set T32 - __field C 20 +: 1 - __field Rn 16 +: 4 - __field Rd 8 +: 4 - __field sz 4 +: 2 - __field Rm 0 +: 4 - __opcode '11111010 1101xxxx 1111xxxx 10xxxxxx' - __guard TRUE - __decode - if InITBlock() then UNPREDICTABLE; - if ! HaveCRCExt() then UNDEFINED; - d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); - size = 8 << UInt(sz); - crc32c = (C == '1'); - if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; - if size == 64 then UNPREDICTABLE; - - __execute __conditional - - acc = R[n]; // accumulator - val = R[m][size-1:0]; // input value - poly = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)[31:0]; - tempacc = BitReverse(acc):Zeros(size); - tempval = BitReverse(val):Zeros(32); - // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation - R[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly)); - -__instruction LDNT1B_Z_P_BR_Contiguous - __encoding LDNT1B_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 000xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(64) offset; - bits(PL) mask = P[g]; - bits(VL) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = X[m]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_STREAM]; - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction BFMLALB_Z_ZZZ__ - __encoding BFMLALB_Z_ZZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 111xxxxx 100000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 32; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(32) element1 = Elem[operand1, 2 * e + 0, 16] : Zeros(16); - bits(32) element2 = Elem[operand2, 2 * e + 0, 16] : Zeros(16); - bits(32) element3 = Elem[operand3, e, 32]; - Elem[result, e, 32] = FPMulAdd(element3, element1, element2, FPCR); - - Z[da] = result; - -__instruction aarch64_branch_unconditional_immediate - __encoding aarch64_branch_unconditional_immediate - __instruction_set A64 - __field op 31 +: 1 - __field imm26 0 +: 26 - __opcode 'x00101xx xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - BranchType branch_type = if op == '1' then BranchType_DIRCALL else BranchType_DIR; - bits(64) offset = SignExtend(imm26:'00', 64); - - __execute - if branch_type == BranchType_DIRCALL then X[30] = PC[] + 4; - - BranchTo(PC[] + offset, branch_type); - -__instruction aarch64_memory_atomicops_cas_single - __encoding aarch64_memory_atomicops_cas_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x1xxxxx x11111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer n = UInt(Rn); - integer t = UInt(Rt); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if L == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if o0 == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) comparevalue; - bits(datasize) newvalue; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - comparevalue = X[s]; - newvalue = X[t]; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomicCompareAndSwap(address, comparevalue, newvalue, ldacctype, stacctype); - - X[s] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_element_mat_mul_int_dotp - __encoding aarch64_vector_arithmetic_binary_element_mat_mul_int_dotp - __instruction_set A64 - __field Q 30 +: 1 - __field US 23 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 x0xxxxxx 1111x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveInt8MatMulExt() then UNDEFINED; - boolean op1_unsigned = (US == '1'); - boolean op2_unsigned = (US == '0'); - integer n = UInt(Rn); - integer m = UInt(M:Rm); - integer d = UInt(Rd); - integer i = UInt(H:L); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 32; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - - for e = 0 to elements-1 - bits(32) res = Elem[operand3, e, 32]; - for b = 0 to 3 - integer element1 = Int(Elem[operand1, 4 * e + b, 8], op1_unsigned); - integer element2 = Int(Elem[operand2, 4 * i + b, 8], op2_unsigned); - res = res + element1 * element2; - Elem[result, e, 32] = res; - V[d] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction aarch64_vector_arithmetic_unary_fp16_round - __encoding aarch64_vector_arithmetic_unary_fp16_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 100x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __encoding aarch64_vector_arithmetic_unary_float_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact); - - V[d] = result; - -__instruction aarch64_float_arithmetic_round_frint_32_64 - __encoding aarch64_float_arithmetic_round_frint_32_64 - __instruction_set A64 - __field ftype 22 +: 2 - __field op 15 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx10100x x10000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFrintExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '1x' UNDEFINED; - - integer intsize = if op[1] == '0' then 32 else 64; - - FPRounding rounding = if op[0] == '0' then FPRounding_ZERO else FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundIntN(operand, FPCR, rounding, intsize); - - V[d] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction PRFW_I_P_BZ_S_x32_scaled - __encoding PRFW_I_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000100 0x1xxxxx 010xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 32; - boolean offs_unsigned = (xs == '0'); - integer scale = 2; - - __encoding PRFW_I_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 0x1xxxxx 010xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 32; - boolean offs_unsigned = (xs == '0'); - integer scale = 2; - - __encoding PRFW_I_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 011xxxxx 110xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) addr; - bits(VL) offset; - - if n == 31 then - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - -__instruction aarch64_vector_crypto_sha3op_sha1_sched0 - __encoding aarch64_vector_crypto_sha3op_sha1_sched0 - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 000xxxxx 001100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if !HaveSHA1Ext() then UNDEFINED; - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) operand1 = V[d]; - bits(128) operand2 = V[n]; - bits(128) operand3 = V[m]; - bits(128) result; - - result = operand2[63:0] : operand1[127:64]; - result = result EOR operand1 EOR operand3; - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_float_widen - __encoding aarch64_vector_arithmetic_unary_float_widen - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 0x100001 011110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16 << UInt(sz); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = Vpart[n, part]; - bits(2*datasize) result; - - for e = 0 to elements-1 - Elem[result, e, 2*esize] = FPConvert(Elem[operand, e, esize], FPCR); - - V[d] = result; - -__instruction aarch64_branch_unconditional_eret - __encoding aarch64_branch_unconditional_eret - __instruction_set A64 - __field A 11 +: 1 - __field M 10 +: 1 - __field Rn 5 +: 5 - __field op4 0 +: 5 - __opcode '11010110 10011111 0000xxxx xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL0 then UNDEFINED; - boolean pac = (A == '1'); - boolean use_key_a = (M == '0'); - - if !pac && op4 != '00000' then - UNDEFINED; - elsif pac && (!HavePACExt() || op4 != '11111') then - UNDEFINED; - - if Rn != '11111' then - UNDEFINED; - - __execute - AArch64.CheckForERetTrap(pac, use_key_a); - bits(64) target = ELR[]; - boolean auth_then_branch = TRUE; - - if pac then - if use_key_a then - target = AuthIA(ELR[], SP[], auth_then_branch); - else - target = AuthIB(ELR[], SP[], auth_then_branch); - - AArch64.ExceptionReturn(target, SPSR[]); - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction LD2W_Z_P_BI_Contiguous - __encoding LD2W_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0010xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_shift_left_sat_sisd - __encoding aarch64_vector_shift_left_sat_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 011x01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = esize; - integer elements = 1; - - integer shift = UInt(immh:immb) - esize; - - boolean src_unsigned; - boolean dst_unsigned; - case op:U of - when '00' UNDEFINED; - when '01' src_unsigned = FALSE; dst_unsigned = TRUE; - when '10' src_unsigned = FALSE; dst_unsigned = FALSE; - when '11' src_unsigned = TRUE; dst_unsigned = TRUE; - - __encoding aarch64_vector_shift_left_sat_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 011x01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = UInt(immh:immb) - esize; - - boolean src_unsigned; - boolean dst_unsigned; - case op:U of - when '00' UNDEFINED; - when '01' src_unsigned = FALSE; dst_unsigned = TRUE; - when '10' src_unsigned = FALSE; dst_unsigned = FALSE; - when '11' src_unsigned = TRUE; dst_unsigned = TRUE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = Int(Elem[operand, e, esize], src_unsigned) << shift; - (Elem[result, e, esize], sat) = SatQ(element, esize, dst_unsigned); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction BFMLALT_Z_ZZZi__ - __encoding BFMLALT_Z_ZZZi__ - __instruction_set A64 - __field i3h 19 +: 2 - __field Zm 16 +: 3 - __field i3l 11 +: 1 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 111xxxxx 0100x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - integer index = UInt(i3h:i3l); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 32; - integer eltspersegment = 128 DIV 32; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = 2 * segmentbase + index; - bits(32) element1 = Elem[operand1, 2 * e + 1, 16] : Zeros(16); - bits(32) element2 = Elem[operand2, s, 16] : Zeros(16); - bits(32) element3 = Elem[operand3, e, 32]; - Elem[result, e, 32] = FPMulAdd(element3, element1, element2, FPCR); - - Z[da] = result; - -__instruction aarch64_memory_single_general_immediate_signed_post_idx - __encoding aarch64_memory_single_general_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_bfmmla - __encoding aarch64_vector_bfmmla - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01101110 010xxxxx 111011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(128) op1 = V[n]; - bits(128) op2 = V[m]; - bits(128) acc = V[d]; - - V[d] = BFMatMulAdd(acc, op1, op2); - -__instruction SUBR_Z_ZI__ - __encoding SUBR_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx100011 11xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer imm = UInt(imm8); - if sh == '1' then imm = imm << 8; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = UInt(Elem[operand1, e, esize]); - Elem[result, e, esize] = (imm - element1)[esize-1:0]; - - Z[dn] = result; - -__instruction BFCVT_Z_P_Z_S2BF - __encoding BFCVT_Z_P_Z_S2BF - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 10001010 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveBF16Ext() then UNDEFINED; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 32; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(32) element = Elem[operand, e, 32]; - if ElemP[mask, e, 32] == '1' then - Elem[result, 2*e, 16] = FPConvertBF(element, FPCR); - Elem[result, 2*e+1, 16] = Zeros(); - - Z[d] = result; - -__instruction aarch64_integer_logical_shiftedreg - __encoding aarch64_integer_logical_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field shift 22 +: 2 - __field N 21 +: 1 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01010 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - boolean invert = (N == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - X[d] = result; - -__instruction aarch64_integer_arithmetic_address_pc_rel - __encoding aarch64_integer_arithmetic_address_pc_rel - __instruction_set A64 - __field op 31 +: 1 - __field immlo 29 +: 2 - __field immhi 5 +: 19 - __field Rd 0 +: 5 - __opcode 'xxx10000 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - boolean page = (op == '1'); - bits(64) imm; - - if page then - imm = SignExtend(immhi:immlo:Zeros(12), 64); - else - imm = SignExtend(immhi:immlo, 64); - - __execute - bits(64) base = PC[]; - - if page then - base[11:0] = Zeros(12); - - X[d] = base + imm; - -__instruction INDEX_Z_RR__ - __encoding INDEX_Z_RR__ - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 010011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(esize) operand1 = X[n]; - integer element1 = SInt(operand1); - bits(esize) operand2 = X[m]; - integer element2 = SInt(operand2); - bits(VL) result; - - for e = 0 to elements-1 - integer index = element1 + e * element2; - Elem[result, e, esize] = index[esize-1:0]; - - Z[d] = result; - -__instruction aarch64_memory_pair_simdfp_no_alloc - __encoding aarch64_memory_pair_simdfp_no_alloc - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101100 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); - AccType acctype = AccType_VECSTREAM; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - if opc == '11' then UNDEFINED; - integer scale = 2 + UInt(opc); - integer datasize = 8 << scale; - bits(64) offset = LSL(SignExtend(imm7, 64), scale); - boolean tag_checked = wback || n != 31; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(datasize) data1; - bits(datasize) data2; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data1 = V[t]; - data2 = V[t2]; - Mem[address + 0 , dbytes, acctype] = data1; - Mem[address + dbytes, dbytes, acctype] = data2; - - when MemOp_LOAD - data1 = Mem[address + 0 , dbytes, acctype]; - data2 = Mem[address + dbytes, dbytes, acctype]; - if rt_unknown then - data1 = bits(datasize) UNKNOWN; - data2 = bits(datasize) UNKNOWN; - V[t] = data1; - V[t2] = data2; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_integer_tags_mcgettagarray - __encoding aarch64_integer_tags_mcgettagarray - __instruction_set A64 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 11100000 000000xx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Xt); - integer n = UInt(Xn); - - __execute - if PSTATE.EL == EL0 then - UNDEFINED; - - bits(64) data = Zeros(64); - bits(64) address; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - integer size = 4*(2^(UInt(GMID_EL1.BS))); - address = Align(address,size); - integer count = size >> LOG2_TAG_GRANULE; - integer index = UInt(address[LOG2_TAG_GRANULE+3:LOG2_TAG_GRANULE]); - - for i = 0 to count-1 - bits(4) tag = AArch64.MemTag[address, AccType_NORMAL]; - data[(index*4)+3:index*4] = tag; - address = address + TAG_GRANULE; - index = index + 1; - - X[t] = data; - -__instruction UZP1_Z_ZZ__ - __encoding UZP1_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx1xxxxx 011010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 0; - - __encoding UZP1_Z_ZZ_Q - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 101xxxxx 000010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer esize = 128; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 0; - - __encoding UZP2_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx1xxxxx 011011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 1; - - __encoding UZP2_Z_ZZ_Q - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 101xxxxx 000011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer esize = 128; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 1; - - __execute - CheckSVEEnabled(); - if VL < esize * 2 then UNDEFINED; - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result = Zeros(); - - bits(VL*2) zipped = operand2:operand1; - for e = 0 to elements-1 - Elem[result, e, esize] = Elem[zipped, 2*e+part, esize]; - - Z[d] = result; - -__instruction UQINCW_R_RS_UW - __encoding UQINCW_R_RS_UW - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1010xxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQINCW_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1011xxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 + (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_vector_shift_right_sisd - __encoding aarch64_vector_shift_right_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __encoding aarch64_vector_shift_right_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - operand2 = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift; - Elem[result, e, esize] = Elem[operand2, e, esize] + element[esize-1:0]; - - V[d] = result; - -__instruction BFMMLA_Z_ZZZ__ - __encoding BFMMLA_Z_ZZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 011xxxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer segments = VL DIV 128; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - bits(128) op1, op2; - bits(128) res, addend; - - for s = 0 to segments-1 - op1 = Elem[operand1, s, 128]; - op2 = Elem[operand2, s, 128]; - addend = Elem[operand3, s, 128]; - res = BFMatMulAdd(addend, op1, op2); - Elem[result, s, 128] = res; - - Z[da] = result; - -__instruction aarch64_vector_reduce_int_max - __encoding aarch64_vector_reduce_int_max - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 16 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx11000x 101010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '100' then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean min = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - integer maxmin; - integer element; - - maxmin = Int(Elem[operand, 0, esize], unsigned); - for e = 1 to elements-1 - element = Int(Elem[operand, e, esize], unsigned); - maxmin = if min then Min(maxmin, element) else Max(maxmin, element); - - V[d] = maxmin[esize-1:0]; - -__instruction aarch64_integer_shift_variable - __encoding aarch64_integer_shift_variable - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field op2 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011010 110xxxxx 0010xxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - ShiftType shift_type = DecodeShift(op2); - - __execute - bits(datasize) result; - bits(datasize) operand2 = X[m]; - - result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize); - X[d] = result; - -__instruction LD1ROH_Z_P_BR_Contiguous - __encoding LD1ROH_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 101xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - - __execute - CheckSVEEnabled(); - if VL < 256 then UNDEFINED; - integer elements = 256 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low bits only - bits(64) offset; - bits(256) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - offset = X[m]; - - addr = base + UInt(offset) * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = ZeroExtend(Replicate(result, VL DIV 256), VL); - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction aarch64_vector_arithmetic_binary_uniform_mat_mul_int_mla - __encoding aarch64_vector_arithmetic_binary_uniform_mat_mul_int_mla - __instruction_set A64 - __field U 29 +: 1 - __field Rm 16 +: 5 - __field B 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x01110 100xxxxx 1010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveInt8MatMulExt() then UNDEFINED; - case B:U of - when '00' op1_unsigned = FALSE; op2_unsigned = FALSE; - when '01' op1_unsigned = TRUE; op2_unsigned = TRUE; - when '10' op1_unsigned = TRUE; op2_unsigned = FALSE; - when '11' UNDEFINED; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(128) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(128) addend = V[d]; - - V[d] = MatMulAdd(addend, operand1, operand2, op1_unsigned, op2_unsigned); - -__instruction aarch64_integer_arithmetic_mul_widening_32_64 - __encoding aarch64_integer_arithmetic_mul_widening_32_64 - __instruction_set A64 - __field U 23 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '10011011 x01xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer a = UInt(Ra); - integer destsize = 64; - integer datasize = 32; - boolean sub_op = (o0 == '1'); - boolean unsigned = (U == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(destsize) operand3 = X[a]; - - integer result; - - if sub_op then - result = Int(operand3, unsigned) - (Int(operand1, unsigned) * Int(operand2, unsigned)); - else - result = Int(operand3, unsigned) + (Int(operand1, unsigned) * Int(operand2, unsigned)); - - X[d] = result[63:0]; - -__instruction aarch64_integer_conditional_select - __encoding aarch64_integer_conditional_select - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field o2 10 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xx011010 100xxxxx xxxx0xxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - bits(4) condition = cond; - boolean else_inv = (op == '1'); - boolean else_inc = (o2 == '1'); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - - if ConditionHolds(condition) then - result = operand1; - else - result = operand2; - if else_inv then result = NOT(result); - if else_inc then result = result + 1; - - X[d] = result; - -__instruction aarch64_vector_reduce_fp16_maxnm_sisd - __encoding aarch64_vector_reduce_fp16_maxnm_sisd - __instruction_set A64 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 xx110000 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - if sz == '1' then UNDEFINED; - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM; - - __encoding aarch64_vector_reduce_fp_maxnm_sisd - __instruction_set A64 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 xx110000 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction FCMLA_Z_P_ZZZ__ - __encoding FCMLA_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field rot 13 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 xx0xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - integer sel_a = UInt(rot[0]); - integer sel_b = UInt(NOT(rot[0])); - boolean neg_i = (rot[1] == '1'); - boolean neg_r = (rot[0] != rot[1]); - - __execute - CheckSVEEnabled(); - integer pairs = VL DIV (2 * esize); - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for p = 0 to pairs-1 - addend_r = Elem[operand3, 2 * p + 0, esize]; - addend_i = Elem[operand3, 2 * p + 1, esize]; - elt1_a = Elem[operand1, 2 * p + sel_a, esize]; - elt2_a = Elem[operand2, 2 * p + sel_a, esize]; - elt2_b = Elem[operand2, 2 * p + sel_b, esize]; - if ElemP[mask, 2 * p + 0, esize] == '1' then - if neg_r then elt2_a = FPNeg(elt2_a); - addend_r = FPMulAdd(addend_r, elt1_a, elt2_a, FPCR); - if ElemP[mask, 2 * p + 1, esize] == '1' then - if neg_i then elt2_b = FPNeg(elt2_b); - addend_i = FPMulAdd(addend_i, elt1_a, elt2_b, FPCR); - Elem[result, 2 * p + 0, esize] = addend_r; - Elem[result, 2 * p + 1, esize] = addend_i; - - Z[da] = result; - -__instruction aarch64_vector_arithmetic_unary_add_pairwise - __encoding aarch64_vector_arithmetic_unary_add_pairwise - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 0x1010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV (2*esize); - boolean acc = (op == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - bits(2*esize) sum; - integer op1; - integer op2; - - if acc then result = V[d]; - for e = 0 to elements-1 - op1 = Int(Elem[operand, 2*e+0, esize], unsigned); - op2 = Int(Elem[operand, 2*e+1, esize], unsigned); - sum = (op1 + op2)[2*esize-1:0]; - if acc then - Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + sum; - else - Elem[result, e, 2*esize] = sum; - - V[d] = result; - -__instruction LD3H_Z_P_BI_Contiguous - __encoding LD3H_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1100xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction SMIN_Z_ZI__ - __encoding SMIN_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx101010 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - boolean unsigned = FALSE; - integer imm = Int(imm8, unsigned); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - Elem[result, e, esize] = Min(element1, imm)[esize-1:0]; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_pair - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_pair - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 1010x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - integer element1; - integer element2; - integer maxmin; - - for e = 0 to elements-1 - element1 = Int(Elem[concat, 2*e, esize], unsigned); - element2 = Int(Elem[concat, (2*e)+1, esize], unsigned); - maxmin = if minimum then Min(element1, element2) else Max(element1, element2); - Elem[result, e, esize] = maxmin[esize-1:0]; - - V[d] = result; - -__instruction aarch64_vector_crypto_sm4_sm4enc - __encoding aarch64_vector_crypto_sm4_sm4enc - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 11000000 100001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSM4Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vn = V[n]; - bits(32) intval; - bits(8) sboxout; - bits(128) roundresult; - bits(32) roundkey; - - roundresult=V[d]; - for index = 0 to 3 - roundkey = Elem[Vn,index,32]; - - intval = roundresult[127:96] EOR roundresult[95:64] EOR roundresult[63:32] EOR roundkey; - - for i = 0 to 3 - Elem[intval,i,8] = Sbox(Elem[intval,i,8]); - - intval = intval EOR ROL(intval,2) EOR ROL(intval,10) EOR ROL(intval,18) EOR ROL(intval,24); - intval = intval EOR roundresult[31:0]; - - roundresult[31:0] = roundresult[63:32]; - roundresult[63:32] = roundresult[95:64]; - roundresult[95:64] = roundresult[127:96]; - roundresult[127:96] = intval; - V[d] = roundresult; - -__instruction aarch64_vector_arithmetic_binary_uniform_mat_mul_int_usdot - __encoding aarch64_vector_arithmetic_binary_uniform_mat_mul_int_usdot - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 100xxxxx 100111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveInt8MatMulExt() then UNDEFINED; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 32; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - - for e = 0 to elements-1 - bits(32) res = Elem[operand3, e, 32]; - for b = 0 to 3 - integer element1 = UInt(Elem[operand1, 4 * e + b, 8]); - integer element2 = SInt(Elem[operand2, 4 * e + b, 8]); - res = res + element1 * element2; - Elem[result, e, 32] = res; - - V[d] = result; - -__instruction ST4H_Z_P_BI_Contiguous - __encoding ST4H_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 1111xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction aarch64_vector_arithmetic_unary_special_sqrt_est_int - __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_int - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 1x100001 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz == '1' then UNDEFINED; - integer esize = 32; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(32) element; - - for e = 0 to elements-1 - element = Elem[operand, e, 32]; - Elem[result, e, 32] = UnsignedRSqrtEstimate(element); - - V[d] = result; - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction WHILELO_P_P_RR__ - __encoding WHILELO_P_P_RR__ - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field sf 12 +: 1 - __field Rn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx1xxxxx 000x11xx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer rsize = 32 << UInt(sf); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Pd); - boolean unsigned = TRUE; - SVECmp op = Cmp_LT; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = Ones(PL); - bits(rsize) operand1 = X[n]; - bits(rsize) operand2 = X[m]; - bits(PL) result; - boolean last = TRUE; - - for e = 0 to elements-1 - boolean cond; - case op of - when Cmp_LT cond = (Int(operand1, unsigned) < Int(operand2, unsigned)); - when Cmp_LE cond = (Int(operand1, unsigned) <= Int(operand2, unsigned)); - - last = last && cond; - ElemP[result, e, esize] = if last then '1' else '0'; - operand1 = operand1 + 1; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_vector_shift_left_sisd - __encoding aarch64_vector_shift_left_sisd - __instruction_set A64 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 0xxxxxxx 010101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = UInt(immh:immb) - esize; - - __encoding aarch64_vector_shift_left_simd - __instruction_set A64 - __field Q 30 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 0xxxxxxx 010101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = UInt(immh:immb) - esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - for e = 0 to elements-1 - Elem[result, e, esize] = LSL(Elem[operand, e, esize], shift); - - V[d] = result; - -__instruction LASTA_R_P_Z__ - __encoding LASTA_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00000101 xx100000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer rsize = if esize < 64 then 32 else 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Rd); - boolean isBefore = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(rsize) result; - integer last = LastActiveElement(mask, esize); - - if isBefore then - if last < 0 then last = elements - 1; - else - last = last + 1; - if last >= elements then last = 0; - result = ZeroExtend(Elem[operand, last, esize]); - - X[d] = result; - -__instruction aarch64_vector_shift_left_sat_sisd - __encoding aarch64_vector_shift_left_sat_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 011x01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = esize; - integer elements = 1; - - integer shift = UInt(immh:immb) - esize; - - boolean src_unsigned; - boolean dst_unsigned; - case op:U of - when '00' UNDEFINED; - when '01' src_unsigned = FALSE; dst_unsigned = TRUE; - when '10' src_unsigned = FALSE; dst_unsigned = FALSE; - when '11' src_unsigned = TRUE; dst_unsigned = TRUE; - - __encoding aarch64_vector_shift_left_sat_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 011x01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = UInt(immh:immb) - esize; - - boolean src_unsigned; - boolean dst_unsigned; - case op:U of - when '00' UNDEFINED; - when '01' src_unsigned = FALSE; dst_unsigned = TRUE; - when '10' src_unsigned = FALSE; dst_unsigned = FALSE; - when '11' src_unsigned = TRUE; dst_unsigned = TRUE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = Int(Elem[operand, e, esize], src_unsigned) << shift; - (Elem[result, e, esize], sat) = SatQ(element, esize, dst_unsigned); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_integer_shift_variable - __encoding aarch64_integer_shift_variable - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field op2 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011010 110xxxxx 0010xxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - ShiftType shift_type = DecodeShift(op2); - - __execute - bits(datasize) result; - bits(datasize) operand2 = X[m]; - - result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize); - X[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp16_sisd - __instruction_set A64 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 00xxxxxx 0x01x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer index = UInt(H:L:M); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - boolean sub_op = (o2 == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 1xxxxxxx 0x01x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi = M; - case sz:L of - when '0x' index = UInt(H:L); - when '10' index = UInt(H); - when '11' UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - boolean sub_op = (o2 == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 00xxxxxx 0x01x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer index = UInt(H:L:M); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (o2 == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 1xxxxxxx 0x01x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi = M; - case sz:L of - when '0x' index = UInt(H:L); - when '10' index = UInt(H); - when '11' UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2 = Elem[operand2, index, esize]; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR); - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 101101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' || size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean rounding = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 101101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' || size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean rounding = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer round_const = if rounding then 1 << (esize - 1) else 0; - integer element1; - integer element2; - integer product; - boolean sat; - - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - element2 = SInt(Elem[operand2, e, esize]); - product = (2 * element1 * element2) + round_const; - (Elem[result, e, esize], sat) = SignedSatQ(product >> esize, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction aarch64_vector_arithmetic_binary_uniform_add_saturating_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_add_saturating_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 000011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_add_saturating_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 000011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer sum; - boolean sat; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - sum = element1 + element2; - (Elem[result, e, esize], sat) = SatQ(sum, esize, unsigned); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_branch_unconditional_eret - __encoding aarch64_branch_unconditional_eret - __instruction_set A64 - __field A 11 +: 1 - __field M 10 +: 1 - __field Rn 5 +: 5 - __field op4 0 +: 5 - __opcode '11010110 10011111 0000xxxx xxxxxxxx' - __guard TRUE - __decode - if PSTATE.EL == EL0 then UNDEFINED; - boolean pac = (A == '1'); - boolean use_key_a = (M == '0'); - - if !pac && op4 != '00000' then - UNDEFINED; - elsif pac && (!HavePACExt() || op4 != '11111') then - UNDEFINED; - - if Rn != '11111' then - UNDEFINED; - - __execute - AArch64.CheckForERetTrap(pac, use_key_a); - bits(64) target = ELR[]; - boolean auth_then_branch = TRUE; - - if pac then - if use_key_a then - target = AuthIA(ELR[], SP[], auth_then_branch); - else - target = AuthIB(ELR[], SP[], auth_then_branch); - - AArch64.ExceptionReturn(target, SPSR[]); - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_fp16_fused - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_fused - __instruction_set A64 - __field Q 30 +: 1 - __field a 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 x10xxxxx 000011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (a == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_fused - __instruction_set A64 - __field Q 30 +: 1 - __field op 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 110011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR); - - V[d] = result; - -__instruction INDEX_Z_RI__ - __encoding INDEX_Z_RI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm5 16 +: 5 - __field Rn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 010001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Rn); - integer d = UInt(Zd); - integer imm = SInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(esize) operand1 = X[n]; - integer element1 = SInt(operand1); - bits(VL) result; - - for e = 0 to elements-1 - integer index = element1 + e * imm; - Elem[result, e, esize] = index[esize-1:0]; - - Z[d] = result; - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_integer_arithmetic_cnt - __encoding aarch64_integer_arithmetic_cnt - __instruction_set A64 - __field sf 31 +: 1 - __field op 10 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x1011010 11000000 00010xxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - CountOp opcode = if op == '0' then CountOp_CLZ else CountOp_CLS; - - __execute - integer result; - bits(datasize) operand1 = X[n]; - - if opcode == CountOp_CLZ then - result = CountLeadingZeroBits(operand1); - else - result = CountLeadingSignBits(operand1); - - X[d] = result[datasize-1:0]; - -__instruction DUP_Z_Zi__ - __encoding DUP_Z_Zi__ - __instruction_set A64 - __field imm2 22 +: 2 - __field tsz 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx1xxxxx 001000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - bits(7) imm = imm2:tsz; - case tsz of - when '00000' UNDEFINED; - when '10000' esize = 128; index = UInt(imm[6:5]); - when 'x1000' esize = 64; index = UInt(imm[6:4]); - when 'xx100' esize = 32; index = UInt(imm[6:3]); - when 'xxx10' esize = 16; index = UInt(imm[6:2]); - when 'xxxx1' esize = 8; index = UInt(imm[6:1]); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) result; - bits(esize) element; - - if index >= elements then - element = Zeros(); - else - element = Elem[operand1, index, esize]; - result = Replicate(element); - - Z[d] = result; - -__instruction FRSQRTS_Z_ZZ__ - __encoding FRSQRTS_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx0xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPRSqrtStepFused(element1, element2); - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_single - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_single - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer maxmin; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - maxmin = if minimum then Min(element1, element2) else Max(element1, element2); - Elem[result, e, esize] = maxmin[esize-1:0]; - - V[d] = result; - -__instruction LD3H_Z_P_BR_Contiguous - __encoding LD3H_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 110xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction STR_P_BI__ - __encoding STR_P_BI__ - __instruction_set A64 - __field imm9h 16 +: 6 - __field imm9l 10 +: 3 - __field Rn 5 +: 5 - __field Pt 0 +: 4 - __opcode '11100101 10xxxxxx 000xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Pt); - integer n = UInt(Rn); - integer imm = SInt(imm9h:imm9l); - - __execute - CheckSVEEnabled(); - integer elements = PL DIV 8; - bits(PL) src; - bits(64) base; - integer offset = imm * elements; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - src = P[t]; - boolean aligned = AArch64.CheckAlignment(base + offset, 2, AccType_NORMAL, TRUE); - for e = 0 to elements-1 - AArch64.MemSingle[base + offset, 1, AccType_NORMAL, aligned] = Elem[src, e, 8]; - offset = offset + 1; - -__instruction MOVPRFX_Z_P_Z__ - __encoding MOVPRFX_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field M 16 +: 1 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx01000x 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean merging = (M == '1'); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) dest = Z[d]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = element; - elsif merging then - Elem[result, e, esize] = Elem[dest, e, esize]; - else - Elem[result, e, esize] = Zeros(); - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 001101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_1985 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - - if minimum then - Elem[result, e, esize] = FPMin(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMax(element1, element2, FPCR); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_int - __encoding aarch64_vector_arithmetic_binary_element_mul_int - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 xxxxxxxx 1000x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - bits(esize) product; - - element2 = UInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = UInt(Elem[operand1, e, esize]); - product = (element1 * element2)[esize-1:0]; - Elem[result, e, esize] = product; - - V[d] = result; - -__instruction FMAX_Z_P_ZS__ - __encoding FMAX_Z_P_ZS__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field i1 5 +: 1 - __field Zdn 0 +: 5 - __opcode '01100101 xx011110 100xxx00 00xxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - bits(esize) imm = if i1 == '0' then Zeros() else FPOne('0'); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMax(element1, imm, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction aarch64_integer_crc - __encoding aarch64_integer_crc - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field C 12 +: 1 - __field sz 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011010 110xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveCRCExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sf == '1' && sz != '11' then UNDEFINED; - if sf == '0' && sz == '11' then UNDEFINED; - integer size = 8 << UInt(sz); // 2-bit size field -> 8, 16, 32, 64 - boolean crc32c = (C == '1'); - - __execute - bits(32) acc = X[n]; // accumulator - bits(size) val = X[m]; // input value - bits(32) poly = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)[31:0]; - - bits(32+size) tempacc = BitReverse(acc) : Zeros(size); - bits(size+32) tempval = BitReverse(val) : Zeros(32); - - // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation - X[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly)); - -__instruction SUDOT_Z_ZZZi_S - __encoding SUDOT_Z_ZZZi_S - __instruction_set A64 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000100 101xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveInt8MatMulExt() then UNDEFINED; - integer esize = 32; - integer index = UInt(i2); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer eltspersegment = 128 DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = segmentbase + index; - bits(esize) res = Elem[operand3, e, esize]; - for i = 0 to 3 - integer element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - integer element2 = UInt(Elem[operand2, 4 * s + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = res; - - Z[da] = result; - -__instruction ST4W_Z_P_BR_Contiguous - __encoding ST4W_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 011xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction ZIP2_P_PP__ - __encoding ZIP2_P_PP__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 16 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00000101 xx10xxxx 0100010x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - integer part = 1; - - __encoding ZIP1_P_PP__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 16 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00000101 xx10xxxx 0100000x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - integer part = 0; - - __execute - CheckSVEEnabled(); - integer pairs = VL DIV (esize * 2); - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - integer base = part * pairs; - for p = 0 to pairs-1 - Elem[result, 2*p+0, esize DIV 8] = Elem[operand1, base+p, esize DIV 8]; - Elem[result, 2*p+1, esize DIV 8] = Elem[operand2, base+p, esize DIV 8]; - - P[d] = result; - -__instruction aarch64_vector_crypto_sm3_sm3tt1a - __encoding aarch64_vector_crypto_sm3_sm3tt1a - __instruction_set A64 - __field Rm 16 +: 5 - __field imm2 12 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 010xxxxx 10xx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSM3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer i = UInt(imm2); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) Vd = V[d]; - bits(32) WjPrime; - bits(128) result; - bits(32) TT1; - bits(32) SS2; - - WjPrime = Elem[Vm,i,32]; - SS2 = Vn[127:96] EOR ROL(Vd[127:96],12); - TT1 = Vd[63:32] EOR (Vd[127:96] EOR Vd[95:64]); - TT1 = (TT1 + Vd[31:0] + SS2 + WjPrime)[31:0]; - result[31:0] = Vd[63:32]; - result[63:32] = ROL(Vd[95:64],9); - result[95:64] = Vd[127:96]; - result[127:96] = TT1; - V[d] = result; - -__instruction ASR_Z_ZW__ - __encoding ASR_Z_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 100000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(64) element2 = Elem[operand2, (e * esize) DIV 64, 64]; - integer shift = Min(UInt(element2), esize); - Elem[result, e, esize] = ASR(element1, shift); - - Z[d] = result; - -__instruction FADD_Z_P_ZZ__ - __encoding FADD_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx000000 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPAdd(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction SUB_Z_ZI__ - __encoding SUB_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx100001 11xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer imm = UInt(imm8); - if sh == '1' then imm = imm << 8; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - Elem[result, e, esize] = element1 - imm; - - Z[dn] = result; - -__instruction LSR_Z_P_ZW__ - __encoding LSR_Z_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx011001 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(64) element2 = Elem[operand2, (e * esize) DIV 64, 64]; - integer shift = Min(UInt(element2), esize); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = LSR(element1, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_unpriv - __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - - unpriv_at_el1 = PSTATE.EL == EL1 && !(EL2Enabled() && HaveNVExt() && HCR_EL2.[NV,NV1] == '11'); - unpriv_at_el2 = PSTATE.EL == EL2 && HaveVirtHostExt() && HCR_EL2.[E2H,TGE] == '11'; - - user_access_override = HaveUAOExt() && PSTATE.UAO == '1'; - if !user_access_override && (unpriv_at_el1 || unpriv_at_el2) then - acctype = AccType_UNPRIV; - else - acctype = AccType_NORMAL; - - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_diff - __encoding aarch64_vector_arithmetic_binary_uniform_diff - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0111x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean accumulate = (ac == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - bits(esize) absdiff; - - result = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - absdiff = Abs(element1 - element2)[esize-1:0]; - Elem[result, e, esize] = Elem[result, e, esize] + absdiff; - V[d] = result; - -__instruction EOR_Z_ZZ__ - __encoding EOR_Z_ZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 101xxxxx 001100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - - Z[d] = operand1 EOR operand2; - -__instruction aarch64_vector_shift_right_narrow_uniform_sisd - __encoding aarch64_vector_shift_right_narrow_uniform_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 1001x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then UNDEFINED; - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_shift_right_narrow_uniform_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 1001x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize*2) operand = V[n]; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = (Int(Elem[operand, e, 2*esize], unsigned) + round_const) >> shift; - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - - Vpart[d, part] = result; - -__instruction ABS_Z_P_Z__ - __encoding ABS_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx010110 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - integer element = SInt(Elem[operand, e, esize]); - if ElemP[mask, e, esize] == '1' then - element = Abs(element); - Elem[result, e, esize] = element[esize-1:0]; - - Z[d] = result; - -__instruction SQDECH_Z_ZS__ - __encoding SQDECH_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 0110xxxx 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_integer_arithmetic_mul_widening_32_64 - __encoding aarch64_integer_arithmetic_mul_widening_32_64 - __instruction_set A64 - __field U 23 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '10011011 x01xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer a = UInt(Ra); - integer destsize = 64; - integer datasize = 32; - boolean sub_op = (o0 == '1'); - boolean unsigned = (U == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(destsize) operand3 = X[a]; - - integer result; - - if sub_op then - result = Int(operand3, unsigned) - (Int(operand1, unsigned) * Int(operand2, unsigned)); - else - result = Int(operand3, unsigned) + (Int(operand1, unsigned) * Int(operand2, unsigned)); - - X[d] = result[63:0]; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction LDNF1B_Z_P_BI_U8 - __encoding LDNF1B_Z_P_BI_U8 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0001xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LDNF1B_Z_P_BI_U16 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0011xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LDNF1B_Z_P_BI_U32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0101xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LDNF1B_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0111xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_single - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_single - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer maxmin; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - maxmin = if minimum then Min(element1, element2) else Max(element1, element2); - Elem[result, e, esize] = maxmin[esize-1:0]; - - V[d] = result; - -__instruction aarch64_integer_arithmetic_mul_uniform_add_sub - __encoding aarch64_integer_arithmetic_mul_uniform_add_sub - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011011 000xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer a = UInt(Ra); - integer destsize = if sf == '1' then 64 else 32; - integer datasize = destsize; - boolean sub_op = (o0 == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(destsize) operand3 = X[a]; - - integer result; - - if sub_op then - result = UInt(operand3) - (UInt(operand1) * UInt(operand2)); - else - result = UInt(operand3) + (UInt(operand1) * UInt(operand2)); - - X[d] = result[destsize-1:0]; - -__instruction LD4D_Z_P_BR_Contiguous - __encoding LD4D_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 111xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_transfer_vector_permute_transpose - __encoding aarch64_vector_transfer_vector_permute_transpose - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx0xxxxx 0x1010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer part = UInt(op); - integer pairs = elements DIV 2; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - for p = 0 to pairs-1 - Elem[result, 2*p+0, esize] = Elem[operand1, 2*p+part, esize]; - Elem[result, 2*p+1, esize] = Elem[operand2, 2*p+part, esize]; - - V[d] = result; - -__instruction aarch64_branch_unconditional_register - __encoding aarch64_branch_unconditional_register - __instruction_set A64 - __field Z 24 +: 1 - __field op 21 +: 2 - __field A 11 +: 1 - __field M 10 +: 1 - __field Rn 5 +: 5 - __field Rm 0 +: 5 - __opcode '1101011x 0xx11111 0000xxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - BranchType branch_type; - integer m = UInt(Rm); - boolean pac = (A == '1'); - boolean use_key_a = (M == '0'); - boolean source_is_sp = ((Z == '1') && (m == 31)); - - if !pac && m != 0 then - UNDEFINED; - elsif pac && !HavePACExt() then - UNDEFINED; - - case op of - when '00' branch_type = BranchType_INDIR; - when '01' branch_type = BranchType_INDCALL; - when '10' branch_type = BranchType_RET; - otherwise UNDEFINED; - - if pac then - if Z == '0' && m != 31 then - UNDEFINED; - - if branch_type == BranchType_RET then - if n != 31 then UNDEFINED; - n = 30; - source_is_sp = TRUE; - - __execute - bits(64) target = X[n]; - boolean auth_then_branch = TRUE; - - if pac then - bits(64) modifier = if source_is_sp then SP[] else X[m]; - - if use_key_a then - target = AuthIA(target, modifier, auth_then_branch); - else - target = AuthIB(target, modifier, auth_then_branch); - - if branch_type == BranchType_INDCALL then X[30] = PC[] + 4; - - // Value in BTypeNext will be used to set PSTATE.BTYPE - case branch_type of - when BranchType_INDIR // BR, BRAA, BRAB, BRAAZ, BRABZ - if InGuardedPage then - if n == 16 || n == 17 then - BTypeNext = '01'; - else - BTypeNext = '11'; - else - BTypeNext = '01'; - when BranchType_INDCALL // BLR, BLRAA, BLRAB, BLRAAZ, BLRABZ - BTypeNext = '10'; - when BranchType_RET // RET, RETAA, RETAB - BTypeNext = '00'; - - BranchTo(target, branch_type); - -__instruction aarch64_vector_arithmetic_unary_cmp_fp16_lessthan_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_lessthan_sisd - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 11111000 111010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - CompareOp comparison = CompareOp_LT; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_lessthan_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 1x100000 111010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison = CompareOp_LT; - - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_lessthan_simd - __instruction_set A64 - __field Q 30 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 11111000 111010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison = CompareOp_LT; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_lessthan_simd - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 1x100000 111010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison = CompareOp_LT; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) zero = FPZero('0'); - bits(esize) element; - boolean test_passed; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - case comparison of - when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR); - when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR); - when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR); - when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_vector_crypto_sha3op_sha1_hash_choose - __encoding aarch64_vector_crypto_sha3op_sha1_hash_choose - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 000xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if !HaveSHA1Ext() then UNDEFINED; - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) X = V[d]; - bits(32) Y = V[n]; // Note: 32 not 128 bits wide - bits(128) W = V[m]; - bits(32) t; - - for e = 0 to 3 - t = SHAchoose(X[63:32], X[95:64], X[127:96]); - Y = Y + ROL(X[31:0], 5) + t + Elem[W, e, 32]; - X[63:32] = ROL(X[63:32], 30); - [Y, X] = ROL(Y : X, 32); - V[d] = X; - -__instruction LD1ROH_Z_P_BI_U16 - __encoding LD1ROH_Z_P_BI_U16 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1010xxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - if VL < 256 then UNDEFINED; - integer elements = 256 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low bits only - bits(256) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * 32; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = ZeroExtend(Replicate(result, VL DIV 256), VL); - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_integer_pac_pacga_dp_2src - __encoding aarch64_integer_pac_pacga_dp_2src - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '10011010 110xxxxx 001100xx xxxxxxxx' - __guard TRUE - __decode - boolean source_is_sp = FALSE; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if !HavePACExt() then - UNDEFINED; - - if m == 31 then source_is_sp = TRUE; - - __execute - if source_is_sp then - X[d] = AddPACGA(X[n], SP[]); - else - X[d] = AddPACGA(X[n], X[m]); - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_double_sisd - __encoding aarch64_vector_arithmetic_binary_disparate_mul_double_sisd - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 xx1xxxxx 110100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '00' || size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - __encoding aarch64_vector_arithmetic_binary_disparate_mul_double_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 110100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '00' || size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - boolean sat; - - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - element2 = SInt(Elem[operand2, e, esize]); - (product, sat) = SignedSatQ(2 * element1 * element2, 2*esize); - Elem[result, e, 2*esize] = product; - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_post_idx - __encoding aarch64_memory_single_general_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction SMIN_Z_P_ZZ__ - __encoding SMIN_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx001010 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer minimum = Min(element1, element2); - Elem[result, e, esize] = minimum[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_long - __encoding aarch64_vector_arithmetic_binary_element_mul_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 xxxxxxxx 1010x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(idxdsize) operand2 = V[m]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - - element2 = Int(Elem[operand2, index, esize], unsigned); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - Elem[result, e, 2*esize] = product; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_add_saturating_sisd - __encoding aarch64_vector_arithmetic_unary_add_saturating_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 001110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_add_saturating_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 001110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - bits(datasize) operand2 = V[d]; - integer op1; - integer op2; - boolean sat; - - for e = 0 to elements-1 - op1 = Int(Elem[operand, e, esize], !unsigned); - op2 = Int(Elem[operand2, e, esize], unsigned); - (Elem[result, e, esize], sat) = SatQ(op1 + op2, esize, unsigned); - if sat then FPSR.QC = '1'; - V[d] = result; - -__instruction aarch64_memory_vector_multiple_no_wb - __encoding aarch64_memory_vector_multiple_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 0x000000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_multiple_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << UInt(size); - integer elements = datasize DIV esize; - - integer rpt; // number of iterations - integer selem; // structure elements - - case opcode of - when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers) - when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers) - when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers) - when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers) - when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register) - when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers) - when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers) - otherwise UNDEFINED; - - // .1D format only permitted with LD1 & ST1 - if size:Q == '110' && selem != 1 then UNDEFINED; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(datasize) rval; - integer tt; - constant integer ebytes = esize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - for r = 0 to rpt-1 - for e = 0 to elements-1 - tt = (t + r) MOD 32; - for s = 0 to selem-1 - rval = V[tt]; - if memop == MemOp_LOAD then - Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[tt] = rval; - else // memop == MemOp_STORE - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize]; - offs = offs + ebytes; - tt = (tt + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_wide - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_wide - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 00x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand1 = V[n]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, 2*esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - Elem[result, e, 2*esize] = sum[2*esize-1:0]; - - V[d] = result; - -__instruction BFMLALT_Z_ZZZ__ - __encoding BFMLALT_Z_ZZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 111xxxxx 100001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 32; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(32) element1 = Elem[operand1, 2 * e + 1, 16] : Zeros(16); - bits(32) element2 = Elem[operand2, 2 * e + 1, 16] : Zeros(16); - bits(32) element3 = Elem[operand3, e, 32]; - Elem[result, e, 32] = FPMulAdd(element3, element1, element2, FPCR); - - Z[da] = result; - -__instruction STNT1B_Z_P_BR_Contiguous - __encoding STNT1B_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 000xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(64) offset = X[m]; - bits(VL) src; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - src = Z[t]; - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_STREAM] = Elem[src, e, esize]; - offset = offset + 1; - -__instruction SUB_Z_P_ZZ__ - __encoding SUB_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx000001 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = element1 - element2; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_pair - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_pair - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 1010x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - integer element1; - integer element2; - integer maxmin; - - for e = 0 to elements-1 - element1 = Int(Elem[concat, 2*e, esize], unsigned); - element2 = Int(Elem[concat, (2*e)+1, esize], unsigned); - maxmin = if minimum then Min(element1, element2) else Max(element1, element2); - Elem[result, e, esize] = maxmin[esize-1:0]; - - V[d] = result; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_vector_arithmetic_binary_uniform_shift_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - if S == '0' && size != '11' then UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer round_const = 0; - integer shift; - integer element; - boolean sat; - - for e = 0 to elements-1 - shift = SInt(Elem[operand2, e, esize][7:0]); - if rounding then - round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift - element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift; - if saturating then - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - else - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_diff - __encoding aarch64_vector_arithmetic_binary_disparate_diff - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 01x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean accumulate = (op == '0'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) absdiff; - - result = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - absdiff = Abs(element1 - element2)[2*esize-1:0]; - Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + absdiff; - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_double_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_double_sisd - __instruction_set A64 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 xxxxxxxx 1011x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - __encoding aarch64_vector_arithmetic_binary_element_mul_double_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 xxxxxxxx 1011x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) operand1 = Vpart[n, part]; - bits(idxdsize) operand2 = V[m]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - boolean sat; - - element2 = SInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - (product, sat) = SignedSatQ(2 * element1 * element2, 2*esize); - Elem[result, e, 2*esize] = product; - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction FMAXNM_Z_P_ZS__ - __encoding FMAXNM_Z_P_ZS__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field i1 5 +: 1 - __field Zdn 0 +: 5 - __opcode '01100101 xx011100 100xxx00 00xxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - bits(esize) imm = if i1 == '0' then Zeros() else FPOne('0'); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMaxNum(element1, imm, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction aarch64_integer_ins_ext_extract_immediate - __encoding aarch64_integer_ins_ext_extract_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field N 22 +: 1 - __field Rm 16 +: 5 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0010011 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - integer lsb; - - if N != sf then UNDEFINED; - if sf == '0' && imms[5] == '1' then UNDEFINED; - lsb = UInt(imms); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(2*datasize) concat = operand1:operand2; - - result = concat[lsb+datasize-1:lsb]; - - X[d] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction ST1H_Z_P_BI__ - __encoding ST1H_Z_P_BI__ - __instruction_set A64 - __field size 21 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 1xx0xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8 << UInt(size); - integer msize = 16; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) src = Z[t]; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - addr = addr + mbytes; - -__instruction FMLA_Z_ZZZi_H - __encoding FMLA_Z_ZZZi_H - __instruction_set A64 - __field i3h 22 +: 1 - __field i3l 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 0x1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer index = UInt(i3h:i3l); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = FALSE; - boolean op3_neg = FALSE; - - __encoding FMLA_Z_ZZZi_S - __instruction_set A64 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 101xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer index = UInt(i2); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = FALSE; - boolean op3_neg = FALSE; - - __encoding FMLA_Z_ZZZi_D - __instruction_set A64 - __field i1 20 +: 1 - __field Zm 16 +: 4 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 111xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer index = UInt(i1); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = FALSE; - boolean op3_neg = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer eltspersegment = 128 DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result = Z[da]; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = segmentbase + index; - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, s, esize]; - bits(esize) element3 = Elem[result, e, esize]; - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - - Z[da] = result; - -__instruction aarch64_vector_transfer_vector_table - __encoding aarch64_vector_transfer_vector_table - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field len 13 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 000xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 8; - integer regs = UInt(len) + 1; - boolean is_tbl = (op == '0'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) indices = V[m]; - bits(128*regs) table = Zeros(); - bits(datasize) result; - integer index; - - // Create table from registers - for i = 0 to regs - 1 - table[128*i+127:128*i] = V[n]; - n = (n + 1) MOD 32; - - result = if is_tbl then Zeros() else V[d]; - for i = 0 to elements - 1 - index = UInt(Elem[indices, i, 8]); - if index < 16 * regs then - Elem[result, i, 8] = Elem[table, index, 8]; - - V[d] = result; - -__instruction aarch64_vector_crypto_sha3_rax1 - __encoding aarch64_vector_crypto_sha3_rax1 - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 011xxxxx 100011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSHA3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - V[d] = Vn EOR (ROL(Vm[127:64],1):ROL(Vm[63:0], 1)); - -__instruction INSR_Z_V__ - __encoding INSR_Z_V__ - __instruction_set A64 - __field size 22 +: 2 - __field Vm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000101 xx110100 001110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer m = UInt(Vm); - - __execute - CheckSVEEnabled(); - bits(VL) dest = Z[dn]; - bits(esize) src = V[m]; - Z[dn] = dest[VL-esize-1:0] : src; - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_memory_exclusive_pair - __encoding aarch64_memory_exclusive_pair - __instruction_set A64 - __field sz 30 +: 1 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '1x001000 0x1xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = TRUE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 32 << UInt(sz); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_complex - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_complex - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field rot 13 +: 2 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 xxxxxxxx 0xx1x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFCADDExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(M:Rm); - if size == '00' || size == '11' then UNDEFINED; - if size == '01' then index = UInt(H:L); - if size == '10' then index = UInt(H); - integer esize = 8 << UInt(size); - if !HaveFP16Ext() && esize == 16 then UNDEFINED; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - if size == '10' && (L == '1' || Q == '0') then UNDEFINED; - if size == '01' && H == '1' && Q=='0' then UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - - for e = 0 to (elements DIV 2) -1 - case rot of - when '00' - element1 = Elem[operand2, index*2, esize]; - element2 = Elem[operand1, e*2, esize]; - element3 = Elem[operand2, index*2+1, esize]; - element4 = Elem[operand1, e*2, esize]; - when '01' - element1 = FPNeg(Elem[operand2, index*2+1, esize]); - element2 = Elem[operand1, e*2+1, esize]; - element3 = Elem[operand2, index*2, esize]; - element4 = Elem[operand1, e*2+1, esize]; - when '10' - element1 = FPNeg(Elem[operand2, index*2,esize]); - element2 = Elem[operand1, e*2, esize]; - element3 = FPNeg(Elem[operand2, index*2+1, esize]); - element4 = Elem[operand1, e*2, esize]; - when '11' - element1 = Elem[operand2, index*2+1, esize]; - element2 = Elem[operand1, e*2+1, esize]; - element3 = FPNeg(Elem[operand2, index*2, esize]); - element4 = Elem[operand1, e*2+1, esize]; - - Elem[result, e*2, esize] = FPMulAdd(Elem[operand3, e*2, esize], element2, element1, FPCR); - Elem[result, e*2+1, esize] = FPMulAdd(Elem[operand3, e*2+1, esize], element4, element3, FPCR); - - V[d] = result; - -__instruction FNMSB_Z_P_ZZZ__ - __encoding FNMSB_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Za 16 +: 5 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx1xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - integer a = UInt(Za); - boolean op1_neg = FALSE; - boolean op3_neg = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[a]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - bits(esize) element3 = Elem[operand3, e, esize]; - - if ElemP[mask, e, esize] == '1' then - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction PRFH_I_P_BR_S - __encoding PRFH_I_P_BR_S - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000100 100xxxxx 110xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer esize = 16; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 1; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) offset = X[m]; - bits(64) addr; - - if n == 31 then - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + (UInt(offset) << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - offset = offset + 1; - -__instruction aarch64_vector_arithmetic_binary_uniform_diff - __encoding aarch64_vector_arithmetic_binary_uniform_diff - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0111x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean accumulate = (ac == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - bits(esize) absdiff; - - result = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - absdiff = Abs(element1 - element2)[esize-1:0]; - Elem[result, e, esize] = Elem[result, e, esize] + absdiff; - V[d] = result; - -__instruction ST3D_Z_P_BI_Contiguous - __encoding ST3D_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 1101xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction FMAXNMV_V_P_Z__ - __encoding FMAXNMV_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '01100101 xx000100 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(esize) identity = FPDefaultNaN(); - - V[d] = ReducePredicated(ReduceOp_FMAXNUM, operand, mask, identity); - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction aarch64_vector_arithmetic_unary_extract_sat_sisd - __encoding aarch64_vector_arithmetic_unary_extract_sat_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 010010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer part = 0; - integer elements = 1; - - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_extract_sat_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 010010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand = V[n]; - bits(datasize) result; - bits(2*esize) element; - boolean sat; - - for e = 0 to elements-1 - element = Elem[operand, e, 2*esize]; - (Elem[result, e, esize], sat) = SatQ(Int(element, unsigned), esize, unsigned); - if sat then FPSR.QC = '1'; - - Vpart[d, part] = result; - -__instruction aarch64_vector_reduce_add_sisd - __encoding aarch64_vector_reduce_add_sisd - __instruction_set A64 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 xx110001 101110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size != '11' then UNDEFINED; - - integer esize = 8 << UInt(size); - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = ReduceOp_ADD; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction UDOT_Z_ZZZi_S - __encoding UDOT_Z_ZZZi_S - __instruction_set A64 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000100 101xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer index = UInt(i2); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __encoding UDOT_Z_ZZZi_D - __instruction_set A64 - __field i1 20 +: 1 - __field Zm 16 +: 4 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000100 111xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer index = UInt(i1); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer eltspersegment = 128 DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = segmentbase + index; - bits(esize) res = Elem[operand3, e, esize]; - for i = 0 to 3 - integer element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - integer element2 = UInt(Elem[operand2, 4 * s + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = res; - - Z[da] = result; - -__instruction aarch64_vector_crypto_sm4_sm4enckey - __encoding aarch64_vector_crypto_sm4_sm4enckey - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 011xxxxx 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSM4Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(32) intval; - bits(8) sboxout; - bits(128) result; - bits(32) const; - bits(128) roundresult; - - roundresult = V[n]; - for index = 0 to 3 - const = Elem[Vm,index,32]; - - intval = roundresult[127:96] EOR roundresult[95:64] EOR roundresult[63:32] EOR const; - - for i = 0 to 3 - Elem[intval,i,8] = Sbox(Elem[intval,i,8]); - - intval = intval EOR ROL(intval,13) EOR ROL(intval,23); - intval = intval EOR roundresult[31:0]; - - roundresult[31:0] = roundresult[63:32]; - roundresult[63:32] = roundresult[95:64]; - roundresult[95:64] = roundresult[127:96]; - roundresult[127:96] = intval; - V[d] = roundresult; - -__instruction aarch64_float_arithmetic_unary - __encoding aarch64_float_arithmetic_unary - __instruction_set A64 - __field ftype 22 +: 2 - __field opc 15 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx10000x x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - FPUnaryOp fpop; - case opc of - when '00' fpop = FPUnaryOp_MOV; - when '01' fpop = FPUnaryOp_ABS; - when '10' fpop = FPUnaryOp_NEG; - when '11' fpop = FPUnaryOp_SQRT; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - case fpop of - when FPUnaryOp_MOV result = operand; - when FPUnaryOp_ABS result = FPAbs(operand); - when FPUnaryOp_NEG result = FPNeg(operand); - when FPUnaryOp_SQRT result = FPSqrt(operand, FPCR); - - V[d] = result; - -__instruction ST3D_Z_P_BR_Contiguous - __encoding ST3D_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 110xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_long - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 xxxxxxxx 0x10x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(idxdsize) operand2 = V[m]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - - element2 = Int(Elem[operand2, index, esize], unsigned); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - if sub_op then - Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] - product; - else - Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] + product; - - V[d] = result; - -__instruction aarch64_memory_pair_general_post_idx - __encoding aarch64_memory_pair_general_post_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101000 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - - __encoding aarch64_memory_pair_general_pre_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101001 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - - __encoding aarch64_memory_pair_general_offset - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101001 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); - AccType acctype = AccType_NORMAL; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - if L:opc[0] == '01' || opc == '11' then UNDEFINED; - boolean signed = (opc[0] != '0'); - integer scale = 2 + UInt(opc[1]); - integer datasize = 8 << scale; - bits(64) offset = LSL(SignExtend(imm7, 64), scale); - boolean tag_checked = wback || n != 31; - __execute - bits(64) address; - bits(datasize) data1; - bits(datasize) data2; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - boolean wb_unknown = FALSE; - - if memop == MemOp_LOAD && wback && (t == n || t2 == n) && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && (t == n || t2 == n) && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is pre-writeback - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_LOAD && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown && t == n then - data1 = bits(datasize) UNKNOWN; - else - data1 = X[t]; - if rt_unknown && t2 == n then - data2 = bits(datasize) UNKNOWN; - else - data2 = X[t2]; - Mem[address + 0 , dbytes, acctype] = data1; - Mem[address + dbytes, dbytes, acctype] = data2; - - when MemOp_LOAD - data1 = Mem[address + 0 , dbytes, acctype]; - data2 = Mem[address + dbytes, dbytes, acctype]; - if rt_unknown then - data1 = bits(datasize) UNKNOWN; - data2 = bits(datasize) UNKNOWN; - if signed then - X[t] = SignExtend(data1, 64); - X[t2] = SignExtend(data2, 64); - else - X[t] = data1; - X[t2] = data2; - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_uniform_shift_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - if S == '0' && size != '11' then UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer round_const = 0; - integer shift; - integer element; - boolean sat; - - for e = 0 to elements-1 - shift = SInt(Elem[operand2, e, esize][7:0]); - if rounding then - round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift - element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift; - if saturating then - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - else - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_memory_pair_general_post_idx - __encoding aarch64_memory_pair_general_post_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101000 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - - __encoding aarch64_memory_pair_general_pre_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101001 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - - __encoding aarch64_memory_pair_general_offset - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101001 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); - AccType acctype = AccType_NORMAL; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - if L:opc[0] == '01' || opc == '11' then UNDEFINED; - boolean signed = (opc[0] != '0'); - integer scale = 2 + UInt(opc[1]); - integer datasize = 8 << scale; - bits(64) offset = LSL(SignExtend(imm7, 64), scale); - boolean tag_checked = wback || n != 31; - __execute - bits(64) address; - bits(datasize) data1; - bits(datasize) data2; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - boolean wb_unknown = FALSE; - - if memop == MemOp_LOAD && wback && (t == n || t2 == n) && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && (t == n || t2 == n) && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is pre-writeback - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_LOAD && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown && t == n then - data1 = bits(datasize) UNKNOWN; - else - data1 = X[t]; - if rt_unknown && t2 == n then - data2 = bits(datasize) UNKNOWN; - else - data2 = X[t2]; - Mem[address + 0 , dbytes, acctype] = data1; - Mem[address + dbytes, dbytes, acctype] = data2; - - when MemOp_LOAD - data1 = Mem[address + 0 , dbytes, acctype]; - data2 = Mem[address + dbytes, dbytes, acctype]; - if rt_unknown then - data1 = bits(datasize) UNKNOWN; - data2 = bits(datasize) UNKNOWN; - if signed then - X[t] = SignExtend(data1, 64); - X[t2] = SignExtend(data2, 64); - else - X[t] = data1; - X[t2] = data2; - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_unary_extract_sqxtun_sisd - __encoding aarch64_vector_arithmetic_unary_extract_sqxtun_sisd - __instruction_set A64 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 xx100001 001010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer part = 0; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_unary_extract_sqxtun_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx100001 001010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand = V[n]; - bits(datasize) result; - bits(2*esize) element; - boolean sat; - - for e = 0 to elements-1 - element = Elem[operand, e, 2*esize]; - (Elem[result, e, esize], sat) = UnsignedSatQ(SInt(element), esize); - if sat then FPSR.QC = '1'; - - Vpart[d, part] = result; - -__instruction aarch64_system_sysops - __encoding aarch64_system_sysops - __instruction_set A64 - __field L 21 +: 1 - __field op1 16 +: 3 - __field CRn 12 +: 4 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __field Rt 0 +: 5 - __opcode '11010101 00x01xxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - AArch64.CheckSystemAccess('01', op1, CRn, CRm, op2, Rt, L); - - integer t = UInt(Rt); - - integer sys_op0 = 1; - integer sys_op1 = UInt(op1); - integer sys_op2 = UInt(op2); - integer sys_crn = UInt(CRn); - integer sys_crm = UInt(CRm); - boolean has_result = (L == '1'); - - __execute - if has_result then - // No architecturally defined instructions here. - X[t] = AArch64.SysInstrWithResult(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2); - else - AArch64.SysInstr(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2, X[t]); - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction CPY_Z_O_I__ - __encoding CPY_Z_O_I__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 16 +: 4 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zd 0 +: 5 - __opcode '00000101 xx01xxxx 00xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer d = UInt(Zd); - boolean merging = FALSE; - integer imm = SInt(imm8); - if sh == '1' then imm = imm << 8; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) dest = Z[d]; - bits(VL) result; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = imm[esize-1:0]; - elsif merging then - Elem[result, e, esize] = Elem[dest, e, esize]; - else - Elem[result, e, esize] = Zeros(); - - Z[d] = result; - -__instruction REV_P_P__ - __encoding REV_P_P__ - __instruction_set A64 - __field size 22 +: 2 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00000101 xx110100 0100000x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Pn); - integer d = UInt(Pd); - - __execute - CheckSVEEnabled(); - bits(PL) operand = P[n]; - bits(PL) result = Reverse(operand, esize DIV 8); - P[d] = result; - -__instruction BIC_Z_ZZ__ - __encoding BIC_Z_ZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 111xxxxx 001100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - - Z[d] = operand1 AND (NOT operand2); - -__instruction aarch64_vector_transfer_integer_insert - __encoding aarch64_vector_transfer_integer_insert - __instruction_set A64 - __field imm5 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01001110 000xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer size = LowestSetBit(imm5); - - if size > 3 then UNDEFINED; - integer index = UInt(imm5[4:size+1]); - - integer esize = 8 << size; - integer datasize = 128; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(esize) element = X[n]; - bits(datasize) result; - - result = V[d]; - Elem[result, index, esize] = element; - V[d] = result; - -__instruction LDFF1SW_Z_P_BR_S64 - __encoding LDFF1SW_Z_P_BR_S64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 100xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + UInt(offset) * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_CNOTFIRST]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - offset = offset + 1; - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_single - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_single - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer maxmin; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - maxmin = if minimum then Min(element1, element2) else Max(element1, element2); - Elem[result, e, esize] = maxmin[esize-1:0]; - - V[d] = result; - -__instruction LD4B_Z_P_BI_Contiguous - __encoding LD4B_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0110xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_integer_logical_shiftedreg - __encoding aarch64_integer_logical_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field shift 22 +: 2 - __field N 21 +: 1 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01010 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - boolean invert = (N == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - X[d] = result; - -__instruction aarch64_memory_exclusive_pair - __encoding aarch64_memory_exclusive_pair - __instruction_set A64 - __field sz 30 +: 1 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '1x001000 0x1xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = TRUE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 32 << UInt(sz); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_int - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_int - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 xxxxxxxx 0x00x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - integer element1; - integer element2; - bits(esize) product; - - element2 = UInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = UInt(Elem[operand1, e, esize]); - product = (element1 * element2)[esize-1:0]; - if sub_op then - Elem[result, e, esize] = Elem[operand3, e, esize] - product; - else - Elem[result, e, esize] = Elem[operand3, e, esize] + product; - V[d] = result; - -__instruction aarch64_vector_crypto_sha3_eor3 - __encoding aarch64_vector_crypto_sha3_eor3 - __instruction_set A64 - __field Rm 16 +: 5 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 000xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSHA3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer a = UInt(Ra); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) Va = V[a]; - V[d] = Vn EOR Vm EOR Va; - -__instruction aarch64_vector_arithmetic_binary_uniform_div_fp16 - __encoding aarch64_vector_arithmetic_binary_uniform_div_fp16 - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 010xxxxx 001111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __encoding aarch64_vector_arithmetic_binary_uniform_div - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 0x1xxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPDiv(element1, element2, FPCR); - - V[d] = result; - -__instruction SQDECP_R_P_R_SX - __encoding SQDECP_R_P_R_SX - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101010 1000100x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQDECP_R_P_R_X - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101010 1000110x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(ssize) operand1 = X[dn]; - bits(PL) operand2 = P[m]; - bits(ssize) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - integer element = Int(operand1, unsigned); - (result, -) = SatQ(element - count, ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction PTEST__P_P__ - __encoding PTEST__P_P__ - __instruction_set A64 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __opcode '00100101 01010000 11xxxx0x xxx00000' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - - __execute - CheckSVEEnabled(); - bits(PL) mask = P[g]; - bits(PL) result = P[n]; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - -__instruction aarch64_integer_arithmetic_div - __encoding aarch64_integer_arithmetic_div - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field o1 10 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011010 110xxxxx 00001xxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean unsigned = (o1 == '0'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - integer result; - - if IsZero(operand2) then - result = 0; - else - result = RoundTowardsZero(Real(Int(operand1, unsigned)) / Real(Int(operand2, unsigned))); - - X[d] = result[datasize-1:0]; - -__instruction aarch64_system_exceptions_runtime_svc - __encoding aarch64_system_exceptions_runtime_svc - __instruction_set A64 - __field imm16 5 +: 16 - __opcode '11010100 000xxxxx xxxxxxxx xxx00001' - __guard TRUE - __decode - bits(16) imm = imm16; - - __execute - AArch64.CheckForSVCTrap(imm); - AArch64.CallSupervisor(imm); - -__instruction INCB_R_RS__ - __encoding INCB_R_RS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0011xxxx 111000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding INCD_R_RS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1111xxxx 111000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding INCH_R_RS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0111xxxx 111000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding INCW_R_RS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1011xxxx 111000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(64) operand1 = X[dn]; - - X[dn] = operand1 + (count * imm); - -__instruction LDFF1SH_Z_P_AI_S - __encoding LDFF1SH_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 101xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __encoding LDFF1SH_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 101xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction STNT1H_Z_P_BI_Contiguous - __encoding STNT1H_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 1001xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - constant integer mbytes = esize DIV 8; - bits(VL) src; - bits(PL) mask = P[g]; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - src = Z[t]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_STREAM] = Elem[src, e, esize]; - addr = addr + mbytes; - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_dmacc_sisd - __encoding aarch64_vector_arithmetic_binary_disparate_mul_dmacc_sisd - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 xx1xxxxx 10x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '00' || size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - boolean sub_op = (o1 == '1'); - - __encoding aarch64_vector_arithmetic_binary_disparate_mul_dmacc_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 10x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '00' || size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - integer accum; - boolean sat1; - boolean sat2; - - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - element2 = SInt(Elem[operand2, e, esize]); - (product, sat1) = SignedSatQ(2 * element1 * element2, 2*esize); - if sub_op then - accum = SInt(Elem[operand3, e, 2*esize]) - SInt(product); - else - accum = SInt(Elem[operand3, e, 2*esize]) + SInt(product); - (Elem[result, e, 2*esize], sat2) = SignedSatQ(accum, 2*esize); - if sat1 || sat2 then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_memory_ordered_rcpc - __encoding aarch64_memory_ordered_rcpc - __instruction_set A64 - __field size 30 +: 2 - __field Rs 16 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 101xxxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = AccType_ORDERED; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_reduce_int_max - __encoding aarch64_vector_reduce_int_max - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 16 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx11000x 101010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '100' then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean min = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - integer maxmin; - integer element; - - maxmin = Int(Elem[operand, 0, esize], unsigned); - for e = 1 to elements-1 - element = Int(Elem[operand, e, esize], unsigned); - maxmin = if min then Min(maxmin, element) else Max(maxmin, element); - - V[d] = maxmin[esize-1:0]; - -__instruction STR_Z_BI__ - __encoding STR_Z_BI__ - __instruction_set A64 - __field imm9h 16 +: 6 - __field imm9l 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 10xxxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer imm = SInt(imm9h:imm9l); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 8; - bits(VL) src; - bits(64) base; - integer offset = imm * elements; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - src = Z[t]; - boolean aligned = AArch64.CheckAlignment(base + offset, 16, AccType_NORMAL, TRUE); - for e = 0 to elements-1 - AArch64.MemSingle[base + offset, 1, AccType_NORMAL, aligned] = Elem[src, e, 8]; - offset = offset + 1; - -__instruction PRFH_I_P_AI_S - __encoding PRFH_I_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000100 100xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 1; - integer offset = UInt(imm5); - - __encoding PRFH_I_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 100xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 1; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) base; - bits(64) addr; - base = Z[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + (offset << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - -__instruction LD4B_Z_P_BR_Contiguous - __encoding LD4B_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 011xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction LD3B_Z_P_BR_Contiguous - __encoding LD3B_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 010xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_shift_conv_float_sisd - __encoding aarch64_vector_shift_conv_float_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then UNDEFINED; - integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16; - integer datasize = esize; - integer elements = 1; - - integer fracbits = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - FPRounding rounding = FPRounding_ZERO; - - __encoding aarch64_vector_shift_conv_float_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then UNDEFINED; - if immh[3]:Q == '10' then UNDEFINED; - integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer fracbits = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - FPRounding rounding = FPRounding_ZERO; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, fracbits, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction UQDECB_R_RS_UW - __encoding UQDECB_R_RS_UW - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0010xxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQDECB_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0011xxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 - (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction PRFH_I_P_BI_S - __encoding PRFH_I_P_BI_S - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000101 11xxxxxx 001xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 1; - integer offset = SInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) addr; - - if n == 31 then - base = SP[]; - else - base = X[n]; - - addr = base + ((offset * elements) << scale); - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Hint_Prefetch(addr, pref_hint, level, stream); - addr = addr + (1 << scale); - -__instruction aarch64_integer_tags_mcsettagandzeroarray - __encoding aarch64_integer_tags_mcsettagandzeroarray - __instruction_set A64 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 00100000 000000xx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Xt); - integer n = UInt(Xn); - - __execute - if PSTATE.EL == EL0 then - UNDEFINED; - - bits(64) data = X[t]; - bits(4) tag = data[3:0]; - bits(64) address; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - integer size = 4*(2^(UInt(DCZID_EL0.BS))); - address = Align(address,size); - integer count = size >> LOG2_TAG_GRANULE; - - for i = 0 to count-1 - AArch64.MemTag[address, AccType_NORMAL] = tag; - Mem[address, TAG_GRANULE, AccType_NORMAL] = Zeros(8*TAG_GRANULE); - address = address + TAG_GRANULE; - -__instruction ASRD_Z_P_ZI__ - __encoding ASRD_Z_P_ZI__ - __instruction_set A64 - __field tszh 22 +: 2 - __field Pg 10 +: 3 - __field tszl 8 +: 2 - __field imm3 5 +: 3 - __field Zdn 0 +: 5 - __opcode '00000100 xx000100 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - bits(4) tsize = tszh:tszl; - case tsize of - when '0000' UNDEFINED; - when '0001' esize = 8; - when '001x' esize = 16; - when '01xx' esize = 32; - when '1xxx' esize = 64; - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer shift = (2 * esize) - UInt(tsize:imm3); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = SInt(Elem[operand1, e, esize]); - if ElemP[mask, e, esize] == '1' then - if element1 < 0 then - element1 = element1 + ((1 << shift) - 1); - Elem[result, e, esize] = (element1 >> shift)[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_shift_right_narrow_logical - __encoding aarch64_vector_shift_right_narrow_logical - __instruction_set A64 - __field Q 30 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 0xxxxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize*2) operand = V[n]; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - for e = 0 to elements-1 - element = (UInt(Elem[operand, e, 2*esize]) + round_const) >> shift; - Elem[result, e, esize] = element[esize-1:0]; - - Vpart[d, part] = result; - -__instruction BRKB_P_P_P__ - __encoding BRKB_P_P_P__ - __instruction_set A64 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field M 4 +: 1 - __field Pd 0 +: 4 - __opcode '00100101 10010000 01xxxx0x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer d = UInt(Pd); - boolean merging = (M == '1'); - boolean setflags = FALSE; - - __encoding BRKBS_P_P_P_Z - __instruction_set A64 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 11010000 01xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer d = UInt(Pd); - boolean merging = FALSE; - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand = P[n]; - bits(PL) operand2 = P[d]; - boolean break = FALSE; - bits(PL) result; - - for e = 0 to elements-1 - boolean element = ElemP[operand, e, esize] == '1'; - if ElemP[mask, e, esize] == '1' then - break = break || element; - ElemP[result, e, esize] = if !break then '1' else '0'; - elsif merging then - ElemP[result, e, esize] = ElemP[operand2, e, esize]; - else - ElemP[result, e, esize] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction UMIN_Z_ZI__ - __encoding UMIN_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx101011 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - boolean unsigned = TRUE; - integer imm = Int(imm8, unsigned); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - Elem[result, e, esize] = Min(element1, imm)[esize-1:0]; - - Z[dn] = result; - -__instruction LD1ROB_Z_P_BR_Contiguous - __encoding LD1ROB_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 001xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - - __execute - CheckSVEEnabled(); - if VL < 256 then UNDEFINED; - integer elements = 256 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low bits only - bits(64) offset; - bits(256) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - offset = X[m]; - - addr = base + UInt(offset) * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = ZeroExtend(Replicate(result, VL DIV 256), VL); - -__instruction aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 11111000 110x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 1x100000 110x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 11111000 110x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 1x100000 110x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) zero = FPZero('0'); - bits(esize) element; - boolean test_passed; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - case comparison of - when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR); - when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR); - when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR); - when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction CNTB_R_S__ - __encoding CNTB_R_S__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rd 0 +: 5 - __opcode '00000100 0010xxxx 111000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer d = UInt(Rd); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding CNTD_R_S__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rd 0 +: 5 - __opcode '00000100 1110xxxx 111000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer d = UInt(Rd); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding CNTH_R_S__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rd 0 +: 5 - __opcode '00000100 0110xxxx 111000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer d = UInt(Rd); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding CNTW_R_S__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rd 0 +: 5 - __opcode '00000100 1010xxxx 111000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer d = UInt(Rd); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - - X[d] = (count * imm)[63:0]; - -__instruction aarch64_memory_literal_general - __encoding aarch64_memory_literal_general - __instruction_set A64 - __field opc 30 +: 2 - __field imm19 5 +: 19 - __field Rt 0 +: 5 - __opcode 'xx011000 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - MemOp memop = MemOp_LOAD; - boolean signed = FALSE; - integer size; - bits(64) offset; - - case opc of - when '00' - size = 4; - when '01' - size = 8; - when '10' - size = 4; - signed = TRUE; - when '11' - memop = MemOp_PREFETCH; - - offset = SignExtend(imm19:'00', 64); - boolean tag_checked = FALSE; - - __execute - bits(64) address = PC[] + offset; - bits(size*8) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - case memop of - when MemOp_LOAD - data = Mem[address, size, AccType_NORMAL]; - if signed then - X[t] = SignExtend(data, 64); - else - X[t] = data; - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - -__instruction aarch64_vector_arithmetic_unary_rev - __encoding aarch64_vector_arithmetic_unary_rev - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 000x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - // size=esize: B(0), H(1), S(1), D(S) - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - - // op=REVx: 64(0), 32(1), 16(2) - bits(2) op = o0:U; - - // => op+size: - // 64+B = 0, 64+H = 1, 64+S = 2, 64+D = X - // 32+B = 1, 32+H = 2, 32+S = X, 32+D = X - // 16+B = 2, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - // => 3-(op+size) (index bits in group) - // 64/B = 3, 64+H = 2, 64+S = 1, 64+D = X - // 32+B = 2, 32+H = 1, 32+S = X, 32+D = X - // 16+B = 1, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - - // index bits within group: 1, 2, 3 - if UInt(op)+UInt(size) >= 3 then UNDEFINED; - - integer container_size; - case op of - when '10' container_size = 16; - when '01' container_size = 32; - when '00' container_size = 64; - - integer containers = datasize DIV container_size; - integer elements_per_container = container_size DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element = 0; - integer rev_element; - for c = 0 to containers-1 - rev_element = element + elements_per_container - 1; - for e = 0 to elements_per_container-1 - Elem[result, rev_element, esize] = Elem[operand, element, esize]; - element = element + 1; - rev_element = rev_element - 1; - - V[d] = result; - -__instruction UADDV_R_P_Z__ - __encoding UADDV_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000100 xx000001 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - integer sum = 0; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer element = UInt(Elem[operand, e, esize]); - sum = sum + element; - - V[d] = sum[63:0]; - -__instruction aarch64_vector_arithmetic_binary_uniform_logical_and_orr - __encoding aarch64_vector_arithmetic_binary_uniform_logical_and_orr - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean invert = (size[0] == '1'); - LogicalOp op = if size[1] == '1' then LogicalOp_ORR else LogicalOp_AND; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND - result = operand1 AND operand2; - when LogicalOp_ORR - result = operand1 OR operand2; - - V[d] = result; - -__instruction FDIV_Z_P_ZZ__ - __encoding FDIV_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx001101 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPDiv(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 11111000 110x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 1x100000 110x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 11111000 110x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 1x100000 110x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) zero = FPZero('0'); - bits(esize) element; - boolean test_passed; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - case comparison of - when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR); - when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR); - when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR); - when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_vector_reduce_fp16_max_simd - __encoding aarch64_vector_reduce_fp16_max_simd - __instruction_set A64 - __field Q 30 +: 1 - __field o1 23 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 x0110000 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX; - - __encoding aarch64_vector_reduce_fp_max_simd - __instruction_set A64 - __field Q 30 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx110000 111110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q != '01' then UNDEFINED; - - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction SUNPKHI_Z_Z__ - __encoding SUNPKHI_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx110001 001110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = FALSE; - boolean hi = TRUE; - - __encoding SUNPKLO_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx110000 001110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = FALSE; - boolean hi = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer hsize = esize DIV 2; - bits(VL) operand = Z[n]; - bits(VL) result; - - for e = 0 to elements-1 - bits(hsize) element = if hi then Elem[operand, e + elements, hsize] else Elem[operand, e, hsize]; - Elem[result, e, esize] = Extend(element, esize, unsigned); - - Z[d] = result; - -__instruction aarch64_float_arithmetic_round_frint - __encoding aarch64_float_arithmetic_round_frint - __instruction_set A64 - __field ftype 22 +: 2 - __field rmode 15 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1001xx x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean exact = FALSE; - FPRounding rounding; - case rmode of - when '0xx' rounding = FPDecodeRounding(rmode[1:0]); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundInt(operand, FPCR, rounding, exact); - - V[d] = result; - -__instruction LD1RW_Z_P_BI_U32 - __encoding LD1RW_Z_P_BI_U32 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 01xxxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __encoding LD1RW_Z_P_BI_U64 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 01xxxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - integer last = LastActiveElement(mask, esize); - if last >= 0 then - addr = base + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_memory_single_general_immediate_signed_post_idx - __encoding aarch64_memory_single_general_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_literal_general - __encoding aarch64_memory_literal_general - __instruction_set A64 - __field opc 30 +: 2 - __field imm19 5 +: 19 - __field Rt 0 +: 5 - __opcode 'xx011000 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - MemOp memop = MemOp_LOAD; - boolean signed = FALSE; - integer size; - bits(64) offset; - - case opc of - when '00' - size = 4; - when '01' - size = 8; - when '10' - size = 4; - signed = TRUE; - when '11' - memop = MemOp_PREFETCH; - - offset = SignExtend(imm19:'00', 64); - boolean tag_checked = FALSE; - - __execute - bits(64) address = PC[] + offset; - bits(size*8) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - case memop of - when MemOp_LOAD - data = Mem[address, size, AccType_NORMAL]; - if signed then - X[t] = SignExtend(data, 64); - else - X[t] = data; - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_double_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_double_sisd - __instruction_set A64 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 xxxxxxxx 0x11x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - boolean sub_op = (o2 == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_double_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 xxxxxxxx 0x11x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(idxdsize) operand2 = V[m]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - integer accum; - boolean sat1; - boolean sat2; - - element2 = SInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - (product, sat1) = SignedSatQ(2 * element1 * element2, 2*esize); - if sub_op then - accum = SInt(Elem[operand3, e, 2*esize]) - SInt(product); - else - accum = SInt(Elem[operand3, e, 2*esize]) + SInt(product); - (Elem[result, e, 2*esize], sat2) = SignedSatQ(accum, 2*esize); - if sat1 || sat2 then FPSR.QC = '1'; - - V[d] = result; - -__instruction SDOT_Z_ZZZ__ - __encoding SDOT_Z_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000100 xx0xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '0x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) res = Elem[operand3, e, esize]; - for i = 0 to 3 - integer element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - integer element2 = SInt(Elem[operand2, 4 * e + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = res; - - Z[da] = result; - -__instruction aarch64_vector_crypto_sha2op_sha1_hash - __encoding aarch64_vector_crypto_sha2op_sha1_hash - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 00101000 000010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - if !HaveSHA1Ext() then UNDEFINED; - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(32) operand = V[n]; // read element [0] only, [1-3] zeroed - V[d] = ROL(operand, 30); - -__instruction SMAX_Z_ZI__ - __encoding SMAX_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx101000 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - boolean unsigned = FALSE; - integer imm = Int(imm8, unsigned); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - Elem[result, e, esize] = Max(element1, imm)[esize-1:0]; - - Z[dn] = result; - -__instruction UDOT_Z_ZZZ__ - __encoding UDOT_Z_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000100 xx0xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '0x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) res = Elem[operand3, e, esize]; - for i = 0 to 3 - integer element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - integer element2 = UInt(Elem[operand2, 4 * e + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = res; - - Z[da] = result; - -__instruction aarch64_branch_unconditional_register - __encoding aarch64_branch_unconditional_register - __instruction_set A64 - __field Z 24 +: 1 - __field op 21 +: 2 - __field A 11 +: 1 - __field M 10 +: 1 - __field Rn 5 +: 5 - __field Rm 0 +: 5 - __opcode '1101011x 0xx11111 0000xxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - BranchType branch_type; - integer m = UInt(Rm); - boolean pac = (A == '1'); - boolean use_key_a = (M == '0'); - boolean source_is_sp = ((Z == '1') && (m == 31)); - - if !pac && m != 0 then - UNDEFINED; - elsif pac && !HavePACExt() then - UNDEFINED; - - case op of - when '00' branch_type = BranchType_INDIR; - when '01' branch_type = BranchType_INDCALL; - when '10' branch_type = BranchType_RET; - otherwise UNDEFINED; - - if pac then - if Z == '0' && m != 31 then - UNDEFINED; - - if branch_type == BranchType_RET then - if n != 31 then UNDEFINED; - n = 30; - source_is_sp = TRUE; - - __execute - bits(64) target = X[n]; - boolean auth_then_branch = TRUE; - - if pac then - bits(64) modifier = if source_is_sp then SP[] else X[m]; - - if use_key_a then - target = AuthIA(target, modifier, auth_then_branch); - else - target = AuthIB(target, modifier, auth_then_branch); - - if branch_type == BranchType_INDCALL then X[30] = PC[] + 4; - - // Value in BTypeNext will be used to set PSTATE.BTYPE - case branch_type of - when BranchType_INDIR // BR, BRAA, BRAB, BRAAZ, BRABZ - if InGuardedPage then - if n == 16 || n == 17 then - BTypeNext = '01'; - else - BTypeNext = '11'; - else - BTypeNext = '01'; - when BranchType_INDCALL // BLR, BLRAA, BLRAB, BLRAAZ, BLRABZ - BTypeNext = '10'; - when BranchType_RET // RET, RETAA, RETAB - BTypeNext = '00'; - - BranchTo(target, branch_type); - -__instruction LD1RQD_Z_P_BR_Contiguous - __encoding LD1RQD_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 100xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - - __execute - CheckSVEEnabled(); - integer elements = 128 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low 16 bits only - bits(64) offset; - bits(128) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = X[m]; - - addr = base + UInt(offset) * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = Replicate(result, VL DIV 128); - -__instruction LSRR_Z_P_ZZ__ - __encoding LSRR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010101 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - integer shift = Min(UInt(element1), esize); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = LSR(element2, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction ZIP2_Z_ZZ__ - __encoding ZIP2_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx1xxxxx 011001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 1; - - __encoding ZIP2_Z_ZZ_Q - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 101xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer esize = 128; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 1; - - __encoding ZIP1_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx1xxxxx 011000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 0; - - __encoding ZIP1_Z_ZZ_Q - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 101xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer esize = 128; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 0; - - __execute - CheckSVEEnabled(); - if VL < esize * 2 then UNDEFINED; - integer pairs = VL DIV (esize * 2); - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result = Zeros(); - - integer base = part * pairs; - for p = 0 to pairs-1 - Elem[result, 2*p+0, esize] = Elem[operand1, base+p, esize]; - Elem[result, 2*p+1, esize] = Elem[operand2, base+p, esize]; - - Z[d] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction LASTB_V_P_Z__ - __encoding LASTB_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000101 xx100011 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - boolean isBefore = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - integer last = LastActiveElement(mask, esize); - - if isBefore then - if last < 0 then last = elements - 1; - else - last = last + 1; - if last >= elements then last = 0; - V[d] = Elem[operand, last, esize]; - -__instruction aarch64_integer_bitfield - __encoding aarch64_integer_bitfield - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field N 22 +: 1 - __field immr 16 +: 6 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10011 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - - boolean inzero; - boolean extend; - integer R; - integer S; - bits(datasize) wmask; - bits(datasize) tmask; - - case opc of - when '00' inzero = TRUE; extend = TRUE; // SBFM - when '01' inzero = FALSE; extend = FALSE; // BFM - when '10' inzero = TRUE; extend = FALSE; // UBFM - when '11' UNDEFINED; - - if sf == '1' && N != '1' then UNDEFINED; - if sf == '0' && (N != '0' || immr[5] != '0' || imms[5] != '0') then UNDEFINED; - - R = UInt(immr); - S = UInt(imms); - (wmask, tmask) = DecodeBitMasks(N, imms, immr, FALSE); - - __execute - bits(datasize) dst = if inzero then Zeros() else X[d]; - bits(datasize) src = X[n]; - - // perform bitfield move on low bits - bits(datasize) bot = (dst AND NOT(wmask)) OR (ROR(src, R) AND wmask); - - // determine extension bits (sign, zero or dest register) - bits(datasize) top = if extend then Replicate(src[S]) else dst; - - // combine extension bits and result bits - X[d] = (top AND NOT(tmask)) OR (bot AND tmask); - -__instruction DUPM_Z_I__ - __encoding DUPM_Z_I__ - __instruction_set A64 - __field imm13 5 +: 13 - __field Zd 0 +: 5 - __opcode '00000101 110000xx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer d = UInt(Zd); - bits(esize) imm; - (imm, -) = DecodeBitMasks(imm13[12], imm13[5:0], imm13[11:6], TRUE); - - __execute - CheckSVEEnabled(); - bits(VL) result = Replicate(imm); - Z[d] = result; - -__instruction ST3B_Z_P_BR_Contiguous - __encoding ST3B_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 010xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction aarch64_memory_single_general_immediate_signed_offset_unpriv - __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - - unpriv_at_el1 = PSTATE.EL == EL1 && !(EL2Enabled() && HaveNVExt() && HCR_EL2.[NV,NV1] == '11'); - unpriv_at_el2 = PSTATE.EL == EL2 && HaveVirtHostExt() && HCR_EL2.[E2H,TGE] == '11'; - - user_access_override = HaveUAOExt() && PSTATE.UAO == '1'; - if !user_access_override && (unpriv_at_el1 || unpriv_at_el2) then - acctype = AccType_UNPRIV; - else - acctype = AccType_NORMAL; - - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction SQADD_Z_ZZ__ - __encoding SQADD_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 000100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + element2, esize, unsigned); - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_halving_rounding - __encoding aarch64_vector_arithmetic_binary_uniform_add_halving_rounding - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 000101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - Elem[result, e, esize] = (element1 + element2 + 1)[esize:1]; - - V[d] = result; - -__instruction aarch64_vector_reduce_int_max - __encoding aarch64_vector_reduce_int_max - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 16 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx11000x 101010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '100' then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean min = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - integer maxmin; - integer element; - - maxmin = Int(Elem[operand, 0, esize], unsigned); - for e = 1 to elements-1 - element = Int(Elem[operand, e, esize], unsigned); - maxmin = if min then Min(maxmin, element) else Max(maxmin, element); - - V[d] = maxmin[esize-1:0]; - -__instruction LD1RSH_Z_P_BI_S32 - __encoding LD1RSH_Z_P_BI_S32 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 01xxxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = UInt(imm6); - - __encoding LD1RSH_Z_P_BI_S64 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 01xxxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = UInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - integer last = LastActiveElement(mask, esize); - if last >= 0 then - addr = base + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction aarch64_integer_logical_shiftedreg - __encoding aarch64_integer_logical_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field shift 22 +: 2 - __field N 21 +: 1 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01010 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - boolean invert = (N == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - X[d] = result; - -__instruction aarch64_integer_shift_variable - __encoding aarch64_integer_shift_variable - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field op2 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011010 110xxxxx 0010xxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - ShiftType shift_type = DecodeShift(op2); - - __execute - bits(datasize) result; - bits(datasize) operand2 = X[m]; - - result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize); - X[d] = result; - -__instruction aarch64_vector_shift_right_sisd - __encoding aarch64_vector_shift_right_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __encoding aarch64_vector_shift_right_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - operand2 = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift; - Elem[result, e, esize] = Elem[operand2, e, esize] + element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_integer_arithmetic_address_pc_rel - __encoding aarch64_integer_arithmetic_address_pc_rel - __instruction_set A64 - __field op 31 +: 1 - __field immlo 29 +: 2 - __field immhi 5 +: 19 - __field Rd 0 +: 5 - __opcode 'xxx10000 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - boolean page = (op == '1'); - bits(64) imm; - - if page then - imm = SignExtend(immhi:immlo:Zeros(12), 64); - else - imm = SignExtend(immhi:immlo, 64); - - __execute - bits(64) base = PC[]; - - if page then - base[11:0] = Zeros(12); - - X[d] = base + imm; - -__instruction SMMLA_Z_ZZZ__ - __encoding SMMLA_Z_ZZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000101 000xxxxx 100110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveInt8MatMulExt() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_unsigned = FALSE; - boolean op2_unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer segments = VL DIV 128; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result = Zeros(); - bits(128) op1, op2; - bits(128) res, addend; - - for s = 0 to segments-1 - op1 = Elem[operand1, s, 128]; - op2 = Elem[operand2, s, 128]; - addend = Elem[operand3, s, 128]; - res = MatMulAdd(addend, op1, op2, op1_unsigned, op2_unsigned); - Elem[result, s, 128] = res; - - Z[da] = result; - -__instruction aarch64_vector_crypto_aes_mix - __encoding aarch64_vector_crypto_aes_mix - __instruction_set A64 - __field D 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01001110 00101000 011x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - if !HaveAESExt() then UNDEFINED; - boolean decrypt = (D == '1'); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) operand = V[n]; - bits(128) result; - if decrypt then - result = AESInvMixColumns(operand); - else - result = AESMixColumns(operand); - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_high_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_high_sisd - __instruction_set A64 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field S 13 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111111 xxxxxxxx 11x1x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - boolean rounding = TRUE; - boolean sub_op = (S == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_high_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field S 13 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 xxxxxxxx 11x1x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean rounding = TRUE; - boolean sub_op = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - integer rounding_const = if rounding then 1 << (esize - 1) else 0; - integer element1; - integer element2; - integer element3; - integer product; - boolean sat; - - element2 = SInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - element3 = SInt(Elem[operand3, e, esize]); - if sub_op then - accum = ((element3 << esize) - 2 * (element1 * element2) + rounding_const); - else - accum = ((element3 << esize) + 2 * (element1 * element2) + rounding_const); - (Elem[result, e, esize], sat) = SignedSatQ(accum >> esize, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction CLASTA_V_P_Z__ - __encoding CLASTA_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Vdn 0 +: 5 - __opcode '00000101 xx101010 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Vdn); - integer m = UInt(Zm); - boolean isBefore = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(esize) operand1 = V[dn]; - bits(VL) operand2 = Z[m]; - bits(esize) result; - integer last = LastActiveElement(mask, esize); - - if last < 0 then - result = ZeroExtend(operand1); - else - if !isBefore then - last = last + 1; - if last >= elements then last = 0; - result = Elem[operand2, last, esize]; - - V[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_product - __encoding aarch64_vector_arithmetic_binary_disparate_mul_product - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - Elem[result, e, 2*esize] = (element1 * element2)[2*esize-1:0]; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_poly - __encoding aarch64_vector_arithmetic_binary_disparate_mul_poly - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 111000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '01' || size == '10' then UNDEFINED; - if size == '11' && !HaveBit128PMULLExt() then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - Elem[result, e, 2*esize] = PolynomialMult(element1, element2); - - V[d] = result; - -__instruction aarch64_float_compare_cond - __encoding aarch64_float_compare_cond - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field Rn 5 +: 5 - __field op 4 +: 1 - __field nzcv 0 +: 4 - __opcode '00011110 xx1xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean signal_all_nans = (op == '1'); - bits(4) condition = cond; - bits(4) flags = nzcv; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) operand1 = V[n]; - bits(datasize) operand2; - - operand2 = V[m]; - - if ConditionHolds(condition) then - flags = FPCompare(operand1, operand2, signal_all_nans, FPCR); - PSTATE.[N,Z,C,V] = flags; - -__instruction aarch64_vector_crypto_sha3op_sha256_sched1 - __encoding aarch64_vector_crypto_sha3op_sha256_sched1 - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 000xxxxx 011000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if !HaveSHA256Ext() then UNDEFINED; - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) operand1 = V[d]; - bits(128) operand2 = V[n]; - bits(128) operand3 = V[m]; - bits(128) result; - bits(128) T0 = operand3[31:0] : operand2[127:32]; - bits(64) T1; - bits(32) elt; - - T1 = operand3[127:64]; - for e = 0 to 1 - elt = Elem[T1, e, 32]; - elt = ROR(elt, 17) EOR ROR(elt, 19) EOR LSR(elt, 10); - elt = elt + Elem[operand1, e, 32] + Elem[T0, e, 32]; - Elem[result, e, 32] = elt; - - T1 = result[63:0]; - for e = 2 to 3 - elt = Elem[T1, e - 2, 32]; - elt = ROR(elt, 17) EOR ROR(elt, 19) EOR LSR(elt, 10); - elt = elt + Elem[operand1, e, 32] + Elem[T0, e, 32]; - Elem[result, e, 32] = elt; - - V[d] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_float_arithmetic_round_frint - __encoding aarch64_float_arithmetic_round_frint - __instruction_set A64 - __field ftype 22 +: 2 - __field rmode 15 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1001xx x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean exact = FALSE; - FPRounding rounding; - case rmode of - when '0xx' rounding = FPDecodeRounding(rmode[1:0]); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundInt(operand, FPCR, rounding, exact); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field eq 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 0011x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean cmp_eq = (eq == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field eq 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0011x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean cmp_eq = (eq == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - test_passed = if cmp_eq then element1 >= element2 else element1 > element2; - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_vector_shift_right_narrow_uniform_sisd - __encoding aarch64_vector_shift_right_narrow_uniform_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 1001x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then UNDEFINED; - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_shift_right_narrow_uniform_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 1001x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize*2) operand = V[n]; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = (Int(Elem[operand, e, 2*esize], unsigned) + round_const) >> shift; - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - - Vpart[d, part] = result; - -__instruction aarch64_memory_pair_general_no_alloc - __encoding aarch64_memory_pair_general_no_alloc - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101000 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); - AccType acctype = AccType_STREAM; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - if opc[0] == '1' then UNDEFINED; - integer scale = 2 + UInt(opc[1]); - integer datasize = 8 << scale; - bits(64) offset = LSL(SignExtend(imm7, 64), scale); - boolean tag_checked = wback || n != 31; - __execute - bits(64) address; - bits(datasize) data1; - bits(datasize) data2; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown && t == n then - data1 = bits(datasize) UNKNOWN; - else - data1 = X[t]; - if rt_unknown && t2 == n then - data2 = bits(datasize) UNKNOWN; - else - data2 = X[t2]; - Mem[address + 0 , dbytes, acctype] = data1; - Mem[address + dbytes, dbytes, acctype] = data2; - - when MemOp_LOAD - data1 = Mem[address + 0 , dbytes, acctype]; - data2 = Mem[address + dbytes, dbytes, acctype]; - if rt_unknown then - data1 = bits(datasize) UNKNOWN; - data2 = bits(datasize) UNKNOWN; - X[t] = data1; - X[t2] = data2; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction LD1SH_Z_P_AI_S - __encoding LD1SH_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 101xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __encoding LD1SH_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 101xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_branch_conditional_test - __encoding aarch64_branch_conditional_test - __instruction_set A64 - __field b5 31 +: 1 - __field op 24 +: 1 - __field b40 19 +: 5 - __field imm14 5 +: 14 - __field Rt 0 +: 5 - __opcode 'x011011x xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - - integer datasize = if b5 == '1' then 64 else 32; - integer bit_pos = UInt(b5:b40); - bit bit_val = op; - bits(64) offset = SignExtend(imm14:'00', 64); - - __execute - bits(datasize) operand = X[t]; - - if operand[bit_pos] == bit_val then - BranchTo(PC[] + offset, BranchType_DIR); - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_dotp - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_dotp - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx0xxxxx 100101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveDOTPExt() then UNDEFINED; - if size!= '10' then UNDEFINED; - boolean signed = (U=='0'); - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - result = V[d]; - for e = 0 to elements-1 - integer res = 0; - integer element1, element2; - for i = 0 to 3 - if signed then - element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = SInt(Elem[operand2, 4 * e + i, esize DIV 4]); - else - element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = UInt(Elem[operand2, 4 * e + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = Elem[result, e, esize] + res; - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_add_pairwise - __encoding aarch64_vector_arithmetic_unary_add_pairwise - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 0x1010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV (2*esize); - boolean acc = (op == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - bits(2*esize) sum; - integer op1; - integer op2; - - if acc then result = V[d]; - for e = 0 to elements-1 - op1 = Int(Elem[operand, 2*e+0, esize], unsigned); - op2 = Int(Elem[operand, 2*e+1, esize], unsigned); - sum = (op1 + op2)[2*esize-1:0]; - if acc then - Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + sum; - else - Elem[result, e, 2*esize] = sum; - - V[d] = result; - -__instruction UQDECD_R_RS_UW - __encoding UQDECD_R_RS_UW - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1110xxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQDECD_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1111xxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 - (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_branch_conditional_cond - __encoding aarch64_branch_conditional_cond - __instruction_set A64 - __field imm19 5 +: 19 - __field cond 0 +: 4 - __opcode '01010100 xxxxxxxx xxxxxxxx xxx0xxxx' - __guard TRUE - __decode - bits(64) offset = SignExtend(imm19:'00', 64); - bits(4) condition = cond; - - __execute - if ConditionHolds(condition) then - BranchTo(PC[] + offset, BranchType_DIR); - -__instruction UMINV_R_P_Z__ - __encoding UMINV_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000100 xx001011 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - integer minimum = if unsigned then (2^esize - 1) else (2^(esize-1) - 1); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer element = Int(Elem[operand, e, esize], unsigned); - minimum = Min(minimum, element); - - V[d] = minimum[esize-1:0]; - -__instruction aarch64_vector_arithmetic_binary_uniform_logical_and_orr - __encoding aarch64_vector_arithmetic_binary_uniform_logical_and_orr - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean invert = (size[0] == '1'); - LogicalOp op = if size[1] == '1' then LogicalOp_ORR else LogicalOp_AND; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND - result = operand1 AND operand2; - when LogicalOp_ORR - result = operand1 OR operand2; - - V[d] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction CMPEQ_P_P_ZZ__ - __encoding CMPEQ_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 101xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_EQ; - boolean unsigned = FALSE; - - __encoding CMPGT_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 100xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GT; - boolean unsigned = FALSE; - - __encoding CMPGE_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 100xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GE; - boolean unsigned = FALSE; - - __encoding CMPHI_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 000xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GT; - boolean unsigned = TRUE; - - __encoding CMPHS_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 000xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GE; - boolean unsigned = TRUE; - - __encoding CMPNE_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 101xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_NE; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(PL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - boolean cond; - case op of - when Cmp_EQ cond = element1 == element2; - when Cmp_NE cond = element1 != element2; - when Cmp_GE cond = element1 >= element2; - when Cmp_LT cond = element1 < element2; - when Cmp_GT cond = element1 > element2; - when Cmp_LE cond = element1 <= element2; - ElemP[result, e, esize] = if cond then '1' else '0'; - else - ElemP[result, e, esize] = '0'; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction ST1W_Z_P_AI_S - __encoding ST1W_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 011xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - integer offset = UInt(imm5); - - __encoding ST1W_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 010xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(VL) src = Z[t]; - bits(PL) mask = P[g]; - bits(64) addr; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - -__instruction aarch64_memory_single_general_immediate_unsigned - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction LDFF1SB_Z_P_BR_S16 - __encoding LDFF1SB_Z_P_BR_S16 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 110xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = FALSE; - - __encoding LDFF1SB_Z_P_BR_S32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 101xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = FALSE; - - __encoding LDFF1SB_Z_P_BR_S64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 100xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + UInt(offset) * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_CNOTFIRST]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - offset = offset + 1; - - Z[t] = result; - -__instruction LDFF1H_Z_P_BZ_S_x32_scaled - __encoding LDFF1H_Z_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 1x1xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding LDFF1H_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 1x1xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding LDFF1H_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 1x0xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1H_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 1x0xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1H_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 111xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 1; - - __encoding LDFF1H_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 110xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction ST4W_Z_P_BI_Contiguous - __encoding ST4W_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 0111xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction aarch64_vector_arithmetic_unary_diff_neg_int_sisd - __encoding aarch64_vector_arithmetic_unary_diff_neg_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 101110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean neg = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_diff_neg_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 101110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean neg = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - - for e = 0 to elements-1 - element = SInt(Elem[operand, e, esize]); - if neg then - element = -element; - else - element = Abs(element); - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction BRKPA_P_P_PP__ - __encoding BRKPA_P_P_PP__ - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0000xxxx 11xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding BRKPAS_P_P_PP__ - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0100xxxx 11xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - boolean last = (LastActive(mask, operand1, 8) == '1'); - - for e = 0 to elements-1 - if ElemP[mask, e, 8] == '1' then - ElemP[result, e, 8] = if last then '1' else '0'; - last = last && (ElemP[operand2, e, 8] == '0'); - else - ElemP[result, e, 8] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction LD3W_Z_P_BI_Contiguous - __encoding LD3W_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0100xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_memory_single_general_immediate_signed_offset_unpriv - __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - - unpriv_at_el1 = PSTATE.EL == EL1 && !(EL2Enabled() && HaveNVExt() && HCR_EL2.[NV,NV1] == '11'); - unpriv_at_el2 = PSTATE.EL == EL2 && HaveVirtHostExt() && HCR_EL2.[E2H,TGE] == '11'; - - user_access_override = HaveUAOExt() && PSTATE.UAO == '1'; - if !user_access_override && (unpriv_at_el1 || unpriv_at_el2) then - acctype = AccType_UNPRIV; - else - acctype = AccType_NORMAL; - - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_single_general_immediate_signed_offset_lda_stl - __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx011001 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_ORDERED; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction PFIRST_P_P_P__ - __encoding PFIRST_P_P_P__ - __instruction_set A64 - __field Pg 5 +: 4 - __field Pdn 0 +: 4 - __opcode '00100101 01011000 1100000x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer dn = UInt(Pdn); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) result = P[dn]; - integer first = -1; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' && first == -1 then - first = e; - - if first >= 0 then - ElemP[result, first, esize] = '1'; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[dn] = result; - -__instruction LD1SB_Z_P_BI_S16 - __encoding LD1SB_Z_P_BI_S16 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1100xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __encoding LD1SB_Z_P_BI_S32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1010xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __encoding LD1SB_Z_P_BI_S64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1000xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction FRECPE_Z_Z__ - __encoding FRECPE_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx001110 001100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand = Z[n]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRecipEstimate(element, FPCR); - - Z[d] = result; - -__instruction LD1ROD_Z_P_BI_U64 - __encoding LD1ROD_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1010xxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - if VL < 256 then UNDEFINED; - integer elements = 256 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low bits only - bits(256) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * 32; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = ZeroExtend(Replicate(result, VL DIV 256), VL); - -__instruction EOR_Z_ZI__ - __encoding EOR_Z_ZI__ - __instruction_set A64 - __field imm13 5 +: 13 - __field Zdn 0 +: 5 - __opcode '00000101 010000xx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer dn = UInt(Zdn); - bits(64) imm; - (imm, -) = DecodeBitMasks(imm13[12], imm13[5:0], imm13[11:6], TRUE); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 64; - bits(VL) operand = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(64) element1 = Elem[operand, e, 64]; - Elem[result, e, 64] = element1 EOR imm; - - Z[dn] = result; - -__instruction FMINV_V_P_Z__ - __encoding FMINV_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '01100101 xx000111 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(esize) identity = FPInfinity('0'); - - V[d] = ReducePredicated(ReduceOp_FMIN, operand, mask, identity); - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction aarch64_vector_crypto_sha512_sha512su0 - __encoding aarch64_vector_crypto_sha512_sha512su0 - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 11000000 100000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSHA512Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(64) sig0; - bits(128) Vtmp; - bits(128) X = V[n]; - bits(128) W = V[d]; - sig0 = ROR(W[127:64], 1) EOR ROR(W[127:64], 8) EOR ('0000000':W[127:71]); - Vtmp[63:0] = W[63:0] + sig0; - sig0 = ROR(X[63:0], 1) EOR ROR(X[63:0], 8) EOR ('0000000':X[63:7]); - Vtmp[127:64] = W[127:64] + sig0; - V[d] = Vtmp; - -__instruction aarch64_integer_tags_mcsubtag - __encoding aarch64_integer_tags_mcsubtag - __instruction_set A64 - __field uimm6 16 +: 6 - __field op3 14 +: 2 - __field uimm4 10 +: 4 - __field Xn 5 +: 5 - __field Xd 0 +: 5 - __opcode '11010001 10xxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Xd); - integer n = UInt(Xn); - bits(4) tag_offset = uimm4; - bits(64) offset = LSL(ZeroExtend(uimm6, 64), LOG2_TAG_GRANULE); - boolean ADD = FALSE; - - __execute - bits(64) operand1 = if n == 31 then SP[] else X[n]; - bits(4) start_tag = AArch64.AllocationTagFromAddress(operand1); - bits(16) exclude = GCR_EL1.Exclude; - bits(64) result; - bits(4) rtag; - - if AArch64.AllocationTagAccessIsEnabled() then - rtag = AArch64.ChooseNonExcludedTag(start_tag, tag_offset, exclude); - else - rtag = '0000'; - - if ADD then - (result, -) = AddWithCarry(operand1, offset, '0'); - else - (result, -) = AddWithCarry(operand1, NOT(offset), '1'); - - result = AArch64.AddressWithAllocationTag(result, rtag); - - if d == 31 then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_lower - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_lower - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field S 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 1xxxxxxx 0x00x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt('0':Rm); // Vm can only be in bottom 16 registers. - if sz == '1' then UNDEFINED; - integer index = UInt(H:L:M); - - integer esize = 32; - integer datasize = if Q=='1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (S == '1'); - integer part = 0; - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_upper - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field S 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 1xxxxxxx 1x00x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt('0':Rm); // Vm can only be in bottom 16 registers. - if sz == '1' then UNDEFINED; - integer index = UInt(H:L:M); - - integer esize = 32; - integer datasize = if Q=='1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (S == '1'); - integer part = 1; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize DIV 2) operand1 = Vpart[n,part]; - bits(128) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize DIV 2) element1; - bits(esize DIV 2) element2 = Elem[operand2, index, esize DIV 2]; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize DIV 2]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAddH(Elem[operand3, e, esize], element1, element2, FPCR); - V[d] = result; - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction EOR_P_P_PP_Z - __encoding EOR_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0000xxxx 01xxxx1x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding EORS_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0100xxxx 01xxxx1x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - for e = 0 to elements-1 - bit element1 = ElemP[operand1, e, esize]; - bit element2 = ElemP[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - ElemP[result, e, esize] = element1 EOR element2; - else - ElemP[result, e, esize] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_vector_reduce_fp16_max_sisd - __encoding aarch64_vector_reduce_fp16_max_sisd - __instruction_set A64 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 xx110000 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - if sz == '1' then UNDEFINED; - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX; - - __encoding aarch64_vector_reduce_fp_max_sisd - __instruction_set A64 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 xx110000 111110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction ST1D_Z_P_AI_D - __encoding ST1D_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 110xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(VL) src = Z[t]; - bits(PL) mask = P[g]; - bits(64) addr; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - -__instruction LDNT1D_Z_P_BR_Contiguous - __encoding LDNT1D_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 100xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(64) offset; - bits(PL) mask = P[g]; - bits(VL) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = X[m]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_STREAM]; - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_unary_extract_nosat - __encoding aarch64_vector_arithmetic_unary_extract_nosat - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx100001 001010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand = V[n]; - bits(datasize) result; - bits(2*esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, 2*esize]; - Elem[result, e, esize] = element[esize-1:0]; - Vpart[d, part] = result; - -__instruction ST2D_Z_P_BR_Contiguous - __encoding ST2D_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 101xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction SQINCH_R_RS_SX - __encoding SQINCH_R_RS_SX - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0110xxxx 111100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQINCH_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0111xxxx 111100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 + (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction LDNF1H_Z_P_BI_U16 - __encoding LDNF1H_Z_P_BI_U16 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1011xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LDNF1H_Z_P_BI_U32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1101xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LDNF1H_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1111xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - addr = addr + mbytes; - - Z[t] = result; - -__instruction FSUB_Z_ZZ__ - __encoding FSUB_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx0xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPSub(element1, element2, FPCR); - - Z[d] = result; - -__instruction UMAX_Z_P_ZZ__ - __encoding UMAX_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx001001 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer maximum = Max(element1, element2); - Elem[result, e, esize] = maximum[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 100001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean sub_op = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 100001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if sub_op then - Elem[result, e, esize] = element1 - element2; - else - Elem[result, e, esize] = element1 + element2; - - V[d] = result; - -__instruction aarch64_float_arithmetic_max_min - __encoding aarch64_float_arithmetic_max_min - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field op 12 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx 01xx10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - FPMaxMinOp operation; - case op of - when '00' operation = FPMaxMinOp_MAX; - when '01' operation = FPMaxMinOp_MIN; - when '10' operation = FPMaxMinOp_MAXNUM; - when '11' operation = FPMaxMinOp_MINNUM; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - case operation of - when FPMaxMinOp_MAX result = FPMax(operand1, operand2, FPCR); - when FPMaxMinOp_MIN result = FPMin(operand1, operand2, FPCR); - when FPMaxMinOp_MAXNUM result = FPMaxNum(operand1, operand2, FPCR); - when FPMaxMinOp_MINNUM result = FPMinNum(operand1, operand2, FPCR); - - V[d] = result; - -__instruction aarch64_float_convert_fix - __encoding aarch64_float_convert_fix - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field scale 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - - case ftype of - when '00' fltsize = 32; - when '01' fltsize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - if sf == '0' && scale[5] == '0' then UNDEFINED; - integer fracbits = 64 - UInt(scale); - - case opcode[2:1]:rmode of - when '00 11' // FCVTZ - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, fracbits, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, fracbits, unsigned, FPCR, rounding); - V[d] = fltval; - -__instruction FRECPX_Z_P_Z__ - __encoding FRECPX_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx001100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPRecpX(element, FPCR); - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_rsqrts_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_rsqrts_fp16_sisd - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 110xxxxx 001111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_binary_uniform_rsqrts_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 1x1xxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_binary_uniform_rsqrts_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 110xxxxx 001111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __encoding aarch64_vector_arithmetic_binary_uniform_rsqrts_simd - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 1x1xxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPRSqrtStepFused(element1, element2); - - V[d] = result; - -__instruction LD4D_Z_P_BI_Contiguous - __encoding LD4D_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1110xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_arithmetic_binary_disparate_diff - __encoding aarch64_vector_arithmetic_binary_disparate_diff - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 01x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean accumulate = (op == '0'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) absdiff; - - result = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - absdiff = Abs(element1 - element2)[2*esize-1:0]; - Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + absdiff; - V[d] = result; - -__instruction SABD_Z_P_ZZ__ - __encoding SABD_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx001100 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer absdiff = Abs(element1 - element2); - Elem[result, e, esize] = absdiff[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction FMUL_Z_ZZ__ - __encoding FMUL_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx0xxxxx 000010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPMul(element1, element2, FPCR); - - Z[d] = result; - -__instruction aarch64_integer_tags_mcgettag - __encoding aarch64_integer_tags_mcgettag - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 011xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Xt); - integer n = UInt(Xn); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - - __execute - bits(64) address; - bits(4) tag; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - address = address + offset; - address = Align(address, TAG_GRANULE); - - tag = AArch64.MemTag[address, AccType_NORMAL]; - X[t] = AArch64.AddressWithAllocationTag(X[t], tag); - -__instruction aarch64_vector_arithmetic_unary_float_round_frint_32_64 - __encoding aarch64_vector_arithmetic_unary_float_round_frint_32_64 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x100001 111x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFrintExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer intsize = if op == '0' then 32 else 64; - FPRounding rounding = if U == '0' then FPRounding_ZERO else FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundIntN(element, FPCR, rounding, intsize); - - V[d] = result; - -__instruction aarch64_float_arithmetic_mul_product - __encoding aarch64_float_arithmetic_mul_product - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field op 15 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx x00010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean negated = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - result = FPMul(operand1, operand2, FPCR); - - if negated then result = FPNeg(result); - - V[d] = result; - -__instruction aarch64_vector_crypto_sha3op_sha256_hash - __encoding aarch64_vector_crypto_sha3op_sha256_hash - __instruction_set A64 - __field Rm 16 +: 5 - __field P 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 000xxxxx 010x00xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if !HaveSHA256Ext() then UNDEFINED; - boolean part1 = (P == '0'); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) result; - if part1 then - result = SHA256hash(V[d], V[n], V[m], TRUE); - else - result = SHA256hash(V[n], V[d], V[m], FALSE); - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 100011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean and_test = (U == '0'); - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 100011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean and_test = (U == '0'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if and_test then - test_passed = !IsZero(element1 AND element2); - else - test_passed = (element1 == element2); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_float_arithmetic_unary - __encoding aarch64_float_arithmetic_unary - __instruction_set A64 - __field ftype 22 +: 2 - __field opc 15 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx10000x x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - FPUnaryOp fpop; - case opc of - when '00' fpop = FPUnaryOp_MOV; - when '01' fpop = FPUnaryOp_ABS; - when '10' fpop = FPUnaryOp_NEG; - when '11' fpop = FPUnaryOp_SQRT; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - case fpop of - when FPUnaryOp_MOV result = operand; - when FPUnaryOp_ABS result = FPAbs(operand); - when FPUnaryOp_NEG result = FPNeg(operand); - when FPUnaryOp_SQRT result = FPSqrt(operand, FPCR); - - V[d] = result; - -__instruction LD4H_Z_P_BI_Contiguous - __encoding LD4H_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1110xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_crypto_sha512_sha512h - __encoding aarch64_vector_crypto_sha512_sha512h - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 011xxxxx 100000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSHA512Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vtmp; - bits(64) MSigma1; - bits(64) tmp; - bits(128) X = V[n]; - bits(128) Y = V[m]; - bits(128) W = V[d]; - - MSigma1 = ROR(Y[127:64], 14) EOR ROR(Y[127:64],18) EOR ROR(Y[127:64],41); - Vtmp[127:64] = (Y[127:64] AND X[63:0]) EOR (NOT(Y[127:64]) AND X[127:64]); - Vtmp[127:64] = (Vtmp[127:64] + MSigma1 + W[127:64]); - tmp = Vtmp[127:64] + Y[63:0]; - MSigma1 = ROR(tmp, 14) EOR ROR(tmp,18) EOR ROR(tmp,41); - Vtmp[63:0] = (tmp AND Y[127:64]) EOR (NOT(tmp) AND X[63:0]); - Vtmp[63:0] = (Vtmp[63:0] + MSigma1 + W[63:0]); - V[d] = Vtmp; - -__instruction aarch64_memory_atomicops_cas_single - __encoding aarch64_memory_atomicops_cas_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x1xxxxx x11111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer n = UInt(Rn); - integer t = UInt(Rt); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if L == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if o0 == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) comparevalue; - bits(datasize) newvalue; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - comparevalue = X[s]; - newvalue = X[t]; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomicCompareAndSwap(address, comparevalue, newvalue, ldacctype, stacctype); - - X[s] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_transfer_vector_cpy_dup_sisd - __encoding aarch64_vector_transfer_vector_cpy_dup_sisd - __instruction_set A64 - __field imm5 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 000xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer size = LowestSetBit(imm5); - if size > 3 then UNDEFINED; - - integer index = UInt(imm5[4:size+1]); - integer idxdsize = if imm5[4] == '1' then 128 else 64; - - integer esize = 8 << size; - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_transfer_vector_cpy_dup_simd - __instruction_set A64 - __field Q 30 +: 1 - __field imm5 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 000xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer size = LowestSetBit(imm5); - if size > 3 then UNDEFINED; - - integer index = UInt(imm5[4:size+1]); - integer idxdsize = if imm5[4] == '1' then 128 else 64; - - if size == 3 && Q == '0' then UNDEFINED; - integer esize = 8 << size; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(idxdsize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - element = Elem[operand, index, esize]; - for e = 0 to elements-1 - Elem[result, e, esize] = element; - V[d] = result; - -__instruction EORV_R_P_Z__ - __encoding EORV_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000100 xx011001 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(esize) result = Zeros(esize); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - result = result EOR Elem[operand, e, esize]; - - V[d] = result; - -__instruction aarch64_branch_conditional_test - __encoding aarch64_branch_conditional_test - __instruction_set A64 - __field b5 31 +: 1 - __field op 24 +: 1 - __field b40 19 +: 5 - __field imm14 5 +: 14 - __field Rt 0 +: 5 - __opcode 'x011011x xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - - integer datasize = if b5 == '1' then 64 else 32; - integer bit_pos = UInt(b5:b40); - bit bit_val = op; - bits(64) offset = SignExtend(imm14:'00', 64); - - __execute - bits(datasize) operand = X[t]; - - if operand[bit_pos] == bit_val then - BranchTo(PC[] + offset, BranchType_DIR); - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction LSR_Z_P_ZZ__ - __encoding LSR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010001 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - integer shift = Min(UInt(element2), esize); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = LSR(element1, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction LD1SH_Z_P_BR_S32 - __encoding LD1SH_Z_P_BR_S32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 001xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = FALSE; - - __encoding LD1SH_Z_P_BR_S64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 000xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction PRFW_I_P_AI_S - __encoding PRFW_I_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000101 000xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 2; - integer offset = UInt(imm5); - - __encoding PRFW_I_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000101 000xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 2; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) base; - bits(64) addr; - base = Z[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + (offset << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - -__instruction LDFF1B_Z_P_AI_S - __encoding LDFF1B_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 001xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __encoding LDFF1B_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 001xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction CNOT_Z_P_Z__ - __encoding CNOT_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx011011 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = ZeroExtend(IsZeroBit(element), esize); - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_bfdot - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_bfdot - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 010xxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 32; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - - for e = 0 to elements-1 - bits(16) elt1_a = Elem[operand1, 2 * e + 0, 16]; - bits(16) elt1_b = Elem[operand1, 2 * e + 1, 16]; - bits(16) elt2_a = Elem[operand2, 2 * e + 0, 16]; - bits(16) elt2_b = Elem[operand2, 2 * e + 1, 16]; - - bits(32) sum = BFAdd(BFMul(elt1_a, elt2_a), BFMul(elt1_b, elt2_b)); - Elem[result, e, 32] = BFAdd(Elem[operand3, e, 32], sum); - - V[d] = result; - -__instruction aarch64_vector_reduce_add_long - __encoding aarch64_vector_reduce_add_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx110000 001110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '100' then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - integer sum; - - sum = Int(Elem[operand, 0, esize], unsigned); - for e = 1 to elements-1 - sum = sum + Int(Elem[operand, e, esize], unsigned); - - V[d] = sum[2*esize-1:0]; - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction FRSQRTE_Z_Z__ - __encoding FRSQRTE_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx001111 001100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand = Z[n]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRSqrtEstimate(element, FPCR); - - Z[d] = result; - -__instruction aarch64_vector_shift_right_narrow_uniform_sisd - __encoding aarch64_vector_shift_right_narrow_uniform_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 1001x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then UNDEFINED; - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_shift_right_narrow_uniform_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 1001x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize*2) operand = V[n]; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = (Int(Elem[operand, e, 2*esize], unsigned) + round_const) >> shift; - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - - Vpart[d, part] = result; - -__instruction LDFF1W_Z_P_BR_U32 - __encoding LDFF1W_Z_P_BR_U32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 010xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - boolean unsigned = TRUE; - - __encoding LDFF1W_Z_P_BR_U64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 011xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + UInt(offset) * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_CNOTFIRST]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - offset = offset + 1; - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_product - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_product - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 100111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if U == '1' && size != '00' then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean poly = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - bits(esize) product; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if poly then - product = PolynomialMult(element1, element2)[esize-1:0]; - else - product = (UInt(element1) * UInt(element2))[esize-1:0]; - Elem[result, e, esize] = product; - - V[d] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_uniform_shift_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - if S == '0' && size != '11' then UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer round_const = 0; - integer shift; - integer element; - boolean sat; - - for e = 0 to elements-1 - shift = SInt(Elem[operand2, e, esize][7:0]); - if rounding then - round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift - element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift; - if saturating then - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - else - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_float_arithmetic_max_min - __encoding aarch64_float_arithmetic_max_min - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field op 12 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx 01xx10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - FPMaxMinOp operation; - case op of - when '00' operation = FPMaxMinOp_MAX; - when '01' operation = FPMaxMinOp_MIN; - when '10' operation = FPMaxMinOp_MAXNUM; - when '11' operation = FPMaxMinOp_MINNUM; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - case operation of - when FPMaxMinOp_MAX result = FPMax(operand1, operand2, FPCR); - when FPMaxMinOp_MIN result = FPMin(operand1, operand2, FPCR); - when FPMaxMinOp_MAXNUM result = FPMaxNum(operand1, operand2, FPCR); - when FPMaxMinOp_MINNUM result = FPMinNum(operand1, operand2, FPCR); - - V[d] = result; - -__instruction LDFF1SW_Z_P_AI_D - __encoding LDFF1SW_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 001xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mat_mul_int_dotp - __encoding aarch64_vector_arithmetic_binary_element_mat_mul_int_dotp - __instruction_set A64 - __field Q 30 +: 1 - __field US 23 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 x0xxxxxx 1111x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveInt8MatMulExt() then UNDEFINED; - boolean op1_unsigned = (US == '1'); - boolean op2_unsigned = (US == '0'); - integer n = UInt(Rn); - integer m = UInt(M:Rm); - integer d = UInt(Rd); - integer i = UInt(H:L); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 32; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - - for e = 0 to elements-1 - bits(32) res = Elem[operand3, e, 32]; - for b = 0 to 3 - integer element1 = Int(Elem[operand1, 4 * e + b, 8], op1_unsigned); - integer element2 = Int(Elem[operand2, 4 * i + b, 8], op2_unsigned); - res = res + element1 * element2; - Elem[result, e, 32] = res; - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 100011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean and_test = (U == '0'); - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_bitwise_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 100011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean and_test = (U == '0'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if and_test then - test_passed = !IsZero(element1 AND element2); - else - test_passed = (element1 == element2); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor - __encoding aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor - __instruction_set A64 - __field Q 30 +: 1 - __field opc2 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx1xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - VBitOp op; - - case opc2 of - when '00' op = VBitOp_VEOR; - when '01' op = VBitOp_VBSL; - when '10' op = VBitOp_VBIT; - when '11' op = VBitOp_VBIF; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1; - bits(datasize) operand2; - bits(datasize) operand3; - bits(datasize) operand4 = V[n]; - - case op of - when VBitOp_VEOR - operand1 = V[m]; - operand2 = Zeros(); - operand3 = Ones(); - when VBitOp_VBSL - operand1 = V[m]; - operand2 = operand1; - operand3 = V[d]; - when VBitOp_VBIT - operand1 = V[d]; - operand2 = operand1; - operand3 = V[m]; - when VBitOp_VBIF - operand1 = V[d]; - operand2 = operand1; - operand3 = NOT(V[m]); - - V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3); - -__instruction aarch64_integer_arithmetic_pointer_mcsubtracttaggedaddresssetflags - __encoding aarch64_integer_arithmetic_pointer_mcsubtracttaggedaddresssetflags - __instruction_set A64 - __field Xm 16 +: 5 - __field Xn 5 +: 5 - __field Xd 0 +: 5 - __opcode '10111010 110xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Xd); - integer n = UInt(Xn); - integer m = UInt(Xm); - boolean setflags = TRUE; - - __execute - bits(64) operand1 = if n == 31 then SP[] else X[n]; - bits(64) operand2 = if m == 31 then SP[] else X[m]; - operand1 = SignExtend(operand1[55:0], 64); - operand2 = SignExtend(operand2[55:0], 64); - - bits(64) result; - bits(4) nzcv; - - operand2 = NOT(operand2); - (result, nzcv) = AddWithCarry(operand1, operand2, '1'); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - X[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_single - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_single - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer maxmin; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - maxmin = if minimum then Min(element1, element2) else Max(element1, element2); - Elem[result, e, esize] = maxmin[esize-1:0]; - - V[d] = result; - -__instruction FMMLA_Z_ZZZ_S - __encoding FMMLA_Z_ZZZ_S - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 101xxxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP32MatMulExt() then UNDEFINED; - integer esize = 32; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __encoding FMMLA_Z_ZZZ_D - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 111xxxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer esize = 64; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - if VL < esize * 4 then UNDEFINED; - integer segments = VL DIV (4 * esize); - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result = Zeros(); - bits(4*esize) op1, op2; - bits(4*esize) res, addend; - - for s = 0 to segments-1 - op1 = Elem[operand1, s, 4*esize]; - op2 = Elem[operand2, s, 4*esize]; - addend = Elem[operand3, s, 4*esize]; - res = FPMatMulAdd(addend, op1, op2, esize, FPCR); - Elem[result, s, 4*esize] = res; - - Z[da] = result; - -__instruction aarch64_integer_arithmetic_div - __encoding aarch64_integer_arithmetic_div - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field o1 10 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011010 110xxxxx 00001xxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean unsigned = (o1 == '0'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - integer result; - - if IsZero(operand2) then - result = 0; - else - result = RoundTowardsZero(Real(Int(operand1, unsigned)) / Real(Int(operand2, unsigned))); - - X[d] = result[datasize-1:0]; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_accum - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_accum - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 100101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - bits(esize) product; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - product = (UInt(element1) * UInt(element2))[esize-1:0]; - if sub_op then - Elem[result, e, esize] = Elem[operand3, e, esize] - product; - else - Elem[result, e, esize] = Elem[operand3, e, esize] + product; - - V[d] = result; - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_system_exceptions_runtime_smc - __encoding aarch64_system_exceptions_runtime_smc - __instruction_set A64 - __field imm16 5 +: 16 - __opcode '11010100 000xxxxx xxxxxxxx xxx00011' - __guard TRUE - __decode - bits(16) imm = imm16; - - __execute - AArch64.CheckForSMCUndefOrTrap(imm); - - if SCR_EL3.SMD == '1' then - // SMC disabled - UNDEFINED; - else - AArch64.CallSecureMonitor(imm); - -__instruction PNEXT_P_P_P__ - __encoding PNEXT_P_P_P__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 5 +: 4 - __field Pdn 0 +: 4 - __opcode '00100101 xx011001 1100010x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Pdn); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand = P[dn]; - bits(PL) result; - - integer next = LastActiveElement(operand, esize) + 1; - - while next < elements && (ElemP[mask, next, esize] == '0') do - next = next + 1; - - result = Zeros(); - if next < elements then - ElemP[result, next, esize] = '1'; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[dn] = result; - -__instruction LDNF1D_Z_P_BI_U64 - __encoding LDNF1D_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1111xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_integer_bitfield - __encoding aarch64_integer_bitfield - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field N 22 +: 1 - __field immr 16 +: 6 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10011 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - - boolean inzero; - boolean extend; - integer R; - integer S; - bits(datasize) wmask; - bits(datasize) tmask; - - case opc of - when '00' inzero = TRUE; extend = TRUE; // SBFM - when '01' inzero = FALSE; extend = FALSE; // BFM - when '10' inzero = TRUE; extend = FALSE; // UBFM - when '11' UNDEFINED; - - if sf == '1' && N != '1' then UNDEFINED; - if sf == '0' && (N != '0' || immr[5] != '0' || imms[5] != '0') then UNDEFINED; - - R = UInt(immr); - S = UInt(imms); - (wmask, tmask) = DecodeBitMasks(N, imms, immr, FALSE); - - __execute - bits(datasize) dst = if inzero then Zeros() else X[d]; - bits(datasize) src = X[n]; - - // perform bitfield move on low bits - bits(datasize) bot = (dst AND NOT(wmask)) OR (ROR(src, R) AND wmask); - - // determine extension bits (sign, zero or dest register) - bits(datasize) top = if extend then Replicate(src[S]) else dst; - - // combine extension bits and result bits - X[d] = (top AND NOT(tmask)) OR (bot AND tmask); - -__instruction aarch64_vector_logical - __encoding aarch64_vector_logical - __instruction_set A64 - __field Q 30 +: 1 - __field op 29 +: 1 - __field a 18 +: 1 - __field b 17 +: 1 - __field c 16 +: 1 - __field cmode 12 +: 4 - __field d 9 +: 1 - __field e 8 +: 1 - __field f 7 +: 1 - __field g 6 +: 1 - __field h 5 +: 1 - __field Rd 0 +: 5 - __opcode '0xx01111 00000xxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer rd = UInt(Rd); - - integer datasize = if Q == '1' then 128 else 64; - bits(datasize) imm; - bits(64) imm64; - - ImmediateOp operation; - case cmode:op of - when '0xx00' operation = ImmediateOp_MOVI; - when '0xx01' operation = ImmediateOp_MVNI; - when '0xx10' operation = ImmediateOp_ORR; - when '0xx11' operation = ImmediateOp_BIC; - when '10x00' operation = ImmediateOp_MOVI; - when '10x01' operation = ImmediateOp_MVNI; - when '10x10' operation = ImmediateOp_ORR; - when '10x11' operation = ImmediateOp_BIC; - when '110x0' operation = ImmediateOp_MOVI; - when '110x1' operation = ImmediateOp_MVNI; - when '1110x' operation = ImmediateOp_MOVI; - when '11110' operation = ImmediateOp_MOVI; - when '11111' - // FMOV Dn,#imm is in main FP instruction set - if Q == '0' then UNDEFINED; - operation = ImmediateOp_MOVI; - - imm64 = AdvSIMDExpandImm(op, cmode, a:b:c:d:e:f:g:h); - imm = Replicate(imm64, datasize DIV 64); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand; - bits(datasize) result; - - case operation of - when ImmediateOp_MOVI - result = imm; - when ImmediateOp_MVNI - result = NOT(imm); - when ImmediateOp_ORR - operand = V[rd]; - result = operand OR imm; - when ImmediateOp_BIC - operand = V[rd]; - result = operand AND NOT(imm); - - V[rd] = result; - -__instruction PRFW_I_P_BI_S - __encoding PRFW_I_P_BI_S - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000101 11xxxxxx 010xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 2; - integer offset = SInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) addr; - - if n == 31 then - base = SP[]; - else - base = X[n]; - - addr = base + ((offset * elements) << scale); - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Hint_Prefetch(addr, pref_hint, level, stream); - addr = addr + (1 << scale); - -__instruction aarch64_vector_arithmetic_unary_float_narrow - __encoding aarch64_vector_arithmetic_unary_float_narrow - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 0x100001 011010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16 << UInt(sz); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand = V[n]; - bits(datasize) result; - - for e = 0 to elements-1 - Elem[result, e, esize] = FPConvert(Elem[operand, e, 2*esize], FPCR); - - Vpart[d, part] = result; - -__instruction aarch64_vector_shift_right_sisd - __encoding aarch64_vector_shift_right_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __encoding aarch64_vector_shift_right_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - operand2 = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift; - Elem[result, e, esize] = Elem[operand2, e, esize] + element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_integer_tags_mcsettagarray - __encoding aarch64_integer_tags_mcsettagarray - __instruction_set A64 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 10100000 000000xx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Xt); - integer n = UInt(Xn); - - __execute - if PSTATE.EL == EL0 then - UNDEFINED; - - bits(64) data = X[t]; - bits(64) address; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - integer size = 4*(2^(UInt(GMID_EL1.BS))); - address = Align(address,size); - integer count = size >> LOG2_TAG_GRANULE; - integer index = UInt(address[LOG2_TAG_GRANULE+3:LOG2_TAG_GRANULE]); - - for i = 0 to count-1 - bits(4) tag = data[(index*4)+3:index*4]; - AArch64.MemTag[address, AccType_NORMAL] = tag; - address = address + TAG_GRANULE; - index = index + 1; - -__instruction aarch64_vector_crypto_sha3op_sha256_hash - __encoding aarch64_vector_crypto_sha3op_sha256_hash - __instruction_set A64 - __field Rm 16 +: 5 - __field P 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 000xxxxx 010x00xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if !HaveSHA256Ext() then UNDEFINED; - boolean part1 = (P == '0'); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) result; - if part1 then - result = SHA256hash(V[d], V[n], V[m], TRUE); - else - result = SHA256hash(V[n], V[d], V[m], FALSE); - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_int - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_int - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 xxxxxxxx 0x00x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - integer element1; - integer element2; - bits(esize) product; - - element2 = UInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = UInt(Elem[operand1, e, esize]); - product = (element1 * element2)[esize-1:0]; - if sub_op then - Elem[result, e, esize] = Elem[operand3, e, esize] - product; - else - Elem[result, e, esize] = Elem[operand3, e, esize] + product; - V[d] = result; - -__instruction BIC_Z_P_ZZ__ - __encoding BIC_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx011011 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = element1 AND (NOT element2); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_unpriv - __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - - unpriv_at_el1 = PSTATE.EL == EL1 && !(EL2Enabled() && HaveNVExt() && HCR_EL2.[NV,NV1] == '11'); - unpriv_at_el2 = PSTATE.EL == EL2 && HaveVirtHostExt() && HCR_EL2.[E2H,TGE] == '11'; - - user_access_override = HaveUAOExt() && PSTATE.UAO == '1'; - if !user_access_override && (unpriv_at_el1 || unpriv_at_el2) then - acctype = AccType_UNPRIV; - else - acctype = AccType_NORMAL; - - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction STNT1H_Z_P_BR_Contiguous - __encoding STNT1H_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 100xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(64) offset = X[m]; - bits(VL) src; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - src = Z[t]; - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_STREAM] = Elem[src, e, esize]; - offset = offset + 1; - -__instruction ST3H_Z_P_BI_Contiguous - __encoding ST3H_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 1101xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction FTSMUL_Z_ZZ__ - __encoding FTSMUL_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx0xxxxx 000011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPTrigSMul(element1, element2, FPCR); - - Z[d] = result; - -__instruction aarch64_integer_logical_immediate - __encoding aarch64_integer_logical_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field N 22 +: 1 - __field immr 16 +: 6 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10010 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - bits(datasize) imm; - if sf == '0' && N != '0' then UNDEFINED; - (imm, -) = DecodeBitMasks(N, imms, immr, TRUE); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = imm; - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction FMSB_Z_P_ZZZ__ - __encoding FMSB_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Za 16 +: 5 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx1xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - integer a = UInt(Za); - boolean op1_neg = TRUE; - boolean op3_neg = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[a]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - bits(esize) element3 = Elem[operand3, e, esize]; - - if ElemP[mask, e, esize] == '1' then - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction LD1H_Z_P_AI_S - __encoding LD1H_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 101xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __encoding LD1H_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 101xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_system_barriers_sb - __encoding aarch64_system_barriers_sb - __instruction_set A64 - __field CRm 8 +: 4 - __field opc 5 +: 2 - __opcode '11010101 00000011 0011xxxx 1xx11111' - __guard TRUE - __decode - if !HaveSBExt() then UNDEFINED; - - __execute - SpeculationBarrier(); - -__instruction aarch64_system_barriers_dmb - __encoding aarch64_system_barriers_dmb - __instruction_set A64 - __field CRm 8 +: 4 - __field opc 5 +: 2 - __opcode '11010101 00000011 0011xxxx 1xx11111' - __guard TRUE - __decode - case CRm[3:2] of - when '00' domain = MBReqDomain_OuterShareable; - when '01' domain = MBReqDomain_Nonshareable; - when '10' domain = MBReqDomain_InnerShareable; - when '11' domain = MBReqDomain_FullSystem; - case CRm[1:0] of - when '00' types = MBReqTypes_All; domain = MBReqDomain_FullSystem; - when '01' types = MBReqTypes_Reads; - when '10' types = MBReqTypes_Writes; - when '11' types = MBReqTypes_All; - - __execute - DataMemoryBarrier(domain, types); - -__instruction aarch64_system_exceptions_debug_exception - __encoding aarch64_system_exceptions_debug_exception - __instruction_set A64 - __field imm16 5 +: 16 - __field LL 0 +: 2 - __opcode '11010100 101xxxxx xxxxxxxx xxx000xx' - __guard TRUE - __decode - bits(2) target_level = LL; - if LL == '00' then UNDEFINED; - if !Halted() then UNDEFINED; - - __execute - DCPSInstruction(target_level); - -__instruction aarch64_vector_arithmetic_unary_float_round_frint_32_64 - __encoding aarch64_vector_arithmetic_unary_float_round_frint_32_64 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x100001 111x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFrintExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer intsize = if op == '0' then 32 else 64; - FPRounding rounding = if U == '0' then FPRounding_ZERO else FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundIntN(element, FPCR, rounding, intsize); - - V[d] = result; - -__instruction LD3B_Z_P_BI_Contiguous - __encoding LD3B_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0100xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction FCPY_Z_P_I__ - __encoding FCPY_Z_P_I__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 16 +: 4 - __field imm8 5 +: 8 - __field Zd 0 +: 5 - __opcode '00000101 xx01xxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer d = UInt(Zd); - bits(esize) imm = VFPExpandImm(imm8); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = imm; - - Z[d] = result; - -__instruction NOR_P_P_PP_Z - __encoding NOR_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 1000xxxx 01xxxx1x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding NORS_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 1100xxxx 01xxxx1x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - for e = 0 to elements-1 - bit element1 = ElemP[operand1, e, esize]; - bit element2 = ElemP[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - ElemP[result, e, esize] = NOT(element1 OR element2); - else - ElemP[result, e, esize] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_memory_vector_multiple_no_wb - __encoding aarch64_memory_vector_multiple_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 0x000000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_multiple_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << UInt(size); - integer elements = datasize DIV esize; - - integer rpt; // number of iterations - integer selem; // structure elements - - case opcode of - when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers) - when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers) - when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers) - when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers) - when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register) - when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers) - when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers) - otherwise UNDEFINED; - - // .1D format only permitted with LD1 & ST1 - if size:Q == '110' && selem != 1 then UNDEFINED; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(datasize) rval; - integer tt; - constant integer ebytes = esize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - for r = 0 to rpt-1 - for e = 0 to elements-1 - tt = (t + r) MOD 32; - for s = 0 to selem-1 - rval = V[tt]; - if memop == MemOp_LOAD then - Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[tt] = rval; - else // memop == MemOp_STORE - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize]; - offs = offs + ebytes; - tt = (tt + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction LD4W_Z_P_BI_Contiguous - __encoding LD4W_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0110xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_integer_bitfield - __encoding aarch64_integer_bitfield - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field N 22 +: 1 - __field immr 16 +: 6 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10011 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - - boolean inzero; - boolean extend; - integer R; - integer S; - bits(datasize) wmask; - bits(datasize) tmask; - - case opc of - when '00' inzero = TRUE; extend = TRUE; // SBFM - when '01' inzero = FALSE; extend = FALSE; // BFM - when '10' inzero = TRUE; extend = FALSE; // UBFM - when '11' UNDEFINED; - - if sf == '1' && N != '1' then UNDEFINED; - if sf == '0' && (N != '0' || immr[5] != '0' || imms[5] != '0') then UNDEFINED; - - R = UInt(immr); - S = UInt(imms); - (wmask, tmask) = DecodeBitMasks(N, imms, immr, FALSE); - - __execute - bits(datasize) dst = if inzero then Zeros() else X[d]; - bits(datasize) src = X[n]; - - // perform bitfield move on low bits - bits(datasize) bot = (dst AND NOT(wmask)) OR (ROR(src, R) AND wmask); - - // determine extension bits (sign, zero or dest register) - bits(datasize) top = if extend then Replicate(src[S]) else dst; - - // combine extension bits and result bits - X[d] = (top AND NOT(tmask)) OR (bot AND tmask); - -__instruction aarch64_memory_single_simdfp_immediate_signed_post_idx - __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111100 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111100 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_simdfp_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111101 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_VEC; - MemOp memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - bits(64) address; - bits(datasize) data; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data = V[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - V[t] = data; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction SDIV_Z_P_ZZ__ - __encoding SDIV_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010100 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '0x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer quotient; - if element2 == 0 then - quotient = 0; - else - quotient = RoundTowardsZero(Real(element1) / Real(element2)); - Elem[result, e, esize] = quotient[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction STNT1D_Z_P_BR_Contiguous - __encoding STNT1D_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 100xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(64) offset = X[m]; - bits(VL) src; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - src = Z[t]; - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_STREAM] = Elem[src, e, esize]; - offset = offset + 1; - -__instruction aarch64_memory_pair_general_post_idx - __encoding aarch64_memory_pair_general_post_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101000 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - - __encoding aarch64_memory_pair_general_pre_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101001 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - - __encoding aarch64_memory_pair_general_offset - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101001 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); - AccType acctype = AccType_NORMAL; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - if L:opc[0] == '01' || opc == '11' then UNDEFINED; - boolean signed = (opc[0] != '0'); - integer scale = 2 + UInt(opc[1]); - integer datasize = 8 << scale; - bits(64) offset = LSL(SignExtend(imm7, 64), scale); - boolean tag_checked = wback || n != 31; - __execute - bits(64) address; - bits(datasize) data1; - bits(datasize) data2; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - boolean wb_unknown = FALSE; - - if memop == MemOp_LOAD && wback && (t == n || t2 == n) && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && (t == n || t2 == n) && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is pre-writeback - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_LOAD && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown && t == n then - data1 = bits(datasize) UNKNOWN; - else - data1 = X[t]; - if rt_unknown && t2 == n then - data2 = bits(datasize) UNKNOWN; - else - data2 = X[t2]; - Mem[address + 0 , dbytes, acctype] = data1; - Mem[address + dbytes, dbytes, acctype] = data2; - - when MemOp_LOAD - data1 = Mem[address + 0 , dbytes, acctype]; - data2 = Mem[address + dbytes, dbytes, acctype]; - if rt_unknown then - data1 = bits(datasize) UNKNOWN; - data2 = bits(datasize) UNKNOWN; - if signed then - X[t] = SignExtend(data1, 64); - X[t2] = SignExtend(data2, 64); - else - X[t] = data1; - X[t2] = data2; - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction LASTA_V_P_Z__ - __encoding LASTA_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000101 xx100010 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - boolean isBefore = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - integer last = LastActiveElement(mask, esize); - - if isBefore then - if last < 0 then last = elements - 1; - else - last = last + 1; - if last >= elements then last = 0; - V[d] = Elem[operand, last, esize]; - -__instruction aarch64_vector_arithmetic_binary_uniform_sub_saturating_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_sub_saturating_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 001011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_sub_saturating_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 001011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer diff; - boolean sat; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - diff = element1 - element2; - (Elem[result, e, esize], sat) = SatQ(diff, esize, unsigned); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_memory_vector_multiple_no_wb - __encoding aarch64_memory_vector_multiple_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 0x000000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_multiple_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << UInt(size); - integer elements = datasize DIV esize; - - integer rpt; // number of iterations - integer selem; // structure elements - - case opcode of - when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers) - when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers) - when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers) - when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers) - when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register) - when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers) - when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers) - otherwise UNDEFINED; - - // .1D format only permitted with LD1 & ST1 - if size:Q == '110' && selem != 1 then UNDEFINED; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(datasize) rval; - integer tt; - constant integer ebytes = esize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - for r = 0 to rpt-1 - for e = 0 to elements-1 - tt = (t + r) MOD 32; - for s = 0 to selem-1 - rval = V[tt]; - if memop == MemOp_LOAD then - Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[tt] = rval; - else // memop == MemOp_STORE - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize]; - offs = offs + ebytes; - tt = (tt + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction FDIVR_Z_P_ZZ__ - __encoding FDIVR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx001100 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPDiv(element2, element1, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction aarch64_integer_ins_ext_insert_movewide - __encoding aarch64_integer_ins_ext_insert_movewide - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field hw 21 +: 2 - __field imm16 5 +: 16 - __field Rd 0 +: 5 - __opcode 'xxx10010 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer datasize = if sf == '1' then 64 else 32; - bits(16) imm = imm16; - integer pos; - MoveWideOp opcode; - - case opc of - when '00' opcode = MoveWideOp_N; - when '10' opcode = MoveWideOp_Z; - when '11' opcode = MoveWideOp_K; - otherwise UNDEFINED; - - if sf == '0' && hw[1] == '1' then UNDEFINED; - pos = UInt(hw:'0000'); - - __execute - bits(datasize) result; - - if opcode == MoveWideOp_K then - result = X[d]; - else - result = Zeros(); - - result[pos+15:pos] = imm; - if opcode == MoveWideOp_N then - result = NOT(result); - X[d] = result; - -__instruction EOR_Z_P_ZZ__ - __encoding EOR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx011001 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = element1 EOR element2; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction FSUBR_Z_P_ZZ__ - __encoding FSUBR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx000011 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPSub(element2, element1, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction PRFD_I_P_AI_S - __encoding PRFD_I_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000101 100xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 3; - integer offset = UInt(imm5); - - __encoding PRFD_I_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000101 100xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 3; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) base; - bits(64) addr; - base = Z[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + (offset << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - -__instruction aarch64_branch_unconditional_dret - __encoding aarch64_branch_unconditional_dret - __instruction_set A64 - __opcode '11010110 10111111 00000011 11100000' - __guard TRUE - __decode - if !Halted() || PSTATE.EL == EL0 then UNDEFINED; - - __execute - DRPSInstruction(); - -__instruction aarch64_vector_arithmetic_unary_extract_sat_sisd - __encoding aarch64_vector_arithmetic_unary_extract_sat_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 010010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer part = 0; - integer elements = 1; - - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_extract_sat_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 010010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand = V[n]; - bits(datasize) result; - bits(2*esize) element; - boolean sat; - - for e = 0 to elements-1 - element = Elem[operand, e, 2*esize]; - (Elem[result, e, esize], sat) = SatQ(Int(element, unsigned), esize, unsigned); - if sat then FPSR.QC = '1'; - - Vpart[d, part] = result; - -__instruction ST3B_Z_P_BI_Contiguous - __encoding ST3B_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 0101xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction LD1RH_Z_P_BI_U16 - __encoding LD1RH_Z_P_BI_U16 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 11xxxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __encoding LD1RH_Z_P_BI_U32 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 11xxxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __encoding LD1RH_Z_P_BI_U64 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 11xxxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - integer last = LastActiveElement(mask, esize); - if last >= 0 then - addr = base + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction UQADD_Z_ZZ__ - __encoding UQADD_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 000101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + element2, esize, unsigned); - - Z[d] = result; - -__instruction LDNF1SH_Z_P_BI_S32 - __encoding LDNF1SH_Z_P_BI_S32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0011xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __encoding LDNF1SH_Z_P_BI_S64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0001xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_integer_flags_xaflag - __encoding aarch64_integer_flags_xaflag - __instruction_set A64 - __field CRm 8 +: 4 - __opcode '11010101 00000000 0100xxxx 00111111' - __guard TRUE - __decode - if !HaveFlagFormatExt() then UNDEFINED; - - __execute - bit N = NOT(PSTATE.C) AND NOT(PSTATE.Z); - bit Z = PSTATE.Z AND PSTATE.C; - bit C = PSTATE.C OR PSTATE.Z; - bit V = NOT(PSTATE.C) AND PSTATE.Z; - - PSTATE.N = N; - PSTATE.Z = Z; - PSTATE.C = C; - PSTATE.V = V; - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction ST1W_Z_P_BZ_S_x32_scaled - __encoding ST1W_Z_P_BZ_S_x32_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 011xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 2; - - __encoding ST1W_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 001xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 2; - - __encoding ST1W_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 000xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding ST1W_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 010xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding ST1W_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 001xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 2; - - __encoding ST1W_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 000xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(VL) offset = Z[m]; - bits(VL) src = Z[t]; - bits(PL) mask = P[g]; - bits(64) addr; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - -__instruction SMAXV_R_P_Z__ - __encoding SMAXV_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000100 xx001000 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - integer maximum = if unsigned then 0 else -(2^(esize-1)); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer element = Int(Elem[operand, e, esize], unsigned); - maximum = Max(maximum, element); - - V[d] = maximum[esize-1:0]; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if abs then - element1 = FPAbs(element1); - element2 = FPAbs(element2); - case cmp of - when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR); - when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction ST1D_Z_P_BZ_D_x32_scaled - __encoding ST1D_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 101xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 3; - - __encoding ST1D_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 100xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding ST1D_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 101xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 3; - - __encoding ST1D_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 100xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(VL) offset = Z[m]; - bits(VL) src = Z[t]; - bits(PL) mask = P[g]; - bits(64) addr; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - -__instruction UQINCH_R_RS_UW - __encoding UQINCH_R_RS_UW - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0110xxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQINCH_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0111xxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 + (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction LDNF1SB_Z_P_BI_S16 - __encoding LDNF1SB_Z_P_BI_S16 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1101xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __encoding LDNF1SB_Z_P_BI_S32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1011xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __encoding LDNF1SB_Z_P_BI_S64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1001xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - addr = addr + mbytes; - - Z[t] = result; - -__instruction CNTP_R_P_P__ - __encoding CNTP_R_P_P__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Rd 0 +: 5 - __opcode '00100101 xx100000 10xxxx0x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Pn); - integer d = UInt(Rd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand = P[n]; - bits(64) sum = Zeros(); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' && ElemP[operand, e, esize] == '1' then - sum = sum + 1; - X[d] = sum; - -__instruction aarch64_vector_reduce_fp16_maxnm_simd - __encoding aarch64_vector_reduce_fp16_maxnm_simd - __instruction_set A64 - __field Q 30 +: 1 - __field o1 23 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 x0110000 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM; - - __encoding aarch64_vector_reduce_fp_maxnm_simd - __instruction_set A64 - __field Q 30 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx110000 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q != '01' then UNDEFINED; // .4S only - - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction PFALSE_P__ - __encoding PFALSE_P__ - __instruction_set A64 - __field Pd 0 +: 4 - __opcode '00100101 00011000 11100100 0000xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer d = UInt(Pd); - - __execute - CheckSVEEnabled(); - P[d] = Zeros(PL); - -__instruction aarch64_vector_shift_conv_int_sisd - __encoding aarch64_vector_shift_conv_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then UNDEFINED; - integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16; - integer datasize = esize; - integer elements = 1; - - integer fracbits = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding aarch64_vector_shift_conv_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then UNDEFINED; - if immh[3]:Q == '10' then UNDEFINED; - integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer fracbits = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - FPRounding rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FixedToFP(element, fracbits, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction aarch64_vector_shift_left_long - __encoding aarch64_vector_shift_left_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 101001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = UInt(immh:immb) - esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = Vpart[n, part]; - bits(datasize*2) result; - integer element; - - for e = 0 to elements-1 - element = Int(Elem[operand, e, esize], unsigned) << shift; - Elem[result, e, 2*esize] = element[2*esize-1:0]; - - V[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction FSUB_Z_P_ZS__ - __encoding FSUB_Z_P_ZS__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field i1 5 +: 1 - __field Zdn 0 +: 5 - __opcode '01100101 xx011001 100xxx00 00xxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - bits(esize) imm = if i1 == '0' then FPPointFive('0') else FPOne('0'); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPSub(element1, imm, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction LDR_Z_BI__ - __encoding LDR_Z_BI__ - __instruction_set A64 - __field imm9h 16 +: 6 - __field imm9l 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 10xxxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer imm = SInt(imm9h:imm9l); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 8; - bits(64) base; - integer offset = imm * elements; - bits(VL) result; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - boolean aligned = AArch64.CheckAlignment(base + offset, 16, AccType_NORMAL, FALSE); - for e = 0 to elements-1 - Elem[result, e, 8] = AArch64.MemSingle[base + offset, 1, AccType_NORMAL, aligned]; - offset = offset + 1; - - Z[t] = result; - -__instruction aarch64_vector_transfer_vector_permute_unzip - __encoding aarch64_vector_transfer_vector_permute_unzip - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx0xxxxx 0x0110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer part = UInt(op); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operandl = V[n]; - bits(datasize) operandh = V[m]; - bits(datasize) result; - - bits(datasize*2) zipped = operandh:operandl; - for e = 0 to elements-1 - Elem[result, e, esize] = Elem[zipped, 2*e+part, esize]; - - V[d] = result; - -__instruction aarch64_float_arithmetic_mul_product - __encoding aarch64_float_arithmetic_mul_product - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field op 15 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx x00010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean negated = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - result = FPMul(operand1, operand2, FPCR); - - if negated then result = FPNeg(result); - - V[d] = result; - -__instruction AND_Z_ZZ__ - __encoding AND_Z_ZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 001xxxxx 001100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - - Z[d] = operand1 AND operand2; - -__instruction FABD_Z_P_ZZ__ - __encoding FABD_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx001000 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPAbs(FPSub(element1, element2, FPCR)); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction CPY_Z_P_V__ - __encoding CPY_Z_P_V__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Vn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx100000 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Vn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(esize) operand1 = V[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = operand1; - - Z[d] = result; - -__instruction ST4D_Z_P_BI_Contiguous - __encoding ST4D_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 1111xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_accum - __encoding aarch64_vector_arithmetic_binary_disparate_mul_accum - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 10x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - bits(2*esize) accum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - if sub_op then - accum = Elem[operand3, e, 2*esize] - product; - else - accum = Elem[operand3, e, 2*esize] + product; - Elem[result, e, 2*esize] = accum; - - V[d] = result; - -__instruction ST1W_Z_P_BR__ - __encoding ST1W_Z_P_BR__ - __instruction_set A64 - __field size 21 +: 2 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 0xxxxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size != '1x' then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8 << UInt(size); - integer msize = 32; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - bits(VL) src = Z[t]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - offset = offset + 1; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_vector_arithmetic_unary_diff_neg_sat_sisd - __encoding aarch64_vector_arithmetic_unary_diff_neg_sat_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 011110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean neg = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_diff_neg_sat_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 011110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean neg = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = SInt(Elem[operand, e, esize]); - if neg then - element = -element; - else - element = Abs(element); - (Elem[result, e, esize], sat) = SignedSatQ(element, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_float_arithmetic_max_min - __encoding aarch64_float_arithmetic_max_min - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field op 12 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx 01xx10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - FPMaxMinOp operation; - case op of - when '00' operation = FPMaxMinOp_MAX; - when '01' operation = FPMaxMinOp_MIN; - when '10' operation = FPMaxMinOp_MAXNUM; - when '11' operation = FPMaxMinOp_MINNUM; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - case operation of - when FPMaxMinOp_MAX result = FPMax(operand1, operand2, FPCR); - when FPMaxMinOp_MIN result = FPMin(operand1, operand2, FPCR); - when FPMaxMinOp_MAXNUM result = FPMaxNum(operand1, operand2, FPCR); - when FPMaxMinOp_MINNUM result = FPMinNum(operand1, operand2, FPCR); - - V[d] = result; - -__instruction ST1W_Z_P_BI__ - __encoding ST1W_Z_P_BI__ - __instruction_set A64 - __field size 21 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 0xx0xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size != '1x' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8 << UInt(size); - integer msize = 32; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) src = Z[t]; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - addr = addr + mbytes; - -__instruction ST4B_Z_P_BR_Contiguous - __encoding ST4B_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 011xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction aarch64_integer_conditional_compare_register - __encoding aarch64_integer_conditional_compare_register - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field Rn 5 +: 5 - __field nzcv 0 +: 4 - __opcode 'xx111010 010xxxxx xxxx00xx xxx0xxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - bits(4) condition = cond; - bits(4) flags = nzcv; - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bit carry_in = '0'; - - if ConditionHolds(condition) then - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - (-, flags) = AddWithCarry(operand1, operand2, carry_in); - PSTATE.[N,Z,C,V] = flags; - -__instruction LD1RD_Z_P_BI_U64 - __encoding LD1RD_Z_P_BI_U64 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 11xxxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - integer last = LastActiveElement(mask, esize); - if last >= 0 then - addr = base + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction ADD_Z_ZZ__ - __encoding ADD_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = element1 + element2; - - Z[d] = result; - -__instruction aarch64_memory_ordered_rcpc - __encoding aarch64_memory_ordered_rcpc - __instruction_set A64 - __field size 30 +: 2 - __field Rs 16 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 101xxxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = AccType_ORDERED; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_float_arithmetic_max_min - __encoding aarch64_float_arithmetic_max_min - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field op 12 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx 01xx10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - FPMaxMinOp operation; - case op of - when '00' operation = FPMaxMinOp_MAX; - when '01' operation = FPMaxMinOp_MIN; - when '10' operation = FPMaxMinOp_MAXNUM; - when '11' operation = FPMaxMinOp_MINNUM; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - case operation of - when FPMaxMinOp_MAX result = FPMax(operand1, operand2, FPCR); - when FPMaxMinOp_MIN result = FPMin(operand1, operand2, FPCR); - when FPMaxMinOp_MAXNUM result = FPMaxNum(operand1, operand2, FPCR); - when FPMaxMinOp_MINNUM result = FPMinNum(operand1, operand2, FPCR); - - V[d] = result; - -__instruction UUNPKHI_Z_Z__ - __encoding UUNPKHI_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx110011 001110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = TRUE; - boolean hi = TRUE; - - __encoding UUNPKLO_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx110010 001110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = TRUE; - boolean hi = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer hsize = esize DIV 2; - bits(VL) operand = Z[n]; - bits(VL) result; - - for e = 0 to elements-1 - bits(hsize) element = if hi then Elem[operand, e + elements, hsize] else Elem[operand, e, hsize]; - Elem[result, e, esize] = Extend(element, esize, unsigned); - - Z[d] = result; - -__instruction DECB_R_RS__ - __encoding DECB_R_RS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0011xxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding DECD_R_RS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1111xxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding DECH_R_RS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0111xxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding DECW_R_RS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1011xxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(64) operand1 = X[dn]; - - X[dn] = operand1 - (count * imm); - -__instruction aarch64_vector_shift_left_insert_sisd - __encoding aarch64_vector_shift_left_insert_sisd - __instruction_set A64 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111111 0xxxxxxx 010101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = UInt(immh:immb) - esize; - - __encoding aarch64_vector_shift_left_insert_simd - __instruction_set A64 - __field Q 30 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 0xxxxxxx 010101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = UInt(immh:immb) - esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2 = V[d]; - bits(datasize) result; - bits(esize) mask = LSL(Ones(esize), shift); - bits(esize) shifted; - - for e = 0 to elements-1 - shifted = LSL(Elem[operand, e, esize], shift); - Elem[result, e, esize] = (Elem[operand2, e, esize] AND NOT(mask)) OR shifted; - V[d] = result; - -__instruction INCP_R_P_R__ - __encoding INCP_R_P_R__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101100 1000100x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) operand1 = X[dn]; - bits(PL) operand2 = P[m]; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - X[dn] = operand1 + count; - -__instruction aarch64_integer_arithmetic_mul_uniform_add_sub - __encoding aarch64_integer_arithmetic_mul_uniform_add_sub - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011011 000xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer a = UInt(Ra); - integer destsize = if sf == '1' then 64 else 32; - integer datasize = destsize; - boolean sub_op = (o0 == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(destsize) operand3 = X[a]; - - integer result; - - if sub_op then - result = UInt(operand3) - (UInt(operand1) * UInt(operand2)); - else - result = UInt(operand3) + (UInt(operand1) * UInt(operand2)); - - X[d] = result[destsize-1:0]; - -__instruction aarch64_vector_arithmetic_unary_special_sqrt_est_fp16_sisd - __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_fp16_sisd - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 11111001 110110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_float_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 1x100001 110110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 11111001 110110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __encoding aarch64_vector_arithmetic_unary_special_sqrt_est_float_simd - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 1x100001 110110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRSqrtEstimate(element, FPCR); - - V[d] = result; - -__instruction aarch64_memory_vector_multiple_no_wb - __encoding aarch64_memory_vector_multiple_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 0x000000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_multiple_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << UInt(size); - integer elements = datasize DIV esize; - - integer rpt; // number of iterations - integer selem; // structure elements - - case opcode of - when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers) - when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers) - when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers) - when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers) - when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register) - when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers) - when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers) - otherwise UNDEFINED; - - // .1D format only permitted with LD1 & ST1 - if size:Q == '110' && selem != 1 then UNDEFINED; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(datasize) rval; - integer tt; - constant integer ebytes = esize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - for r = 0 to rpt-1 - for e = 0 to elements-1 - tt = (t + r) MOD 32; - for s = 0 to selem-1 - rval = V[tt]; - if memop == MemOp_LOAD then - Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[tt] = rval; - else // memop == MemOp_STORE - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize]; - offs = offs + ebytes; - tt = (tt + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction RDVL_R_I__ - __encoding RDVL_R_I__ - __instruction_set A64 - __field imm6 5 +: 6 - __field Rd 0 +: 5 - __opcode '00000100 10111111 01010xxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer d = UInt(Rd); - integer imm = SInt(imm6); - - __execute - CheckSVEEnabled(); - integer len = imm * (VL DIV 8); - X[d] = len[63:0]; - -__instruction LDFF1D_Z_P_BR_U64 - __encoding LDFF1D_Z_P_BR_U64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 111xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + UInt(offset) * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_CNOTFIRST]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - offset = offset + 1; - - Z[t] = result; - -__instruction LD1ROW_Z_P_BI_U32 - __encoding LD1ROW_Z_P_BI_U32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0010xxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - if VL < 256 then UNDEFINED; - integer elements = 256 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low bits only - bits(256) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * 32; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = ZeroExtend(Replicate(result, VL DIV 256), VL); - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 001101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_1985 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - - if minimum then - Elem[result, e, esize] = FPMin(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMax(element1, element2, FPCR); - - V[d] = result; - -__instruction FNMLS_Z_P_ZZZ__ - __encoding FNMLS_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100101 xx1xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = FALSE; - boolean op3_neg = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - bits(esize) element3 = Elem[operand3, e, esize]; - - if ElemP[mask, e, esize] == '1' then - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - else - Elem[result, e, esize] = element3; - - Z[da] = result; - -__instruction ST1B_Z_P_AI_S - __encoding ST1B_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 011xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - integer offset = UInt(imm5); - - __encoding ST1B_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 010xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(VL) src = Z[t]; - bits(PL) mask = P[g]; - bits(64) addr; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction LDFF1H_Z_P_AI_S - __encoding LDFF1H_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 101xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __encoding LDFF1H_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 101xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_narrow - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_narrow - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 01x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean round = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand1 = V[n]; - bits(2*datasize) operand2 = V[m]; - bits(datasize) result; - integer round_const = if round then 1 << (esize - 1) else 0; - bits(2*esize) element1; - bits(2*esize) element2; - bits(2*esize) sum; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, 2*esize]; - element2 = Elem[operand2, e, 2*esize]; - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - sum = sum + round_const; - Elem[result, e, esize] = sum[2*esize-1:esize]; - - Vpart[d, part] = result; - -__instruction FMAX_Z_P_ZZ__ - __encoding FMAX_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx000110 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMax(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_sisd - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 xx0xxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' || size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean rounding = TRUE; - boolean sub_op = (S == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx0xxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' || size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean rounding = TRUE; - boolean sub_op = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - integer rounding_const = if rounding then 1 << (esize - 1) else 0; - integer element1; - integer element2; - integer element3; - integer product; - boolean sat; - - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - element2 = SInt(Elem[operand2, e, esize]); - element3 = SInt(Elem[operand3, e, esize]); - if sub_op then - accum = ((element3 << esize) - 2 * (element1 * element2) + rounding_const); - else - accum = ((element3 << esize) + 2 * (element1 * element2) + rounding_const); - (Elem[result, e, esize], sat) = SignedSatQ(accum >> esize, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction LSR_Z_ZI__ - __encoding LSR_Z_ZI__ - __instruction_set A64 - __field tszh 22 +: 2 - __field tszl 19 +: 2 - __field imm3 16 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 100101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - bits(4) tsize = tszh:tszl; - case tsize of - when '0000' UNDEFINED; - when '0001' esize = 8; - when '001x' esize = 16; - when '01xx' esize = 32; - when '1xxx' esize = 64; - integer n = UInt(Zn); - integer d = UInt(Zd); - integer shift = (2 * esize) - UInt(tsize:imm3); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - Elem[result, e, esize] = LSR(element1, shift); - - Z[d] = result; - -__instruction LD1RSW_Z_P_BI_S64 - __encoding LD1RSW_Z_P_BI_S64 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 11xxxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = FALSE; - integer offset = UInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - integer last = LastActiveElement(mask, esize); - if last >= 0 then - addr = base + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_branch_unconditional_register - __encoding aarch64_branch_unconditional_register - __instruction_set A64 - __field Z 24 +: 1 - __field op 21 +: 2 - __field A 11 +: 1 - __field M 10 +: 1 - __field Rn 5 +: 5 - __field Rm 0 +: 5 - __opcode '1101011x 0xx11111 0000xxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - BranchType branch_type; - integer m = UInt(Rm); - boolean pac = (A == '1'); - boolean use_key_a = (M == '0'); - boolean source_is_sp = ((Z == '1') && (m == 31)); - - if !pac && m != 0 then - UNDEFINED; - elsif pac && !HavePACExt() then - UNDEFINED; - - case op of - when '00' branch_type = BranchType_INDIR; - when '01' branch_type = BranchType_INDCALL; - when '10' branch_type = BranchType_RET; - otherwise UNDEFINED; - - if pac then - if Z == '0' && m != 31 then - UNDEFINED; - - if branch_type == BranchType_RET then - if n != 31 then UNDEFINED; - n = 30; - source_is_sp = TRUE; - - __execute - bits(64) target = X[n]; - boolean auth_then_branch = TRUE; - - if pac then - bits(64) modifier = if source_is_sp then SP[] else X[m]; - - if use_key_a then - target = AuthIA(target, modifier, auth_then_branch); - else - target = AuthIB(target, modifier, auth_then_branch); - - if branch_type == BranchType_INDCALL then X[30] = PC[] + 4; - - // Value in BTypeNext will be used to set PSTATE.BTYPE - case branch_type of - when BranchType_INDIR // BR, BRAA, BRAB, BRAAZ, BRABZ - if InGuardedPage then - if n == 16 || n == 17 then - BTypeNext = '01'; - else - BTypeNext = '11'; - else - BTypeNext = '01'; - when BranchType_INDCALL // BLR, BLRAA, BLRAB, BLRAAZ, BLRABZ - BTypeNext = '10'; - when BranchType_RET // RET, RETAA, RETAB - BTypeNext = '00'; - - BranchTo(target, branch_type); - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp16_sisd - __instruction_set A64 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 00xxxxxx 0x01x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer index = UInt(H:L:M); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - boolean sub_op = (o2 == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 1xxxxxxx 0x01x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi = M; - case sz:L of - when '0x' index = UInt(H:L); - when '10' index = UInt(H); - when '11' UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - boolean sub_op = (o2 == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 00xxxxxx 0x01x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer index = UInt(H:L:M); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (o2 == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 1xxxxxxx 0x01x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi = M; - case sz:L of - when '0x' index = UInt(H:L); - when '10' index = UInt(H); - when '11' UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2 = Elem[operand2, index, esize]; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR); - V[d] = result; - -__instruction ORV_R_P_Z__ - __encoding ORV_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000100 xx011000 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(esize) result = Zeros(esize); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - result = result OR Elem[operand, e, esize]; - - V[d] = result; - -__instruction aarch64_integer_flags_rmif - __encoding aarch64_integer_flags_rmif - __instruction_set A64 - __field sf 31 +: 1 - __field imm6 15 +: 6 - __field Rn 5 +: 5 - __field mask 0 +: 4 - __opcode 'x0111010 000xxxxx x00001xx xxx0xxxx' - __guard TRUE - __decode - if !HaveFlagManipulateExt() || sf != '1' then UNDEFINED; - integer lsb = UInt(imm6); - integer n = UInt(Rn); - - __execute - bits(4) tmp; - bits(64) tmpreg = X[n]; - tmp = (tmpreg:tmpreg)[lsb+3:lsb]; - if mask[3] == '1' then PSTATE.N = tmp[3]; - if mask[2] == '1' then PSTATE.Z = tmp[2]; - if mask[1] == '1' then PSTATE.C = tmp[1]; - if mask[0] == '1' then PSTATE.V = tmp[0]; - -__instruction FMLS_Z_ZZZi_H - __encoding FMLS_Z_ZZZi_H - __instruction_set A64 - __field i3h 22 +: 1 - __field i3l 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 0x1xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer index = UInt(i3h:i3l); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = TRUE; - boolean op3_neg = FALSE; - - __encoding FMLS_Z_ZZZi_S - __instruction_set A64 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 101xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer index = UInt(i2); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = TRUE; - boolean op3_neg = FALSE; - - __encoding FMLS_Z_ZZZi_D - __instruction_set A64 - __field i1 20 +: 1 - __field Zm 16 +: 4 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 111xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer index = UInt(i1); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = TRUE; - boolean op3_neg = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer eltspersegment = 128 DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result = Z[da]; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = segmentbase + index; - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, s, esize]; - bits(esize) element3 = Elem[result, e, esize]; - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - - Z[da] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_long - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 xxxxxxxx 0x10x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(idxdsize) operand2 = V[m]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - - element2 = Int(Elem[operand2, index, esize], unsigned); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - if sub_op then - Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] - product; - else - Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] + product; - - V[d] = result; - -__instruction UQINCD_Z_ZS__ - __encoding UQINCD_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1110xxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_pair - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_pair - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 1010x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - integer element1; - integer element2; - integer maxmin; - - for e = 0 to elements-1 - element1 = Int(Elem[concat, 2*e, esize], unsigned); - element2 = Int(Elem[concat, (2*e)+1, esize], unsigned); - maxmin = if minimum then Min(element1, element2) else Max(element1, element2); - Elem[result, e, esize] = maxmin[esize-1:0]; - - V[d] = result; - -__instruction ADDPL_R_RI__ - __encoding ADDPL_R_RI__ - __instruction_set A64 - __field Rn 16 +: 5 - __field imm6 5 +: 6 - __field Rd 0 +: 5 - __opcode '00000100 011xxxxx 01010xxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer n = UInt(Rn); - integer d = UInt(Rd); - integer imm = SInt(imm6); - - __execute - CheckSVEEnabled(); - bits(64) operand1 = if n == 31 then SP[] else X[n]; - bits(64) result = operand1 + (imm * (PL DIV 8)); - - if d == 31 then - SP[] = result; - else - X[d] = result; - -__instruction BRKPB_P_P_PP__ - __encoding BRKPB_P_P_PP__ - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0000xxxx 11xxxx0x xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding BRKPBS_P_P_PP__ - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0100xxxx 11xxxx0x xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - boolean last = (LastActive(mask, operand1, 8) == '1'); - - for e = 0 to elements-1 - if ElemP[mask, e, 8] == '1' then - last = last && (ElemP[operand2, e, 8] == '0'); - ElemP[result, e, 8] = if last then '1' else '0'; - else - ElemP[result, e, 8] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction USDOT_Z_ZZZi_S - __encoding USDOT_Z_ZZZi_S - __instruction_set A64 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000100 101xxxxx 000110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveInt8MatMulExt() then UNDEFINED; - integer esize = 32; - integer index = UInt(i2); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer eltspersegment = 128 DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = segmentbase + index; - bits(esize) res = Elem[operand3, e, esize]; - for i = 0 to 3 - integer element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - integer element2 = SInt(Elem[operand2, 4 * s + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = res; - - Z[da] = result; - -__instruction CLASTA_Z_P_ZZ__ - __encoding CLASTA_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000101 xx101000 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean isBefore = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - integer last = LastActiveElement(mask, esize); - - if last < 0 then - result = operand1; - else - if !isBefore then - last = last + 1; - if last >= elements then last = 0; - for e = 0 to elements-1 - Elem[result, e, esize] = Elem[operand2, last, esize]; - - Z[dn] = result; - -__instruction FMAXV_V_P_Z__ - __encoding FMAXV_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '01100101 xx000110 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(esize) identity = FPInfinity('1'); - - V[d] = ReducePredicated(ReduceOp_FMAX, operand, mask, identity); - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 001101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_1985 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - - if minimum then - Elem[result, e, esize] = FPMin(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMax(element1, element2, FPCR); - - V[d] = result; - -__instruction FMUL_Z_P_ZS__ - __encoding FMUL_Z_P_ZS__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field i1 5 +: 1 - __field Zdn 0 +: 5 - __opcode '01100101 xx011010 100xxx00 00xxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - bits(esize) imm = if i1 == '0' then FPPointFive('0') else FPTwo('0'); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMul(element1, imm, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction FSQRT_Z_P_Z__ - __encoding FSQRT_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx001101 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPSqrt(element, FPCR); - - Z[d] = result; - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction PRFB_I_P_BR_S - __encoding PRFB_I_P_BR_S - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000100 000xxxxx 110xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) offset = X[m]; - bits(64) addr; - - if n == 31 then - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + (UInt(offset) << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - offset = offset + 1; - -__instruction LDFF1D_Z_P_AI_D - __encoding LDFF1D_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 101xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction COMPACT_Z_P_Z__ - __encoding COMPACT_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx100001 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '0x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) result; - integer x = 0; - - for e = 0 to elements-1 - Elem[result, e, esize] = Zeros(); - if ElemP[mask, e, esize] == '1' then - bits(esize) element = Elem[operand1, e, esize]; - Elem[result, x, esize] = element; - x = x + 1; - - Z[d] = result; - -__instruction BRKA_P_P_P__ - __encoding BRKA_P_P_P__ - __instruction_set A64 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field M 4 +: 1 - __field Pd 0 +: 4 - __opcode '00100101 00010000 01xxxx0x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer d = UInt(Pd); - boolean merging = (M == '1'); - boolean setflags = FALSE; - - __encoding BRKAS_P_P_P_Z - __instruction_set A64 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 01010000 01xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer d = UInt(Pd); - boolean merging = FALSE; - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand = P[n]; - bits(PL) operand2 = P[d]; - boolean break = FALSE; - bits(PL) result; - - for e = 0 to elements-1 - boolean element = ElemP[operand, e, esize] == '1'; - if ElemP[mask, e, esize] == '1' then - ElemP[result, e, esize] = if !break then '1' else '0'; - break = break || element; - elsif merging then - ElemP[result, e, esize] = ElemP[operand2, e, esize]; - else - ElemP[result, e, esize] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_halving_truncating - __encoding aarch64_vector_arithmetic_binary_uniform_add_halving_truncating - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - sum = element1 + element2; - Elem[result, e, esize] = sum[esize:1]; - - V[d] = result; - -__instruction aarch64_integer_arithmetic_add_sub_extendedreg - __encoding aarch64_integer_arithmetic_add_sub_extendedreg - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field imm3 10 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01011 001xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - ExtendType extend_type = DecodeRegExtend(option); - integer shift = UInt(imm3); - if shift > 4 then UNDEFINED; - - __execute - bits(datasize) result; - bits(datasize) operand1 = if n == 31 then SP[] else X[n]; - bits(datasize) operand2 = ExtendReg(m, extend_type, shift); - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction UQDECW_Z_ZS__ - __encoding UQDECW_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1010xxxx 110011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 100001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean sub_op = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_single_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 100001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if sub_op then - Elem[result, e, esize] = element1 - element2; - else - Elem[result, e, esize] = element1 + element2; - - V[d] = result; - -__instruction aarch64_system_exceptions_debug_exception - __encoding aarch64_system_exceptions_debug_exception - __instruction_set A64 - __field imm16 5 +: 16 - __field LL 0 +: 2 - __opcode '11010100 101xxxxx xxxxxxxx xxx000xx' - __guard TRUE - __decode - bits(2) target_level = LL; - if LL == '00' then UNDEFINED; - if !Halted() then UNDEFINED; - - __execute - DCPSInstruction(target_level); - -__instruction LD1SW_Z_P_AI_D - __encoding LD1SW_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 001xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction SQSUB_Z_ZI__ - __encoding SQSUB_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx100110 11xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer imm = UInt(imm8); - if sh == '1' then imm = imm << 8; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - imm, esize, unsigned); - - Z[dn] = result; - -__instruction ST1H_Z_P_AI_S - __encoding ST1H_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 111xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offset = UInt(imm5); - - __encoding ST1H_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 110xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(VL) src = Z[t]; - bits(PL) mask = P[g]; - bits(64) addr; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - -__instruction LD1ROW_Z_P_BR_Contiguous - __encoding LD1ROW_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 001xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - - __execute - CheckSVEEnabled(); - if VL < 256 then UNDEFINED; - integer elements = 256 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low bits only - bits(64) offset; - bits(256) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - offset = X[m]; - - addr = base + UInt(offset) * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = ZeroExtend(Replicate(result, VL DIV 256), VL); - -__instruction ADD_Z_ZI__ - __encoding ADD_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx100000 11xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer imm = UInt(imm8); - if sh == '1' then imm = imm << 8; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - Elem[result, e, esize] = element1 + imm; - - Z[dn] = result; - -__instruction aarch64_float_arithmetic_round_frint - __encoding aarch64_float_arithmetic_round_frint - __instruction_set A64 - __field ftype 22 +: 2 - __field rmode 15 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1001xx x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean exact = FALSE; - FPRounding rounding; - case rmode of - when '0xx' rounding = FPDecodeRounding(rmode[1:0]); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundInt(operand, FPCR, rounding, exact); - - V[d] = result; - -__instruction LDFF1D_Z_P_BZ_D_x32_scaled - __encoding LDFF1D_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 1x1xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 3; - - __encoding LDFF1D_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 1x0xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1D_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 111xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 3; - - __encoding LDFF1D_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 110xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction PUNPKHI_P_P__ - __encoding PUNPKHI_P_P__ - __instruction_set A64 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00000101 00110001 0100000x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer n = UInt(Pn); - integer d = UInt(Pd); - boolean hi = TRUE; - - __encoding PUNPKLO_P_P__ - __instruction_set A64 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00000101 00110000 0100000x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer n = UInt(Pn); - integer d = UInt(Pd); - boolean hi = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) operand = P[n]; - bits(PL) result; - - for e = 0 to elements-1 - ElemP[result, e, esize] = ElemP[operand, if hi then e + elements else e, esize DIV 2]; - - P[d] = result; - -__instruction DUP_Z_I__ - __encoding DUP_Z_I__ - __instruction_set A64 - __field size 22 +: 2 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zd 0 +: 5 - __opcode '00100101 xx111000 11xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer d = UInt(Zd); - integer imm = SInt(imm8); - if sh == '1' then imm = imm << 8; - - __execute - CheckSVEEnabled(); - bits(VL) result = Replicate(imm[esize-1:0]); - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field a 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (a == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_2008 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - - if minimum then - Elem[result, e, esize] = FPMinNum(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR); - - V[d] = result; - -__instruction LDFF1B_Z_P_BR_U8 - __encoding LDFF1B_Z_P_BR_U8 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 000xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - integer msize = 8; - boolean unsigned = TRUE; - - __encoding LDFF1B_Z_P_BR_U16 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 001xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = TRUE; - - __encoding LDFF1B_Z_P_BR_U32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 010xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = TRUE; - - __encoding LDFF1B_Z_P_BR_U64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 011xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + UInt(offset) * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_CNOTFIRST]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - offset = offset + 1; - - Z[t] = result; - -__instruction LD2D_Z_P_BR_Contiguous - __encoding LD2D_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 101xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_transfer_vector_permute_transpose - __encoding aarch64_vector_transfer_vector_permute_transpose - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx0xxxxx 0x1010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer part = UInt(op); - integer pairs = elements DIV 2; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - for p = 0 to pairs-1 - Elem[result, 2*p+0, esize] = Elem[operand1, 2*p+part, esize]; - Elem[result, 2*p+1, esize] = Elem[operand2, 2*p+part, esize]; - - V[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_lda_stl - __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx011001 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_ORDERED; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_integer_arithmetic_add_sub_immediate - __encoding aarch64_integer_arithmetic_add_sub_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field sh 22 +: 1 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10001 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - bits(datasize) imm; - - case sh of - when '0' imm = ZeroExtend(imm12, datasize); - when '1' imm = ZeroExtend(imm12 : Zeros(12), datasize); - - __execute - bits(datasize) result; - bits(datasize) operand1 = if n == 31 then SP[] else X[n]; - bits(datasize) operand2 = imm; - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction LSR_Z_ZW__ - __encoding LSR_Z_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 100001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(64) element2 = Elem[operand2, (e * esize) DIV 64, 64]; - integer shift = Min(UInt(element2), esize); - Elem[result, e, esize] = LSR(element1, shift); - - Z[d] = result; - -__instruction aarch64_memory_vector_multiple_no_wb - __encoding aarch64_memory_vector_multiple_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 0x000000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_multiple_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << UInt(size); - integer elements = datasize DIV esize; - - integer rpt; // number of iterations - integer selem; // structure elements - - case opcode of - when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers) - when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers) - when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers) - when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers) - when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register) - when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers) - when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers) - otherwise UNDEFINED; - - // .1D format only permitted with LD1 & ST1 - if size:Q == '110' && selem != 1 then UNDEFINED; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(datasize) rval; - integer tt; - constant integer ebytes = esize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - for r = 0 to rpt-1 - for e = 0 to elements-1 - tt = (t + r) MOD 32; - for s = 0 to selem-1 - rval = V[tt]; - if memop == MemOp_LOAD then - Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[tt] = rval; - else // memop == MemOp_STORE - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize]; - offs = offs + ebytes; - tt = (tt + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction ST2B_Z_P_BI_Contiguous - __encoding ST2B_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 0011xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction aarch64_integer_tags_mcsettaganddatapairpost - __encoding aarch64_integer_tags_mcsettaganddatapairpost - __instruction_set A64 - __field simm7 15 +: 7 - __field Xt2 10 +: 5 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '01101000 10xxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - integer t2 = UInt(Xt2); - bits(64) offset = LSL(SignExtend(simm7, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = TRUE; - - __encoding aarch64_integer_tags_mcsettaganddatapairpre - __instruction_set A64 - __field simm7 15 +: 7 - __field Xt2 10 +: 5 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '01101001 10xxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - integer t2 = UInt(Xt2); - bits(64) offset = LSL(SignExtend(simm7, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = FALSE; - - __encoding aarch64_integer_tags_mcsettaganddatapair - __instruction_set A64 - __field simm7 15 +: 7 - __field Xt2 10 +: 5 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '01101001 00xxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - integer t2 = UInt(Xt2); - bits(64) offset = LSL(SignExtend(simm7, 64), LOG2_TAG_GRANULE); - boolean writeback = FALSE; - boolean postindex = FALSE; - - __execute - bits(64) address; - bits(64) data1; - bits(64) data2; - - SetTagCheckedInstruction(FALSE); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data1 = X[t]; - data2 = X[t2]; - - if !postindex then - address = address + offset; - - Mem[address, 8, AccType_NORMAL] = data1; - Mem[address+8, 8, AccType_NORMAL] = data2; - - AArch64.MemTag[address, AccType_NORMAL] = AArch64.AllocationTagFromAddress(address); - - if writeback then - if postindex then - address = address + offset; - - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_halving_rounding - __encoding aarch64_vector_arithmetic_binary_uniform_add_halving_rounding - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 000101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - Elem[result, e, esize] = (element1 + element2 + 1)[esize:1]; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_float_round_frint_32_64 - __encoding aarch64_vector_arithmetic_unary_float_round_frint_32_64 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x100001 111x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFrintExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer intsize = if op == '0' then 32 else 64; - FPRounding rounding = if U == '0' then FPRounding_ZERO else FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundIntN(element, FPCR, rounding, intsize); - - V[d] = result; - -__instruction aarch64_branch_unconditional_register - __encoding aarch64_branch_unconditional_register - __instruction_set A64 - __field Z 24 +: 1 - __field op 21 +: 2 - __field A 11 +: 1 - __field M 10 +: 1 - __field Rn 5 +: 5 - __field Rm 0 +: 5 - __opcode '1101011x 0xx11111 0000xxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - BranchType branch_type; - integer m = UInt(Rm); - boolean pac = (A == '1'); - boolean use_key_a = (M == '0'); - boolean source_is_sp = ((Z == '1') && (m == 31)); - - if !pac && m != 0 then - UNDEFINED; - elsif pac && !HavePACExt() then - UNDEFINED; - - case op of - when '00' branch_type = BranchType_INDIR; - when '01' branch_type = BranchType_INDCALL; - when '10' branch_type = BranchType_RET; - otherwise UNDEFINED; - - if pac then - if Z == '0' && m != 31 then - UNDEFINED; - - if branch_type == BranchType_RET then - if n != 31 then UNDEFINED; - n = 30; - source_is_sp = TRUE; - - __execute - bits(64) target = X[n]; - boolean auth_then_branch = TRUE; - - if pac then - bits(64) modifier = if source_is_sp then SP[] else X[m]; - - if use_key_a then - target = AuthIA(target, modifier, auth_then_branch); - else - target = AuthIB(target, modifier, auth_then_branch); - - if branch_type == BranchType_INDCALL then X[30] = PC[] + 4; - - // Value in BTypeNext will be used to set PSTATE.BTYPE - case branch_type of - when BranchType_INDIR // BR, BRAA, BRAB, BRAAZ, BRABZ - if InGuardedPage then - if n == 16 || n == 17 then - BTypeNext = '01'; - else - BTypeNext = '11'; - else - BTypeNext = '01'; - when BranchType_INDCALL // BLR, BLRAA, BLRAB, BLRAAZ, BLRABZ - BTypeNext = '10'; - when BranchType_RET // RET, RETAA, RETAB - BTypeNext = '00'; - - BranchTo(target, branch_type); - -__instruction SQDECD_R_RS_SX - __encoding SQDECD_R_RS_SX - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1110xxxx 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQDECD_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1111xxxx 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 - (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_memory_pair_general_no_alloc - __encoding aarch64_memory_pair_general_no_alloc - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101000 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); - AccType acctype = AccType_STREAM; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - if opc[0] == '1' then UNDEFINED; - integer scale = 2 + UInt(opc[1]); - integer datasize = 8 << scale; - bits(64) offset = LSL(SignExtend(imm7, 64), scale); - boolean tag_checked = wback || n != 31; - __execute - bits(64) address; - bits(datasize) data1; - bits(datasize) data2; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown && t == n then - data1 = bits(datasize) UNKNOWN; - else - data1 = X[t]; - if rt_unknown && t2 == n then - data2 = bits(datasize) UNKNOWN; - else - data2 = X[t2]; - Mem[address + 0 , dbytes, acctype] = data1; - Mem[address + dbytes, dbytes, acctype] = data2; - - when MemOp_LOAD - data1 = Mem[address + 0 , dbytes, acctype]; - data2 = Mem[address + dbytes, dbytes, acctype]; - if rt_unknown then - data1 = bits(datasize) UNKNOWN; - data2 = bits(datasize) UNKNOWN; - X[t] = data1; - X[t2] = data2; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction ADD_Z_P_ZZ__ - __encoding ADD_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx000000 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = element1 + element2; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction UQSUB_Z_ZI__ - __encoding UQSUB_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx100111 11xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer imm = UInt(imm8); - if sh == '1' then imm = imm << 8; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - imm, esize, unsigned); - - Z[dn] = result; - -__instruction TRN1_Z_ZZ__ - __encoding TRN1_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx1xxxxx 011100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 0; - - __encoding TRN1_Z_ZZ_Q - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 101xxxxx 000110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer esize = 128; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 0; - - __encoding TRN2_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx1xxxxx 011101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 1; - - __encoding TRN2_Z_ZZ_Q - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 101xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer esize = 128; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer part = 1; - - __execute - CheckSVEEnabled(); - if VL < esize * 2 then UNDEFINED; - integer pairs = VL DIV (esize * 2); - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result = Zeros(); - - for p = 0 to pairs-1 - Elem[result, 2*p+0, esize] = Elem[operand1, 2*p+part, esize]; - Elem[result, 2*p+1, esize] = Elem[operand2, 2*p+part, esize]; - - Z[d] = result; - -__instruction LD1B_Z_P_BI_U8 - __encoding LD1B_Z_P_BI_U8 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0000xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LD1B_Z_P_BI_U16 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0010xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LD1B_Z_P_BI_U32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0100xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LD1B_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0110xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction SQDECH_R_RS_SX - __encoding SQDECH_R_RS_SX - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0110xxxx 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQDECH_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0111xxxx 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 - (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_integer_arithmetic_add_sub_extendedreg - __encoding aarch64_integer_arithmetic_add_sub_extendedreg - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field imm3 10 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01011 001xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - ExtendType extend_type = DecodeRegExtend(option); - integer shift = UInt(imm3); - if shift > 4 then UNDEFINED; - - __execute - bits(datasize) result; - bits(datasize) operand1 = if n == 31 then SP[] else X[n]; - bits(datasize) operand2 = ExtendReg(m, extend_type, shift); - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction FCVT_Z_P_Z_H2S - __encoding FCVT_Z_P_Z_H2S - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 10001001 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 32; - - __encoding FCVT_Z_P_Z_H2D - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11001001 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 64; - - __encoding FCVT_Z_P_Z_S2H - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 10001000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 16; - - __encoding FCVT_Z_P_Z_S2D - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11001011 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 64; - - __encoding FCVT_Z_P_Z_D2H - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11001000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 16; - - __encoding FCVT_Z_P_Z_D2S - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11001010 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 32; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - bits(d_esize) res = FPConvertSVE(element[s_esize-1:0], FPCR); - Elem[result, e, esize] = ZeroExtend(res); - - Z[d] = result; - -__instruction aarch64_vector_cvt_bf16_vector - __encoding aarch64_vector_cvt_bf16_vector - __instruction_set A64 - __field Q 30 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 10100001 011010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Rn); - integer d = UInt(Rd); - integer part = UInt(Q); - integer elements = 64 DIV 16; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(128) operand = V[n]; - bits(64) result; - - for e = 0 to elements-1 - Elem[result, e, 16] = FPConvertBF(Elem[operand, e, 32], FPCR); - - Vpart[d, part] = result; - -__instruction SXTB_Z_P_Z__ - __encoding SXTB_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx010000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer s_esize = 8; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = FALSE; - - __encoding SXTH_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx010010 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size != '1x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer s_esize = 16; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = FALSE; - - __encoding SXTW_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx010100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer s_esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Extend(element[s_esize-1:0], esize, unsigned); - - Z[d] = result; - -__instruction aarch64_integer_flags_cfinv - __encoding aarch64_integer_flags_cfinv - __instruction_set A64 - __field CRm 8 +: 4 - __opcode '11010101 00000000 0100xxxx 00011111' - __guard TRUE - __decode - if !HaveFlagManipulateExt() then UNDEFINED; - - __execute - PSTATE.C = NOT(PSTATE.C); - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_fp_complex - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_complex - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field rot 11 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx0xxxxx 110xx1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFCADDExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '00' then UNDEFINED; - if Q == '0' && size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - if !HaveFP16Ext() && esize == 16 then UNDEFINED; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - bits(esize) element3; - bits(esize) element4; - - for e = 0 to (elements DIV 2) -1 - case rot of - when '00' - element1 = Elem[operand2, e*2, esize]; - element2 = Elem[operand1, e*2, esize]; - element3 = Elem[operand2, e*2+1, esize]; - element4 = Elem[operand1, e*2, esize]; - when '01' - element1 = FPNeg(Elem[operand2, e*2+1, esize]); - element2 = Elem[operand1, e*2+1, esize]; - element3 = Elem[operand2, e*2, esize]; - element4 = Elem[operand1, e*2+1, esize]; - when '10' - element1 = FPNeg(Elem[operand2, e*2, esize]); - element2 = Elem[operand1, e*2, esize]; - element3 = FPNeg(Elem[operand2, e*2+1, esize]); - element4 = Elem[operand1, e*2, esize]; - when '11' - element1 = Elem[operand2, e*2+1, esize]; - element2 = Elem[operand1, e*2+1, esize]; - element3 = FPNeg(Elem[operand2, e*2, esize]); - element4 = Elem[operand1, e*2+1, esize]; - - Elem[result, e*2, esize] = FPMulAdd(Elem[operand3, e*2, esize], element2, element1, FPCR); - Elem[result, e*2+1, esize] = FPMulAdd(Elem[operand3, e*2+1, esize], element4, element3, FPCR); - - V[d] = result; - -__instruction ASR_Z_ZI__ - __encoding ASR_Z_ZI__ - __instruction_set A64 - __field tszh 22 +: 2 - __field tszl 19 +: 2 - __field imm3 16 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 100100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - bits(4) tsize = tszh:tszl; - case tsize of - when '0000' UNDEFINED; - when '0001' esize = 8; - when '001x' esize = 16; - when '01xx' esize = 32; - when '1xxx' esize = 64; - integer n = UInt(Zn); - integer d = UInt(Zd); - integer shift = (2 * esize) - UInt(tsize:imm3); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - Elem[result, e, esize] = ASR(element1, shift); - - Z[d] = result; - -__instruction UDIVR_Z_P_ZZ__ - __encoding UDIVR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010111 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '0x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer quotient; - if element1 == 0 then - quotient = 0; - else - quotient = RoundTowardsZero(Real(element2) / Real(element1)); - Elem[result, e, esize] = quotient[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction ORR_Z_P_ZZ__ - __encoding ORR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx011000 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = element1 OR element2; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_integer_pac_pacda_dp_1src - __encoding aarch64_integer_pac_pacda_dp_1src - __instruction_set A64 - __field Z 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11011010 11000001 00x010xx xxxxxxxx' - __guard TRUE - __decode - boolean source_is_sp = FALSE; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if !HavePACExt() then - UNDEFINED; - - if Z == '0' then // PACDA - if n == 31 then source_is_sp = TRUE; - else // PACDZA - if n != 31 then UNDEFINED; - - __execute - if source_is_sp then - X[d] = AddPACDA(X[d], SP[]); - else - X[d] = AddPACDA(X[d], X[n]); - -__instruction aarch64_vector_arithmetic_binary_uniform_diff - __encoding aarch64_vector_arithmetic_binary_uniform_diff - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0111x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean accumulate = (ac == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - bits(esize) absdiff; - - result = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - absdiff = Abs(element1 - element2)[esize-1:0]; - Elem[result, e, esize] = Elem[result, e, esize] + absdiff; - V[d] = result; - -__instruction ADDVL_R_RI__ - __encoding ADDVL_R_RI__ - __instruction_set A64 - __field Rn 16 +: 5 - __field imm6 5 +: 6 - __field Rd 0 +: 5 - __opcode '00000100 001xxxxx 01010xxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer n = UInt(Rn); - integer d = UInt(Rd); - integer imm = SInt(imm6); - - __execute - CheckSVEEnabled(); - bits(64) operand1 = if n == 31 then SP[] else X[n]; - bits(64) result = operand1 + (imm * (VL DIV 8)); - - if d == 31 then - SP[] = result; - else - X[d] = result; - -__instruction LD1ROD_Z_P_BR_Contiguous - __encoding LD1ROD_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 101xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - - __execute - CheckSVEEnabled(); - if VL < 256 then UNDEFINED; - integer elements = 256 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low bits only - bits(64) offset; - bits(256) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - offset = X[m]; - - addr = base + UInt(offset) * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = ZeroExtend(Replicate(result, VL DIV 256), VL); - -__instruction CLASTB_V_P_Z__ - __encoding CLASTB_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Vdn 0 +: 5 - __opcode '00000101 xx101011 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Vdn); - integer m = UInt(Zm); - boolean isBefore = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(esize) operand1 = V[dn]; - bits(VL) operand2 = Z[m]; - bits(esize) result; - integer last = LastActiveElement(mask, esize); - - if last < 0 then - result = ZeroExtend(operand1); - else - if !isBefore then - last = last + 1; - if last >= elements then last = 0; - result = Elem[operand2, last, esize]; - - V[dn] = result; - -__instruction aarch64_float_move_fp_select - __encoding aarch64_float_move_fp_select - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - bits(4) condition = cond; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - - result = if ConditionHolds(condition) then V[n] else V[m]; - - V[d] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction SDIVR_Z_P_ZZ__ - __encoding SDIVR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010110 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '0x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer quotient; - if element1 == 0 then - quotient = 0; - else - quotient = RoundTowardsZero(Real(element2) / Real(element1)); - Elem[result, e, esize] = quotient[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_float_move_fp_imm - __encoding aarch64_float_move_fp_imm - __instruction_set A64 - __field ftype 22 +: 2 - __field imm8 13 +: 8 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx xxx10000 000xxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - bits(datasize) imm = VFPExpandImm(imm8); - - __execute - CheckFPAdvSIMDEnabled64(); - - V[d] = imm; - -__instruction EXT_Z_ZI_Des - __encoding EXT_Z_ZI_Des - __instruction_set A64 - __field imm8h 16 +: 5 - __field imm8l 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000101 001xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Zdn); - integer m = UInt(Zm); - integer position = UInt(imm8h:imm8l); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - if position >= elements then - position = 0; - - position = position << 3; - bits(VL*2) concat = operand2 : operand1; - result = concat[position+VL-1:position]; - - Z[dn] = result; - -__instruction aarch64_vector_transfer_vector_extract - __encoding aarch64_vector_transfer_vector_extract - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field imm4 11 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 000xxxxx 0xxxx0xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if Q == '0' && imm4[3] == '1' then UNDEFINED; - - integer datasize = if Q == '1' then 128 else 64; - integer position = UInt(imm4) << 3; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) hi = V[m]; - bits(datasize) lo = V[n]; - bits(datasize*2) concat = hi : lo; - - V[d] = concat[position+datasize-1:position]; - -__instruction aarch64_memory_single_general_immediate_signed_offset_unpriv - __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - - unpriv_at_el1 = PSTATE.EL == EL1 && !(EL2Enabled() && HaveNVExt() && HCR_EL2.[NV,NV1] == '11'); - unpriv_at_el2 = PSTATE.EL == EL2 && HaveVirtHostExt() && HCR_EL2.[E2H,TGE] == '11'; - - user_access_override = HaveUAOExt() && PSTATE.UAO == '1'; - if !user_access_override && (unpriv_at_el1 || unpriv_at_el2) then - acctype = AccType_UNPRIV; - else - acctype = AccType_NORMAL; - - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_crypto_sm3_sm3ss1 - __encoding aarch64_vector_crypto_sm3_sm3ss1 - __instruction_set A64 - __field Rm 16 +: 5 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 010xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSM3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer a = UInt(Ra); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) Vd = V[d]; - bits(128) Va = V[a]; - Vd[127:96] = ROL((ROL(Vn[127:96],12) + Vm[127:96] + Va[127:96]) , 7); - Vd[95:0] = Zeros(); - V[d] = Vd; - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_dmacc_sisd - __encoding aarch64_vector_arithmetic_binary_disparate_mul_dmacc_sisd - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 xx1xxxxx 10x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '00' || size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - boolean sub_op = (o1 == '1'); - - __encoding aarch64_vector_arithmetic_binary_disparate_mul_dmacc_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 10x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '00' || size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - integer accum; - boolean sat1; - boolean sat2; - - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - element2 = SInt(Elem[operand2, e, esize]); - (product, sat1) = SignedSatQ(2 * element1 * element2, 2*esize); - if sub_op then - accum = SInt(Elem[operand3, e, 2*esize]) - SInt(product); - else - accum = SInt(Elem[operand3, e, 2*esize]) + SInt(product); - (Elem[result, e, 2*esize], sat2) = SignedSatQ(accum, 2*esize); - if sat1 || sat2 then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if abs then - element1 = FPAbs(element1); - element2 = FPAbs(element2); - case cmp of - when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR); - when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction CMPEQ_P_P_ZI__ - __encoding CMPEQ_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx0xxxxx 100xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_EQ; - integer imm = SInt(imm5); - boolean unsigned = FALSE; - - __encoding CMPGT_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx0xxxxx 000xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_GT; - integer imm = SInt(imm5); - boolean unsigned = FALSE; - - __encoding CMPGE_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx0xxxxx 000xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_GE; - integer imm = SInt(imm5); - boolean unsigned = FALSE; - - __encoding CMPHI_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm7 14 +: 7 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx1xxxxx xx0xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_GT; - integer imm = UInt(imm7); - boolean unsigned = TRUE; - - __encoding CMPHS_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm7 14 +: 7 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx1xxxxx xx0xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_GE; - integer imm = UInt(imm7); - boolean unsigned = TRUE; - - __encoding CMPLT_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx0xxxxx 001xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_LT; - integer imm = SInt(imm5); - boolean unsigned = FALSE; - - __encoding CMPLE_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx0xxxxx 001xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_LE; - integer imm = SInt(imm5); - boolean unsigned = FALSE; - - __encoding CMPLO_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm7 14 +: 7 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx1xxxxx xx1xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_LT; - integer imm = UInt(imm7); - boolean unsigned = TRUE; - - __encoding CMPLS_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm7 14 +: 7 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx1xxxxx xx1xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_LE; - integer imm = UInt(imm7); - boolean unsigned = TRUE; - - __encoding CMPNE_P_P_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx0xxxxx 100xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_NE; - integer imm = SInt(imm5); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(PL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - boolean cond; - case op of - when Cmp_EQ cond = element1 == imm; - when Cmp_NE cond = element1 != imm; - when Cmp_GE cond = element1 >= imm; - when Cmp_LT cond = element1 < imm; - when Cmp_GT cond = element1 > imm; - when Cmp_LE cond = element1 <= imm; - ElemP[result, e, esize] = if cond then '1' else '0'; - else - ElemP[result, e, esize] = '0'; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_integer_logical_shiftedreg - __encoding aarch64_integer_logical_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field shift 22 +: 2 - __field N 21 +: 1 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01010 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - boolean invert = (N == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - X[d] = result; - -__instruction aarch64_vector_arithmetic_unary_rev - __encoding aarch64_vector_arithmetic_unary_rev - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 000x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - // size=esize: B(0), H(1), S(1), D(S) - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - - // op=REVx: 64(0), 32(1), 16(2) - bits(2) op = o0:U; - - // => op+size: - // 64+B = 0, 64+H = 1, 64+S = 2, 64+D = X - // 32+B = 1, 32+H = 2, 32+S = X, 32+D = X - // 16+B = 2, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - // => 3-(op+size) (index bits in group) - // 64/B = 3, 64+H = 2, 64+S = 1, 64+D = X - // 32+B = 2, 32+H = 1, 32+S = X, 32+D = X - // 16+B = 1, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - - // index bits within group: 1, 2, 3 - if UInt(op)+UInt(size) >= 3 then UNDEFINED; - - integer container_size; - case op of - when '10' container_size = 16; - when '01' container_size = 32; - when '00' container_size = 64; - - integer containers = datasize DIV container_size; - integer elements_per_container = container_size DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element = 0; - integer rev_element; - for c = 0 to containers-1 - rev_element = element + elements_per_container - 1; - for e = 0 to elements_per_container-1 - Elem[result, rev_element, esize] = Elem[operand, element, esize]; - element = element + 1; - rev_element = rev_element - 1; - - V[d] = result; - -__instruction aarch64_vector_crypto_aes_round - __encoding aarch64_vector_crypto_aes_round - __instruction_set A64 - __field D 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01001110 00101000 010x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - if !HaveAESExt() then UNDEFINED; - boolean decrypt = (D == '1'); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) operand1 = V[d]; - bits(128) operand2 = V[n]; - bits(128) result; - result = operand1 EOR operand2; - if decrypt then - result = AESInvSubBytes(AESInvShiftRows(result)); - else - result = AESSubBytes(AESShiftRows(result)); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_sub_int - __encoding aarch64_vector_arithmetic_binary_uniform_sub_int - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 001001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer diff; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - diff = element1 - element2; - Elem[result, e, esize] = diff[esize:1]; - - V[d] = result; - -__instruction PRFW_I_P_BR_S - __encoding PRFW_I_P_BR_S - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000101 000xxxxx 110xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) offset = X[m]; - bits(64) addr; - - if n == 31 then - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + (UInt(offset) << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - offset = offset + 1; - -__instruction aarch64_float_arithmetic_round_frint_32_64 - __encoding aarch64_float_arithmetic_round_frint_32_64 - __instruction_set A64 - __field ftype 22 +: 2 - __field op 15 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx10100x x10000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFrintExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '1x' UNDEFINED; - - integer intsize = if op[1] == '0' then 32 else 64; - - FPRounding rounding = if op[0] == '0' then FPRounding_ZERO else FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundIntN(operand, FPCR, rounding, intsize); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field eq 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 0011x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean cmp_eq = (eq == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field eq 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0011x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean cmp_eq = (eq == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - test_passed = if cmp_eq then element1 >= element2 else element1 > element2; - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_high_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_high_sisd - __instruction_set A64 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field S 13 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111111 xxxxxxxx 11x1x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - boolean rounding = TRUE; - boolean sub_op = (S == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_high_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field S 13 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 xxxxxxxx 11x1x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean rounding = TRUE; - boolean sub_op = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - integer rounding_const = if rounding then 1 << (esize - 1) else 0; - integer element1; - integer element2; - integer element3; - integer product; - boolean sat; - - element2 = SInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - element3 = SInt(Elem[operand3, e, esize]); - if sub_op then - accum = ((element3 << esize) - 2 * (element1 * element2) + rounding_const); - else - accum = ((element3 << esize) + 2 * (element1 * element2) + rounding_const); - (Elem[result, e, esize], sat) = SignedSatQ(accum >> esize, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction BFDOT_Z_ZZZi__ - __encoding BFDOT_Z_ZZZi__ - __instruction_set A64 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 011xxxxx 010000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - integer index = UInt(i2); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 32; - integer eltspersegment = 128 DIV 32; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = segmentbase + index; - bits(16) elt1_a = Elem[operand1, 2 * e + 0, 16]; - bits(16) elt1_b = Elem[operand1, 2 * e + 1, 16]; - bits(16) elt2_a = Elem[operand2, 2 * s + 0, 16]; - bits(16) elt2_b = Elem[operand2, 2 * s + 1, 16]; - - bits(32) sum = BFAdd(BFMul(elt1_a, elt2_a), BFMul(elt1_b, elt2_b)); - Elem[result, e, 32] = BFAdd(Elem[operand3, e, 32], sum); - - Z[da] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_lda_stl - __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx011001 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_ORDERED; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_binary_uniform_sub_fp16_simd - __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 110xxxxx 000101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean abs = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 1x1xxxxx 110101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean abs = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - bits(esize) diff; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - diff = FPSub(element1, element2, FPCR); - Elem[result, e, esize] = if abs then FPAbs(diff) else diff; - - V[d] = result; - -__instruction PRFB_I_P_BI_S - __encoding PRFB_I_P_BI_S - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000101 11xxxxxx 000xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 0; - integer offset = SInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) addr; - - if n == 31 then - base = SP[]; - else - base = X[n]; - - addr = base + ((offset * elements) << scale); - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Hint_Prefetch(addr, pref_hint, level, stream); - addr = addr + (1 << scale); - -__instruction aarch64_integer_arithmetic_add_sub_shiftedreg - __encoding aarch64_integer_arithmetic_add_sub_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field shift 22 +: 2 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01011 xx0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - - if shift == '11' then UNDEFINED; - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - X[d] = result; - -__instruction UXTB_Z_P_Z__ - __encoding UXTB_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx010001 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer s_esize = 8; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = TRUE; - - __encoding UXTH_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx010011 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size != '1x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer s_esize = 16; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = TRUE; - - __encoding UXTW_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx010101 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer s_esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Extend(element[s_esize-1:0], esize, unsigned); - - Z[d] = result; - -__instruction INDEX_Z_IR__ - __encoding INDEX_Z_IR__ - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field imm5 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 010010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Rm); - integer d = UInt(Zd); - integer imm = SInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(esize) operand2 = X[m]; - integer element2 = SInt(operand2); - bits(VL) result; - - for e = 0 to elements-1 - integer index = imm + e * element2; - Elem[result, e, esize] = index[esize-1:0]; - - Z[d] = result; - -__instruction aarch64_integer_arithmetic_mul_widening_64_128hi - __encoding aarch64_integer_arithmetic_mul_widening_64_128hi - __instruction_set A64 - __field U 23 +: 1 - __field Rm 16 +: 5 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '10011011 x10xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer a = UInt(Ra); // ignored by UMULH/SMULH - integer destsize = 64; - integer datasize = destsize; - boolean unsigned = (U == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - - integer result; - - result = Int(operand1, unsigned) * Int(operand2, unsigned); - - X[d] = result[127:64]; - -__instruction FEXPA_Z_Z__ - __encoding FEXPA_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx100000 101110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand = Z[n]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPExpA(element); - - Z[d] = result; - -__instruction ANDV_R_P_Z__ - __encoding ANDV_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000100 xx011010 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(esize) result = Ones(esize); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - result = result AND Elem[operand, e, esize]; - - V[d] = result; - -__instruction LD1RQH_Z_P_BI_U16 - __encoding LD1RQH_Z_P_BI_U16 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1000xxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = 128 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low 16 bits only - bits(128) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * 16; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = Replicate(result, VL DIV 128); - -__instruction ST1D_Z_P_BI__ - __encoding ST1D_Z_P_BI__ - __instruction_set A64 - __field size 21 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 1xx0xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size != '11' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8 << UInt(size); - integer msize = 64; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) src = Z[t]; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - addr = addr + mbytes; - -__instruction BRKN_P_P_PP__ - __encoding BRKN_P_P_PP__ - __instruction_set A64 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pdm 0 +: 4 - __opcode '00100101 00011000 01xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer dm = UInt(Pdm); - boolean setflags = FALSE; - - __encoding BRKNS_P_P_PP__ - __instruction_set A64 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pdm 0 +: 4 - __opcode '00100101 01011000 01xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer dm = UInt(Pdm); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[dm]; - bits(PL) result; - - if LastActive(mask, operand1, 8) == '1' then - result = operand2; - else - result = Zeros(); - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(Ones(PL), result, 8); - P[dm] = result; - -__instruction LD1SB_Z_P_BR_S16 - __encoding LD1SB_Z_P_BR_S16 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 110xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = FALSE; - - __encoding LD1SB_Z_P_BR_S32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 101xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = FALSE; - - __encoding LD1SB_Z_P_BR_S64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 100xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction PRFH_I_P_BZ_S_x32_scaled - __encoding PRFH_I_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000100 0x1xxxxx 001xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 32; - boolean offs_unsigned = (xs == '0'); - integer scale = 1; - - __encoding PRFH_I_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 0x1xxxxx 001xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 32; - boolean offs_unsigned = (xs == '0'); - integer scale = 1; - - __encoding PRFH_I_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 011xxxxx 101xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 1; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) addr; - bits(VL) offset; - - if n == 31 then - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_wide - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_wide - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 00x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand1 = V[n]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, 2*esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - Elem[result, e, 2*esize] = sum[2*esize-1:0]; - - V[d] = result; - -__instruction aarch64_integer_tags_mcsettagpost - __encoding aarch64_integer_tags_mcsettagpost - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 001xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = TRUE; - boolean zero_data = FALSE; - - __encoding aarch64_integer_tags_mcsettagpre - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 001xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = FALSE; - boolean zero_data = FALSE; - - __encoding aarch64_integer_tags_mcsettag - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 001xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = FALSE; - boolean postindex = FALSE; - boolean zero_data = FALSE; - - __execute - bits(64) address; - - SetTagCheckedInstruction(FALSE); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if !postindex then - address = address + offset; - - if zero_data then - Mem[address, TAG_GRANULE, AccType_NORMAL] = Zeros(TAG_GRANULE * 8); - - bits(64) data = if t == 31 then SP[] else X[t]; - bits(4) tag = AArch64.AllocationTagFromAddress(data); - AArch64.MemTag[address, AccType_NORMAL] = tag; - - if writeback then - if postindex then - address = address + offset; - - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field eq 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 0011x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean cmp_eq = (eq == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field eq 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0011x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean cmp_eq = (eq == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - test_passed = if cmp_eq then element1 >= element2 else element1 > element2; - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction LD1D_Z_P_BR_U64 - __encoding LD1D_Z_P_BR_U64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 111xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction LSL_Z_P_ZZ__ - __encoding LSL_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010011 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - integer shift = Min(UInt(element2), esize); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = LSL(element1, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_crypto_sha2op_sha1_sched1 - __encoding aarch64_vector_crypto_sha2op_sha1_sched1 - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 00101000 000110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - if !HaveSHA1Ext() then UNDEFINED; - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) operand1 = V[d]; - bits(128) operand2 = V[n]; - bits(128) result; - bits(128) T = operand1 EOR LSR(operand2, 32); - result[31:0] = ROL(T[31:0], 1); - result[63:32] = ROL(T[63:32], 1); - result[95:64] = ROL(T[95:64], 1); - result[127:96] = ROL(T[127:96], 1) EOR ROL(T[31:0], 2); - V[d] = result; - -__instruction LDFF1SB_Z_P_BZ_D_x32_unscaled - __encoding LDFF1SB_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 0x0xxxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1SB_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 0x0xxxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1SB_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 010xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction ST2W_Z_P_BR_Contiguous - __encoding ST2W_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 001xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction aarch64_memory_single_general_immediate_signed_post_idx - __encoding aarch64_memory_single_general_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_crypto_sm3_sm3partw1 - __encoding aarch64_vector_crypto_sm3_sm3partw1 - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 011xxxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSM3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) Vd = V[d]; - bits(128) result; - - result[95:0] = (Vd EOR Vn)[95:0] EOR (ROL(Vm[127:96],15):ROL(Vm[95:64],15):ROL(Vm[63:32],15)); - - for i = 0 to 3 - if i == 3 then - result[127:96] = (Vd EOR Vn)[127:96] EOR (ROL(result[31:0],15)); - result[(32*i)+31:(32*i)] = result[(32*i)+31:(32*i)] EOR ROL(result[(32*i)+31:(32*i)],15) EOR ROL(result[(32*i)+31:(32*i)],23); - V[d] = result; - -__instruction INDEX_Z_II__ - __encoding INDEX_Z_II__ - __instruction_set A64 - __field size 22 +: 2 - __field imm5b 16 +: 5 - __field imm5 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 010000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer d = UInt(Zd); - integer imm1 = SInt(imm5); - integer imm2 = SInt(imm5b); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) result; - - for e = 0 to elements-1 - integer index = imm1 + e * imm2; - Elem[result, e, esize] = index[esize-1:0]; - - Z[d] = result; - -__instruction aarch64_system_exceptions_debug_exception - __encoding aarch64_system_exceptions_debug_exception - __instruction_set A64 - __field imm16 5 +: 16 - __field LL 0 +: 2 - __opcode '11010100 101xxxxx xxxxxxxx xxx000xx' - __guard TRUE - __decode - bits(2) target_level = LL; - if LL == '00' then UNDEFINED; - if !Halted() then UNDEFINED; - - __execute - DCPSInstruction(target_level); - -__instruction aarch64_branch_unconditional_immediate - __encoding aarch64_branch_unconditional_immediate - __instruction_set A64 - __field op 31 +: 1 - __field imm26 0 +: 26 - __opcode 'x00101xx xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - BranchType branch_type = if op == '1' then BranchType_DIRCALL else BranchType_DIR; - bits(64) offset = SignExtend(imm26:'00', 64); - - __execute - if branch_type == BranchType_DIRCALL then X[30] = PC[] + 4; - - BranchTo(PC[] + offset, branch_type); - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction UQDECP_Z_P_Z__ - __encoding UQDECP_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Zdn 0 +: 5 - __opcode '00100101 xx101011 1000000x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Zdn); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(PL) operand2 = P[m]; - bits(VL) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - for e = 0 to elements-1 - integer element = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element - count, esize, unsigned); - - Z[dn] = result; - -__instruction UZP1_P_PP__ - __encoding UZP1_P_PP__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 16 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00000101 xx10xxxx 0100100x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - integer part = 0; - - __encoding UZP2_P_PP__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 16 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00000101 xx10xxxx 0100110x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - integer part = 1; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - bits(PL*2) zipped = operand2:operand1; - for e = 0 to elements-1 - Elem[result, e, esize DIV 8] = Elem[zipped, 2*e+part, esize DIV 8]; - - P[d] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_long - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 00x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - Elem[result, e, 2*esize] = sum[2*esize-1:0]; - - V[d] = result; - -__instruction ST1H_Z_P_BZ_S_x32_scaled - __encoding ST1H_Z_P_BZ_S_x32_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 111xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding ST1H_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 101xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding ST1H_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 100xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding ST1H_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 110xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding ST1H_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 101xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 1; - - __encoding ST1H_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 100xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(VL) offset = Z[m]; - bits(VL) src = Z[t]; - bits(PL) mask = P[g]; - bits(64) addr; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - -__instruction aarch64_vector_transfer_integer_move_unsigned - __encoding aarch64_vector_transfer_integer_move_unsigned - __instruction_set A64 - __field Q 30 +: 1 - __field imm5 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 000xxxxx 001111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer size; - case Q:imm5 of - when '0xxxx1' size = 0; // UMOV Wd, Vn.B - when '0xxx10' size = 1; // UMOV Wd, Vn.H - when '0xx100' size = 2; // UMOV Wd, Vn.S - when '1x1000' size = 3; // UMOV Xd, Vn.D - otherwise UNDEFINED; - - integer idxdsize = if imm5[4] == '1' then 128 else 64; - integer index = UInt(imm5[4:size+1]); - integer esize = 8 << size; - integer datasize = if Q == '1' then 64 else 32; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(idxdsize) operand = V[n]; - - X[d] = ZeroExtend(Elem[operand, index, esize], datasize); - -__instruction LSL_Z_ZI__ - __encoding LSL_Z_ZI__ - __instruction_set A64 - __field tszh 22 +: 2 - __field tszl 19 +: 2 - __field imm3 16 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 100111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - bits(4) tsize = tszh:tszl; - case tsize of - when '0000' UNDEFINED; - when '0001' esize = 8; - when '001x' esize = 16; - when '01xx' esize = 32; - when '1xxx' esize = 64; - integer n = UInt(Zn); - integer d = UInt(Zd); - integer shift = UInt(tsize:imm3) - esize; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - Elem[result, e, esize] = LSL(element1, shift); - - Z[d] = result; - -__instruction aarch64_system_register_system - __encoding aarch64_system_register_system - __instruction_set A64 - __field L 21 +: 1 - __field o0 19 +: 1 - __field op1 16 +: 3 - __field CRn 12 +: 4 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __field Rt 0 +: 5 - __opcode '11010101 00x1xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - AArch64.CheckSystemAccess('1':o0, op1, CRn, CRm, op2, Rt, L); - - integer t = UInt(Rt); - - integer sys_op0 = 2 + UInt(o0); - integer sys_op1 = UInt(op1); - integer sys_op2 = UInt(op2); - integer sys_crn = UInt(CRn); - integer sys_crm = UInt(CRm); - boolean read = (L == '1'); - - __execute - if read then - X[t] = AArch64.SysRegRead(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2); - else - AArch64.SysRegWrite(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2, X[t]); - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction UQDECW_R_RS_UW - __encoding UQDECW_R_RS_UW - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1010xxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQDECW_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1011xxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 - (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction CLS_Z_P_Z__ - __encoding CLS_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx011000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = CountLeadingSignBits(element)[esize-1:0]; - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_product - __encoding aarch64_vector_arithmetic_binary_disparate_mul_product - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - Elem[result, e, 2*esize] = (element1 * element2)[2*esize-1:0]; - - V[d] = result; - -__instruction LDNT1D_Z_P_BI_Contiguous - __encoding LDNT1D_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1000xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_STREAM]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_integer_arithmetic_add_sub_shiftedreg - __encoding aarch64_integer_arithmetic_add_sub_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field shift 22 +: 2 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01011 xx0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - - if shift == '11' then UNDEFINED; - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - X[d] = result; - -__instruction aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 11111000 110x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 1x100000 110x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 11111000 110x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 1x100000 110x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) zero = FPZero('0'); - bits(esize) element; - boolean test_passed; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - case comparison of - when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR); - when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR); - when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR); - when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_integer_arithmetic_add_sub_immediate - __encoding aarch64_integer_arithmetic_add_sub_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field sh 22 +: 1 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10001 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - bits(datasize) imm; - - case sh of - when '0' imm = ZeroExtend(imm12, datasize); - when '1' imm = ZeroExtend(imm12 : Zeros(12), datasize); - - __execute - bits(datasize) result; - bits(datasize) operand1 = if n == 31 then SP[] else X[n]; - bits(datasize) operand2 = imm; - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction aarch64_vector_arithmetic_unary_clsz - __encoding aarch64_vector_arithmetic_unary_clsz - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 010010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CountOp countop = if U == '1' then CountOp_CLZ else CountOp_CLS; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - integer count; - for e = 0 to elements-1 - if countop == CountOp_CLS then - count = CountLeadingSignBits(Elem[operand, e, esize]); - else - count = CountLeadingZeroBits(Elem[operand, e, esize]); - Elem[result, e, esize] = count[esize-1:0]; - V[d] = result; - -__instruction SQINCD_Z_ZS__ - __encoding SQINCD_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1110xxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_memory_atomicops_swp - __encoding aarch64_memory_atomicops_swp - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 100000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - bits(datasize) store_value; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - store_value = X[s]; - data = MemAtomic(address, MemAtomicOp_SWP, store_value, ldacctype, stacctype); - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_system_exceptions_debug_halt - __encoding aarch64_system_exceptions_debug_halt - __instruction_set A64 - __field imm16 5 +: 16 - __opcode '11010100 010xxxxx xxxxxxxx xxx00000' - __guard TRUE - __decode - if EDSCR.HDE == '0' || !HaltingAllowed() then UNDEFINED; - if HaveBTIExt() then - SetBTypeCompatible(TRUE); - - __execute - Halt(DebugHalt_HaltInstruction); - -__instruction ST1D_Z_P_BR__ - __encoding ST1D_Z_P_BR__ - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 111xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - bits(VL) src = Z[t]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - offset = offset + 1; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction SMULH_Z_P_ZZ__ - __encoding SMULH_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010010 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer product = (element1 * element2) >> esize; - Elem[result, e, esize] = product[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_float_arithmetic_mul_add_sub - __encoding aarch64_float_arithmetic_mul_add_sub - __instruction_set A64 - __field ftype 22 +: 2 - __field o1 21 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011111 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer a = UInt(Ra); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean opa_neg = (o1 == '1'); - boolean op1_neg = (o0 != o1); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operanda = V[a]; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - if opa_neg then operanda = FPNeg(operanda); - if op1_neg then operand1 = FPNeg(operand1); - result = FPMulAdd(operanda, operand1, operand2, FPCR); - - V[d] = result; - -__instruction aarch64_float_arithmetic_add_sub - __encoding aarch64_float_arithmetic_add_sub - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx 001x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean sub_op = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - if sub_op then - result = FPSub(operand1, operand2, FPCR); - else - result = FPAdd(operand1, operand2, FPCR); - - V[d] = result; - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_float_convert_fix - __encoding aarch64_float_convert_fix - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field scale 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - - case ftype of - when '00' fltsize = 32; - when '01' fltsize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - if sf == '0' && scale[5] == '0' then UNDEFINED; - integer fracbits = 64 - UInt(scale); - - case opcode[2:1]:rmode of - when '00 11' // FCVTZ - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, fracbits, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, fracbits, unsigned, FPCR, rounding); - V[d] = fltval; - -__instruction FMIN_Z_P_ZS__ - __encoding FMIN_Z_P_ZS__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field i1 5 +: 1 - __field Zdn 0 +: 5 - __opcode '01100101 xx011111 100xxx00 00xxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - bits(esize) imm = if i1 == '0' then Zeros() else FPOne('0'); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMin(element1, imm, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction LDNT1B_Z_P_BI_Contiguous - __encoding LDNT1B_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0000xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_STREAM]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_vector_crypto_sha3op_sha1_hash_majority - __encoding aarch64_vector_crypto_sha3op_sha1_hash_majority - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 000xxxxx 001000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if !HaveSHA1Ext() then UNDEFINED; - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) X = V[d]; - bits(32) Y = V[n]; // Note: 32 not 128 bits wide - bits(128) W = V[m]; - bits(32) t; - - for e = 0 to 3 - t = SHAmajority(X[63:32], X[95:64], X[127:96]); - Y = Y + ROL(X[31:0], 5) + t + Elem[W, e, 32]; - X[63:32] = ROL(X[63:32], 30); - [Y, X] = ROL(Y : X, 32); - V[d] = X; - -__instruction LD1SH_Z_P_BI_S32 - __encoding LD1SH_Z_P_BI_S32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0010xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __encoding LD1SH_Z_P_BI_S64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0000xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_int_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 01111001 110110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 0x100001 110110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 01111001 110110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x100001 110110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - FPRounding rounding = FPRoundingMode(FPCR); - bits(esize) element; - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FixedToFP(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction SPLICE_Z_P_ZZ_Des - __encoding SPLICE_Z_P_ZZ_Des - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000101 xx101100 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - integer x = 0; - boolean active = FALSE; - integer lastnum = LastActiveElement(mask, esize); - - if lastnum >= 0 then - for e = 0 to lastnum - active = active || ElemP[mask, e, esize] == '1'; - if active then - Elem[result, x, esize] = Elem[operand1, e, esize]; - x = x + 1; - - elements = elements - x - 1; - for e = 0 to elements - Elem[result, x, esize] = Elem[operand2, e, esize]; - x = x + 1; - - Z[dn] = result; - -__instruction aarch64_branch_conditional_compare - __encoding aarch64_branch_conditional_compare - __instruction_set A64 - __field sf 31 +: 1 - __field op 24 +: 1 - __field imm19 5 +: 19 - __field Rt 0 +: 5 - __opcode 'x011010x xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer datasize = if sf == '1' then 64 else 32; - boolean iszero = (op == '0'); - bits(64) offset = SignExtend(imm19:'00', 64); - - __execute - bits(datasize) operand1 = X[t]; - - if IsZero(operand1) == iszero then - BranchTo(PC[] + offset, BranchType_DIR); - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction LDFF1SB_Z_P_AI_S - __encoding LDFF1SB_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 001xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __encoding LDFF1SB_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 001xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction aarch64_system_barriers_ssbb - __encoding aarch64_system_barriers_ssbb - __instruction_set A64 - __field CRm 8 +: 4 - __field opc 5 +: 2 - __opcode '11010101 00000011 0011xxxx 1xx11111' - __guard TRUE - __decode - // No additional decoding required - - __execute - SpeculativeStoreBypassBarrierToVA(); - -__instruction aarch64_vector_arithmetic_unary_diff_neg_sat_sisd - __encoding aarch64_vector_arithmetic_unary_diff_neg_sat_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 011110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean neg = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_diff_neg_sat_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 011110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean neg = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = SInt(Elem[operand, e, esize]); - if neg then - element = -element; - else - element = Abs(element); - (Elem[result, e, esize], sat) = SignedSatQ(element, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_halving_truncating - __encoding aarch64_vector_arithmetic_binary_uniform_add_halving_truncating - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - sum = element1 + element2; - Elem[result, e, esize] = sum[esize:1]; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_round - __encoding aarch64_vector_arithmetic_unary_fp16_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 100x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __encoding aarch64_vector_arithmetic_unary_float_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact); - - V[d] = result; - -__instruction MLA_Z_P_ZZZ__ - __encoding MLA_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '00000100 xx0xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean sub_op = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = UInt(Elem[operand1, e, esize]); - integer element2 = UInt(Elem[operand2, e, esize]); - if ElemP[mask, e, esize] == '1' then - integer product = element1 * element2; - if sub_op then - Elem[result, e, esize] = Elem[operand3, e, esize] - product; - else - Elem[result, e, esize] = Elem[operand3, e, esize] + product; - else - Elem[result, e, esize] = Elem[operand3, e, esize]; - - Z[da] = result; - -__instruction aarch64_vector_crypto_sha512_sha512su1 - __encoding aarch64_vector_crypto_sha512_sha512su1 - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 011xxxxx 100010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSHA512Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(64) sig1; - bits(128) Vtmp; - bits(128) X = V[n]; - bits(128) Y = V[m]; - bits(128) W = V[d]; - - sig1 = ROR(X[127:64], 19) EOR ROR(X[127:64],61) EOR ('000000':X[127:70]); - Vtmp[127:64] = W[127:64] + sig1 + Y[127:64]; - sig1 = ROR(X[63:0], 19) EOR ROR(X[63:0],61) EOR ('000000':X[63:6]); - Vtmp[63:0] = W[63:0] + sig1 + Y[63:0]; - V[d] = Vtmp; - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_sisd - __instruction_set A64 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 01111001 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPRounding_TIEAWAY; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_tieaway_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 0x100001 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPRounding_TIEAWAY; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 01111001 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPRounding_TIEAWAY; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_tieaway_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x100001 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPRounding_TIEAWAY; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_special_frecpx_fp16 - __encoding aarch64_vector_arithmetic_unary_special_frecpx_fp16 - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 11111001 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_unary_special_frecpx - __instruction_set A64 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 1x100001 111110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRecpX(element, FPCR); - - V[d] = result; - -__instruction aarch64_branch_conditional_compare - __encoding aarch64_branch_conditional_compare - __instruction_set A64 - __field sf 31 +: 1 - __field op 24 +: 1 - __field imm19 5 +: 19 - __field Rt 0 +: 5 - __opcode 'x011010x xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer datasize = if sf == '1' then 64 else 32; - boolean iszero = (op == '0'); - bits(64) offset = SignExtend(imm19:'00', 64); - - __execute - bits(datasize) operand1 = X[t]; - - if IsZero(operand1) == iszero then - BranchTo(PC[] + offset, BranchType_DIR); - -__instruction aarch64_integer_conditional_compare_immediate - __encoding aarch64_integer_conditional_compare_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field imm5 16 +: 5 - __field cond 12 +: 4 - __field Rn 5 +: 5 - __field nzcv 0 +: 4 - __opcode 'xx111010 010xxxxx xxxx10xx xxx0xxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - bits(4) condition = cond; - bits(4) flags = nzcv; - bits(datasize) imm = ZeroExtend(imm5, datasize); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = imm; - bit carry_in = '0'; - - if ConditionHolds(condition) then - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - (-, flags) = AddWithCarry(operand1, operand2, carry_in); - PSTATE.[N,Z,C,V] = flags; - -__instruction AND_P_P_PP_Z - __encoding AND_P_P_PP_Z - __instruction_set A64 - __field S 22 +: 1 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0000xxxx 01xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding ANDS_P_P_PP_Z - __instruction_set A64 - __field S 22 +: 1 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0100xxxx 01xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - for e = 0 to elements-1 - bit element1 = ElemP[operand1, e, esize]; - bit element2 = ElemP[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - ElemP[result, e, esize] = element1 AND element2; - else - ElemP[result, e, esize] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_integer_arithmetic_rev - __encoding aarch64_integer_arithmetic_rev - __instruction_set A64 - __field sf 31 +: 1 - __field opc 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x1011010 11000000 0000xxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize = if sf == '1' then 64 else 32; - - integer container_size; - case opc of - when '00' - Unreachable(); - when '01' - container_size = 16; - when '10' - container_size = 32; - when '11' - if sf == '0' then UNDEFINED; - container_size = 64; - - __execute - bits(datasize) operand = X[n]; - bits(datasize) result; - - integer containers = datasize DIV container_size; - integer elements_per_container = container_size DIV 8; - integer index = 0; - integer rev_index; - for c = 0 to containers-1 - rev_index = index + ((elements_per_container - 1) * 8); - for e = 0 to elements_per_container-1 - result[rev_index + 7:rev_index] = operand[index + 7:index]; - index = index + 8; - rev_index = rev_index - 8; - - X[d] = result; - -__instruction aarch64_memory_vector_multiple_no_wb - __encoding aarch64_memory_vector_multiple_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 0x000000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_multiple_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << UInt(size); - integer elements = datasize DIV esize; - - integer rpt; // number of iterations - integer selem; // structure elements - - case opcode of - when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers) - when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers) - when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers) - when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers) - when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register) - when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers) - when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers) - otherwise UNDEFINED; - - // .1D format only permitted with LD1 & ST1 - if size:Q == '110' && selem != 1 then UNDEFINED; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(datasize) rval; - integer tt; - constant integer ebytes = esize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - for r = 0 to rpt-1 - for e = 0 to elements-1 - tt = (t + r) MOD 32; - for s = 0 to selem-1 - rval = V[tt]; - if memop == MemOp_LOAD then - Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[tt] = rval; - else // memop == MemOp_STORE - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize]; - offs = offs + ebytes; - tt = (tt + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_memory_exclusive_pair - __encoding aarch64_memory_exclusive_pair - __instruction_set A64 - __field sz 30 +: 1 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '1x001000 0x1xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = TRUE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 32 << UInt(sz); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_element_bfdot - __encoding aarch64_vector_arithmetic_binary_element_bfdot - __instruction_set A64 - __field Q 30 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 01xxxxxx 1111x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Rn); - integer m = UInt(M:Rm); - integer d = UInt(Rd); - integer i = UInt(H:L); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 32; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - - for e = 0 to elements-1 - bits(16) elt1_a = Elem[operand1, 2 * e + 0, 16]; - bits(16) elt1_b = Elem[operand1, 2 * e + 1, 16]; - bits(16) elt2_a = Elem[operand2, 2 * i + 0, 16]; - bits(16) elt2_b = Elem[operand2, 2 * i + 1, 16]; - - bits(32) sum = BFAdd(BFMul(elt1_a, elt2_a), BFMul(elt1_b, elt2_b)); - Elem[result, e, 32] = BFAdd(Elem[operand3, e, 32], sum); - - V[d] = result; - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction ST3H_Z_P_BR_Contiguous - __encoding ST3H_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 110xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction WRFFR_F_P__ - __encoding WRFFR_F_P__ - __instruction_set A64 - __field Pn 5 +: 4 - __opcode '00100101 00101000 1001000x xxx00000' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer n = UInt(Pn); - - __execute - CheckSVEEnabled(); - bits(PL) operand = P[n]; - - hsb = HighestSetBit(operand); - if hsb < 0 || IsOnes(operand[hsb:0]) then - FFR[] = operand; - else // not a monotonic predicate - FFR[] = bits(PL) UNKNOWN; - -__instruction aarch64_integer_logical_shiftedreg - __encoding aarch64_integer_logical_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field shift 22 +: 2 - __field N 21 +: 1 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01010 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - boolean invert = (N == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - X[d] = result; - -__instruction UMMLA_Z_ZZZ__ - __encoding UMMLA_Z_ZZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000101 110xxxxx 100110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveInt8MatMulExt() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_unsigned = TRUE; - boolean op2_unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer segments = VL DIV 128; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result = Zeros(); - bits(128) op1, op2; - bits(128) res, addend; - - for s = 0 to segments-1 - op1 = Elem[operand1, s, 128]; - op2 = Elem[operand2, s, 128]; - addend = Elem[operand3, s, 128]; - res = MatMulAdd(addend, op1, op2, op1_unsigned, op2_unsigned); - Elem[result, s, 128] = res; - - Z[da] = result; - -__instruction LD1W_Z_P_BI_U32 - __encoding LD1W_Z_P_BI_U32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0100xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LD1W_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0110xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_vector_shift_left_long - __encoding aarch64_vector_shift_left_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 101001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = UInt(immh:immb) - esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = Vpart[n, part]; - bits(datasize*2) result; - integer element; - - for e = 0 to elements-1 - element = Int(Elem[operand, e, esize], unsigned) << shift; - Elem[result, e, 2*esize] = element[2*esize-1:0]; - - V[d] = result; - -__instruction WHILELE_P_P_RR__ - __encoding WHILELE_P_P_RR__ - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field sf 12 +: 1 - __field Rn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx1xxxxx 000x01xx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer rsize = 32 << UInt(sf); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Pd); - boolean unsigned = FALSE; - SVECmp op = Cmp_LE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = Ones(PL); - bits(rsize) operand1 = X[n]; - bits(rsize) operand2 = X[m]; - bits(PL) result; - boolean last = TRUE; - - for e = 0 to elements-1 - boolean cond; - case op of - when Cmp_LT cond = (Int(operand1, unsigned) < Int(operand2, unsigned)); - when Cmp_LE cond = (Int(operand1, unsigned) <= Int(operand2, unsigned)); - - last = last && cond; - ElemP[result, e, esize] = if last then '1' else '0'; - operand1 = operand1 + 1; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_vector_reduce_int_max - __encoding aarch64_vector_reduce_int_max - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 16 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx11000x 101010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '100' then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean min = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - integer maxmin; - integer element; - - maxmin = Int(Elem[operand, 0, esize], unsigned); - for e = 1 to elements-1 - element = Int(Elem[operand, e, esize], unsigned); - maxmin = if min then Min(maxmin, element) else Max(maxmin, element); - - V[d] = maxmin[esize-1:0]; - -__instruction LD1SW_Z_P_BZ_D_x32_scaled - __encoding LD1SW_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 0x1xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 2; - - __encoding LD1SW_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 0x0xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1SW_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 011xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 2; - - __encoding LD1SW_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 010xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset = Z[m]; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor - __encoding aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor - __instruction_set A64 - __field Q 30 +: 1 - __field opc2 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx1xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - VBitOp op; - - case opc2 of - when '00' op = VBitOp_VEOR; - when '01' op = VBitOp_VBSL; - when '10' op = VBitOp_VBIT; - when '11' op = VBitOp_VBIF; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1; - bits(datasize) operand2; - bits(datasize) operand3; - bits(datasize) operand4 = V[n]; - - case op of - when VBitOp_VEOR - operand1 = V[m]; - operand2 = Zeros(); - operand3 = Ones(); - when VBitOp_VBSL - operand1 = V[m]; - operand2 = operand1; - operand3 = V[d]; - when VBitOp_VBIT - operand1 = V[d]; - operand2 = operand1; - operand3 = V[m]; - when VBitOp_VBIF - operand1 = V[d]; - operand2 = operand1; - operand3 = NOT(V[m]); - - V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3); - -__instruction STNT1D_Z_P_BI_Contiguous - __encoding STNT1D_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 1001xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - constant integer mbytes = esize DIV 8; - bits(VL) src; - bits(PL) mask = P[g]; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - src = Z[t]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_STREAM] = Elem[src, e, esize]; - addr = addr + mbytes; - -__instruction aarch64_vector_crypto_sha2op_sha256_sched0 - __encoding aarch64_vector_crypto_sha2op_sha256_sched0 - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 00101000 001010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - if !HaveSHA256Ext() then UNDEFINED; - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) operand1 = V[d]; - bits(128) operand2 = V[n]; - bits(128) result; - bits(128) T = operand2[31:0] : operand1[127:32]; - bits(32) elt; - - for e = 0 to 3 - elt = Elem[T, e, 32]; - elt = ROR(elt, 7) EOR ROR(elt, 18) EOR LSR(elt, 3); - Elem[result, e, 32] = elt + Elem[operand1, e, 32]; - V[d] = result; - -__instruction aarch64_vector_shift_right_sisd - __encoding aarch64_vector_shift_right_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __encoding aarch64_vector_shift_right_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - operand2 = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift; - Elem[result, e, esize] = Elem[operand2, e, esize] + element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_memory_vector_multiple_no_wb - __encoding aarch64_memory_vector_multiple_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 0x000000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_multiple_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << UInt(size); - integer elements = datasize DIV esize; - - integer rpt; // number of iterations - integer selem; // structure elements - - case opcode of - when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers) - when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers) - when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers) - when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers) - when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register) - when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers) - when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers) - otherwise UNDEFINED; - - // .1D format only permitted with LD1 & ST1 - if size:Q == '110' && selem != 1 then UNDEFINED; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(datasize) rval; - integer tt; - constant integer ebytes = esize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - for r = 0 to rpt-1 - for e = 0 to elements-1 - tt = (t + r) MOD 32; - for s = 0 to selem-1 - rval = V[tt]; - if memop == MemOp_LOAD then - Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[tt] = rval; - else // memop == MemOp_STORE - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize]; - offs = offs + ebytes; - tt = (tt + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_integer_arithmetic_mul_widening_32_64 - __encoding aarch64_integer_arithmetic_mul_widening_32_64 - __instruction_set A64 - __field U 23 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '10011011 x01xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer a = UInt(Ra); - integer destsize = 64; - integer datasize = 32; - boolean sub_op = (o0 == '1'); - boolean unsigned = (U == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(destsize) operand3 = X[a]; - - integer result; - - if sub_op then - result = Int(operand3, unsigned) - (Int(operand1, unsigned) * Int(operand2, unsigned)); - else - result = Int(operand3, unsigned) + (Int(operand1, unsigned) * Int(operand2, unsigned)); - - X[d] = result[63:0]; - -__instruction aarch64_integer_arithmetic_add_sub_immediate - __encoding aarch64_integer_arithmetic_add_sub_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field sh 22 +: 1 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10001 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - bits(datasize) imm; - - case sh of - when '0' imm = ZeroExtend(imm12, datasize); - when '1' imm = ZeroExtend(imm12 : Zeros(12), datasize); - - __execute - bits(datasize) result; - bits(datasize) operand1 = if n == 31 then SP[] else X[n]; - bits(datasize) operand2 = imm; - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_shift_right_narrow_nonuniform_sisd - __encoding aarch64_vector_shift_right_narrow_nonuniform_sisd - __instruction_set A64 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111111 0xxxxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then UNDEFINED; - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - - __encoding aarch64_vector_shift_right_narrow_nonuniform_simd - __instruction_set A64 - __field Q 30 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 0xxxxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize*2) operand = V[n]; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = (SInt(Elem[operand, e, 2*esize]) + round_const) >> shift; - (Elem[result, e, esize], sat) = UnsignedSatQ(element, esize); - if sat then FPSR.QC = '1'; - - Vpart[d, part] = result; - -__instruction LDNT1W_Z_P_BI_Contiguous - __encoding LDNT1W_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0000xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_STREAM]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction FCMLA_Z_ZZZi_H - __encoding FCMLA_Z_ZZZi_H - __instruction_set A64 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field rot 10 +: 2 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 101xxxxx 0001xxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer index = UInt(i2); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - integer sel_a = UInt(rot[0]); - integer sel_b = UInt(NOT(rot[0])); - boolean neg_i = (rot[1] == '1'); - boolean neg_r = (rot[0] != rot[1]); - - __encoding FCMLA_Z_ZZZi_S - __instruction_set A64 - __field i1 20 +: 1 - __field Zm 16 +: 4 - __field rot 10 +: 2 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 111xxxxx 0001xxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer index = UInt(i1); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - integer sel_a = UInt(rot[0]); - integer sel_b = UInt(NOT(rot[0])); - boolean neg_i = (rot[1] == '1'); - boolean neg_r = (rot[0] != rot[1]); - - __execute - CheckSVEEnabled(); - integer pairs = VL DIV (2 * esize); - integer pairspersegment = 128 DIV (2 * esize); - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for p = 0 to pairs-1 - segmentbase = p - (p MOD pairspersegment); - s = segmentbase + index; - addend_r = Elem[operand3, 2 * p + 0, esize]; - addend_i = Elem[operand3, 2 * p + 1, esize]; - elt1_a = Elem[operand1, 2 * p + sel_a, esize]; - elt2_a = Elem[operand2, 2 * s + sel_a, esize]; - elt2_b = Elem[operand2, 2 * s + sel_b, esize]; - if neg_r then elt2_a = FPNeg(elt2_a); - if neg_i then elt2_b = FPNeg(elt2_b); - addend_r = FPMulAdd(addend_r, elt1_a, elt2_a, FPCR); - addend_i = FPMulAdd(addend_i, elt1_a, elt2_b, FPCR); - Elem[result, 2 * p + 0, esize] = addend_r; - Elem[result, 2 * p + 1, esize] = addend_i; - - Z[da] = result; - -__instruction LDNF1SW_Z_P_BI_S64 - __encoding LDNF1SW_Z_P_BI_S64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1001xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - addr = addr + mbytes; - - Z[t] = result; - -__instruction FNMAD_Z_P_ZZZ__ - __encoding FNMAD_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Za 16 +: 5 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx1xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - integer a = UInt(Za); - boolean op1_neg = TRUE; - boolean op3_neg = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[a]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - bits(esize) element3 = Elem[operand3, e, esize]; - - if ElemP[mask, e, esize] == '1' then - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction ORR_Z_ZZ__ - __encoding ORR_Z_ZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 011xxxxx 001100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - - Z[d] = operand1 OR operand2; - -__instruction FMINNM_Z_P_ZS__ - __encoding FMINNM_Z_P_ZS__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field i1 5 +: 1 - __field Zdn 0 +: 5 - __opcode '01100101 xx011101 100xxx00 00xxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - bits(esize) imm = if i1 == '0' then Zeros() else FPOne('0'); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMinNum(element1, imm, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction CPY_Z_P_I__ - __encoding CPY_Z_P_I__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 16 +: 4 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zd 0 +: 5 - __opcode '00000101 xx01xxxx 01xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer d = UInt(Zd); - boolean merging = TRUE; - integer imm = SInt(imm8); - if sh == '1' then imm = imm << 8; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) dest = Z[d]; - bits(VL) result; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = imm[esize-1:0]; - elsif merging then - Elem[result, e, esize] = Elem[dest, e, esize]; - else - Elem[result, e, esize] = Zeros(); - - Z[d] = result; - -__instruction LDNT1W_Z_P_BR_Contiguous - __encoding LDNT1W_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 000xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(64) offset; - bits(PL) mask = P[g]; - bits(VL) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = X[m]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_STREAM]; - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction LSLR_Z_P_ZZ__ - __encoding LSLR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010111 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - integer shift = Min(UInt(element1), esize); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = LSL(element2, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction CTERMEQ_RR__ - __encoding CTERMEQ_RR__ - __instruction_set A64 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __opcode '00100101 1x1xxxxx 001000xx xxx00000' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32 << UInt(sz); - integer n = UInt(Rn); - integer m = UInt(Rm); - SVECmp op = Cmp_EQ; - - __encoding CTERMNE_RR__ - __instruction_set A64 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __opcode '00100101 1x1xxxxx 001000xx xxx10000' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32 << UInt(sz); - integer n = UInt(Rn); - integer m = UInt(Rm); - SVECmp op = Cmp_NE; - - __execute - CheckSVEEnabled(); - bits(esize) operand1 = X[n]; - bits(esize) operand2 = X[m]; - integer element1 = UInt(operand1); - integer element2 = UInt(operand2); - boolean term; - - case op of - when Cmp_EQ term = element1 == element2; - when Cmp_NE term = element1 != element2; - if term then - PSTATE.N = '1'; - PSTATE.V = '0'; - else - PSTATE.N = '0'; - PSTATE.V = (NOT PSTATE.C); - -__instruction UQADD_Z_ZI__ - __encoding UQADD_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx100101 11xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer imm = UInt(imm8); - if sh == '1' then imm = imm << 8; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + imm, esize, unsigned); - - Z[dn] = result; - -__instruction LD1W_Z_P_BR_U32 - __encoding LD1W_Z_P_BR_U32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 010xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - boolean unsigned = TRUE; - - __encoding LD1W_Z_P_BR_U64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 011xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction CPY_Z_P_R__ - __encoding CPY_Z_P_R__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx101000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Rn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) operand1; - if n == 31 then - operand1 = SP[]; - else - operand1 = X[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = operand1[esize-1:0]; - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_fp16_product - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_product - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 010xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_product - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 0x1xxxxx 110111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPMul(element1, element2, FPCR); - - V[d] = result; - -__instruction WHILELS_P_P_RR__ - __encoding WHILELS_P_P_RR__ - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field sf 12 +: 1 - __field Rn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx1xxxxx 000x11xx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer rsize = 32 << UInt(sf); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Pd); - boolean unsigned = TRUE; - SVECmp op = Cmp_LE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = Ones(PL); - bits(rsize) operand1 = X[n]; - bits(rsize) operand2 = X[m]; - bits(PL) result; - boolean last = TRUE; - - for e = 0 to elements-1 - boolean cond; - case op of - when Cmp_LT cond = (Int(operand1, unsigned) < Int(operand2, unsigned)); - when Cmp_LE cond = (Int(operand1, unsigned) <= Int(operand2, unsigned)); - - last = last && cond; - ElemP[result, e, esize] = if last then '1' else '0'; - operand1 = operand1 + 1; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_post_idx - __encoding aarch64_memory_single_general_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_single_general_immediate_signed_post_idx - __encoding aarch64_memory_single_general_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field eq 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 0011x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean cmp_eq = (eq == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field eq 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0011x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean cmp_eq = (eq == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - test_passed = if cmp_eq then element1 >= element2 else element1 > element2; - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_vector_reduce_fp16_add_sisd - __encoding aarch64_vector_reduce_fp16_add_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 0x110000 110110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer esize = 16; - if sz == '1' then UNDEFINED; - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = ReduceOp_FADD; - - __encoding aarch64_vector_reduce_fp_add_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 0x110000 110110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = ReduceOp_FADD; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction aarch64_vector_arithmetic_unary_clsz - __encoding aarch64_vector_arithmetic_unary_clsz - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 010010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CountOp countop = if U == '1' then CountOp_CLZ else CountOp_CLS; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - integer count; - for e = 0 to elements-1 - if countop == CountOp_CLS then - count = CountLeadingSignBits(Elem[operand, e, esize]); - else - count = CountLeadingZeroBits(Elem[operand, e, esize]); - Elem[result, e, esize] = count[esize-1:0]; - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 11111000 110x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 1x100000 110x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_fp16_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 11111000 110x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 1x100000 110x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) zero = FPZero('0'); - bits(esize) element; - boolean test_passed; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - case comparison of - when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR); - when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR); - when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR); - when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_integer_logical_immediate - __encoding aarch64_integer_logical_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field N 22 +: 1 - __field immr 16 +: 6 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10010 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - bits(datasize) imm; - if sf == '0' && N != '0' then UNDEFINED; - (imm, -) = DecodeBitMasks(N, imms, immr, TRUE); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = imm; - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_round - __encoding aarch64_vector_arithmetic_unary_fp16_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 100x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __encoding aarch64_vector_arithmetic_unary_float_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact); - - V[d] = result; - -__instruction aarch64_vector_reduce_add_simd - __encoding aarch64_vector_reduce_add_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx110001 101110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '100' then UNDEFINED; - if size == '11' then UNDEFINED; - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - ReduceOp op = ReduceOp_ADD; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction LDFF1B_Z_P_BZ_D_x32_unscaled - __encoding LDFF1B_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 0x0xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1B_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 0x0xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1B_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 010xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction LD1RB_Z_P_BI_U8 - __encoding LD1RB_Z_P_BI_U8 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 01xxxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __encoding LD1RB_Z_P_BI_U16 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 01xxxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __encoding LD1RB_Z_P_BI_U32 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 01xxxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __encoding LD1RB_Z_P_BI_U64 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 01xxxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = UInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - integer last = LastActiveElement(mask, esize); - if last >= 0 then - addr = base + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction LD1H_Z_P_BR_U16 - __encoding LD1H_Z_P_BR_U16 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 101xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 16; - boolean unsigned = TRUE; - - __encoding LD1H_Z_P_BR_U32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 110xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = TRUE; - - __encoding LD1H_Z_P_BR_U64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 111xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction aarch64_float_convert_fp - __encoding aarch64_float_convert_fp - __instruction_set A64 - __field ftype 22 +: 2 - __field opc 15 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx10001x x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer srcsize; - integer dstsize; - - if ftype == opc then UNDEFINED; - - case ftype of - when '00' srcsize = 32; - when '01' srcsize = 64; - when '10' UNDEFINED; - when '11' srcsize = 16; - case opc of - when '00' dstsize = 32; - when '01' dstsize = 64; - when '10' UNDEFINED; - when '11' dstsize = 16; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(dstsize) result; - bits(srcsize) operand = V[n]; - - result = FPConvert(operand, FPCR); - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction LD3D_Z_P_BR_Contiguous - __encoding LD3D_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 110xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_fp16 - __encoding aarch64_vector_arithmetic_binary_uniform_add_fp16 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 010xxxxx 000101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_add_fp - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x1xxxxx 110101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPAdd(element1, element2, FPCR); - - V[d] = result; - -__instruction UMAXV_R_P_Z__ - __encoding UMAXV_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000100 xx001001 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - integer maximum = if unsigned then 0 else -(2^(esize-1)); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer element = Int(Elem[operand, e, esize], unsigned); - maximum = Max(maximum, element); - - V[d] = maximum[esize-1:0]; - -__instruction LD4W_Z_P_BR_Contiguous - __encoding LD4W_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 011xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_crypto_sm3_sm3tt2b - __encoding aarch64_vector_crypto_sm3_sm3tt2b - __instruction_set A64 - __field Rm 16 +: 5 - __field imm2 12 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 010xxxxx 10xx11xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSM3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer i = UInt(imm2); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) Vd = V[d]; - bits(32) Wj; - bits(128) result; - bits(32) TT2; - - Wj = Elem[Vm,i,32]; - TT2 = (Vd[127:96] AND Vd[95:64]) OR (NOT(Vd[127:96]) AND Vd[63:32]); - TT2 = (TT2 + Vd[31:0] + Vn[127:96] + Wj)[31:0]; - - result[31:0] = Vd[63:32]; - result[63:32] = ROL(Vd[95:64],19); - result[95:64] = Vd[127:96]; - result[127:96] = TT2 EOR ROL(TT2,9) EOR ROL(TT2,17); - V[d] = result; - -__instruction CMPEQ_P_P_ZW__ - __encoding CMPEQ_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 001xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_EQ; - boolean unsigned = FALSE; - - __encoding CMPGT_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 010xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GT; - boolean unsigned = FALSE; - - __encoding CMPGE_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 010xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GE; - boolean unsigned = FALSE; - - __encoding CMPHI_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 110xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GT; - boolean unsigned = TRUE; - - __encoding CMPHS_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 110xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GE; - boolean unsigned = TRUE; - - __encoding CMPLT_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 011xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_LT; - boolean unsigned = FALSE; - - __encoding CMPLE_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 011xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_LE; - boolean unsigned = FALSE; - - __encoding CMPLO_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_LT; - boolean unsigned = TRUE; - - __encoding CMPLS_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 111xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_LE; - boolean unsigned = TRUE; - - __encoding CMPNE_P_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100100 xx0xxxxx 001xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_NE; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(PL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, (e * esize) DIV 64, 64], unsigned); - if ElemP[mask, e, esize] == '1' then - boolean cond; - case op of - when Cmp_EQ cond = element1 == element2; - when Cmp_NE cond = element1 != element2; - when Cmp_GE cond = element1 >= element2; - when Cmp_LT cond = element1 < element2; - when Cmp_GT cond = element1 > element2; - when Cmp_LE cond = element1 <= element2; - ElemP[result, e, esize] = if cond then '1' else '0'; - else - ElemP[result, e, esize] = '0'; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_float_arithmetic_round_frint - __encoding aarch64_float_arithmetic_round_frint - __instruction_set A64 - __field ftype 22 +: 2 - __field rmode 15 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1001xx x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean exact = FALSE; - FPRounding rounding; - case rmode of - when '0xx' rounding = FPDecodeRounding(rmode[1:0]); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundInt(operand, FPCR, rounding, exact); - - V[d] = result; - -__instruction UMAX_Z_ZI__ - __encoding UMAX_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx101001 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - boolean unsigned = TRUE; - integer imm = Int(imm8, unsigned); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - Elem[result, e, esize] = Max(element1, imm)[esize-1:0]; - - Z[dn] = result; - -__instruction aarch64_vector_shift_conv_float_sisd - __encoding aarch64_vector_shift_conv_float_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then UNDEFINED; - integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16; - integer datasize = esize; - integer elements = 1; - - integer fracbits = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - FPRounding rounding = FPRounding_ZERO; - - __encoding aarch64_vector_shift_conv_float_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then UNDEFINED; - if immh[3]:Q == '10' then UNDEFINED; - integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer fracbits = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - FPRounding rounding = FPRounding_ZERO; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, fracbits, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction TBL_Z_ZZ_1 - __encoding TBL_Z_ZZ_1 - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx1xxxxx 001100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer idx = UInt(Elem[operand2, e, esize]); - Elem[result, e, esize] = if idx < elements then Elem[operand1, idx, esize] else Zeros(); - - Z[d] = result; - -__instruction FMINNMV_V_P_Z__ - __encoding FMINNMV_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '01100101 xx000101 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(esize) identity = FPDefaultNaN(); - - V[d] = ReducePredicated(ReduceOp_FMINNUM, operand, mask, identity); - -__instruction UQINCH_Z_ZS__ - __encoding UQINCH_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 0110xxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_unary_diff_neg_fp16 - __encoding aarch64_vector_arithmetic_unary_diff_neg_fp16 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 11111000 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean neg = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_diff_neg_float - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 1x100000 111110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean neg = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - if neg then - element = FPNeg(element); - else - element = FPAbs(element); - Elem[result, e, esize] = element; - - V[d] = result; - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction SQINCH_Z_ZS__ - __encoding SQINCH_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 0110xxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction FMLA_Z_P_ZZZ__ - __encoding FMLA_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100101 xx1xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = FALSE; - boolean op3_neg = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - bits(esize) element3 = Elem[operand3, e, esize]; - - if ElemP[mask, e, esize] == '1' then - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - else - Elem[result, e, esize] = element3; - - Z[da] = result; - -__instruction ST2W_Z_P_BI_Contiguous - __encoding ST2W_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 0011xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction aarch64_integer_arithmetic_rev - __encoding aarch64_integer_arithmetic_rev - __instruction_set A64 - __field sf 31 +: 1 - __field opc 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x1011010 11000000 0000xxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize = if sf == '1' then 64 else 32; - - integer container_size; - case opc of - when '00' - Unreachable(); - when '01' - container_size = 16; - when '10' - container_size = 32; - when '11' - if sf == '0' then UNDEFINED; - container_size = 64; - - __execute - bits(datasize) operand = X[n]; - bits(datasize) result; - - integer containers = datasize DIV container_size; - integer elements_per_container = container_size DIV 8; - integer index = 0; - integer rev_index; - for c = 0 to containers-1 - rev_index = index + ((elements_per_container - 1) * 8); - for e = 0 to elements_per_container-1 - result[rev_index + 7:rev_index] = operand[index + 7:index]; - index = index + 8; - rev_index = rev_index - 8; - - X[d] = result; - -__instruction SQADD_Z_ZI__ - __encoding SQADD_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field sh 13 +: 1 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx100100 11xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size:sh == '001' then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer imm = UInt(imm8); - if sh == '1' then imm = imm << 8; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + imm, esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor - __encoding aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor - __instruction_set A64 - __field Q 30 +: 1 - __field opc2 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx1xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - VBitOp op; - - case opc2 of - when '00' op = VBitOp_VEOR; - when '01' op = VBitOp_VBSL; - when '10' op = VBitOp_VBIT; - when '11' op = VBitOp_VBIF; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1; - bits(datasize) operand2; - bits(datasize) operand3; - bits(datasize) operand4 = V[n]; - - case op of - when VBitOp_VEOR - operand1 = V[m]; - operand2 = Zeros(); - operand3 = Ones(); - when VBitOp_VBSL - operand1 = V[m]; - operand2 = operand1; - operand3 = V[d]; - when VBitOp_VBIT - operand1 = V[d]; - operand2 = operand1; - operand3 = V[m]; - when VBitOp_VBIF - operand1 = V[d]; - operand2 = operand1; - operand3 = NOT(V[m]); - - V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3); - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_int_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 01111001 110110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 0x100001 110110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 01111001 110110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x100001 110110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - FPRounding rounding = FPRoundingMode(FPCR); - bits(esize) element; - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FixedToFP(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction aarch64_vector_logical - __encoding aarch64_vector_logical - __instruction_set A64 - __field Q 30 +: 1 - __field op 29 +: 1 - __field a 18 +: 1 - __field b 17 +: 1 - __field c 16 +: 1 - __field cmode 12 +: 4 - __field d 9 +: 1 - __field e 8 +: 1 - __field f 7 +: 1 - __field g 6 +: 1 - __field h 5 +: 1 - __field Rd 0 +: 5 - __opcode '0xx01111 00000xxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer rd = UInt(Rd); - - integer datasize = if Q == '1' then 128 else 64; - bits(datasize) imm; - bits(64) imm64; - - ImmediateOp operation; - case cmode:op of - when '0xx00' operation = ImmediateOp_MOVI; - when '0xx01' operation = ImmediateOp_MVNI; - when '0xx10' operation = ImmediateOp_ORR; - when '0xx11' operation = ImmediateOp_BIC; - when '10x00' operation = ImmediateOp_MOVI; - when '10x01' operation = ImmediateOp_MVNI; - when '10x10' operation = ImmediateOp_ORR; - when '10x11' operation = ImmediateOp_BIC; - when '110x0' operation = ImmediateOp_MOVI; - when '110x1' operation = ImmediateOp_MVNI; - when '1110x' operation = ImmediateOp_MOVI; - when '11110' operation = ImmediateOp_MOVI; - when '11111' - // FMOV Dn,#imm is in main FP instruction set - if Q == '0' then UNDEFINED; - operation = ImmediateOp_MOVI; - - imm64 = AdvSIMDExpandImm(op, cmode, a:b:c:d:e:f:g:h); - imm = Replicate(imm64, datasize DIV 64); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand; - bits(datasize) result; - - case operation of - when ImmediateOp_MOVI - result = imm; - when ImmediateOp_MVNI - result = NOT(imm); - when ImmediateOp_ORR - operand = V[rd]; - result = operand OR imm; - when ImmediateOp_BIC - operand = V[rd]; - result = operand AND NOT(imm); - - V[rd] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_diff - __encoding aarch64_vector_arithmetic_binary_uniform_diff - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 0111x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean accumulate = (ac == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - bits(esize) absdiff; - - result = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - absdiff = Abs(element1 - element2)[esize-1:0]; - Elem[result, e, esize] = Elem[result, e, esize] + absdiff; - V[d] = result; - -__instruction PRFD_I_P_BR_S - __encoding PRFD_I_P_BR_S - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000101 100xxxxx 110xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) offset = X[m]; - bits(64) addr; - - if n == 31 then - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + (UInt(offset) << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - offset = offset + 1; - -__instruction ADR_Z_AZ_SD_same_scaled - __encoding ADR_Z_AZ_SD_same_scaled - __instruction_set A64 - __field sz 22 +: 1 - __field Zm 16 +: 5 - __field msz 10 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 1x1xxxxx 1010xxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32 << UInt(sz); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer osize = esize; - boolean unsigned = TRUE; - integer mbytes = 1 << UInt(msz); - - __encoding ADR_Z_AZ_D_s32_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field msz 10 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 001xxxxx 1010xxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer osize = 32; - boolean unsigned = FALSE; - integer mbytes = 1 << UInt(msz); - - __encoding ADR_Z_AZ_D_u32_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field msz 10 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 011xxxxx 1010xxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - integer osize = 32; - boolean unsigned = TRUE; - integer mbytes = 1 << UInt(msz); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(VL) offs = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) addr = Elem[base, e, esize]; - integer offset = Int(Elem[offs, e, esize][osize-1:0], unsigned); - Elem[result, e, esize] = addr + (offset * mbytes); - - Z[d] = result; - -__instruction FADDA_V_P_Z__ - __encoding FADDA_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Vdn 0 +: 5 - __opcode '01100101 xx011000 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Vdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(esize) operand1 = V[dn]; - bits(VL) operand2 = Z[m]; - bits(esize) result = operand1; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - bits(esize) element = Elem[operand2, e, esize]; - result = FPAdd(result, element, FPCR); - - V[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_long - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 xxxxxxxx 0x10x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(idxdsize) operand2 = V[m]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - - element2 = Int(Elem[operand2, index, esize], unsigned); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - if sub_op then - Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] - product; - else - Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] + product; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_narrow - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_narrow - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 01x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean round = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand1 = V[n]; - bits(2*datasize) operand2 = V[m]; - bits(datasize) result; - integer round_const = if round then 1 << (esize - 1) else 0; - bits(2*esize) element1; - bits(2*esize) element2; - bits(2*esize) sum; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, 2*esize]; - element2 = Elem[operand2, e, 2*esize]; - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - sum = sum + round_const; - Elem[result, e, esize] = sum[2*esize-1:esize]; - - Vpart[d, part] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_fp16_sisd - __instruction_set A64 - __field U 29 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 00xxxxxx 1001x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer index = UInt(H:L:M); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - boolean mulx_op = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_fp_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 1xxxxxxx 1001x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi = M; - case sz:L of - when '0x' index = UInt(H:L); - when '10' index = UInt(H); - when '11' UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - boolean mulx_op = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 00xxxxxx 1001x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer index = UInt(H:L:M); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean mulx_op = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 1xxxxxxx 1001x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi = M; - case sz:L of - when '0x' index = UInt(H:L); - when '10' index = UInt(H); - when '11' UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean mulx_op = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2 = Elem[operand2, index, esize]; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - if mulx_op then - Elem[result, e, esize] = FPMulX(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMul(element1, element2, FPCR); - - V[d] = result; - -__instruction SQDECW_R_RS_SX - __encoding SQDECW_R_RS_SX - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1010xxxx 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQDECW_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1011xxxx 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 - (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_uniform_recps_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_recps_fp16_sisd - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 010xxxxx 001111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_binary_uniform_recps_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 0x1xxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_binary_uniform_recps_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 010xxxxx 001111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __encoding aarch64_vector_arithmetic_binary_uniform_recps_simd - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 0x1xxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPRecipStepFused(element1, element2); - - V[d] = result; - -__instruction aarch64_vector_logical - __encoding aarch64_vector_logical - __instruction_set A64 - __field Q 30 +: 1 - __field op 29 +: 1 - __field a 18 +: 1 - __field b 17 +: 1 - __field c 16 +: 1 - __field cmode 12 +: 4 - __field d 9 +: 1 - __field e 8 +: 1 - __field f 7 +: 1 - __field g 6 +: 1 - __field h 5 +: 1 - __field Rd 0 +: 5 - __opcode '0xx01111 00000xxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer rd = UInt(Rd); - - integer datasize = if Q == '1' then 128 else 64; - bits(datasize) imm; - bits(64) imm64; - - ImmediateOp operation; - case cmode:op of - when '0xx00' operation = ImmediateOp_MOVI; - when '0xx01' operation = ImmediateOp_MVNI; - when '0xx10' operation = ImmediateOp_ORR; - when '0xx11' operation = ImmediateOp_BIC; - when '10x00' operation = ImmediateOp_MOVI; - when '10x01' operation = ImmediateOp_MVNI; - when '10x10' operation = ImmediateOp_ORR; - when '10x11' operation = ImmediateOp_BIC; - when '110x0' operation = ImmediateOp_MOVI; - when '110x1' operation = ImmediateOp_MVNI; - when '1110x' operation = ImmediateOp_MOVI; - when '11110' operation = ImmediateOp_MOVI; - when '11111' - // FMOV Dn,#imm is in main FP instruction set - if Q == '0' then UNDEFINED; - operation = ImmediateOp_MOVI; - - imm64 = AdvSIMDExpandImm(op, cmode, a:b:c:d:e:f:g:h); - imm = Replicate(imm64, datasize DIV 64); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand; - bits(datasize) result; - - case operation of - when ImmediateOp_MOVI - result = imm; - when ImmediateOp_MVNI - result = NOT(imm); - when ImmediateOp_ORR - operand = V[rd]; - result = operand OR imm; - when ImmediateOp_BIC - operand = V[rd]; - result = operand AND NOT(imm); - - V[rd] = result; - -__instruction FABS_Z_P_Z__ - __encoding FABS_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx011100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPAbs(element); - - Z[d] = result; - -__instruction FTSSEL_Z_ZZ__ - __encoding FTSSEL_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 101100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPTrigSSel(element1, element2); - - Z[d] = result; - -__instruction SQSUB_Z_ZZ__ - __encoding SQSUB_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 000110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - element2, esize, unsigned); - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_sub_saturating_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_sub_saturating_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 001011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_sub_saturating_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 001011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer diff; - boolean sat; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - diff = element1 - element2; - (Elem[result, e, esize], sat) = SatQ(diff, esize, unsigned); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction aarch64_memory_single_general_immediate_signed_pac - __encoding aarch64_memory_single_general_immediate_signed_pac - __instruction_set A64 - __field size 30 +: 2 - __field M 23 +: 1 - __field S 22 +: 1 - __field imm9 12 +: 9 - __field W 11 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxxx1xx xxxxxxxx' - __guard TRUE - __decode - if !HavePACExt() || size != '11' then UNDEFINED; - integer t = UInt(Rt); - integer n = UInt(Rn); - boolean wback = (W == '1'); - boolean use_key_a = (M == '0'); - bits(10) S10 = S:imm9; - integer scale = 3; - bits(64) offset = LSL(SignExtend(S10, 64), scale); - boolean tag_checked = wback || n != 31; - - __execute - bits(64) address; - bits(64) data; - boolean wb_unknown = FALSE; - boolean auth_then_branch = TRUE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - address = SP[]; - else - address = X[n]; - - if use_key_a then - address = AuthDA(address, X[31], auth_then_branch); - else - address = AuthDB(address, X[31], auth_then_branch); - - if n == 31 then - CheckSPAlignment(); - - address = address + offset; - data = Mem[address, 8, AccType_NORMAL]; - X[t] = data; - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction STNT1W_Z_P_BI_Contiguous - __encoding STNT1W_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 0001xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - constant integer mbytes = esize DIV 8; - bits(VL) src; - bits(PL) mask = P[g]; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - src = Z[t]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_STREAM] = Elem[src, e, esize]; - addr = addr + mbytes; - -__instruction FADD_Z_P_ZS__ - __encoding FADD_Z_P_ZS__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field i1 5 +: 1 - __field Zdn 0 +: 5 - __opcode '01100101 xx011000 100xxx00 00xxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - bits(esize) imm = if i1 == '0' then FPPointFive('0') else FPOne('0'); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPAdd(element1, imm, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction SETFFR_F__ - __encoding SETFFR_F__ - __instruction_set A64 - __opcode '00100101 00101100 10010000 00000000' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - - __execute - CheckSVEEnabled(); - FFR[] = Ones(PL); - -__instruction MUL_Z_ZI__ - __encoding MUL_Z_ZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm8 5 +: 8 - __field Zdn 0 +: 5 - __opcode '00100101 xx110000 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer imm = SInt(imm8); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = SInt(Elem[operand1, e, esize]); - Elem[result, e, esize] = (element1 * imm)[esize-1:0]; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field a 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (a == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_2008 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - - if minimum then - Elem[result, e, esize] = FPMinNum(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR); - - V[d] = result; - -__instruction aarch64_integer_pac_pacdb_dp_1src - __encoding aarch64_integer_pac_pacdb_dp_1src - __instruction_set A64 - __field Z 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11011010 11000001 00x011xx xxxxxxxx' - __guard TRUE - __decode - boolean source_is_sp = FALSE; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if !HavePACExt() then - UNDEFINED; - - if Z == '0' then // PACDB - if n == 31 then source_is_sp = TRUE; - else // PACDZB - if n != 31 then UNDEFINED; - - __execute - if source_is_sp then - X[d] = AddPACDB(X[d], SP[]); - else - X[d] = AddPACDB(X[d], X[n]); - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_float_arithmetic_mul_add_sub - __encoding aarch64_float_arithmetic_mul_add_sub - __instruction_set A64 - __field ftype 22 +: 2 - __field o1 21 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011111 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer a = UInt(Ra); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean opa_neg = (o1 == '1'); - boolean op1_neg = (o0 != o1); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operanda = V[a]; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - if opa_neg then operanda = FPNeg(operanda); - if op1_neg then operand1 = FPNeg(operand1); - result = FPMulAdd(operanda, operand1, operand2, FPCR); - - V[d] = result; - -__instruction USMMLA_Z_ZZZ__ - __encoding USMMLA_Z_ZZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000101 100xxxxx 100110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveInt8MatMulExt() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_unsigned = TRUE; - boolean op2_unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer segments = VL DIV 128; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result = Zeros(); - bits(128) op1, op2; - bits(128) res, addend; - - for s = 0 to segments-1 - op1 = Elem[operand1, s, 128]; - op2 = Elem[operand2, s, 128]; - addend = Elem[operand3, s, 128]; - res = MatMulAdd(addend, op1, op2, op1_unsigned, op2_unsigned); - Elem[result, s, 128] = res; - - Z[da] = result; - -__instruction SEL_Z_P_ZZ__ - __encoding SEL_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 4 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx1xxxxx 11xxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = element1; - else - Elem[result, e, esize] = element2; - - Z[d] = result; - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_branch_unconditional_register - __encoding aarch64_branch_unconditional_register - __instruction_set A64 - __field Z 24 +: 1 - __field op 21 +: 2 - __field A 11 +: 1 - __field M 10 +: 1 - __field Rn 5 +: 5 - __field Rm 0 +: 5 - __opcode '1101011x 0xx11111 0000xxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - BranchType branch_type; - integer m = UInt(Rm); - boolean pac = (A == '1'); - boolean use_key_a = (M == '0'); - boolean source_is_sp = ((Z == '1') && (m == 31)); - - if !pac && m != 0 then - UNDEFINED; - elsif pac && !HavePACExt() then - UNDEFINED; - - case op of - when '00' branch_type = BranchType_INDIR; - when '01' branch_type = BranchType_INDCALL; - when '10' branch_type = BranchType_RET; - otherwise UNDEFINED; - - if pac then - if Z == '0' && m != 31 then - UNDEFINED; - - if branch_type == BranchType_RET then - if n != 31 then UNDEFINED; - n = 30; - source_is_sp = TRUE; - - __execute - bits(64) target = X[n]; - boolean auth_then_branch = TRUE; - - if pac then - bits(64) modifier = if source_is_sp then SP[] else X[m]; - - if use_key_a then - target = AuthIA(target, modifier, auth_then_branch); - else - target = AuthIB(target, modifier, auth_then_branch); - - if branch_type == BranchType_INDCALL then X[30] = PC[] + 4; - - // Value in BTypeNext will be used to set PSTATE.BTYPE - case branch_type of - when BranchType_INDIR // BR, BRAA, BRAB, BRAAZ, BRABZ - if InGuardedPage then - if n == 16 || n == 17 then - BTypeNext = '01'; - else - BTypeNext = '11'; - else - BTypeNext = '01'; - when BranchType_INDCALL // BLR, BLRAA, BLRAB, BLRAAZ, BLRABZ - BTypeNext = '10'; - when BranchType_RET // RET, RETAA, RETAB - BTypeNext = '00'; - - BranchTo(target, branch_type); - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_product - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_product - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 100111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if U == '1' && size != '00' then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean poly = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - bits(esize) product; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if poly then - product = PolynomialMult(element1, element2)[esize-1:0]; - else - product = (UInt(element1) * UInt(element2))[esize-1:0]; - Elem[result, e, esize] = product; - - V[d] = result; - -__instruction aarch64_integer_shift_variable - __encoding aarch64_integer_shift_variable - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field op2 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011010 110xxxxx 0010xxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - ShiftType shift_type = DecodeShift(op2); - - __execute - bits(datasize) result; - bits(datasize) operand2 = X[m]; - - result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize); - X[d] = result; - -__instruction ST2B_Z_P_BR_Contiguous - __encoding ST2B_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 001xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction LD1H_Z_P_BZ_S_x32_scaled - __encoding LD1H_Z_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 1x1xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding LD1H_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 1x1xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding LD1H_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 1x0xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1H_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 1x0xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1H_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 111xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 1; - - __encoding LD1H_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 110xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset = Z[m]; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction STNT1B_Z_P_BI_Contiguous - __encoding STNT1B_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 0001xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - constant integer mbytes = esize DIV 8; - bits(VL) src; - bits(PL) mask = P[g]; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - src = Z[t]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_STREAM] = Elem[src, e, esize]; - addr = addr + mbytes; - -__instruction aarch64_vector_arithmetic_binary_uniform_shift_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - if S == '0' && size != '11' then UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer round_const = 0; - integer shift; - integer element; - boolean sat; - - for e = 0 to elements-1 - shift = SInt(Elem[operand2, e, esize][7:0]); - if rounding then - round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift - element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift; - if saturating then - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - else - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_vector_crypto_sha512_sha512h2 - __encoding aarch64_vector_crypto_sha512_sha512h2 - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 011xxxxx 100001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSHA512Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vtmp; - bits(64) NSigma0; - bits(64) tmp; - bits(128) X = V[n]; - bits(128) Y = V[m]; - bits(128) W = V[d]; - - NSigma0 = ROR(Y[63:0], 28) EOR ROR(Y[63:0],34) EOR ROR(Y[63:0],39); - Vtmp[127:64] = (X[63:0] AND Y[127:64]) EOR (X[63:0] AND Y[63:0]) EOR (Y[127:64] AND Y[63:0]); - Vtmp[127:64] = (Vtmp[127:64] + NSigma0 + W[127:64]); - NSigma0 = ROR(Vtmp[127:64], 28) EOR ROR(Vtmp[127:64],34) EOR ROR(Vtmp[127:64],39); - Vtmp[63:0] = (Vtmp[127:64] AND Y[63:0]) EOR (Vtmp[127:64] AND Y[127:64]) EOR (Y[127:64] AND Y[63:0]); - Vtmp[63:0] = (Vtmp[63:0] + NSigma0 + W[63:0]); - - V[d] = Vtmp; - -__instruction LD4H_Z_P_BR_Contiguous - __encoding LD4H_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 111xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_dotp - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_dotp - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx0xxxxx 100101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveDOTPExt() then UNDEFINED; - if size!= '10' then UNDEFINED; - boolean signed = (U=='0'); - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - result = V[d]; - for e = 0 to elements-1 - integer res = 0; - integer element1, element2; - for i = 0 to 3 - if signed then - element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = SInt(Elem[operand2, 4 * e + i, esize DIV 4]); - else - element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = UInt(Elem[operand2, 4 * e + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = Elem[result, e, esize] + res; - V[d] = result; - -__instruction aarch64_memory_pair_simdfp_no_alloc - __encoding aarch64_memory_pair_simdfp_no_alloc - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101100 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); - AccType acctype = AccType_VECSTREAM; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - if opc == '11' then UNDEFINED; - integer scale = 2 + UInt(opc); - integer datasize = 8 << scale; - bits(64) offset = LSL(SignExtend(imm7, 64), scale); - boolean tag_checked = wback || n != 31; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(datasize) data1; - bits(datasize) data2; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data1 = V[t]; - data2 = V[t2]; - Mem[address + 0 , dbytes, acctype] = data1; - Mem[address + dbytes, dbytes, acctype] = data2; - - when MemOp_LOAD - data1 = Mem[address + 0 , dbytes, acctype]; - data2 = Mem[address + dbytes, dbytes, acctype]; - if rt_unknown then - data1 = bits(datasize) UNKNOWN; - data2 = bits(datasize) UNKNOWN; - V[t] = data1; - V[t2] = data2; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_unary_add_pairwise - __encoding aarch64_vector_arithmetic_unary_add_pairwise - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 0x1010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV (2*esize); - boolean acc = (op == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - bits(2*esize) sum; - integer op1; - integer op2; - - if acc then result = V[d]; - for e = 0 to elements-1 - op1 = Int(Elem[operand, 2*e+0, esize], unsigned); - op2 = Int(Elem[operand, 2*e+1, esize], unsigned); - sum = (op1 + op2)[2*esize-1:0]; - if acc then - Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + sum; - else - Elem[result, e, 2*esize] = sum; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_lower - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_lower - __instruction_set A64 - __field Q 30 +: 1 - __field S 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 111011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz == '1' then UNDEFINED; - integer esize = 32; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (S == '1'); - integer part = 0; - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_upper - __instruction_set A64 - __field Q 30 +: 1 - __field S 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx1xxxxx 110011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz == '1' then UNDEFINED; - integer esize = 32; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (S == '1'); - integer part = 1; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize DIV 2) operand1 = Vpart[n,part]; - bits(datasize DIV 2) operand2 = Vpart[m,part]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize DIV 2) element1; - bits(esize DIV 2) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize DIV 2]; - element2 = Elem[operand2, e, esize DIV 2]; - if sub_op then element1 = FPNeg(element1); - Elem[result,e,esize] = FPMulAddH(Elem[operand3, e, esize], element1, element2, FPCR); - V[d] = result; - -__instruction aarch64_vector_shift_conv_int_sisd - __encoding aarch64_vector_shift_conv_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then UNDEFINED; - integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16; - integer datasize = esize; - integer elements = 1; - - integer fracbits = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding aarch64_vector_shift_conv_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 111001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then UNDEFINED; - if immh[3]:Q == '10' then UNDEFINED; - integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer fracbits = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - FPRounding rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FixedToFP(element, fracbits, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_transfer_integer_dup - __encoding aarch64_vector_transfer_integer_dup - __instruction_set A64 - __field Q 30 +: 1 - __field imm5 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 000xxxxx 000011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer size = LowestSetBit(imm5); - if size > 3 then UNDEFINED; - - // imm5[4:size+1] is IGNORED - - if size == 3 && Q == '0' then UNDEFINED; - integer esize = 8 << size; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(esize) element = X[n]; - bits(datasize) result; - - for e = 0 to elements-1 - Elem[result, e, esize] = element; - V[d] = result; - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_cvt_bf16_scalar - __encoding aarch64_vector_cvt_bf16_scalar - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 01100011 010000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Rn); - integer d = UInt(Rd); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(32) operand = V[n]; - bits(16) result; - - result = FPConvertBF(operand, FPCR); - V[d] = result; - -__instruction LDFF1H_Z_P_BR_U16 - __encoding LDFF1H_Z_P_BR_U16 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 101xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 16; - boolean unsigned = TRUE; - - __encoding LDFF1H_Z_P_BR_U32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 110xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = TRUE; - - __encoding LDFF1H_Z_P_BR_U64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 111xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + UInt(offset) * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_CNOTFIRST]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - offset = offset + 1; - - Z[t] = result; - -__instruction LD1RSB_Z_P_BI_S16 - __encoding LD1RSB_Z_P_BI_S16 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 11xxxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = UInt(imm6); - - __encoding LD1RSB_Z_P_BI_S32 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 11xxxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = UInt(imm6); - - __encoding LD1RSB_Z_P_BI_S64 - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 11xxxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = UInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - integer last = LastActiveElement(mask, esize); - if last >= 0 then - addr = base + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction RDFFR_P_F__ - __encoding RDFFR_P_F__ - __instruction_set A64 - __field Pd 0 +: 4 - __opcode '00100101 00011001 11110000 0000xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer d = UInt(Pd); - - __execute - CheckSVEEnabled(); - bits(PL) ffr = FFR[]; - P[d] = ffr; - -__instruction LDNT1H_Z_P_BR_Contiguous - __encoding LDNT1H_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 100xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(64) offset; - bits(PL) mask = P[g]; - bits(VL) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = X[m]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_STREAM]; - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_unary_fp16_round - __encoding aarch64_vector_arithmetic_unary_fp16_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 100x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __encoding aarch64_vector_arithmetic_unary_float_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean test_passed; - - for e = 0 to elements-1 - element = SInt(Elem[operand, e, esize]); - case comparison of - when CompareOp_GT test_passed = element > 0; - when CompareOp_GE test_passed = element >= 0; - when CompareOp_EQ test_passed = element == 0; - when CompareOp_LE test_passed = element <= 0; - when CompareOp_LT test_passed = element < 0; - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction SQINCB_R_RS_SX - __encoding SQINCB_R_RS_SX - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0010xxxx 111100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQINCB_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0011xxxx 111100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 + (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_vector_arithmetic_binary_uniform_mat_mul_int_mla - __encoding aarch64_vector_arithmetic_binary_uniform_mat_mul_int_mla - __instruction_set A64 - __field U 29 +: 1 - __field Rm 16 +: 5 - __field B 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x01110 100xxxxx 1010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveInt8MatMulExt() then UNDEFINED; - case B:U of - when '00' op1_unsigned = FALSE; op2_unsigned = FALSE; - when '01' op1_unsigned = TRUE; op2_unsigned = TRUE; - when '10' op1_unsigned = TRUE; op2_unsigned = FALSE; - when '11' UNDEFINED; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(128) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(128) addend = V[d]; - - V[d] = MatMulAdd(addend, operand1, operand2, op1_unsigned, op2_unsigned); - -__instruction SDOT_Z_ZZZi_S - __encoding SDOT_Z_ZZZi_S - __instruction_set A64 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000100 101xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer index = UInt(i2); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __encoding SDOT_Z_ZZZi_D - __instruction_set A64 - __field i1 20 +: 1 - __field Zm 16 +: 4 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000100 111xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer index = UInt(i1); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer eltspersegment = 128 DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = segmentbase + index; - bits(esize) res = Elem[operand3, e, esize]; - for i = 0 to 3 - integer element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - integer element2 = SInt(Elem[operand2, 4 * s + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = res; - - Z[da] = result; - -__instruction aarch64_vector_transfer_integer_move_signed - __encoding aarch64_vector_transfer_integer_move_signed - __instruction_set A64 - __field Q 30 +: 1 - __field imm5 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 000xxxxx 001011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer size; - case Q:imm5 of - when 'xxxxx1' size = 0; // SMOV [WX]d, Vn.B - when 'xxxx10' size = 1; // SMOV [WX]d, Vn.H - when '1xx100' size = 2; // SMOV Xd, Vn.S - otherwise UNDEFINED; - - integer idxdsize = if imm5[4] == '1' then 128 else 64; - integer index = UInt(imm5[4:size+1]); - integer esize = 8 << size; - integer datasize = if Q == '1' then 64 else 32; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(idxdsize) operand = V[n]; - - X[d] = SignExtend(Elem[operand, index, esize], datasize); - -__instruction aarch64_memory_exclusive_pair - __encoding aarch64_memory_exclusive_pair - __instruction_set A64 - __field sz 30 +: 1 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '1x001000 0x1xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = TRUE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 32 << UInt(sz); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_reduce_fp16_maxnm_sisd - __encoding aarch64_vector_reduce_fp16_maxnm_sisd - __instruction_set A64 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 xx110000 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - if sz == '1' then UNDEFINED; - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM; - - __encoding aarch64_vector_reduce_fp_maxnm_sisd - __instruction_set A64 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 xx110000 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_accum - __encoding aarch64_vector_arithmetic_binary_disparate_mul_accum - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 10x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - bits(2*esize) accum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - if sub_op then - accum = Elem[operand3, e, 2*esize] - product; - else - accum = Elem[operand3, e, 2*esize] + product; - Elem[result, e, 2*esize] = accum; - - V[d] = result; - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction UQDECP_R_P_R_UW - __encoding UQDECP_R_P_R_UW - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101011 1000100x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQDECP_R_P_R_X - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101011 1000110x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(ssize) operand1 = X[dn]; - bits(PL) operand2 = P[m]; - bits(ssize) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - integer element = Int(operand1, unsigned); - (result, -) = SatQ(element - count, ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction LD1H_Z_P_BI_U16 - __encoding LD1H_Z_P_BI_U16 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1010xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LD1H_Z_P_BI_U32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1100xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LD1H_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1110xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_vector_shift_left_sat_sisd - __encoding aarch64_vector_shift_left_sat_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 011x01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = esize; - integer elements = 1; - - integer shift = UInt(immh:immb) - esize; - - boolean src_unsigned; - boolean dst_unsigned; - case op:U of - when '00' UNDEFINED; - when '01' src_unsigned = FALSE; dst_unsigned = TRUE; - when '10' src_unsigned = FALSE; dst_unsigned = FALSE; - when '11' src_unsigned = TRUE; dst_unsigned = TRUE; - - __encoding aarch64_vector_shift_left_sat_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 011x01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = UInt(immh:immb) - esize; - - boolean src_unsigned; - boolean dst_unsigned; - case op:U of - when '00' UNDEFINED; - when '01' src_unsigned = FALSE; dst_unsigned = TRUE; - when '10' src_unsigned = FALSE; dst_unsigned = FALSE; - when '11' src_unsigned = TRUE; dst_unsigned = TRUE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = Int(Elem[operand, e, esize], src_unsigned) << shift; - (Elem[result, e, esize], sat) = SatQ(element, esize, dst_unsigned); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction ST2H_Z_P_BR_Contiguous - __encoding ST2H_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 101xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction aarch64_integer_pac_pacia_dp_1src - __encoding aarch64_integer_pac_pacia_dp_1src - __instruction_set A64 - __field Z 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11011010 11000001 00x000xx xxxxxxxx' - __guard TRUE - __decode - boolean source_is_sp = FALSE; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if !HavePACExt() then - UNDEFINED; - - if Z == '0' then // PACIA - if n == 31 then source_is_sp = TRUE; - else // PACIZA - if n != 31 then UNDEFINED; - - __encoding aarch64_integer_pac_pacia_hint - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - integer d; - integer n; - boolean source_is_sp = FALSE; - - case CRm:op2 of - when '0011 000' // PACIAZ - d = 30; - n = 31; - when '0011 001' // PACIASP - d = 30; - source_is_sp = TRUE; - if HaveBTIExt() then - // Check for branch target compatibility between PSTATE.BTYPE - // and implicit branch target of PACIASP instruction. - SetBTypeCompatible(BTypeCompatible_PACIXSP()); - - when '0001 000' // PACIA1716 - d = 17; - n = 16; - when '0001 010' SEE "PACIB"; - when '0001 100' SEE "AUTIA"; - when '0001 110' SEE "AUTIB"; - when '0011 01x' SEE "PACIB"; - when '0011 10x' SEE "AUTIA"; - when '0011 11x' SEE "AUTIB"; - when '0000 111' SEE "XPACLRI"; - otherwise SEE "HINT"; - - __execute - if HavePACExt() then - if source_is_sp then - X[d] = AddPACIA(X[d], SP[]); - else - X[d] = AddPACIA(X[d], X[n]); - -__instruction LD3D_Z_P_BI_Contiguous - __encoding LD3D_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1100xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction SADDV_R_P_Z__ - __encoding SADDV_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000100 xx000000 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - integer sum = 0; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer element = SInt(Elem[operand, e, esize]); - sum = sum + element; - - V[d] = sum[63:0]; - -__instruction aarch64_float_compare_cond - __encoding aarch64_float_compare_cond - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field Rn 5 +: 5 - __field op 4 +: 1 - __field nzcv 0 +: 4 - __opcode '00011110 xx1xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean signal_all_nans = (op == '1'); - bits(4) condition = cond; - bits(4) flags = nzcv; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) operand1 = V[n]; - bits(datasize) operand2; - - operand2 = V[m]; - - if ConditionHolds(condition) then - flags = FPCompare(operand1, operand2, signal_all_nans, FPCR); - PSTATE.[N,Z,C,V] = flags; - -__instruction LD1RQW_Z_P_BR_Contiguous - __encoding LD1RQW_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 000xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - - __execute - CheckSVEEnabled(); - integer elements = 128 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low 16 bits only - bits(64) offset; - bits(128) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = X[m]; - - addr = base + UInt(offset) * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = Replicate(result, VL DIV 128); - -__instruction FMULX_Z_P_ZZ__ - __encoding FMULX_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx001010 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMulX(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction LD2W_Z_P_BR_Contiguous - __encoding LD2W_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 001xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_arithmetic_binary_uniform_logical_and_orr - __encoding aarch64_vector_arithmetic_binary_uniform_logical_and_orr - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean invert = (size[0] == '1'); - LogicalOp op = if size[1] == '1' then LogicalOp_ORR else LogicalOp_AND; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND - result = operand1 AND operand2; - when LogicalOp_ORR - result = operand1 OR operand2; - - V[d] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_memory_pair_simdfp_post_idx - __encoding aarch64_memory_pair_simdfp_post_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101100 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - - __encoding aarch64_memory_pair_simdfp_pre_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - - __encoding aarch64_memory_pair_simdfp_offset - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101101 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); - AccType acctype = AccType_VEC; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - if opc == '11' then UNDEFINED; - integer scale = 2 + UInt(opc); - integer datasize = 8 << scale; - bits(64) offset = LSL(SignExtend(imm7, 64), scale); - boolean tag_checked = wback || n != 31; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(datasize) data1; - bits(datasize) data2; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data1 = V[t]; - data2 = V[t2]; - Mem[address + 0 , dbytes, acctype] = data1; - Mem[address + dbytes, dbytes, acctype] = data2; - - when MemOp_LOAD - data1 = Mem[address + 0 , dbytes, acctype]; - data2 = Mem[address + dbytes, dbytes, acctype]; - if rt_unknown then - data1 = bits(datasize) UNKNOWN; - data2 = bits(datasize) UNKNOWN; - V[t] = data1; - V[t2] = data2; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction NOT_Z_P_Z__ - __encoding NOT_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx011110 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = NOT element; - - Z[d] = result; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction ORR_Z_ZI__ - __encoding ORR_Z_ZI__ - __instruction_set A64 - __field imm13 5 +: 13 - __field Zdn 0 +: 5 - __opcode '00000101 000000xx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer dn = UInt(Zdn); - bits(64) imm; - (imm, -) = DecodeBitMasks(imm13[12], imm13[5:0], imm13[11:6], TRUE); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 64; - bits(VL) operand = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(64) element1 = Elem[operand, e, 64]; - Elem[result, e, 64] = element1 OR imm; - - Z[dn] = result; - -__instruction aarch64_integer_arithmetic_add_sub_carry - __encoding aarch64_integer_arithmetic_add_sub_carry - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx11010 000xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(4) nzcv; - - if sub_op then - operand2 = NOT(operand2); - - (result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - X[d] = result; - -__instruction FACGT_P_P_ZZ__ - __encoding FACGT_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx0xxxxx 111xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GT; - - __encoding FACGE_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx0xxxxx 110xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(PL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - case op of - when Cmp_GE res = FPCompareGE(FPAbs(element1), FPAbs(element2), FPCR); - when Cmp_GT res = FPCompareGT(FPAbs(element1), FPAbs(element2), FPCR); - ElemP[result, e, esize] = if res then '1' else '0'; - else - ElemP[result, e, esize] = '0'; - - P[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_fp16_sisd - __instruction_set A64 - __field U 29 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 00xxxxxx 1001x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer index = UInt(H:L:M); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - boolean mulx_op = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_fp_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 1xxxxxxx 1001x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi = M; - case sz:L of - when '0x' index = UInt(H:L); - when '10' index = UInt(H); - when '11' UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - boolean mulx_op = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 00xxxxxx 1001x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer idxdsize = if H == '1' then 128 else 64; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - integer index = UInt(H:L:M); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean mulx_op = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 1xxxxxxx 1001x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi = M; - case sz:L of - when '0x' index = UInt(H:L); - when '10' index = UInt(H); - when '11' UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean mulx_op = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2 = Elem[operand2, index, esize]; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - if mulx_op then - Elem[result, e, esize] = FPMulX(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMul(element1, element2, FPCR); - - V[d] = result; - -__instruction MLS_Z_P_ZZZ__ - __encoding MLS_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '00000100 xx0xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean sub_op = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = UInt(Elem[operand1, e, esize]); - integer element2 = UInt(Elem[operand2, e, esize]); - if ElemP[mask, e, esize] == '1' then - integer product = element1 * element2; - if sub_op then - Elem[result, e, esize] = Elem[operand3, e, esize] - product; - else - Elem[result, e, esize] = Elem[operand3, e, esize] + product; - else - Elem[result, e, esize] = Elem[operand3, e, esize]; - - Z[da] = result; - -__instruction LD1W_Z_P_BZ_S_x32_scaled - __encoding LD1W_Z_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 0x1xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 2; - - __encoding LD1W_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 0x1xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 2; - - __encoding LD1W_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 0x0xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1W_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 0x0xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1W_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 011xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 2; - - __encoding LD1W_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 010xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset = Z[m]; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_bf16_long - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_bf16_long - __instruction_set A64 - __field Q 30 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 11xxxxxx 1111x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Rn); - integer m = UInt('0':Rm); - integer d = UInt(Rd); - integer index = UInt(H:L:M); - - integer elements = 128 DIV 32; - integer sel = UInt(Q); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(128) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(128) operand3 = V[d]; - bits(128) result; - - bits(32) element2 = Elem[operand2, index, 16] : Zeros(16); - - for e = 0 to elements-1 - bits(32) element1 = Elem[operand1, 2 * e + sel, 16] : Zeros(16); - bits(32) addend = Elem[operand3, e, 32]; - Elem[result, e, 32] = FPMulAdd(addend, element1, element2, FPCR); - - V[d] = result; - -__instruction aarch64_integer_arithmetic_add_sub_carry - __encoding aarch64_integer_arithmetic_add_sub_carry - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx11010 000xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(4) nzcv; - - if sub_op then - operand2 = NOT(operand2); - - (result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - X[d] = result; - -__instruction LD1W_Z_P_AI_S - __encoding LD1W_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 001xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __encoding LD1W_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 001xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction FSCALE_Z_P_ZZ__ - __encoding FSCALE_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx001001 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - integer element2 = SInt(Elem[operand2, e, esize]); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPScale(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction FRECPS_Z_ZZ__ - __encoding FRECPS_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx0xxxxx 000110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPRecipStepFused(element1, element2); - - Z[d] = result; - -__instruction aarch64_integer_tags_mcinsertrandomtag - __encoding aarch64_integer_tags_mcinsertrandomtag - __instruction_set A64 - __field Xm 16 +: 5 - __field Xn 5 +: 5 - __field Xd 0 +: 5 - __opcode '10011010 110xxxxx 000100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Xd); - integer n = UInt(Xn); - integer m = UInt(Xm); - - __execute - bits(64) operand = if n == 31 then SP[] else X[n]; - bits(64) exclude_reg = X[m]; - bits(16) exclude = exclude_reg[15:0] OR GCR_EL1.Exclude; - - if AArch64.AllocationTagAccessIsEnabled() then - if GCR_EL1.RRND == '1' then - RGSR_EL1 = bits(32) UNKNOWN; - rtag = _ChooseRandomNonExcludedTag(exclude); - else - bits(4) start = RGSR_EL1.TAG; - bits(4) offset = AArch64.RandomTag(); - - rtag = AArch64.ChooseNonExcludedTag(start, offset, exclude); - - RGSR_EL1.TAG = rtag; - else - rtag = '0000'; - - bits(64) result = AArch64.AddressWithAllocationTag(operand, rtag); - - if d == 31 then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_long - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 xxxxxxxx 0x10x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(idxdsize) operand2 = V[m]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - - element2 = Int(Elem[operand2, index, esize], unsigned); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - if sub_op then - Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] - product; - else - Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] + product; - - V[d] = result; - -__instruction LD2H_Z_P_BR_Contiguous - __encoding LD2H_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 101xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction LD1B_Z_P_AI_S - __encoding LD1B_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 001xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __encoding LD1B_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 001xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_unpriv - __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - - unpriv_at_el1 = PSTATE.EL == EL1 && !(EL2Enabled() && HaveNVExt() && HCR_EL2.[NV,NV1] == '11'); - unpriv_at_el2 = PSTATE.EL == EL2 && HaveVirtHostExt() && HCR_EL2.[E2H,TGE] == '11'; - - user_access_override = HaveUAOExt() && PSTATE.UAO == '1'; - if !user_access_override && (unpriv_at_el1 || unpriv_at_el2) then - acctype = AccType_UNPRIV; - else - acctype = AccType_NORMAL; - - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction SQDECB_R_RS_SX - __encoding SQDECB_R_RS_SX - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0010xxxx 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQDECB_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0011xxxx 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 - (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction PRFB_I_P_BZ_S_x32_scaled - __encoding PRFB_I_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000100 0x1xxxxx 000xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 32; - boolean offs_unsigned = (xs == '0'); - integer scale = 0; - - __encoding PRFB_I_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 0x1xxxxx 000xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 32; - boolean offs_unsigned = (xs == '0'); - integer scale = 0; - - __encoding PRFB_I_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 011xxxxx 100xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) addr; - bits(VL) offset; - - if n == 31 then - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - -__instruction LD1SW_Z_P_BR_S64 - __encoding LD1SW_Z_P_BR_S64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 100xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_round - __encoding aarch64_vector_arithmetic_unary_fp16_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 100x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __encoding aarch64_vector_arithmetic_unary_float_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_shift_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - if S == '0' && size != '11' then UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer round_const = 0; - integer shift; - integer element; - boolean sat; - - for e = 0 to elements-1 - shift = SInt(Elem[operand2, e, esize][7:0]); - if rounding then - round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift - element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift; - if saturating then - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - else - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_branch_unconditional_register - __encoding aarch64_branch_unconditional_register - __instruction_set A64 - __field Z 24 +: 1 - __field op 21 +: 2 - __field A 11 +: 1 - __field M 10 +: 1 - __field Rn 5 +: 5 - __field Rm 0 +: 5 - __opcode '1101011x 0xx11111 0000xxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - BranchType branch_type; - integer m = UInt(Rm); - boolean pac = (A == '1'); - boolean use_key_a = (M == '0'); - boolean source_is_sp = ((Z == '1') && (m == 31)); - - if !pac && m != 0 then - UNDEFINED; - elsif pac && !HavePACExt() then - UNDEFINED; - - case op of - when '00' branch_type = BranchType_INDIR; - when '01' branch_type = BranchType_INDCALL; - when '10' branch_type = BranchType_RET; - otherwise UNDEFINED; - - if pac then - if Z == '0' && m != 31 then - UNDEFINED; - - if branch_type == BranchType_RET then - if n != 31 then UNDEFINED; - n = 30; - source_is_sp = TRUE; - - __execute - bits(64) target = X[n]; - boolean auth_then_branch = TRUE; - - if pac then - bits(64) modifier = if source_is_sp then SP[] else X[m]; - - if use_key_a then - target = AuthIA(target, modifier, auth_then_branch); - else - target = AuthIB(target, modifier, auth_then_branch); - - if branch_type == BranchType_INDCALL then X[30] = PC[] + 4; - - // Value in BTypeNext will be used to set PSTATE.BTYPE - case branch_type of - when BranchType_INDIR // BR, BRAA, BRAB, BRAAZ, BRABZ - if InGuardedPage then - if n == 16 || n == 17 then - BTypeNext = '01'; - else - BTypeNext = '11'; - else - BTypeNext = '01'; - when BranchType_INDCALL // BLR, BLRAA, BLRAB, BLRAAZ, BLRABZ - BTypeNext = '10'; - when BranchType_RET // RET, RETAA, RETAB - BTypeNext = '00'; - - BranchTo(target, branch_type); - -__instruction aarch64_vector_shift_right_sisd - __encoding aarch64_vector_shift_right_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __encoding aarch64_vector_shift_right_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - operand2 = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift; - Elem[result, e, esize] = Elem[operand2, e, esize] + element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_1985 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 001101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_1985 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - - if minimum then - Elem[result, e, esize] = FPMin(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMax(element1, element2, FPCR); - - V[d] = result; - -__instruction aarch64_integer_tags_mcaddtag - __encoding aarch64_integer_tags_mcaddtag - __instruction_set A64 - __field uimm6 16 +: 6 - __field op3 14 +: 2 - __field uimm4 10 +: 4 - __field Xn 5 +: 5 - __field Xd 0 +: 5 - __opcode '10010001 10xxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Xd); - integer n = UInt(Xn); - bits(4) tag_offset = uimm4; - bits(64) offset = LSL(ZeroExtend(uimm6, 64), LOG2_TAG_GRANULE); - boolean ADD = TRUE; - - __execute - bits(64) operand1 = if n == 31 then SP[] else X[n]; - bits(4) start_tag = AArch64.AllocationTagFromAddress(operand1); - bits(16) exclude = GCR_EL1.Exclude; - bits(64) result; - bits(4) rtag; - - if AArch64.AllocationTagAccessIsEnabled() then - rtag = AArch64.ChooseNonExcludedTag(start_tag, tag_offset, exclude); - else - rtag = '0000'; - - if ADD then - (result, -) = AddWithCarry(operand1, offset, '0'); - else - (result, -) = AddWithCarry(operand1, NOT(offset), '1'); - - result = AArch64.AddressWithAllocationTag(result, rtag); - - if d == 31 then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_integer_arithmetic_pointer_mcsubtracttaggedaddress - __encoding aarch64_integer_arithmetic_pointer_mcsubtracttaggedaddress - __instruction_set A64 - __field Xm 16 +: 5 - __field Xn 5 +: 5 - __field Xd 0 +: 5 - __opcode '10011010 110xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Xd); - integer n = UInt(Xn); - integer m = UInt(Xm); - boolean setflags = FALSE; - - __execute - bits(64) operand1 = if n == 31 then SP[] else X[n]; - bits(64) operand2 = if m == 31 then SP[] else X[m]; - operand1 = SignExtend(operand1[55:0], 64); - operand2 = SignExtend(operand2[55:0], 64); - - bits(64) result; - bits(4) nzcv; - - operand2 = NOT(operand2); - (result, nzcv) = AddWithCarry(operand1, operand2, '1'); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - X[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field a 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (a == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_2008 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - - if minimum then - Elem[result, e, esize] = FPMinNum(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR); - - V[d] = result; - -__instruction PRFD_I_P_BZ_S_x32_scaled - __encoding PRFD_I_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000100 0x1xxxxx 011xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 32; - boolean offs_unsigned = (xs == '0'); - integer scale = 3; - - __encoding PRFD_I_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 0x1xxxxx 011xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 32; - boolean offs_unsigned = (xs == '0'); - integer scale = 3; - - __encoding PRFD_I_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 011xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) addr; - bits(VL) offset; - - if n == 31 then - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction LD1RQD_Z_P_BI_U64 - __encoding LD1RQD_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1000xxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = 128 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low 16 bits only - bits(128) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * 16; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = Replicate(result, VL DIV 128); - -__instruction FSUB_Z_P_ZZ__ - __encoding FSUB_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx000001 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPSub(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction LD1ROB_Z_P_BI_U8 - __encoding LD1ROB_Z_P_BI_U8 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0010xxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVEFP64MatMulExt() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - if VL < 256 then UNDEFINED; - integer elements = 256 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low bits only - bits(256) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * 32; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = ZeroExtend(Replicate(result, VL DIV 256), VL); - -__instruction aarch64_vector_arithmetic_unary_special_recip_fp16_sisd - __encoding aarch64_vector_arithmetic_unary_special_recip_fp16_sisd - __instruction_set A64 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 11111001 110110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_unary_special_recip_float_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 1x100001 110110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_unary_special_recip_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 11111001 110110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __encoding aarch64_vector_arithmetic_unary_special_recip_float_simd - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 1x100001 110110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRecipEstimate(element, FPCR); - - V[d] = result; - -__instruction FADD_Z_ZZ__ - __encoding FADD_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx0xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPAdd(element1, element2, FPCR); - - Z[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_lda_stl - __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx011001 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_ORDERED; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_single_simdfp_register - __encoding aarch64_memory_single_simdfp_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111100 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_VEC; - MemOp memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - bits(64) address; - bits(datasize) data; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data = V[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - V[t] = data; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_integer_arithmetic_add_sub_shiftedreg - __encoding aarch64_integer_arithmetic_add_sub_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field shift 22 +: 2 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01011 xx0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - - if shift == '11' then UNDEFINED; - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - X[d] = result; - -__instruction aarch64_vector_reduce_fp16_max_simd - __encoding aarch64_vector_reduce_fp16_max_simd - __instruction_set A64 - __field Q 30 +: 1 - __field o1 23 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 x0110000 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX; - - __encoding aarch64_vector_reduce_fp_max_simd - __instruction_set A64 - __field Q 30 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx110000 111110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q != '01' then UNDEFINED; - - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction aarch64_integer_pac_autda_dp_1src - __encoding aarch64_integer_pac_autda_dp_1src - __instruction_set A64 - __field Z 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11011010 11000001 00x110xx xxxxxxxx' - __guard TRUE - __decode - boolean source_is_sp = FALSE; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if !HavePACExt() then - UNDEFINED; - - if Z == '0' then // AUTDA - if n == 31 then source_is_sp = TRUE; - else // AUTDZA - if n != 31 then UNDEFINED; - - __execute - auth_then_branch = FALSE; - - if HavePACExt() then - if source_is_sp then - X[d] = AuthDA(X[d], SP[], auth_then_branch); - else - X[d] = AuthDA(X[d], X[n], auth_then_branch); - -__instruction aarch64_memory_single_general_immediate_signed_offset_lda_stl - __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx011001 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_ORDERED; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_single_general_immediate_signed_offset_unpriv - __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - - unpriv_at_el1 = PSTATE.EL == EL1 && !(EL2Enabled() && HaveNVExt() && HCR_EL2.[NV,NV1] == '11'); - unpriv_at_el2 = PSTATE.EL == EL2 && HaveVirtHostExt() && HCR_EL2.[E2H,TGE] == '11'; - - user_access_override = HaveUAOExt() && PSTATE.UAO == '1'; - if !user_access_override && (unpriv_at_el1 || unpriv_at_el2) then - acctype = AccType_UNPRIV; - else - acctype = AccType_NORMAL; - - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_wrapping_pair - __encoding aarch64_vector_arithmetic_binary_uniform_add_wrapping_pair - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 101111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - Elem[result, e, esize] = element1 + element2; - - V[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_shift_right_sisd - __encoding aarch64_vector_shift_right_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __encoding aarch64_vector_shift_right_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - operand2 = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift; - Elem[result, e, esize] = Elem[operand2, e, esize] + element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_integer_arithmetic_add_sub_carry - __encoding aarch64_integer_arithmetic_add_sub_carry - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx11010 000xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(4) nzcv; - - if sub_op then - operand2 = NOT(operand2); - - (result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - X[d] = result; - -__instruction aarch64_vector_arithmetic_unary_add_pairwise - __encoding aarch64_vector_arithmetic_unary_add_pairwise - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 0x1010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV (2*esize); - boolean acc = (op == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - bits(2*esize) sum; - integer op1; - integer op2; - - if acc then result = V[d]; - for e = 0 to elements-1 - op1 = Int(Elem[operand, 2*e+0, esize], unsigned); - op2 = Int(Elem[operand, 2*e+1, esize], unsigned); - sum = (op1 + op2)[2*esize-1:0]; - if acc then - Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + sum; - else - Elem[result, e, 2*esize] = sum; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_accum - __encoding aarch64_vector_arithmetic_binary_disparate_mul_accum - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 10x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - bits(2*esize) accum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - if sub_op then - accum = Elem[operand3, e, 2*esize] - product; - else - accum = Elem[operand3, e, 2*esize] + product; - Elem[result, e, 2*esize] = accum; - - V[d] = result; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction ST3W_Z_P_BR_Contiguous - __encoding ST3W_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 010xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_narrow - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_narrow - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 01x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean round = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand1 = V[n]; - bits(2*datasize) operand2 = V[m]; - bits(datasize) result; - integer round_const = if round then 1 << (esize - 1) else 0; - bits(2*esize) element1; - bits(2*esize) element2; - bits(2*esize) sum; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, 2*esize]; - element2 = Elem[operand2, e, 2*esize]; - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - sum = sum + round_const; - Elem[result, e, esize] = sum[2*esize-1:esize]; - - Vpart[d, part] = result; - -__instruction aarch64_vector_arithmetic_unary_cnt - __encoding aarch64_vector_arithmetic_unary_cnt - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx100000 010110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size != '00' then UNDEFINED; - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 8; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - integer count; - for e = 0 to elements-1 - count = BitCount(Elem[operand, e, esize]); - Elem[result, e, esize] = count[esize-1:0]; - V[d] = result; - -__instruction LDFF1W_Z_P_BZ_S_x32_scaled - __encoding LDFF1W_Z_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 0x1xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 2; - - __encoding LDFF1W_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 0x1xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 2; - - __encoding LDFF1W_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 0x0xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1W_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 0x0xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1W_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 011xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 2; - - __encoding LDFF1W_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 010xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction aarch64_float_arithmetic_mul_add_sub - __encoding aarch64_float_arithmetic_mul_add_sub - __instruction_set A64 - __field ftype 22 +: 2 - __field o1 21 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011111 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer a = UInt(Ra); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean opa_neg = (o1 == '1'); - boolean op1_neg = (o0 != o1); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operanda = V[a]; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - if opa_neg then operanda = FPNeg(operanda); - if op1_neg then operand1 = FPNeg(operand1); - result = FPMulAdd(operanda, operand1, operand2, FPCR); - - V[d] = result; - -__instruction UABD_Z_P_ZZ__ - __encoding UABD_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx001101 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer absdiff = Abs(element1 - element2); - Elem[result, e, esize] = absdiff[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction ST1B_Z_P_BR__ - __encoding ST1B_Z_P_BR__ - __instruction_set A64 - __field size 21 +: 2 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 0xxxxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8 << UInt(size); - integer msize = 8; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - bits(VL) src = Z[t]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - offset = offset + 1; - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_long - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 00x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - Elem[result, e, 2*esize] = sum[2*esize-1:0]; - - V[d] = result; - -__instruction aarch64_vector_crypto_sm3_sm3tt1b - __encoding aarch64_vector_crypto_sm3_sm3tt1b - __instruction_set A64 - __field Rm 16 +: 5 - __field imm2 12 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 010xxxxx 10xx01xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSM3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer i = UInt(imm2); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) Vd = V[d]; - bits(32) WjPrime; - bits(128) result; - bits(32) TT1; - bits(32) SS2; - - WjPrime = Elem[Vm,i,32]; - SS2 = Vn[127:96] EOR ROL(Vd[127:96],12); - TT1 = (Vd[127:96] AND Vd[63:32]) OR (Vd[127:96] AND Vd[95:64]) OR (Vd[63:32] AND Vd[95:64]); - TT1 = (TT1 + Vd[31:0] + SS2 + WjPrime)[31:0]; - result[31:0] = Vd[63:32]; - result[63:32] = ROL(Vd[95:64],9); - result[95:64] = Vd[127:96]; - result[127:96] = TT1; - V[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_unpriv - __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - - unpriv_at_el1 = PSTATE.EL == EL1 && !(EL2Enabled() && HaveNVExt() && HCR_EL2.[NV,NV1] == '11'); - unpriv_at_el2 = PSTATE.EL == EL2 && HaveVirtHostExt() && HCR_EL2.[E2H,TGE] == '11'; - - user_access_override = HaveUAOExt() && PSTATE.UAO == '1'; - if !user_access_override && (unpriv_at_el1 || unpriv_at_el2) then - acctype = AccType_UNPRIV; - else - acctype = AccType_NORMAL; - - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_float_arithmetic_round_frint_32_64 - __encoding aarch64_float_arithmetic_round_frint_32_64 - __instruction_set A64 - __field ftype 22 +: 2 - __field op 15 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx10100x x10000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFrintExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '1x' UNDEFINED; - - integer intsize = if op[1] == '0' then 32 else 64; - - FPRounding rounding = if op[0] == '0' then FPRounding_ZERO else FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundIntN(operand, FPCR, rounding, intsize); - - V[d] = result; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_vector_arithmetic_binary_disparate_diff - __encoding aarch64_vector_arithmetic_binary_disparate_diff - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 01x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean accumulate = (op == '0'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) absdiff; - - result = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - absdiff = Abs(element1 - element2)[2*esize-1:0]; - Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + absdiff; - V[d] = result; - -__instruction LD2H_Z_P_BI_Contiguous - __encoding LD2H_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1010xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_shift_right_narrow_uniform_sisd - __encoding aarch64_vector_shift_right_narrow_uniform_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 1001x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then UNDEFINED; - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_shift_right_narrow_uniform_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 1001x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize*2) operand = V[n]; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = (Int(Elem[operand, e, 2*esize], unsigned) + round_const) >> shift; - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - - Vpart[d, part] = result; - -__instruction aarch64_integer_flags_setf - __encoding aarch64_integer_flags_setf - __instruction_set A64 - __field sf 31 +: 1 - __field sz 14 +: 1 - __field Rn 5 +: 5 - __opcode 'x0111010 00000000 0x0010xx xxx01101' - __guard TRUE - __decode - if !HaveFlagManipulateExt() || sf != '0' then UNDEFINED; - integer msb = if sz=='1' then 15 else 7; - integer n = UInt(Rn); - - __execute - bits(32) tmpreg = X[n]; - PSTATE.N = tmpreg[msb]; - PSTATE.Z = if (tmpreg[msb:0] == Zeros(msb+1)) then '1' else '0'; - PSTATE.V = tmpreg[msb+1] EOR tmpreg[msb]; - //PSTATE.C unchanged; - -__instruction LD1SB_Z_P_AI_S - __encoding LD1SB_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 001xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __encoding LD1SB_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 001xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = FALSE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_integer_pac_autdb_dp_1src - __encoding aarch64_integer_pac_autdb_dp_1src - __instruction_set A64 - __field Z 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11011010 11000001 00x111xx xxxxxxxx' - __guard TRUE - __decode - boolean source_is_sp = FALSE; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if !HavePACExt() then - UNDEFINED; - - if Z == '0' then // AUTDB - if n == 31 then source_is_sp = TRUE; - else // AUTDZB - if n != 31 then UNDEFINED; - - __execute - auth_then_branch = FALSE; - - if HavePACExt() then - if source_is_sp then - X[d] = AuthDB(X[d], SP[], auth_then_branch); - else - X[d] = AuthDB(X[d], X[n], auth_then_branch); - -__instruction aarch64_vector_shift_right_narrow_nonuniform_sisd - __encoding aarch64_vector_shift_right_narrow_nonuniform_sisd - __instruction_set A64 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111111 0xxxxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then UNDEFINED; - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - - __encoding aarch64_vector_shift_right_narrow_nonuniform_simd - __instruction_set A64 - __field Q 30 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 0xxxxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize*2) operand = V[n]; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - boolean sat; - - for e = 0 to elements-1 - element = (SInt(Elem[operand, e, 2*esize]) + round_const) >> shift; - (Elem[result, e, esize], sat) = UnsignedSatQ(element, esize); - if sat then FPSR.QC = '1'; - - Vpart[d, part] = result; - -__instruction UCVTF_Z_P_Z_H2FP16 - __encoding UCVTF_Z_P_Z_H2FP16 - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01010011 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 16; - boolean unsigned = TRUE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding UCVTF_Z_P_Z_W2FP16 - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01010101 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 16; - boolean unsigned = TRUE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding UCVTF_Z_P_Z_W2S - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 10010101 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 32; - boolean unsigned = TRUE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding UCVTF_Z_P_Z_W2D - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11010001 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 64; - boolean unsigned = TRUE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding UCVTF_Z_P_Z_X2FP16 - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01010111 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 16; - boolean unsigned = TRUE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding UCVTF_Z_P_Z_X2S - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11010101 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 32; - boolean unsigned = TRUE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding UCVTF_Z_P_Z_X2D - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11010111 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 64; - boolean unsigned = TRUE; - FPRounding rounding = FPRoundingMode(FPCR); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - bits(d_esize) fpval = FixedToFP(element[s_esize-1:0], 0, unsigned, FPCR, rounding); - Elem[result, e, esize] = ZeroExtend(fpval); - - Z[d] = result; - -__instruction ASR_Z_P_ZZ__ - __encoding ASR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010000 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - integer shift = Min(UInt(element2), esize); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = ASR(element1, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_acc_bf16_long - __encoding aarch64_vector_arithmetic_binary_uniform_mul_acc_bf16_long - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 110xxxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveBF16Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer elements = 128 DIV 32; - integer sel = UInt(Q); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(128) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(128) operand3 = V[d]; - bits(128) result; - - for e = 0 to elements-1 - bits(32) element1 = Elem[operand1, 2 * e + sel, 16] : Zeros(16); - bits(32) element2 = Elem[operand2, 2 * e + sel, 16] : Zeros(16); - bits(32) addend = Elem[operand3, e, 32]; - Elem[result, e, 32] = FPMulAdd(addend, element1, element2, FPCR); - - V[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_unpriv - __encoding aarch64_memory_single_general_immediate_signed_offset_unpriv - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - - unpriv_at_el1 = PSTATE.EL == EL1 && !(EL2Enabled() && HaveNVExt() && HCR_EL2.[NV,NV1] == '11'); - unpriv_at_el2 = PSTATE.EL == EL2 && HaveVirtHostExt() && HCR_EL2.[E2H,TGE] == '11'; - - user_access_override = HaveUAOExt() && PSTATE.UAO == '1'; - if !user_access_override && (unpriv_at_el1 || unpriv_at_el2) then - acctype = AccType_UNPRIV; - else - acctype = AccType_NORMAL; - - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction LSL_Z_P_ZI__ - __encoding LSL_Z_P_ZI__ - __instruction_set A64 - __field tszh 22 +: 2 - __field Pg 10 +: 3 - __field tszl 8 +: 2 - __field imm3 5 +: 3 - __field Zdn 0 +: 5 - __opcode '00000100 xx000011 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - bits(4) tsize = tszh:tszl; - case tsize of - when '0000' UNDEFINED; - when '0001' esize = 8; - when '001x' esize = 16; - when '01xx' esize = 32; - when '1xxx' esize = 64; - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer shift = UInt(tsize:imm3) - esize; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(PL) mask = P[g]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = LSL(element1, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_float_arithmetic_mul_add_sub - __encoding aarch64_float_arithmetic_mul_add_sub - __instruction_set A64 - __field ftype 22 +: 2 - __field o1 21 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011111 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer a = UInt(Ra); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean opa_neg = (o1 == '1'); - boolean op1_neg = (o0 != o1); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operanda = V[a]; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - if opa_neg then operanda = FPNeg(operanda); - if op1_neg then operand1 = FPNeg(operand1); - result = FPMulAdd(operanda, operand1, operand2, FPCR); - - V[d] = result; - -__instruction ORR_P_P_PP_Z - __encoding ORR_P_P_PP_Z - __instruction_set A64 - __field S 22 +: 1 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 1000xxxx 01xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding ORRS_P_P_PP_Z - __instruction_set A64 - __field S 22 +: 1 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 1100xxxx 01xxxx0x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - for e = 0 to elements-1 - bit element1 = ElemP[operand1, e, esize]; - bit element2 = ElemP[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - ElemP[result, e, esize] = element1 OR element2; - else - ElemP[result, e, esize] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_pair - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_pair - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 1010x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - integer element1; - integer element2; - integer maxmin; - - for e = 0 to elements-1 - element1 = Int(Elem[concat, 2*e, esize], unsigned); - element2 = Int(Elem[concat, (2*e)+1, esize], unsigned); - maxmin = if minimum then Min(element1, element2) else Max(element1, element2); - Elem[result, e, esize] = maxmin[esize-1:0]; - - V[d] = result; - -__instruction aarch64_vector_crypto_sm3_sm3tt2a - __encoding aarch64_vector_crypto_sm3_sm3tt2a - __instruction_set A64 - __field Rm 16 +: 5 - __field imm2 12 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 010xxxxx 10xx10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSM3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer i = UInt(imm2); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) Vd = V[d]; - bits(32) Wj; - bits(128) result; - bits(32) TT2; - - Wj = Elem[Vm,i,32]; - TT2 = Vd[63:32] EOR (Vd[127:96] EOR Vd[95:64]); - TT2 = (TT2 + Vd[31:0] + Vn[127:96] + Wj)[31:0]; - - result[31:0] = Vd[63:32]; - result[63:32] = ROL(Vd[95:64],19); - result[95:64] = Vd[127:96]; - result[127:96] = TT2 EOR ROL(TT2,9) EOR ROL(TT2,17); - V[d] = result; - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction CLASTA_R_P_Z__ - __encoding CLASTA_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000101 xx110000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Rdn); - integer m = UInt(Zm); - integer csize = if esize < 64 then 32 else 64; - boolean isBefore = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(esize) operand1 = X[dn]; - bits(VL) operand2 = Z[m]; - bits(csize) result; - integer last = LastActiveElement(mask, esize); - - if last < 0 then - result = ZeroExtend(operand1); - else - if !isBefore then - last = last + 1; - if last >= elements then last = 0; - result = ZeroExtend(Elem[operand2, last, esize]); - - X[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_element_dotp - __encoding aarch64_vector_arithmetic_binary_element_dotp - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 xxxxxxxx 1110x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveDOTPExt() then UNDEFINED; - if size != '10' then UNDEFINED; - boolean signed = (U=='0'); - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(M:Rm); - integer index = UInt(H:L); - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(datasize) result = V[d]; - for e = 0 to elements-1 - integer res = 0; - integer element1, element2; - for i = 0 to 3 - if signed then - element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = SInt(Elem[operand2, 4 * index + i, esize DIV 4]); - else - element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = UInt(Elem[operand2, 4 * index + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = Elem[result, e, esize] + res; - V[d] = result; - -__instruction aarch64_integer_tags_mcsettagpairandzerodatapost - __encoding aarch64_integer_tags_mcsettagpairandzerodatapost - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 111xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = TRUE; - boolean zero_data = TRUE; - - __encoding aarch64_integer_tags_mcsettagpairandzerodatapre - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 111xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = FALSE; - boolean zero_data = TRUE; - - __encoding aarch64_integer_tags_mcsettagpairandzerodata - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 111xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = FALSE; - boolean postindex = FALSE; - boolean zero_data = TRUE; - - __execute - bits(64) address; - bits(64) data = if t == 31 then SP[] else X[t]; - bits(4) tag = AArch64.AllocationTagFromAddress(data); - - SetTagCheckedInstruction(FALSE); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if !postindex then - address = address + offset; - - if zero_data then - Mem[address, TAG_GRANULE, AccType_NORMAL] = Zeros(8*TAG_GRANULE); - Mem[address+TAG_GRANULE, TAG_GRANULE, AccType_NORMAL] = Zeros(8*TAG_GRANULE); - - AArch64.MemTag[address, AccType_NORMAL] = tag; - AArch64.MemTag[address+TAG_GRANULE, AccType_NORMAL] = tag; - - if writeback then - if postindex then - address = address + offset; - - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction ASRR_Z_P_ZZ__ - __encoding ASRR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010100 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - integer shift = Min(UInt(element1), esize); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = ASR(element2, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_round - __encoding aarch64_vector_arithmetic_unary_fp16_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 100x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __encoding aarch64_vector_arithmetic_unary_float_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact); - - V[d] = result; - -__instruction aarch64_memory_single_simdfp_immediate_signed_offset_normal - __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111100 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_VEC; - MemOp memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - bits(64) address; - bits(datasize) data; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data = V[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - V[t] = data; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor - __encoding aarch64_vector_arithmetic_binary_uniform_logical_bsl_eor - __instruction_set A64 - __field Q 30 +: 1 - __field opc2 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx1xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - VBitOp op; - - case opc2 of - when '00' op = VBitOp_VEOR; - when '01' op = VBitOp_VBSL; - when '10' op = VBitOp_VBIT; - when '11' op = VBitOp_VBIF; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1; - bits(datasize) operand2; - bits(datasize) operand3; - bits(datasize) operand4 = V[n]; - - case op of - when VBitOp_VEOR - operand1 = V[m]; - operand2 = Zeros(); - operand3 = Ones(); - when VBitOp_VBSL - operand1 = V[m]; - operand2 = operand1; - operand3 = V[d]; - when VBitOp_VBIT - operand1 = V[d]; - operand2 = operand1; - operand3 = V[m]; - when VBitOp_VBIF - operand1 = V[d]; - operand2 = operand1; - operand3 = NOT(V[m]); - - V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3); - -__instruction aarch64_vector_crypto_aes_mix - __encoding aarch64_vector_crypto_aes_mix - __instruction_set A64 - __field D 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01001110 00101000 011x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - if !HaveAESExt() then UNDEFINED; - boolean decrypt = (D == '1'); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) operand = V[n]; - bits(128) result; - if decrypt then - result = AESInvMixColumns(operand); - else - result = AESMixColumns(operand); - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_rev - __encoding aarch64_vector_arithmetic_unary_rev - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 000x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - // size=esize: B(0), H(1), S(1), D(S) - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - - // op=REVx: 64(0), 32(1), 16(2) - bits(2) op = o0:U; - - // => op+size: - // 64+B = 0, 64+H = 1, 64+S = 2, 64+D = X - // 32+B = 1, 32+H = 2, 32+S = X, 32+D = X - // 16+B = 2, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - // => 3-(op+size) (index bits in group) - // 64/B = 3, 64+H = 2, 64+S = 1, 64+D = X - // 32+B = 2, 32+H = 1, 32+S = X, 32+D = X - // 16+B = 1, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - - // index bits within group: 1, 2, 3 - if UInt(op)+UInt(size) >= 3 then UNDEFINED; - - integer container_size; - case op of - when '10' container_size = 16; - when '01' container_size = 32; - when '00' container_size = 64; - - integer containers = datasize DIV container_size; - integer elements_per_container = container_size DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element = 0; - integer rev_element; - for c = 0 to containers-1 - rev_element = element + elements_per_container - 1; - for e = 0 to elements_per_container-1 - Elem[result, rev_element, esize] = Elem[operand, element, esize]; - element = element + 1; - rev_element = rev_element - 1; - - V[d] = result; - -__instruction aarch64_system_barriers_dsb - __encoding aarch64_system_barriers_dsb - __instruction_set A64 - __field CRm 8 +: 4 - __field opc 5 +: 2 - __opcode '11010101 00000011 0011xxxx 1xx11111' - __guard TRUE - __decode - case CRm[3:2] of - when '00' domain = MBReqDomain_OuterShareable; - when '01' domain = MBReqDomain_Nonshareable; - when '10' domain = MBReqDomain_InnerShareable; - when '11' domain = MBReqDomain_FullSystem; - case CRm[1:0] of - when '00' types = MBReqTypes_All; domain = MBReqDomain_FullSystem; - when '01' types = MBReqTypes_Reads; - when '10' types = MBReqTypes_Writes; - when '11' types = MBReqTypes_All; - - __execute - DataSynchronizationBarrier(domain, types); - -__instruction aarch64_integer_logical_immediate - __encoding aarch64_integer_logical_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field N 22 +: 1 - __field immr 16 +: 6 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10010 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - bits(datasize) imm; - if sf == '0' && N != '0' then UNDEFINED; - (imm, -) = DecodeBitMasks(N, imms, immr, TRUE); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = imm; - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_vector_transfer_vector_permute_unzip - __encoding aarch64_vector_transfer_vector_permute_unzip - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx0xxxxx 0x0110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer part = UInt(op); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operandl = V[n]; - bits(datasize) operandh = V[m]; - bits(datasize) result; - - bits(datasize*2) zipped = operandh:operandl; - for e = 0 to elements-1 - Elem[result, e, esize] = Elem[zipped, 2*e+part, esize]; - - V[d] = result; - -__instruction aarch64_integer_arithmetic_rev - __encoding aarch64_integer_arithmetic_rev - __instruction_set A64 - __field sf 31 +: 1 - __field opc 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x1011010 11000000 0000xxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize = if sf == '1' then 64 else 32; - - integer container_size; - case opc of - when '00' - Unreachable(); - when '01' - container_size = 16; - when '10' - container_size = 32; - when '11' - if sf == '0' then UNDEFINED; - container_size = 64; - - __execute - bits(datasize) operand = X[n]; - bits(datasize) result; - - integer containers = datasize DIV container_size; - integer elements_per_container = container_size DIV 8; - integer index = 0; - integer rev_index; - for c = 0 to containers-1 - rev_index = index + ((elements_per_container - 1) * 8); - for e = 0 to elements_per_container-1 - result[rev_index + 7:rev_index] = operand[index + 7:index]; - index = index + 8; - rev_index = rev_index - 8; - - X[d] = result; - -__instruction ST1H_Z_P_BR__ - __encoding ST1H_Z_P_BR__ - __instruction_set A64 - __field size 21 +: 2 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 1xxxxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8 << UInt(size); - integer msize = 16; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - bits(VL) src = Z[t]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - offset = offset + 1; - -__instruction FCVTZU_Z_P_Z_FP162H - __encoding FCVTZU_Z_P_Z_FP162H - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01011011 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 16; - boolean unsigned = TRUE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZU_Z_P_Z_FP162W - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01011101 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 32; - boolean unsigned = TRUE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZU_Z_P_Z_FP162X - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01011111 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 64; - boolean unsigned = TRUE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZU_Z_P_Z_S2W - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 10011101 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 32; - boolean unsigned = TRUE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZU_Z_P_Z_S2X - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11011101 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 64; - boolean unsigned = TRUE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZU_Z_P_Z_D2W - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11011001 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 32; - boolean unsigned = TRUE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZU_Z_P_Z_D2X - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11011111 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 64; - boolean unsigned = TRUE; - FPRounding rounding = FPRounding_ZERO; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - bits(d_esize) res = FPToFixed(element[s_esize-1:0], 0, unsigned, FPCR, rounding); - Elem[result, e, esize] = Extend(res, unsigned); - - Z[d] = result; - -__instruction SQDECW_Z_ZS__ - __encoding SQDECW_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1010xxxx 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction RDFFR_P_P_F__ - __encoding RDFFR_P_P_F__ - __instruction_set A64 - __field Pg 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 00011000 1111000x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer g = UInt(Pg); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding RDFFRS_P_P_F__ - __instruction_set A64 - __field Pg 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 01011000 1111000x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer g = UInt(Pg); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - bits(PL) mask = P[g]; - bits(PL) ffr = FFR[]; - bits(PL) result = ffr AND mask; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, 8); - P[d] = result; - -__instruction UQINCP_Z_P_Z__ - __encoding UQINCP_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Zdn 0 +: 5 - __opcode '00100101 xx101001 1000000x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Zdn); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(PL) operand2 = P[m]; - bits(VL) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - for e = 0 to elements-1 - integer element = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element + count, esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction NEG_Z_P_Z__ - __encoding NEG_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx010111 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - integer element = SInt(Elem[operand, e, esize]); - if ElemP[mask, e, esize] == '1' then - element = -element; - Elem[result, e, esize] = element[esize-1:0]; - - Z[d] = result; - -__instruction LSL_Z_P_ZW__ - __encoding LSL_Z_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx011011 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(64) element2 = Elem[operand2, (e * esize) DIV 64, 64]; - integer shift = Min(UInt(element2), esize); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = LSL(element1, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_narrow - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_narrow - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 01x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean round = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand1 = V[n]; - bits(2*datasize) operand2 = V[m]; - bits(datasize) result; - integer round_const = if round then 1 << (esize - 1) else 0; - bits(2*esize) element1; - bits(2*esize) element2; - bits(2*esize) sum; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, 2*esize]; - element2 = Elem[operand2, e, 2*esize]; - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - sum = sum + round_const; - Elem[result, e, esize] = sum[2*esize-1:esize]; - - Vpart[d, part] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction LDR_P_BI__ - __encoding LDR_P_BI__ - __instruction_set A64 - __field imm9h 16 +: 6 - __field imm9l 10 +: 3 - __field Rn 5 +: 5 - __field Pt 0 +: 4 - __opcode '10000101 10xxxxxx 000xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Pt); - integer n = UInt(Rn); - integer imm = SInt(imm9h:imm9l); - - __execute - CheckSVEEnabled(); - integer elements = PL DIV 8; - bits(64) base; - integer offset = imm * elements; - bits(PL) result; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - boolean aligned = AArch64.CheckAlignment(base + offset, 2, AccType_NORMAL, FALSE); - for e = 0 to elements-1 - Elem[result, e, 8] = AArch64.MemSingle[base + offset, 1, AccType_NORMAL, aligned]; - offset = offset + 1; - - P[t] = result; - -__instruction UMIN_Z_P_ZZ__ - __encoding UMIN_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx001011 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer minimum = Min(element1, element2); - Elem[result, e, esize] = minimum[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction NAND_P_P_PP_Z - __encoding NAND_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 1000xxxx 01xxxx1x xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding NANDS_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 1100xxxx 01xxxx1x xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - for e = 0 to elements-1 - bit element1 = ElemP[operand1, e, esize]; - bit element2 = ElemP[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - ElemP[result, e, esize] = NOT(element1 AND element2); - else - ElemP[result, e, esize] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction aarch64_integer_pac_autia_dp_1src - __encoding aarch64_integer_pac_autia_dp_1src - __instruction_set A64 - __field Z 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11011010 11000001 00x100xx xxxxxxxx' - __guard TRUE - __decode - boolean source_is_sp = FALSE; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if !HavePACExt() then - UNDEFINED; - - if Z == '0' then // AUTIA - if n == 31 then source_is_sp = TRUE; - else // AUTIZA - if n != 31 then UNDEFINED; - - __encoding aarch64_integer_pac_autia_hint - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - integer d; - integer n; - boolean source_is_sp = FALSE; - - case CRm:op2 of - when '0011 100' // AUTIAZ - d = 30; - n = 31; - when '0011 101' // AUTIASP - d = 30; - source_is_sp = TRUE; - when '0001 100' // AUTIA1716 - d = 17; - n = 16; - when '0001 000' SEE "PACIA"; - when '0001 010' SEE "PACIB"; - when '0001 110' SEE "AUTIB"; - when '0011 00x' SEE "PACIA"; - when '0011 01x' SEE "PACIB"; - when '0011 11x' SEE "AUTIB"; - when '0000 111' SEE "XPACLRI"; - otherwise SEE "HINT"; - - __execute - auth_then_branch = FALSE; - - if HavePACExt() then - if source_is_sp then - X[d] = AuthIA(X[d], SP[], auth_then_branch); - else - X[d] = AuthIA(X[d], X[n], auth_then_branch); - -__instruction LDFF1SH_Z_P_BZ_S_x32_scaled - __encoding LDFF1SH_Z_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 1x1xxxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding LDFF1SH_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 1x1xxxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding LDFF1SH_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 1x0xxxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1SH_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 1x0xxxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1SH_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 111xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 1; - - __encoding LDFF1SH_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 110xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction LD1RQB_Z_P_BR_Contiguous - __encoding LD1RQB_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 000xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - - __execute - CheckSVEEnabled(); - integer elements = 128 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low 16 bits only - bits(64) offset; - bits(128) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = X[m]; - - addr = base + UInt(offset) * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = Replicate(result, VL DIV 128); - -__instruction PTRUE_P_S__ - __encoding PTRUE_P_S__ - __instruction_set A64 - __field size 22 +: 2 - __field pattern 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx011000 111000xx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer d = UInt(Pd); - boolean setflags = FALSE; - bits(5) pat = pattern; - - __encoding PTRUES_P_S__ - __instruction_set A64 - __field size 22 +: 2 - __field pattern 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx011001 111000xx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer d = UInt(Pd); - boolean setflags = TRUE; - bits(5) pat = pattern; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(PL) result; - - for e = 0 to elements-1 - ElemP[result, e, esize] = if e < count then '1' else '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(result, result, esize); - P[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction ST4H_Z_P_BR_Contiguous - __encoding ST4H_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 111xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction ST1B_Z_P_BZ_D_x32_unscaled - __encoding ST1B_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 000xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding ST1B_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field xs 14 +: 1 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 010xxxxx 1x0xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - integer offs_size = 32; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding ST1B_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 000xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 64; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(VL) offset = Z[m]; - bits(VL) src = Z[t]; - bits(PL) mask = P[g]; - bits(64) addr; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - -__instruction aarch64_vector_reduce_add_long - __encoding aarch64_vector_reduce_add_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx110000 001110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '100' then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - integer sum; - - sum = Int(Elem[operand, 0, esize], unsigned); - for e = 1 to elements-1 - sum = sum + Int(Elem[operand, e, esize], unsigned); - - V[d] = sum[2*esize-1:0]; - -__instruction aarch64_vector_arithmetic_unary_float_xtn_sisd - __encoding aarch64_vector_arithmetic_unary_float_xtn_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 0x100001 011010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz == '0' then UNDEFINED; - integer esize = 32; - integer datasize = esize; - integer elements = 1; - integer part = 0; - - __encoding aarch64_vector_arithmetic_unary_float_xtn_simd - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 0x100001 011010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz == '0' then UNDEFINED; - integer esize = 32; - integer datasize = 64; - integer elements = 2; - integer part = UInt(Q); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand = V[n]; - bits(datasize) result; - - for e = 0 to elements-1 - Elem[result, e, esize] = FPConvert(Elem[operand, e, 2*esize], FPCR, FPRounding_ODD); - - Vpart[d, part] = result; - -__instruction UQINCW_Z_ZS__ - __encoding UQINCW_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1010xxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction aarch64_integer_logical_immediate - __encoding aarch64_integer_logical_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field N 22 +: 1 - __field immr 16 +: 6 - __field imms 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10010 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - bits(datasize) imm; - if sf == '0' && N != '0' then UNDEFINED; - (imm, -) = DecodeBitMasks(N, imms, immr, TRUE); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = imm; - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_post_idx - __encoding aarch64_memory_single_general_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_lower - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_lower - __instruction_set A64 - __field Q 30 +: 1 - __field S 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 111011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz == '1' then UNDEFINED; - integer esize = 32; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (S == '1'); - integer part = 0; - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_mul_norounding_upper - __instruction_set A64 - __field Q 30 +: 1 - __field S 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx1xxxxx 110011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz == '1' then UNDEFINED; - integer esize = 32; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean sub_op = (S == '1'); - integer part = 1; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize DIV 2) operand1 = Vpart[n,part]; - bits(datasize DIV 2) operand2 = Vpart[m,part]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize DIV 2) element1; - bits(esize DIV 2) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize DIV 2]; - element2 = Elem[operand2, e, esize DIV 2]; - if sub_op then element1 = FPNeg(element1); - Elem[result,e,esize] = FPMulAddH(Elem[operand3, e, esize], element1, element2, FPCR); - V[d] = result; - -__instruction SMINV_R_P_Z__ - __encoding SMINV_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '00000100 xx001010 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - integer minimum = if unsigned then (2^esize - 1) else (2^(esize-1) - 1); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer element = Int(Elem[operand, e, esize], unsigned); - minimum = Min(minimum, element); - - V[d] = minimum[esize-1:0]; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_integer_pac_autib_dp_1src - __encoding aarch64_integer_pac_autib_dp_1src - __instruction_set A64 - __field Z 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11011010 11000001 00x101xx xxxxxxxx' - __guard TRUE - __decode - boolean source_is_sp = FALSE; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if !HavePACExt() then - UNDEFINED; - - if Z == '0' then // AUTIB - if n == 31 then source_is_sp = TRUE; - else // AUTIZB - if n != 31 then UNDEFINED; - - __encoding aarch64_integer_pac_autib_hint - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - integer d; - integer n; - boolean source_is_sp = FALSE; - - case CRm:op2 of - when '0011 110' // AUTIBZ - d = 30; - n = 31; - when '0011 111' // AUTIBSP - d = 30; - source_is_sp = TRUE; - when '0001 110' // AUTIB1716 - d = 17; - n = 16; - when '0001 000' SEE "PACIA"; - when '0001 010' SEE "PACIB"; - when '0001 100' SEE "AUTIA"; - when '0011 00x' SEE "PACIA"; - when '0011 01x' SEE "PACIB"; - when '0011 10x' SEE "AUTIA"; - when '0000 111' SEE "XPACLRI"; - otherwise SEE "HINT"; - - __execute - auth_then_branch = FALSE; - - if HavePACExt() then - if source_is_sp then - X[d] = AuthIB(X[d], SP[], auth_then_branch); - else - X[d] = AuthIB(X[d], X[n], auth_then_branch); - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_lower - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_lower - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field S 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 1xxxxxxx 0x00x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt('0':Rm); // Vm can only be in bottom 16 registers. - if sz == '1' then UNDEFINED; - integer index = UInt(H:L:M); - - integer esize = 32; - integer datasize = if Q=='1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (S == '1'); - integer part = 0; - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_mul_norounding_i_upper - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field S 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 1xxxxxxx 1x00x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16MulNoRoundingToFP32Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt('0':Rm); // Vm can only be in bottom 16 registers. - if sz == '1' then UNDEFINED; - integer index = UInt(H:L:M); - - integer esize = 32; - integer datasize = if Q=='1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (S == '1'); - integer part = 1; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize DIV 2) operand1 = Vpart[n,part]; - bits(128) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize DIV 2) element1; - bits(esize DIV 2) element2 = Elem[operand2, index, esize DIV 2]; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize DIV 2]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAddH(Elem[operand3, e, esize], element1, element2, FPCR); - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_high_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_high_sisd - __instruction_set A64 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field op 12 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 xxxxxxxx 110xx0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - boolean round = (op == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_high_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field op 12 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 xxxxxxxx 110xx0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean round = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) result; - integer round_const = if round then 1 << (esize - 1) else 0; - integer element1; - integer element2; - integer product; - boolean sat; - - element2 = SInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - product = (2 * element1 * element2) + round_const; - // The following only saturates if element1 and element2 equal -(2^(esize-1)) - (Elem[result, e, esize], sat) = SignedSatQ(product >> esize, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_shift - __encoding aarch64_vector_arithmetic_unary_shift - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx100001 001110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = esize; - boolean unsigned = FALSE; // Or TRUE without change of functionality - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = Vpart[n, part]; - bits(2*datasize) result; - integer element; - - for e = 0 to elements-1 - element = Int(Elem[operand, e, esize], unsigned) << shift; - Elem[result, e, 2*esize] = element[2*esize-1:0]; - - V[d] = result; - -__instruction LASTB_R_P_Z__ - __encoding LASTB_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00000101 xx100001 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer rsize = if esize < 64 then 32 else 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Rd); - boolean isBefore = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(rsize) result; - integer last = LastActiveElement(mask, esize); - - if isBefore then - if last < 0 then last = elements - 1; - else - last = last + 1; - if last >= elements then last = 0; - result = ZeroExtend(Elem[operand, last, esize]); - - X[d] = result; - -__instruction aarch64_integer_arithmetic_add_sub_shiftedreg - __encoding aarch64_integer_arithmetic_add_sub_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field shift 22 +: 2 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01011 xx0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - - if shift == '11' then UNDEFINED; - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - X[d] = result; - -__instruction aarch64_integer_tags_mcsettagandzerodatapost - __encoding aarch64_integer_tags_mcsettagandzerodatapost - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 011xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = TRUE; - boolean zero_data = TRUE; - - __encoding aarch64_integer_tags_mcsettagandzerodatapre - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 011xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = FALSE; - boolean zero_data = TRUE; - - __encoding aarch64_integer_tags_mcsettagandzerodata - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 011xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = FALSE; - boolean postindex = FALSE; - boolean zero_data = TRUE; - - __execute - bits(64) address; - - SetTagCheckedInstruction(FALSE); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if !postindex then - address = address + offset; - - if zero_data then - Mem[address, TAG_GRANULE, AccType_NORMAL] = Zeros(TAG_GRANULE * 8); - - bits(64) data = if t == 31 then SP[] else X[t]; - bits(4) tag = AArch64.AllocationTagFromAddress(data); - AArch64.MemTag[address, AccType_NORMAL] = tag; - - if writeback then - if postindex then - address = address + offset; - - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 101101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' || size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean rounding = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 101101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' || size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean rounding = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer round_const = if rounding then 1 << (esize - 1) else 0; - integer element1; - integer element2; - integer product; - boolean sat; - - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - element2 = SInt(Elem[operand2, e, esize]); - product = (2 * element1 * element2) + round_const; - (Elem[result, e, esize], sat) = SignedSatQ(product >> esize, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction LDFF1SH_Z_P_BR_S32 - __encoding LDFF1SH_Z_P_BR_S32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 001xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - boolean unsigned = FALSE; - - __encoding LDFF1SH_Z_P_BR_S64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 000xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = base + UInt(offset) * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_CNOTFIRST]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - offset = offset + 1; - - Z[t] = result; - -__instruction FSUBR_Z_P_ZS__ - __encoding FSUBR_Z_P_ZS__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field i1 5 +: 1 - __field Zdn 0 +: 5 - __opcode '01100101 xx011011 100xxx00 00xxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - bits(esize) imm = if i1 == '0' then FPPointFive('0') else FPOne('0'); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPSub(imm, element1, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction LDNT1H_Z_P_BI_Contiguous - __encoding LDNT1H_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1000xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_STREAM]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction UQINCP_R_P_R_UW - __encoding UQINCP_R_P_R_UW - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101001 1000100x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQINCP_R_P_R_X - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101001 1000110x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(ssize) operand1 = X[dn]; - bits(PL) operand2 = P[m]; - bits(ssize) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - integer element = Int(operand1, unsigned); - (result, -) = SatQ(element + count, ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_vector_arithmetic_binary_element_mul_acc_double_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_double_sisd - __instruction_set A64 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 xxxxxxxx 0x11x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - integer part = 0; - - boolean sub_op = (o2 == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_acc_double_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field o2 14 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 xxxxxxxx 0x11x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o2 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(idxdsize) operand2 = V[m]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - integer accum; - boolean sat1; - boolean sat2; - - element2 = SInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - (product, sat1) = SignedSatQ(2 * element1 * element2, 2*esize); - if sub_op then - accum = SInt(Elem[operand3, e, 2*esize]) - SInt(product); - else - accum = SInt(Elem[operand3, e, 2*esize]) + SInt(product); - (Elem[result, e, 2*esize], sat2) = SignedSatQ(accum, 2*esize); - if sat1 || sat2 then FPSR.QC = '1'; - - V[d] = result; - -__instruction DUP_Z_R__ - __encoding DUP_Z_R__ - __instruction_set A64 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx100000 001110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Rn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) operand; - if n == 31 then - operand = SP[]; - else - operand = X[n]; - bits(VL) result; - - for e = 0 to elements-1 - Elem[result, e, esize] = operand[esize-1:0]; - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_unary_add_saturating_sisd - __encoding aarch64_vector_arithmetic_unary_add_saturating_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 001110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_add_saturating_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 001110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - - bits(datasize) operand2 = V[d]; - integer op1; - integer op2; - boolean sat; - - for e = 0 to elements-1 - op1 = Int(Elem[operand, e, esize], !unsigned); - op2 = Int(Elem[operand2, e, esize], unsigned); - (Elem[result, e, esize], sat) = SatQ(op1 + op2, esize, unsigned); - if sat then FPSR.QC = '1'; - V[d] = result; - -__instruction aarch64_memory_atomicops_swp - __encoding aarch64_memory_atomicops_swp - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 100000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - bits(datasize) store_value; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - store_value = X[s]; - data = MemAtomic(address, MemAtomicOp_SWP, store_value, ldacctype, stacctype); - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_integer_conditional_select - __encoding aarch64_integer_conditional_select - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field o2 10 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xx011010 100xxxxx xxxx0xxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - bits(4) condition = cond; - boolean else_inv = (op == '1'); - boolean else_inc = (o2 == '1'); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - - if ConditionHolds(condition) then - result = operand1; - else - result = operand2; - if else_inv then result = NOT(result); - if else_inc then result = result + 1; - - X[d] = result; - -__instruction ST1B_Z_P_BI__ - __encoding ST1B_Z_P_BI__ - __instruction_set A64 - __field size 21 +: 2 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 0xx0xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8 << UInt(size); - integer msize = 8; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) src = Z[t]; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[src, e, esize][msize-1:0]; - addr = addr + mbytes; - -__instruction LDNF1W_Z_P_BI_U32 - __encoding LDNF1W_Z_P_BI_U32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0101xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __encoding LDNF1W_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0111xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_lda_stl - __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx011001 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_ORDERED; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_integer_flags_axflag - __encoding aarch64_integer_flags_axflag - __instruction_set A64 - __field CRm 8 +: 4 - __opcode '11010101 00000000 0100xxxx 01011111' - __guard TRUE - __decode - if !HaveFlagFormatExt() then UNDEFINED; - - __execute - bit N = '0'; - bit Z = PSTATE.Z OR PSTATE.V; - bit C = PSTATE.C AND NOT(PSTATE.V); - bit V = '0'; - - PSTATE.N = N; - PSTATE.Z = Z; - PSTATE.C = C; - PSTATE.V = V; - -__instruction FNEG_Z_P_Z__ - __encoding FNEG_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx011101 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPNeg(element); - - Z[d] = result; - -__instruction FCMEQ_P_P_ZZ__ - __encoding FCMEQ_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx0xxxxx 011xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_EQ; - - __encoding FCMGT_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx0xxxxx 010xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GT; - - __encoding FCMGE_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx0xxxxx 010xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_GE; - - __encoding FCMNE_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx0xxxxx 011xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_NE; - - __encoding FCMUO_P_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx0xxxxx 110xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Pd); - SVECmp op = Cmp_UN; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(PL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - case op of - when Cmp_EQ res = FPCompareEQ(element1, element2, FPCR); - when Cmp_GE res = FPCompareGE(element1, element2, FPCR); - when Cmp_GT res = FPCompareGT(element1, element2, FPCR); - when Cmp_UN res = FPCompareUN(element1, element2, FPCR); - when Cmp_NE res = FPCompareNE(element1, element2, FPCR); - when Cmp_LT res = FPCompareGT(element2, element1, FPCR); - when Cmp_LE res = FPCompareGE(element2, element1, FPCR); - ElemP[result, e, esize] = if res then '1' else '0'; - else - ElemP[result, e, esize] = '0'; - - P[d] = result; - -__instruction CLASTB_R_P_Z__ - __encoding CLASTB_R_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000101 xx110001 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Rdn); - integer m = UInt(Zm); - integer csize = if esize < 64 then 32 else 64; - boolean isBefore = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(esize) operand1 = X[dn]; - bits(VL) operand2 = Z[m]; - bits(csize) result; - integer last = LastActiveElement(mask, esize); - - if last < 0 then - result = ZeroExtend(operand1); - else - if !isBefore then - last = last + 1; - if last >= elements then last = 0; - result = ZeroExtend(Elem[operand2, last, esize]); - - X[dn] = result; - -__instruction aarch64_integer_conditional_select - __encoding aarch64_integer_conditional_select - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field o2 10 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xx011010 100xxxxx xxxx0xxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - bits(4) condition = cond; - boolean else_inv = (op == '1'); - boolean else_inc = (o2 == '1'); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - - if ConditionHolds(condition) then - result = operand1; - else - result = operand2; - if else_inv then result = NOT(result); - if else_inc then result = result + 1; - - X[d] = result; - -__instruction SQDECP_Z_P_Z__ - __encoding SQDECP_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Zdn 0 +: 5 - __opcode '00100101 xx101010 1000000x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Zdn); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(PL) operand2 = P[m]; - bits(VL) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - for e = 0 to elements-1 - integer element = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element - count, esize, unsigned); - - Z[dn] = result; - -__instruction UQSUB_Z_ZZ__ - __encoding UQSUB_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - element2, esize, unsigned); - - Z[d] = result; - -__instruction STNT1W_Z_P_BR_Contiguous - __encoding STNT1W_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 000xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(64) offset = X[m]; - bits(VL) src; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - src = Z[t]; - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_STREAM] = Elem[src, e, esize]; - offset = offset + 1; - -__instruction aarch64_integer_arithmetic_cnt - __encoding aarch64_integer_arithmetic_cnt - __instruction_set A64 - __field sf 31 +: 1 - __field op 10 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x1011010 11000000 00010xxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - CountOp opcode = if op == '0' then CountOp_CLZ else CountOp_CLS; - - __execute - integer result; - bits(datasize) operand1 = X[n]; - - if opcode == CountOp_CLZ then - result = CountLeadingZeroBits(operand1); - else - result = CountLeadingSignBits(operand1); - - X[d] = result[datasize-1:0]; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_float_arithmetic_round_frint_32_64 - __encoding aarch64_float_arithmetic_round_frint_32_64 - __instruction_set A64 - __field ftype 22 +: 2 - __field op 15 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx10100x x10000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFrintExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '1x' UNDEFINED; - - integer intsize = if op[1] == '0' then 32 else 64; - - FPRounding rounding = if op[0] == '0' then FPRounding_ZERO else FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundIntN(operand, FPCR, rounding, intsize); - - V[d] = result; - -__instruction SQINCW_Z_ZS__ - __encoding SQINCW_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1010xxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 + (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_float_compare_uncond - __encoding aarch64_float_compare_uncond - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field opc 3 +: 2 - __opcode '00011110 xx1xxxxx 001000xx xxxxx000' - __guard TRUE - __decode - integer n = UInt(Rn); - integer m = UInt(Rm); // ignored when opc[0] == '1' - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean signal_all_nans = (opc[1] == '1'); - boolean cmp_with_zero = (opc[0] == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) operand1 = V[n]; - bits(datasize) operand2; - - operand2 = if cmp_with_zero then FPZero('0') else V[m]; - - PSTATE.[N,Z,C,V] = FPCompare(operand1, operand2, signal_all_nans, FPCR); - -__instruction FMAXNM_Z_P_ZZ__ - __encoding FMAXNM_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx000100 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if abs then - element1 = FPAbs(element1); - element2 = FPAbs(element2); - case cmp of - when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR); - when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_system_exceptions_debug_breakpoint - __encoding aarch64_system_exceptions_debug_breakpoint - __instruction_set A64 - __field imm16 5 +: 16 - __opcode '11010100 001xxxxx xxxxxxxx xxx00000' - __guard TRUE - __decode - bits(16) comment = imm16; - if HaveBTIExt() then - SetBTypeCompatible(TRUE); - - __execute - AArch64.SoftwareBreakpoint(comment); - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_sisd - __instruction_set A64 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 01111001 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPRounding_TIEAWAY; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_tieaway_sisd - __instruction_set A64 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 0x100001 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPRounding_TIEAWAY; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_tieaway_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 01111001 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPRounding_TIEAWAY; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_tieaway_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x100001 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPRounding_TIEAWAY; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction USDOT_Z_ZZZ_S - __encoding USDOT_Z_ZZZ_S - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01000100 100xxxxx 011110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveInt8MatMulExt() then UNDEFINED; - integer esize = 32; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) res = Elem[operand3, e, esize]; - for i = 0 to 3 - integer element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - integer element2 = SInt(Elem[operand2, 4 * e + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = res; - - Z[da] = result; - -__instruction aarch64_vector_shift_right_insert_sisd - __encoding aarch64_vector_shift_right_insert_sisd - __instruction_set A64 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111111 0xxxxxxx 010001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = (esize * 2) - UInt(immh:immb); - - __encoding aarch64_vector_shift_right_insert_simd - __instruction_set A64 - __field Q 30 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101111 0xxxxxxx 010001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = (esize * 2) - UInt(immh:immb); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2 = V[d]; - bits(datasize) result; - bits(esize) mask = LSR(Ones(esize), shift); - bits(esize) shifted; - - for e = 0 to elements-1 - shifted = LSR(Elem[operand, e, esize], shift); - Elem[result, e, esize] = (Elem[operand2, e, esize] AND NOT(mask)) OR shifted; - V[d] = result; - -__instruction aarch64_integer_conditional_select - __encoding aarch64_integer_conditional_select - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field o2 10 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xx011010 100xxxxx xxxx0xxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - bits(4) condition = cond; - boolean else_inv = (op == '1'); - boolean else_inc = (o2 == '1'); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - - if ConditionHolds(condition) then - result = operand1; - else - result = operand2; - if else_inv then result = NOT(result); - if else_inc then result = result + 1; - - X[d] = result; - -__instruction aarch64_system_barriers_pssbb - __encoding aarch64_system_barriers_pssbb - __instruction_set A64 - __field CRm 8 +: 4 - __field opc 5 +: 2 - __opcode '11010101 00000011 0011xxxx 1xx11111' - __guard TRUE - __decode - // No additional decoding required - - __execute - SpeculativeStoreBypassBarrierToPA(); - -__instruction aarch64_vector_arithmetic_unary_cmp_int_lessthan_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_int_lessthan_sisd - __instruction_set A64 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 xx100000 101010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison = CompareOp_LT; - - __encoding aarch64_vector_arithmetic_unary_cmp_int_lessthan_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx100000 101010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison = CompareOp_LT; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean test_passed; - - for e = 0 to elements-1 - element = SInt(Elem[operand, e, esize]); - case comparison of - when CompareOp_GT test_passed = element > 0; - when CompareOp_GE test_passed = element >= 0; - when CompareOp_EQ test_passed = element == 0; - when CompareOp_LE test_passed = element <= 0; - when CompareOp_LT test_passed = element < 0; - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction ST2D_Z_P_BI_Contiguous - __encoding ST2D_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 1011xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction LD3W_Z_P_BR_Contiguous - __encoding LD3W_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 010xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction BFMLALB_Z_ZZZi__ - __encoding BFMLALB_Z_ZZZi__ - __instruction_set A64 - __field i3h 19 +: 2 - __field Zm 16 +: 3 - __field i3l 11 +: 1 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 111xxxxx 0100x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - integer index = UInt(i3h:i3l); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 32; - integer eltspersegment = 128 DIV 32; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = 2 * segmentbase + index; - bits(32) element1 = Elem[operand1, 2 * e + 0, 16] : Zeros(16); - bits(32) element2 = Elem[operand2, s, 16] : Zeros(16); - bits(32) element3 = Elem[operand3, e, 32]; - Elem[result, e, 32] = FPMulAdd(element3, element1, element2, FPCR); - - Z[da] = result; - -__instruction ST4D_Z_P_BR_Contiguous - __encoding ST4D_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 111xxxxx 011xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - offset = offset + nreg; - -__instruction UDIV_Z_P_ZZ__ - __encoding UDIV_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010101 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '0x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer quotient; - if element2 == 0 then - quotient = 0; - else - quotient = RoundTowardsZero(Real(element1) / Real(element2)); - Elem[result, e, esize] = quotient[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction SMAX_Z_P_ZZ__ - __encoding SMAX_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx001000 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer maximum = Max(element1, element2); - Elem[result, e, esize] = maximum[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction MSB_Z_P_ZZZ__ - __encoding MSB_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Za 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx0xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - integer a = UInt(Za); - boolean sub_op = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[a]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = UInt(Elem[operand1, e, esize]); - integer element2 = UInt(Elem[operand2, e, esize]); - if ElemP[mask, e, esize] == '1' then - integer product = element1 * element2; - if sub_op then - Elem[result, e, esize] = Elem[operand3, e, esize] - product; - else - Elem[result, e, esize] = Elem[operand3, e, esize] + product; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_long - __encoding aarch64_vector_arithmetic_binary_element_mul_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 xxxxxxxx 1010x0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(idxdsize) operand2 = V[m]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - - element2 = Int(Elem[operand2, index, esize], unsigned); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - Elem[result, e, 2*esize] = product; - - V[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_lda_stl - __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx011001 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_ORDERED; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction ASR_Z_P_ZI__ - __encoding ASR_Z_P_ZI__ - __instruction_set A64 - __field tszh 22 +: 2 - __field Pg 10 +: 3 - __field tszl 8 +: 2 - __field imm3 5 +: 3 - __field Zdn 0 +: 5 - __opcode '00000100 xx000000 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - bits(4) tsize = tszh:tszl; - case tsize of - when '0000' UNDEFINED; - when '0001' esize = 8; - when '001x' esize = 16; - when '01xx' esize = 32; - when '1xxx' esize = 64; - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer shift = (2 * esize) - UInt(tsize:imm3); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(PL) mask = P[g]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = ASR(element1, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction LD1B_Z_P_BR_U8 - __encoding LD1B_Z_P_BR_U8 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 000xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - integer msize = 8; - boolean unsigned = TRUE; - - __encoding LD1B_Z_P_BR_U16 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 001xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - integer msize = 8; - boolean unsigned = TRUE; - - __encoding LD1B_Z_P_BR_U32 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 010xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - boolean unsigned = TRUE; - - __encoding LD1B_Z_P_BR_U64 - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 011xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - bits(64) offset = X[m]; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - offset = offset + 1; - - Z[t] = result; - -__instruction aarch64_vector_fp16_movi - __encoding aarch64_vector_fp16_movi - __instruction_set A64 - __field Q 30 +: 1 - __field a 18 +: 1 - __field b 17 +: 1 - __field c 16 +: 1 - __field d 9 +: 1 - __field e 8 +: 1 - __field f 7 +: 1 - __field g 6 +: 1 - __field h 5 +: 1 - __field Rd 0 +: 5 - __opcode '0x001111 00000xxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer rd = UInt(Rd); - - integer datasize = if Q == '1' then 128 else 64; - bits(datasize) imm; - - imm8 = a:b:c:d:e:f:g:h; - imm16 = imm8[7]:NOT(imm8[6]):Replicate(imm8[6],2):imm8[5:0]:Zeros(6); - - imm = Replicate(imm16, datasize DIV 16); - - __encoding aarch64_vector_logical - __instruction_set A64 - __field Q 30 +: 1 - __field op 29 +: 1 - __field a 18 +: 1 - __field b 17 +: 1 - __field c 16 +: 1 - __field cmode 12 +: 4 - __field d 9 +: 1 - __field e 8 +: 1 - __field f 7 +: 1 - __field g 6 +: 1 - __field h 5 +: 1 - __field Rd 0 +: 5 - __opcode '0xx01111 00000xxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer rd = UInt(Rd); - - integer datasize = if Q == '1' then 128 else 64; - bits(datasize) imm; - bits(64) imm64; - - ImmediateOp operation; - case cmode:op of - when '0xx00' operation = ImmediateOp_MOVI; - when '0xx01' operation = ImmediateOp_MVNI; - when '0xx10' operation = ImmediateOp_ORR; - when '0xx11' operation = ImmediateOp_BIC; - when '10x00' operation = ImmediateOp_MOVI; - when '10x01' operation = ImmediateOp_MVNI; - when '10x10' operation = ImmediateOp_ORR; - when '10x11' operation = ImmediateOp_BIC; - when '110x0' operation = ImmediateOp_MOVI; - when '110x1' operation = ImmediateOp_MVNI; - when '1110x' operation = ImmediateOp_MOVI; - when '11110' operation = ImmediateOp_MOVI; - when '11111' - // FMOV Dn,#imm is in main FP instruction set - if Q == '0' then UNDEFINED; - operation = ImmediateOp_MOVI; - - imm64 = AdvSIMDExpandImm(op, cmode, a:b:c:d:e:f:g:h); - imm = Replicate(imm64, datasize DIV 64); - - __execute - CheckFPAdvSIMDEnabled64(); - - V[rd] = imm; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_sisd - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 xx0xxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' || size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean rounding = TRUE; - boolean sub_op = (S == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_doubling_accum_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx0xxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveQRDMLAHExt() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' || size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean rounding = TRUE; - boolean sub_op = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - integer rounding_const = if rounding then 1 << (esize - 1) else 0; - integer element1; - integer element2; - integer element3; - integer product; - boolean sat; - - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - element2 = SInt(Elem[operand2, e, esize]); - element3 = SInt(Elem[operand3, e, esize]); - if sub_op then - accum = ((element3 << esize) - 2 * (element1 * element2) + rounding_const); - else - accum = ((element3 << esize) + 2 * (element1 * element2) + rounding_const); - (Elem[result, e, esize], sat) = SignedSatQ(accum >> esize, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_vector_crypto_sha3_bcax - __encoding aarch64_vector_crypto_sha3_bcax - __instruction_set A64 - __field Rm 16 +: 5 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 001xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSHA3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer a = UInt(Ra); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) Va = V[a]; - V[d] = Vn EOR (Vm AND NOT(Va)); - -__instruction aarch64_integer_arithmetic_add_sub_extendedreg - __encoding aarch64_integer_arithmetic_add_sub_extendedreg - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field imm3 10 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01011 001xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - ExtendType extend_type = DecodeRegExtend(option); - integer shift = UInt(imm3); - if shift > 4 then UNDEFINED; - - __execute - bits(datasize) result; - bits(datasize) operand1 = if n == 31 then SP[] else X[n]; - bits(datasize) operand2 = ExtendReg(m, extend_type, shift); - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_memory_pair_simdfp_post_idx - __encoding aarch64_memory_pair_simdfp_post_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101100 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - - __encoding aarch64_memory_pair_simdfp_pre_idx - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - - __encoding aarch64_memory_pair_simdfp_offset - __instruction_set A64 - __field opc 30 +: 2 - __field L 22 +: 1 - __field imm7 15 +: 7 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx101101 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); - AccType acctype = AccType_VEC; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - if opc == '11' then UNDEFINED; - integer scale = 2 + UInt(opc); - integer datasize = 8 << scale; - bits(64) offset = LSL(SignExtend(imm7, 64), scale); - boolean tag_checked = wback || n != 31; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(datasize) data1; - bits(datasize) data2; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data1 = V[t]; - data2 = V[t2]; - Mem[address + 0 , dbytes, acctype] = data1; - Mem[address + dbytes, dbytes, acctype] = data2; - - when MemOp_LOAD - data1 = Mem[address + 0 , dbytes, acctype]; - data2 = Mem[address + dbytes, dbytes, acctype]; - if rt_unknown then - data1 = bits(datasize) UNKNOWN; - data2 = bits(datasize) UNKNOWN; - V[t] = data1; - V[t2] = data2; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp16_2008 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field a 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (a == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_max_min_fp_2008 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - boolean minimum = (o1 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - - if minimum then - Elem[result, e, esize] = FPMinNum(element1, element2, FPCR); - else - Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_fp16_fused - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_fused - __instruction_set A64 - __field Q 30 +: 1 - __field a 23 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 x10xxxxx 000011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (a == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_fused - __instruction_set A64 - __field Q 30 +: 1 - __field op 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 110011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if sub_op then element1 = FPNeg(element1); - Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_shift_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - if S == '0' && size != '11' then UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer round_const = 0; - integer shift; - integer element; - boolean sat; - - for e = 0 to elements-1 - shift = SInt(Elem[operand2, e, esize][7:0]); - if rounding then - round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift - element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift; - if saturating then - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - else - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction AND_Z_P_ZZ__ - __encoding AND_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx011010 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = element1 AND element2; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_memory_single_general_immediate_signed_offset_lda_stl - __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx011001 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_ORDERED; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_system_exceptions_runtime_hvc - __encoding aarch64_system_exceptions_runtime_hvc - __instruction_set A64 - __field imm16 5 +: 16 - __opcode '11010100 000xxxxx xxxxxxxx xxx00010' - __guard TRUE - __decode - bits(16) imm = imm16; - - __execute - if !HaveEL(EL2) || PSTATE.EL == EL0 || (PSTATE.EL == EL1 && (!IsSecureEL2Enabled() && IsSecure())) then - UNDEFINED; - - hvc_enable = if HaveEL(EL3) then SCR_EL3.HCE else NOT(HCR_EL2.HCD); - - if hvc_enable == '0' then - UNDEFINED; - else - AArch64.CallHypervisor(imm); - -__instruction aarch64_vector_shift_right_narrow_logical - __encoding aarch64_vector_shift_right_narrow_logical - __instruction_set A64 - __field Q 30 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field op 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 0xxxxxxx 1000x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3] == '1' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - integer shift = (2 * esize) - UInt(immh:immb); - boolean round = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize*2) operand = V[n]; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - for e = 0 to elements-1 - element = (UInt(Elem[operand, e, 2*esize]) + round_const) >> shift; - Elem[result, e, esize] = element[esize-1:0]; - - Vpart[d, part] = result; - -__instruction aarch64_integer_logical_shiftedreg - __encoding aarch64_integer_logical_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field shift 22 +: 2 - __field N 21 +: 1 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01010 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - boolean invert = (N == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - X[d] = result; - -__instruction ST3W_Z_P_BI_Contiguous - __encoding ST3W_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100101 0101xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - integer nreg = 3; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..2] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction SUB_Z_ZZ__ - __encoding SUB_Z_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 000001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = element1 - element2; - - Z[d] = result; - -__instruction aarch64_system_barriers_isb - __encoding aarch64_system_barriers_isb - __instruction_set A64 - __field CRm 8 +: 4 - __field opc 5 +: 2 - __opcode '11010101 00000011 0011xxxx 1xx11111' - __guard TRUE - __decode - // No additional decoding required - - __execute - InstructionSynchronizationBarrier(); - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_long - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 00x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - Elem[result, e, 2*esize] = sum[2*esize-1:0]; - - V[d] = result; - -__instruction REV_Z_Z__ - __encoding REV_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx111000 001110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - bits(VL) operand = Z[n]; - bits(VL) result = Reverse(operand, esize); - Z[d] = result; - -__instruction FMIN_Z_P_ZZ__ - __encoding FMIN_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx000111 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMin(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction LD1B_Z_P_BZ_D_x32_unscaled - __encoding LD1B_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 0x0xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1B_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 0x0xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1B_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 010xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset = Z[m]; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_system_register_system - __encoding aarch64_system_register_system - __instruction_set A64 - __field L 21 +: 1 - __field o0 19 +: 1 - __field op1 16 +: 3 - __field CRn 12 +: 4 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __field Rt 0 +: 5 - __opcode '11010101 00x1xxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - AArch64.CheckSystemAccess('1':o0, op1, CRn, CRm, op2, Rt, L); - - integer t = UInt(Rt); - - integer sys_op0 = 2 + UInt(o0); - integer sys_op1 = UInt(op1); - integer sys_op2 = UInt(op2); - integer sys_crn = UInt(CRn); - integer sys_crm = UInt(CRm); - boolean read = (L == '1'); - - __execute - if read then - X[t] = AArch64.SysRegRead(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2); - else - AArch64.SysRegWrite(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2, X[t]); - -__instruction FMUL_Z_ZZi_H - __encoding FMUL_Z_ZZi_H - __instruction_set A64 - __field i3h 22 +: 1 - __field i3l 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100100 0x1xxxxx 001000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer index = UInt(i3h:i3l); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __encoding FMUL_Z_ZZi_S - __instruction_set A64 - __field i2 19 +: 2 - __field Zm 16 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100100 101xxxxx 001000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer index = UInt(i2); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __encoding FMUL_Z_ZZi_D - __instruction_set A64 - __field i1 20 +: 1 - __field Zm 16 +: 4 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100100 111xxxxx 001000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer index = UInt(i1); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer eltspersegment = 128 DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer segmentbase = e - (e MOD eltspersegment); - integer s = segmentbase + index; - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, s, esize]; - Elem[result, e, esize] = FPMul(element1, element2, FPCR); - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_mul_accum - __encoding aarch64_vector_arithmetic_binary_disparate_mul_accum - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 10x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) operand3 = V[d]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) product; - bits(2*esize) accum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - product = (element1 * element2)[2*esize-1:0]; - if sub_op then - accum = Elem[operand3, e, 2*esize] - product; - else - accum = Elem[operand3, e, 2*esize] + product; - Elem[result, e, 2*esize] = accum; - - V[d] = result; - -__instruction DECP_Z_P_Z__ - __encoding DECP_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Zdn 0 +: 5 - __opcode '00100101 xx101101 1000000x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Zdn); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(PL) operand2 = P[m]; - bits(VL) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - for e = 0 to elements-1 - Elem[result, e, esize] = Elem[operand1, e, esize] - count; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_element_dotp - __encoding aarch64_vector_arithmetic_binary_element_dotp - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 xxxxxxxx 1110x0xx xxxxxxxx' - __guard TRUE - __decode - if !HaveDOTPExt() then UNDEFINED; - if size != '10' then UNDEFINED; - boolean signed = (U=='0'); - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(M:Rm); - integer index = UInt(H:L); - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(datasize) result = V[d]; - for e = 0 to elements-1 - integer res = 0; - integer element1, element2; - for i = 0 to 3 - if signed then - element1 = SInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = SInt(Elem[operand2, 4 * index + i, esize DIV 4]); - else - element1 = UInt(Elem[operand1, 4 * e + i, esize DIV 4]); - element2 = UInt(Elem[operand2, 4 * index + i, esize DIV 4]); - res = res + element1 * element2; - Elem[result, e, esize] = Elem[result, e, esize] + res; - V[d] = result; - -__instruction aarch64_system_sysops - __encoding aarch64_system_sysops - __instruction_set A64 - __field L 21 +: 1 - __field op1 16 +: 3 - __field CRn 12 +: 4 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __field Rt 0 +: 5 - __opcode '11010101 00x01xxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - AArch64.CheckSystemAccess('01', op1, CRn, CRm, op2, Rt, L); - - integer t = UInt(Rt); - - integer sys_op0 = 1; - integer sys_op1 = UInt(op1); - integer sys_op2 = UInt(op2); - integer sys_crn = UInt(CRn); - integer sys_crm = UInt(CRm); - boolean has_result = (L == '1'); - - __execute - if has_result then - // No architecturally defined instructions here. - X[t] = AArch64.SysInstrWithResult(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2); - else - AArch64.SysInstr(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2, X[t]); - -__instruction LD1SW_Z_P_BI_S64 - __encoding LD1SW_Z_P_BI_S64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 1000xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = FALSE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction FMUL_Z_P_ZZ__ - __encoding FMUL_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx000010 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMul(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction LD1RQH_Z_P_BR_Contiguous - __encoding LD1RQH_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 100xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 16; - - __execute - CheckSVEEnabled(); - integer elements = 128 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low 16 bits only - bits(64) offset; - bits(128) result; - constant integer mbytes = esize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = X[m]; - - addr = base + UInt(offset) * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = Replicate(result, VL DIV 128); - -__instruction LD1RQB_Z_P_BI_U8 - __encoding LD1RQB_Z_P_BI_U8 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0000xxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = 128 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low 16 bits only - bits(128) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * 16; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = Replicate(result, VL DIV 128); - -__instruction aarch64_vector_arithmetic_binary_uniform_logical_and_orr - __encoding aarch64_vector_arithmetic_binary_uniform_logical_and_orr - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx1xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean invert = (size[0] == '1'); - LogicalOp op = if size[1] == '1' then LogicalOp_ORR else LogicalOp_AND; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND - result = operand1 AND operand2; - when LogicalOp_ORR - result = operand1 OR operand2; - - V[d] = result; - -__instruction BFDOT_Z_ZZZ__ - __encoding BFDOT_Z_ZZZ__ - __instruction_set A64 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100100 011xxxxx 100000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveBF16Ext() then UNDEFINED; - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 32; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(16) elt1_a = Elem[operand1, 2 * e + 0, 16]; - bits(16) elt1_b = Elem[operand1, 2 * e + 1, 16]; - bits(16) elt2_a = Elem[operand2, 2 * e + 0, 16]; - bits(16) elt2_b = Elem[operand2, 2 * e + 1, 16]; - - bits(32) sum = BFAdd(BFMul(elt1_a, elt2_a), BFMul(elt1_b, elt2_b)); - Elem[result, e, 32] = BFAdd(Elem[operand3, e, 32], sum); - - Z[da] = result; - -__instruction aarch64_integer_tags_mcinserttagmask - __encoding aarch64_integer_tags_mcinserttagmask - __instruction_set A64 - __field Xm 16 +: 5 - __field Xn 5 +: 5 - __field Xd 0 +: 5 - __opcode '10011010 110xxxxx 000101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Xd); - integer n = UInt(Xn); - integer m = UInt(Xm); - - __execute - bits(64) address = if n == 31 then SP[] else X[n]; - bits(64) mask = X[m]; - bits(4) tag = AArch64.AllocationTagFromAddress(address); - - mask[UInt(tag)] = '1'; - X[d] = mask; - -__instruction LD1SB_Z_P_BZ_D_x32_unscaled - __encoding LD1SB_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 0x0xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1SB_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 0x0xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 8; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1SB_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 010xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 8; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset = Z[m]; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_diff - __encoding aarch64_vector_arithmetic_binary_disparate_diff - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 01x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean accumulate = (op == '0'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - bits(2*esize) absdiff; - - result = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - absdiff = Abs(element1 - element2)[2*esize-1:0]; - Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + absdiff; - V[d] = result; - -__instruction CLZ_Z_P_Z__ - __encoding CLZ_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx011001 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = CountLeadingZeroBits(element)[esize-1:0]; - - Z[d] = result; - -__instruction BIC_P_P_PP_Z - __encoding BIC_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0000xxxx 01xxxx0x xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding BICS_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0100xxxx 01xxxx0x xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - for e = 0 to elements-1 - bit element1 = ElemP[operand1, e, esize]; - bit element2 = ElemP[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - ElemP[result, e, esize] = element1 AND (NOT element2); - else - ElemP[result, e, esize] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction LD1RQW_Z_P_BI_U32 - __encoding LD1RQW_Z_P_BI_U32 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 0000xxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 32; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = 128 DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; // low 16 bits only - bits(128) result; - constant integer mbytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * 16; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = Replicate(result, VL DIV 128); - -__instruction ST2H_Z_P_BI_Contiguous - __encoding ST2H_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 1011xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 16; - integer offset = SInt(imm4); - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction aarch64_vector_arithmetic_binary_uniform_sub_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp16_sisd - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 110xxxxx 000101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = esize; - integer elements = 1; - boolean abs = TRUE; - - __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 1x1xxxxx 110101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - boolean abs = TRUE; - - __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 110xxxxx 000101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean abs = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_sub_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 1x1xxxxx 110101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean abs = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - bits(esize) diff; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - diff = FPSub(element1, element2, FPCR); - Elem[result, e, esize] = if abs then FPAbs(diff) else diff; - - V[d] = result; - -__instruction aarch64_memory_ordered_rcpc - __encoding aarch64_memory_ordered_rcpc - __instruction_set A64 - __field size 30 +: 2 - __field Rs 16 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 101xxxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = AccType_ORDERED; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction UQDECD_Z_ZS__ - __encoding UQDECD_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1110xxxx 110011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_unary_special_sqrt_fp16 - __encoding aarch64_vector_arithmetic_unary_special_sqrt_fp16 - __instruction_set A64 - __field Q 30 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 11111001 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __encoding aarch64_vector_arithmetic_unary_special_sqrt - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 1x100001 111110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPSqrt(element, FPCR); - - V[d] = result; - -__instruction aarch64_float_arithmetic_unary - __encoding aarch64_float_arithmetic_unary - __instruction_set A64 - __field ftype 22 +: 2 - __field opc 15 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx10000x x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - FPUnaryOp fpop; - case opc of - when '00' fpop = FPUnaryOp_MOV; - when '01' fpop = FPUnaryOp_ABS; - when '10' fpop = FPUnaryOp_NEG; - when '11' fpop = FPUnaryOp_SQRT; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - case fpop of - when FPUnaryOp_MOV result = operand; - when FPUnaryOp_ABS result = FPAbs(operand); - when FPUnaryOp_NEG result = FPNeg(operand); - when FPUnaryOp_SQRT result = FPSqrt(operand, FPCR); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_rbit - __encoding aarch64_vector_arithmetic_unary_rbit - __instruction_set A64 - __field Q 30 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 01100000 010110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 8; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - bits(esize) rev; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - for i = 0 to esize-1 - rev[esize-1-i] = element[i]; - Elem[result, e, esize] = rev; - - V[d] = result; - -__instruction FADDV_V_P_Z__ - __encoding FADDV_V_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Vd 0 +: 5 - __opcode '01100101 xx000000 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Vd); - - __execute - CheckSVEEnabled(); - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(esize) identity = FPZero('0'); - - V[d] = ReducePredicated(ReduceOp_FADD, operand, mask, identity); - -__instruction SUBR_Z_P_ZZ__ - __encoding SUBR_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx000011 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = element2 - element1; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_float_arithmetic_div - __encoding aarch64_float_arithmetic_div - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx 000110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - result = FPDiv(operand1, operand2, FPCR); - - V[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if abs then - element1 = FPAbs(element1); - element2 = FPAbs(element2); - case cmp of - when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR); - when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_float_convert_fix - __encoding aarch64_float_convert_fix - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field scale 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - - case ftype of - when '00' fltsize = 32; - when '01' fltsize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - if sf == '0' && scale[5] == '0' then UNDEFINED; - integer fracbits = 64 - UInt(scale); - - case opcode[2:1]:rmode of - when '00 11' // FCVTZ - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, fracbits, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, fracbits, unsigned, FPCR, rounding); - V[d] = fltval; - -__instruction aarch64_memory_atomicops_swp - __encoding aarch64_memory_atomicops_swp - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 100000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - bits(datasize) store_value; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - store_value = X[s]; - data = MemAtomic(address, MemAtomicOp_SWP, store_value, ldacctype, stacctype); - X[t] = ZeroExtend(data, regsize); - -__instruction SQINCP_R_P_R_SX - __encoding SQINCP_R_P_R_SX - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101000 1000100x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQINCP_R_P_R_X - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101000 1000110x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(ssize) operand1 = X[dn]; - bits(PL) operand2 = P[m]; - bits(ssize) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - integer element = Int(operand1, unsigned); - (result, -) = SatQ(element + count, ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction FRINTI_Z_P_Z__ - __encoding FRINTI_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx000111 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean exact = FALSE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding FRINTX_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx000110 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean exact = TRUE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding FRINTA_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx000100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean exact = FALSE; - FPRounding rounding = FPRounding_TIEAWAY; - - __encoding FRINTN_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx000000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean exact = FALSE; - FPRounding rounding = FPRounding_TIEEVEN; - - __encoding FRINTZ_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx000011 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean exact = FALSE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FRINTM_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx000010 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean exact = FALSE; - FPRounding rounding = FPRounding_NEGINF; - - __encoding FRINTP_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 xx000001 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - boolean exact = FALSE; - FPRounding rounding = FPRounding_POSINF; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact); - - Z[d] = result; - -__instruction LDFF1W_Z_P_AI_S - __encoding LDFF1W_Z_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000101 001xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __encoding LDFF1W_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 001xxxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_memory_single_simdfp_register - __encoding aarch64_memory_single_simdfp_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111100 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_VEC; - MemOp memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - bits(64) address; - bits(datasize) data; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data = V[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - V[t] = data; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_integer_tags_mcsettagpairpost - __encoding aarch64_integer_tags_mcsettagpairpost - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 101xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = TRUE; - boolean zero_data = FALSE; - - __encoding aarch64_integer_tags_mcsettagpairpre - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 101xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = TRUE; - boolean postindex = FALSE; - boolean zero_data = FALSE; - - __encoding aarch64_integer_tags_mcsettagpair - __instruction_set A64 - __field imm9 12 +: 9 - __field Xn 5 +: 5 - __field Xt 0 +: 5 - __opcode '11011001 101xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Xn); - integer t = UInt(Xt); - bits(64) offset = LSL(SignExtend(imm9, 64), LOG2_TAG_GRANULE); - boolean writeback = FALSE; - boolean postindex = FALSE; - boolean zero_data = FALSE; - - __execute - bits(64) address; - bits(64) data = if t == 31 then SP[] else X[t]; - bits(4) tag = AArch64.AllocationTagFromAddress(data); - - SetTagCheckedInstruction(FALSE); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if !postindex then - address = address + offset; - - if zero_data then - Mem[address, TAG_GRANULE, AccType_NORMAL] = Zeros(8*TAG_GRANULE); - Mem[address+TAG_GRANULE, TAG_GRANULE, AccType_NORMAL] = Zeros(8*TAG_GRANULE); - - AArch64.MemTag[address, AccType_NORMAL] = tag; - AArch64.MemTag[address+TAG_GRANULE, AccType_NORMAL] = tag; - - if writeback then - if postindex then - address = address + offset; - - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction LD2D_Z_P_BI_Contiguous - __encoding LD2D_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1010xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer offset = SInt(imm4); - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_saturating_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_add_saturating_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 000011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_add_saturating_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 000011xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer sum; - boolean sat; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - sum = element1 + element2; - (Elem[result, e, esize], sat) = SatQ(sum, esize, unsigned); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction aarch64_system_register_cpsr - __encoding aarch64_system_register_cpsr - __instruction_set A64 - __field op1 16 +: 3 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000xxx 0100xxxx xxx11111' - __guard TRUE - __decode - if op1 == '000' && op2 == '000' then SEE "CFINV"; - if op1 == '000' && op2 == '001' then SEE "XAFLAG"; - if op1 == '000' && op2 == '010' then SEE "AXFLAG"; - - AArch64.CheckSystemAccess('00', op1, '0100', CRm, op2, '11111', '0'); - bits(2) min_EL; - boolean need_secure; - (min_EL, need_secure) = AArch64.GetMinELSecurityState(op1); - if UInt(PSTATE.EL) < UInt(min_EL) || (need_secure && !IsSecure()) then - UNDEFINED; - - bits(4) operand = CRm; - PSTATEField field; - case op1:op2 of - when '000 011' - if !HaveUAOExt() then - UNDEFINED; - field = PSTATEField_UAO; - when '000 100' - if !HavePANExt() then - UNDEFINED; - field = PSTATEField_PAN; - when '000 101' field = PSTATEField_SP; - when '011 010' - if !HaveDITExt() then - UNDEFINED; - field = PSTATEField_DIT; - when '011 100' - if !HaveMTEExt() then - UNDEFINED; - field = PSTATEField_TCO; - when '011 110' field = PSTATEField_DAIFSet; - when '011 111' field = PSTATEField_DAIFClr; - when '011 001' - if !HaveSSBSExt() then - UNDEFINED; - field = PSTATEField_SSBS; - otherwise UNDEFINED; - - // Check that an AArch64 MSR/MRS access to the DAIF flags is permitted - if PSTATE.EL == EL0 && field IN {PSTATEField_DAIFSet, PSTATEField_DAIFClr} then - if !ELUsingAArch32(EL1) && ((EL2Enabled() && HCR_EL2.[E2H,TGE] == '11') || SCTLR_EL1.UMA == '0') then - if EL2Enabled() && !ELUsingAArch32(EL2) && HCR_EL2.TGE == '1' then - AArch64.SystemAccessTrap(EL2, 0x18); - else - AArch64.SystemAccessTrap(EL1, 0x18); - - __execute - case field of - when PSTATEField_SSBS - PSTATE.SSBS = operand[0]; - when PSTATEField_SP - PSTATE.SP = operand[0]; - when PSTATEField_DAIFSet - PSTATE.D = PSTATE.D OR operand[3]; - PSTATE.A = PSTATE.A OR operand[2]; - PSTATE.I = PSTATE.I OR operand[1]; - PSTATE.F = PSTATE.F OR operand[0]; - when PSTATEField_DAIFClr - PSTATE.D = PSTATE.D AND NOT(operand[3]); - PSTATE.A = PSTATE.A AND NOT(operand[2]); - PSTATE.I = PSTATE.I AND NOT(operand[1]); - PSTATE.F = PSTATE.F AND NOT(operand[0]); - when PSTATEField_PAN - PSTATE.PAN = operand[0]; - when PSTATEField_UAO - PSTATE.UAO = operand[0]; - when PSTATEField_DIT - PSTATE.DIT = operand[0]; - when PSTATEField_TCO - PSTATE.TCO = operand[0]; - -__instruction aarch64_float_compare_uncond - __encoding aarch64_float_compare_uncond - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field opc 3 +: 2 - __opcode '00011110 xx1xxxxx 001000xx xxxxx000' - __guard TRUE - __decode - integer n = UInt(Rn); - integer m = UInt(Rm); // ignored when opc[0] == '1' - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean signal_all_nans = (opc[1] == '1'); - boolean cmp_with_zero = (opc[0] == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) operand1 = V[n]; - bits(datasize) operand2; - - operand2 = if cmp_with_zero then FPZero('0') else V[m]; - - PSTATE.[N,Z,C,V] = FPCompare(operand1, operand2, signal_all_nans, FPCR); - -__instruction aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean test_passed; - - for e = 0 to elements-1 - element = SInt(Elem[operand, e, esize]); - case comparison of - when CompareOp_GT test_passed = element > 0; - when CompareOp_GE test_passed = element >= 0; - when CompareOp_EQ test_passed = element == 0; - when CompareOp_LE test_passed = element <= 0; - when CompareOp_LT test_passed = element < 0; - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction UQDECH_R_RS_UW - __encoding UQDECH_R_RS_UW - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0110xxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQDECH_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0111xxxx 111111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 - (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_vector_shift_right_sisd - __encoding aarch64_vector_shift_right_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __encoding aarch64_vector_shift_right_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - operand2 = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift; - Elem[result, e, esize] = Elem[operand2, e, esize] + element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_memory_vector_multiple_no_wb - __encoding aarch64_memory_vector_multiple_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 0x000000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_multiple_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field Rm 16 +: 5 - __field opcode 12 +: 4 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001100 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << UInt(size); - integer elements = datasize DIV esize; - - integer rpt; // number of iterations - integer selem; // structure elements - - case opcode of - when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers) - when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers) - when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers) - when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers) - when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register) - when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers) - when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers) - otherwise UNDEFINED; - - // .1D format only permitted with LD1 & ST1 - if size:Q == '110' && selem != 1 then UNDEFINED; - __execute - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(datasize) rval; - integer tt; - constant integer ebytes = esize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - for r = 0 to rpt-1 - for e = 0 to elements-1 - tt = (t + r) MOD 32; - for s = 0 to selem-1 - rval = V[tt]; - if memop == MemOp_LOAD then - Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[tt] = rval; - else // memop == MemOp_STORE - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize]; - offs = offs + ebytes; - tt = (tt + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_float_arithmetic_add_sub - __encoding aarch64_float_arithmetic_add_sub - __instruction_set A64 - __field ftype 22 +: 2 - __field Rm 16 +: 5 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1xxxxx 001x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean sub_op = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) result; - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - - if sub_op then - result = FPSub(operand1, operand2, FPCR); - else - result = FPAdd(operand1, operand2, FPCR); - - V[d] = result; - -__instruction aarch64_integer_logical_shiftedreg - __encoding aarch64_integer_logical_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field shift 22 +: 2 - __field N 21 +: 1 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01010 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - boolean invert = (N == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - X[d] = result; - -__instruction aarch64_integer_conditional_compare_immediate - __encoding aarch64_integer_conditional_compare_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field imm5 16 +: 5 - __field cond 12 +: 4 - __field Rn 5 +: 5 - __field nzcv 0 +: 4 - __opcode 'xx111010 010xxxxx xxxx10xx xxx0xxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - bits(4) condition = cond; - bits(4) flags = nzcv; - bits(datasize) imm = ZeroExtend(imm5, datasize); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = imm; - bit carry_in = '0'; - - if ConditionHolds(condition) then - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - (-, flags) = AddWithCarry(operand1, operand2, carry_in); - PSTATE.[N,Z,C,V] = flags; - -__instruction aarch64_udf - __encoding aarch64_udf - __instruction_set A64 - __field imm16 0 +: 16 - __opcode '00000000 00000000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - // The imm16 field is ignored by hardware. - UNDEFINED; - - __execute - // No operation. - -__instruction PRFD_I_P_BI_S - __encoding PRFD_I_P_BI_S - __instruction_set A64 - __field imm6 16 +: 6 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000101 11xxxxxx 011xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Rn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 3; - integer offset = SInt(imm6); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(64) base; - bits(64) addr; - - if n == 31 then - base = SP[]; - else - base = X[n]; - - addr = base + ((offset * elements) << scale); - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - Hint_Prefetch(addr, pref_hint, level, stream); - addr = addr + (1 << scale); - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_fp16_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 101x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_float_conv_float_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 101x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - FPRounding rounding = FPDecodeRounding(o1:o2); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding); - - V[d] = result; - -__instruction SQINCP_Z_P_Z__ - __encoding SQINCP_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Zdn 0 +: 5 - __opcode '00100101 xx101000 1000000x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Zdn); - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(PL) operand2 = P[m]; - bits(VL) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - for e = 0 to elements-1 - integer element = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element + count, esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_int_accum - __encoding aarch64_vector_arithmetic_binary_uniform_mul_int_accum - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 100101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean sub_op = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - bits(esize) product; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - product = (UInt(element1) * UInt(element2))[esize-1:0]; - if sub_op then - Elem[result, e, esize] = Elem[operand3, e, esize] - product; - else - Elem[result, e, esize] = Elem[operand3, e, esize] + product; - - V[d] = result; - -__instruction SQDECD_Z_ZS__ - __encoding SQDECD_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1110xxxx 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_memory_single_general_immediate_signed_offset_normal - __encoding aarch64_memory_single_general_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction ASR_Z_P_ZW__ - __encoding ASR_Z_P_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx011000 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(64) element2 = Elem[operand2, (e * esize) DIV 64, 64]; - integer shift = Min(UInt(element2), esize); - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = ASR(element1, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction FDUP_Z_I__ - __encoding FDUP_Z_I__ - __instruction_set A64 - __field size 22 +: 2 - __field imm8 5 +: 8 - __field Zd 0 +: 5 - __opcode '00100101 xx111001 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer d = UInt(Zd); - bits(esize) imm = VFPExpandImm(imm8); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) result; - - for e = 0 to elements-1 - Elem[result, e, esize] = imm; - - Z[d] = result; - -__instruction aarch64_integer_arithmetic_mul_widening_64_128hi - __encoding aarch64_integer_arithmetic_mul_widening_64_128hi - __instruction_set A64 - __field U 23 +: 1 - __field Rm 16 +: 5 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '10011011 x10xxxxx 0xxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer a = UInt(Ra); // ignored by UMULH/SMULH - integer destsize = 64; - integer datasize = destsize; - boolean unsigned = (U == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - - integer result; - - result = Int(operand1, unsigned) * Int(operand2, unsigned); - - X[d] = result[127:64]; - -__instruction UQINCB_R_RS_UW - __encoding UQINCB_R_RS_UW - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0010xxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQINCB_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 0011xxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 + (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_vector_arithmetic_binary_uniform_mul_fp16_extended_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_extended_sisd - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 010xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_extended_sisd - __instruction_set A64 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 0x1xxxxx 110111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp16_extended_simd - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 010xxxxx 000111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __encoding aarch64_vector_arithmetic_binary_uniform_mul_fp_extended_simd - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 0x1xxxxx 110111xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPMulX(element1, element2, FPCR); - V[d] = result; - -__instruction aarch64_system_hints - __encoding aarch64_system_hints - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - SystemHintOp op; - - case CRm:op2 of - when '0000 000' op = SystemHintOp_NOP; - when '0000 001' op = SystemHintOp_YIELD; - when '0000 010' op = SystemHintOp_WFE; - when '0000 011' op = SystemHintOp_WFI; - when '0000 100' op = SystemHintOp_SEV; - when '0000 101' op = SystemHintOp_SEVL; - when '0000 110' - if !HaveDGHExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_DGH; - when '0000 111' SEE "XPACLRI"; - when '0001 xxx' - case op2 of - when '000' SEE "PACIA1716"; - when '010' SEE "PACIB1716"; - when '100' SEE "AUTIA1716"; - when '110' SEE "AUTIB1716"; - otherwise EndOfInstruction(); // Instruction executes as NOP - when '0010 000' - if !HaveRASExt() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_ESB; - when '0010 001' - if !HaveStatisticalProfiling() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_PSB; - when '0010 010' - if !HaveSelfHostedTrace() then EndOfInstruction(); // Instruction executes as NOP - op = SystemHintOp_TSB; - when '0010 100' - op = SystemHintOp_CSDB; - when '0011 xxx' - case op2 of - when '000' SEE "PACIAZ"; - when '001' SEE "PACIASP"; - when '010' SEE "PACIBZ"; - when '011' SEE "PACIBSP"; - when '100' SEE "AUTIAZ"; - when '101' SEE "AUTHASP"; - when '110' SEE "AUTIBZ"; - when '111' SEE "AUTIBSP"; - when '0100 xx0' - op = SystemHintOp_BTI; - // Check branch target compatibility between BTI instruction and PSTATE.BTYPE - SetBTypeCompatible(BTypeCompatible_BTI(op2[2:1])); - otherwise EndOfInstruction(); // Instruction executes as NOP - - __execute - case op of - when SystemHintOp_YIELD - Hint_Yield(); - - when SystemHintOp_DGH - Hint_DGH(); - - when SystemHintOp_WFE - if IsEventRegisterSet() then - ClearEventRegister(); - else - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, TRUE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, TRUE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, TRUE); - WaitForEvent(); - - when SystemHintOp_WFI - if !InterruptPending() then - if PSTATE.EL == EL0 then - // Check for traps described by the OS which may be EL1 or EL2. - AArch64.CheckForWFxTrap(EL1, FALSE); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() && !IsInHost() then - // Check for traps described by the Hypervisor. - AArch64.CheckForWFxTrap(EL2, FALSE); - if HaveEL(EL3) && PSTATE.EL != EL3 then - // Check for traps described by the Secure Monitor. - AArch64.CheckForWFxTrap(EL3, FALSE); - WaitForInterrupt(); - - when SystemHintOp_SEV - SendEvent(); - - when SystemHintOp_SEVL - SendEventLocal(); - - when SystemHintOp_ESB - SynchronizeErrors(); - AArch64.ESBOperation(); - if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then AArch64.vESBOperation(); - TakeUnmaskedSErrorInterrupts(); - - when SystemHintOp_PSB - ProfilingSynchronizationBarrier(); - - when SystemHintOp_TSB - TraceSynchronizationBarrier(); - - when SystemHintOp_CSDB - ConsumptionOfSpeculativeDataBarrier(); - - when SystemHintOp_BTI - SetBTypeNext('00'); - - otherwise // do nothing - -__instruction SCVTF_Z_P_Z_H2FP16 - __encoding SCVTF_Z_P_Z_H2FP16 - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01010010 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 16; - boolean unsigned = FALSE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding SCVTF_Z_P_Z_W2FP16 - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01010100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 16; - boolean unsigned = FALSE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding SCVTF_Z_P_Z_W2S - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 10010100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 32; - boolean unsigned = FALSE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding SCVTF_Z_P_Z_W2D - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11010000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 64; - boolean unsigned = FALSE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding SCVTF_Z_P_Z_X2FP16 - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01010110 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 16; - boolean unsigned = FALSE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding SCVTF_Z_P_Z_X2S - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11010100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 32; - boolean unsigned = FALSE; - FPRounding rounding = FPRoundingMode(FPCR); - - __encoding SCVTF_Z_P_Z_X2D - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11010110 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 64; - boolean unsigned = FALSE; - FPRounding rounding = FPRoundingMode(FPCR); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - bits(d_esize) fpval = FixedToFP(element[s_esize-1:0], 0, unsigned, FPCR, rounding); - Elem[result, e, esize] = ZeroExtend(fpval); - - Z[d] = result; - -__instruction LSR_Z_P_ZI__ - __encoding LSR_Z_P_ZI__ - __instruction_set A64 - __field tszh 22 +: 2 - __field Pg 10 +: 3 - __field tszl 8 +: 2 - __field imm3 5 +: 3 - __field Zdn 0 +: 5 - __opcode '00000100 xx000001 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - bits(4) tsize = tszh:tszl; - case tsize of - when '0000' UNDEFINED; - when '0001' esize = 8; - when '001x' esize = 16; - when '01xx' esize = 32; - when '1xxx' esize = 64; - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer shift = (2 * esize) - UInt(tsize:imm3); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(PL) mask = P[g]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = LSR(element1, shift); - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_float_arithmetic_unary - __encoding aarch64_float_arithmetic_unary - __instruction_set A64 - __field ftype 22 +: 2 - __field opc 15 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx10000x x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - FPUnaryOp fpop; - case opc of - when '00' fpop = FPUnaryOp_MOV; - when '01' fpop = FPUnaryOp_ABS; - when '10' fpop = FPUnaryOp_NEG; - when '11' fpop = FPUnaryOp_SQRT; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - case fpop of - when FPUnaryOp_MOV result = operand; - when FPUnaryOp_ABS result = FPAbs(operand); - when FPUnaryOp_NEG result = FPNeg(operand); - when FPUnaryOp_SQRT result = FPSqrt(operand, FPCR); - - V[d] = result; - -__instruction aarch64_float_arithmetic_round_frint - __encoding aarch64_float_arithmetic_round_frint - __instruction_set A64 - __field ftype 22 +: 2 - __field rmode 15 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1001xx x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean exact = FALSE; - FPRounding rounding; - case rmode of - when '0xx' rounding = FPDecodeRounding(rmode[1:0]); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundInt(operand, FPCR, rounding, exact); - - V[d] = result; - -__instruction FCMEQ_P_P_Z0__ - __encoding FCMEQ_P_P_Z0__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx010010 001xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_EQ; - - __encoding FCMGT_P_P_Z0__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx010000 001xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_GT; - - __encoding FCMGE_P_P_Z0__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx010000 001xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_GE; - - __encoding FCMLT_P_P_Z0__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx010001 001xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_LT; - - __encoding FCMLE_P_P_Z0__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx010001 001xxxxx xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_LE; - - __encoding FCMNE_P_P_Z0__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Pd 0 +: 4 - __opcode '01100101 xx010011 001xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Pd); - SVECmp op = Cmp_NE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(PL) result; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - case op of - when Cmp_EQ res = FPCompareEQ(element, 0[esize-1:0], FPCR); - when Cmp_GE res = FPCompareGE(element, 0[esize-1:0], FPCR); - when Cmp_GT res = FPCompareGT(element, 0[esize-1:0], FPCR); - when Cmp_NE res = FPCompareNE(element, 0[esize-1:0], FPCR); - when Cmp_LT res = FPCompareGT(0[esize-1:0], element, FPCR); - when Cmp_LE res = FPCompareGE(0[esize-1:0], element, FPCR); - ElemP[result, e, esize] = if res then '1' else '0'; - else - ElemP[result, e, esize] = '0'; - - P[d] = result; - -__instruction TRN1_P_PP__ - __encoding TRN1_P_PP__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 16 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00000101 xx10xxxx 0101000x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - integer part = 0; - - __encoding TRN2_P_PP__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 16 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00000101 xx10xxxx 0101010x xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - integer part = 1; - - __execute - CheckSVEEnabled(); - integer pairs = VL DIV (esize * 2); - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - for p = 0 to pairs-1 - Elem[result, 2*p+0, esize DIV 8] = Elem[operand1, 2*p+part, esize DIV 8]; - Elem[result, 2*p+1, esize DIV 8] = Elem[operand2, 2*p+part, esize DIV 8]; - - P[d] = result; - -__instruction aarch64_vector_arithmetic_unary_diff_neg_fp16 - __encoding aarch64_vector_arithmetic_unary_diff_neg_fp16 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 11111000 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean neg = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_diff_neg_float - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 1x100000 111110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean neg = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - if neg then - element = FPNeg(element); - else - element = FPAbs(element); - Elem[result, e, esize] = element; - - V[d] = result; - -__instruction AND_Z_ZI__ - __encoding AND_Z_ZI__ - __instruction_set A64 - __field imm13 5 +: 13 - __field Zdn 0 +: 5 - __opcode '00000101 100000xx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer dn = UInt(Zdn); - bits(64) imm; - (imm, -) = DecodeBitMasks(imm13[12], imm13[5:0], imm13[11:6], TRUE); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 64; - bits(VL) operand = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - bits(64) element1 = Elem[operand, e, 64]; - Elem[result, e, 64] = element1 AND imm; - - Z[dn] = result; - -__instruction aarch64_integer_arithmetic_add_sub_extendedreg - __encoding aarch64_integer_arithmetic_add_sub_extendedreg - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field imm3 10 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01011 001xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - ExtendType extend_type = DecodeRegExtend(option); - integer shift = UInt(imm3); - if shift > 4 then UNDEFINED; - - __execute - bits(datasize) result; - bits(datasize) operand1 = if n == 31 then SP[] else X[n]; - bits(datasize) operand2 = ExtendReg(m, extend_type, shift); - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction MUL_Z_P_ZZ__ - __encoding MUL_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010000 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = UInt(Elem[operand1, e, esize]); - integer element2 = UInt(Elem[operand2, e, esize]); - if ElemP[mask, e, esize] == '1' then - integer product = element1 * element2; - Elem[result, e, esize] = product[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction SEL_P_P_PP__ - __encoding SEL_P_P_PP__ - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 0000xxxx 01xxxx1x xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - for e = 0 to elements-1 - bit element1 = ElemP[operand1, e, esize]; - bit element2 = ElemP[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - ElemP[result, e, esize] = element1; - else - ElemP[result, e, esize] = element2; - - P[d] = result; - -__instruction aarch64_memory_atomicops_cas_single - __encoding aarch64_memory_atomicops_cas_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x1xxxxx x11111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer n = UInt(Rn); - integer t = UInt(Rt); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if L == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if o0 == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) comparevalue; - bits(datasize) newvalue; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - comparevalue = X[s]; - newvalue = X[t]; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomicCompareAndSwap(address, comparevalue, newvalue, ldacctype, stacctype); - - X[s] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_unary_fp16_round - __encoding aarch64_vector_arithmetic_unary_fp16_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x1111001 100x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __encoding aarch64_vector_arithmetic_unary_float_round - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field o2 23 +: 1 - __field sz 22 +: 1 - __field o1 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100001 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean exact = FALSE; - FPRounding rounding; - case U:o1:o2 of - when '0xx' rounding = FPDecodeRounding(o1:o2); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact); - - V[d] = result; - -__instruction UQDECH_Z_ZS__ - __encoding UQDECH_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 0110xxxx 110011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - (Elem[result, e, esize], -) = SatQ(element1 - (count * imm), esize, unsigned); - - Z[dn] = result; - -__instruction aarch64_float_convert_fix - __encoding aarch64_float_convert_fix - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field scale 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - - case ftype of - when '00' fltsize = 32; - when '01' fltsize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - if sf == '0' && scale[5] == '0' then UNDEFINED; - integer fracbits = 64 - UInt(scale); - - case opcode[2:1]:rmode of - when '00 11' // FCVTZ - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, fracbits, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, fracbits, unsigned, FPCR, rounding); - V[d] = fltval; - -__instruction MOVPRFX_Z_Z__ - __encoding MOVPRFX_Z_Z__ - __instruction_set A64 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 00100000 101111xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - bits(VL) result = Z[n]; - Z[d] = result; - -__instruction aarch64_integer_pac_strip_dp_1src - __encoding aarch64_integer_pac_strip_dp_1src - __instruction_set A64 - __field D 10 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11011010 11000001 01000xxx xxxxxxxx' - __guard TRUE - __decode - boolean data = (D == '1'); - integer d = UInt(Rd); - integer n = UInt(Rn); - - if !HavePACExt() then - UNDEFINED; - - if n != 31 then UNDEFINED; - - __encoding aarch64_integer_pac_strip_hint - __instruction_set A64 - __opcode '11010101 00000011 00100000 11111111' - __guard TRUE - __decode - integer d = 30; - boolean data = FALSE; - - __execute - if HavePACExt() then - X[d] = Strip(X[d], data); - -__instruction aarch64_vector_shift_right_sisd - __encoding aarch64_vector_shift_right_sisd - __instruction_set A64 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh[3] != '1' then UNDEFINED; - integer esize = 8 << 3; - integer datasize = esize; - integer elements = 1; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __encoding aarch64_vector_shift_right_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field immh 19 +: 4 - __field immb 16 +: 3 - __field o1 13 +: 1 - __field o0 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01111 0xxxxxxx 00xx01xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if immh == '0000' then SEE(asimdimm); - if immh[3]:Q == '10' then UNDEFINED; - integer esize = 8 << HighestSetBit(immh); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - integer shift = (esize * 2) - UInt(immh:immb); - boolean unsigned = (U == '1'); - boolean round = (o1 == '1'); - boolean accumulate = (o0 == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) operand2; - bits(datasize) result; - integer round_const = if round then (1 << (shift - 1)) else 0; - integer element; - - operand2 = if accumulate then V[d] else Zeros(); - for e = 0 to elements-1 - element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift; - Elem[result, e, esize] = Elem[operand2, e, esize] + element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_memory_single_simdfp_immediate_signed_offset_normal - __encoding aarch64_memory_single_simdfp_immediate_signed_offset_normal - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111100 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_VEC; - MemOp memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - bits(64) address; - bits(datasize) data; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data = V[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - V[t] = data; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_uniform_sub_int - __encoding aarch64_vector_arithmetic_binary_uniform_sub_int - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 001001xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - integer element1; - integer element2; - integer diff; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - diff = element1 - element2; - Elem[result, e, esize] = diff[esize:1]; - - V[d] = result; - -__instruction aarch64_memory_single_simdfp_immediate_signed_post_idx - __encoding aarch64_memory_single_simdfp_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111100 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_simdfp_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111100 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_simdfp_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111101 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(opc[1]:size); - if scale > 4 then UNDEFINED; - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_VEC; - MemOp memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - bits(64) address; - bits(datasize) data; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - data = V[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - V[t] = data; - - if wback then - if postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction FTMAD_Z_ZZI__ - __encoding FTMAD_Z_ZZI__ - __instruction_set A64 - __field size 22 +: 2 - __field imm3 16 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx010xxx 100000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - integer imm = UInt(imm3); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPTrigMAdd(imm, element1, element2, FPCR); - - Z[dn] = result; - -__instruction aarch64_vector_reduce_fp16_maxnm_simd - __encoding aarch64_vector_reduce_fp16_maxnm_simd - __instruction_set A64 - __field Q 30 +: 1 - __field o1 23 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 x0110000 110010xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM; - - __encoding aarch64_vector_reduce_fp_maxnm_simd - __instruction_set A64 - __field Q 30 +: 1 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx110000 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q != '01' then UNDEFINED; // .4S only - - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction aarch64_float_arithmetic_round_frint - __encoding aarch64_float_arithmetic_round_frint - __instruction_set A64 - __field ftype 22 +: 2 - __field rmode 15 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1001xx x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean exact = FALSE; - FPRounding rounding; - case rmode of - when '0xx' rounding = FPDecodeRounding(rmode[1:0]); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundInt(operand, FPCR, rounding, exact); - - V[d] = result; - -__instruction RBIT_Z_P_Z__ - __encoding RBIT_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx100111 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = BitReverse(element); - - Z[d] = result; - -__instruction UMULH_Z_P_ZZ__ - __encoding UMULH_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx010011 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean unsigned = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = Int(Elem[operand1, e, esize], unsigned); - integer element2 = Int(Elem[operand2, e, esize], unsigned); - if ElemP[mask, e, esize] == '1' then - integer product = (element1 * element2) >> esize; - Elem[result, e, esize] = product[esize-1:0]; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_sisd - __instruction_set A64 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 32 << UInt(sz); - integer datasize = esize; - integer elements = 1; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp16_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 x10xxxxx 0010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_cmp_fp_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field E 23 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field ac 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 1110x1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - CompareOp cmp; - boolean abs; - - case E:U:ac of - when '000' cmp = CompareOp_EQ; abs = FALSE; - when '010' cmp = CompareOp_GE; abs = FALSE; - when '011' cmp = CompareOp_GE; abs = TRUE; - when '110' cmp = CompareOp_GT; abs = FALSE; - when '111' cmp = CompareOp_GT; abs = TRUE; - otherwise UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element2; - boolean test_passed; - - for e = 0 to elements-1 - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - if abs then - element1 = FPAbs(element1); - element2 = FPAbs(element2); - case cmp of - when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR); - when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR); - when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR); - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_integer_arithmetic_add_sub_carry - __encoding aarch64_integer_arithmetic_add_sub_carry - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx11010 000xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - - __execute - bits(datasize) result; - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(4) nzcv; - - if sub_op then - operand2 = NOT(operand2); - - (result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - X[d] = result; - -__instruction LD1D_Z_P_BZ_D_x32_scaled - __encoding LD1D_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 1x1xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 3; - - __encoding LD1D_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 1x0xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 32; - boolean unsigned = TRUE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1D_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 111xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 3; - - __encoding LD1D_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 110xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - integer offs_size = 64; - boolean unsigned = TRUE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset = Z[m]; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_long - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_long - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 00x000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = Vpart[n, part]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - Elem[result, e, 2*esize] = sum[2*esize-1:0]; - - V[d] = result; - -__instruction LD1D_Z_P_BI_U64 - __encoding LD1D_Z_P_BI_U64 - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100101 1110xxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - boolean unsigned = TRUE; - integer offset = SInt(imm4); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * mbytes; - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - addr = addr + mbytes; - - Z[t] = result; - -__instruction aarch64_integer_arithmetic_add_sub_immediate - __encoding aarch64_integer_arithmetic_add_sub_immediate - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field S 29 +: 1 - __field sh 22 +: 1 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx10001 0xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - boolean setflags = (S == '1'); - bits(datasize) imm; - - case sh of - when '0' imm = ZeroExtend(imm12, datasize); - when '1' imm = ZeroExtend(imm12 : Zeros(12), datasize); - - __execute - bits(datasize) result; - bits(datasize) operand1 = if n == 31 then SP[] else X[n]; - bits(datasize) operand2 = imm; - bits(4) nzcv; - bit carry_in; - - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - else - carry_in = '0'; - - (result, nzcv) = AddWithCarry(operand1, operand2, carry_in); - - if setflags then - PSTATE.[N,Z,C,V] = nzcv; - - if d == 31 && !setflags then - SP[] = result; - else - X[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_fp_complex - __encoding aarch64_vector_arithmetic_binary_uniform_add_fp_complex - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field rot 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 xx0xxxxx 111x01xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFCADDExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size == '00' then UNDEFINED; - if Q == '0' && size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - if !HaveFP16Ext() && esize == 16 then UNDEFINED; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) operand3 = V[d]; - bits(datasize) result; - bits(esize) element1; - bits(esize) element3; - - for e = 0 to (elements DIV 2) -1 - case rot of - when '0' - element1 = FPNeg(Elem[operand2, e*2+1, esize]); - element3 = Elem[operand2, e*2, esize]; - when '1' - element1 = Elem[operand2, e*2+1, esize]; - element3 = FPNeg(Elem[operand2, e*2, esize]); - Elem[result, e*2, esize] = FPAdd(Elem[operand1, e*2, esize], element1, FPCR); - Elem[result, e*2+1, esize] = FPAdd(Elem[operand1, e*2+1, esize], element3, FPCR); - - V[d] = result; - -__instruction aarch64_integer_ins_ext_insert_movewide - __encoding aarch64_integer_ins_ext_insert_movewide - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field hw 21 +: 2 - __field imm16 5 +: 16 - __field Rd 0 +: 5 - __opcode 'xxx10010 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer datasize = if sf == '1' then 64 else 32; - bits(16) imm = imm16; - integer pos; - MoveWideOp opcode; - - case opc of - when '00' opcode = MoveWideOp_N; - when '10' opcode = MoveWideOp_Z; - when '11' opcode = MoveWideOp_K; - otherwise UNDEFINED; - - if sf == '0' && hw[1] == '1' then UNDEFINED; - pos = UInt(hw:'0000'); - - __execute - bits(datasize) result; - - if opcode == MoveWideOp_K then - result = X[d]; - else - result = Zeros(); - - result[pos+15:pos] = imm; - if opcode == MoveWideOp_N then - result = NOT(result); - X[d] = result; - -__instruction LD1SH_Z_P_BZ_S_x32_scaled - __encoding LD1SH_Z_P_BZ_S_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 1x1xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding LD1SH_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 1x1xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 1; - - __encoding LD1SH_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 1x0xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1SH_Z_P_BZ_S_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10000100 1x0xxxxx 000xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 32; - integer msize = 16; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LD1SH_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 111xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 1; - - __encoding LD1SH_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000100 110xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 16; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset = Z[m]; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction LSL_Z_ZW__ - __encoding LSL_Z_ZW__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx1xxxxx 100011xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(64) element2 = Elem[operand2, (e * esize) DIV 64, 64]; - integer shift = Min(UInt(element2), esize); - Elem[result, e, esize] = LSL(element1, shift); - - Z[d] = result; - -__instruction aarch64_vector_transfer_vector_permute_zip - __encoding aarch64_vector_transfer_vector_permute_zip - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx0xxxxx 0x1110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer part = UInt(op); - integer pairs = elements DIV 2; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer base = part * pairs; - - for p = 0 to pairs-1 - Elem[result, 2*p+0, esize] = Elem[operand1, base+p, esize]; - Elem[result, 2*p+1, esize] = Elem[operand2, base+p, esize]; - - V[d] = result; - -__instruction UQINCD_R_RS_UW - __encoding UQINCD_R_RS_UW - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1110xxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 32; - - __encoding UQINCD_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1111xxxx 111101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = TRUE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 + (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction CNT_Z_P_Z__ - __encoding CNT_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000100 xx011010 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = BitCount(element)[esize-1:0]; - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_add_fp16 - __encoding aarch64_vector_arithmetic_binary_uniform_add_fp16 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 010xxxxx 000101xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 16; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - - __encoding aarch64_vector_arithmetic_binary_uniform_add_fp - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x1xxxxx 110101xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean pair = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - bits(2*datasize) concat = operand2:operand1; - bits(esize) element1; - bits(esize) element2; - - for e = 0 to elements-1 - if pair then - element1 = Elem[concat, 2*e, esize]; - element2 = Elem[concat, (2*e)+1, esize]; - else - element1 = Elem[operand1, e, esize]; - element2 = Elem[operand2, e, esize]; - Elem[result, e, esize] = FPAdd(element1, element2, FPCR); - - V[d] = result; - -__instruction aarch64_memory_exclusive_single - __encoding aarch64_memory_exclusive_single - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 0x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '1' then AccType_ORDEREDATOMIC else AccType_ATOMIC; - boolean pair = FALSE; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = if pair then elsize * 2 else elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - boolean rt_unknown = FALSE; - boolean rn_unknown = FALSE; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if memop == MemOp_LOAD && pair && t == t2 then - Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE then - if s == t || (pair && s == t2) then - Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value - when Constraint_NONE rt_unknown = FALSE; // store original value - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - if s == n && n != 31 then - Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP); - assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN - when Constraint_NONE rn_unknown = FALSE; // address is original base - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - elsif rn_unknown then - address = bits(64) UNKNOWN; - else - address = X[n]; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - elsif pair then - bits(datasize DIV 2) el1 = X[t]; - bits(datasize DIV 2) el2 = X[t2]; - data = if BigEndian() then el1 : el2 else el2 : el1; - else - data = X[t]; - - bit status = '1'; - // Check whether the Exclusives monitors are set to include the - // physical memory locations corresponding to virtual address - // range [address, address+dbytes-1]. - if AArch64.ExclusiveMonitorsPass(address, dbytes) then - // This atomic write will be rejected if it does not refer - // to the same physical locations after address translation. - Mem[address, dbytes, acctype] = data; - status = ExclusiveMonitorsStatus(); - X[s] = ZeroExtend(status, 32); - - when MemOp_LOAD - // Tell the Exclusives monitors to record a sequence of one or more atomic - // memory reads from virtual address range [address, address+dbytes-1]. - // The Exclusives monitor will only be set if all the reads are from the - // same dbytes-aligned physical address, to allow for the possibility of - // an atomicity break if the translation is changed between reads. - AArch64.SetExclusiveMonitors(address, dbytes); - - if pair then - if rt_unknown then - // ConstrainedUNPREDICTABLE case - X[t] = bits(datasize) UNKNOWN; // In this case t = t2 - elsif elsize == 32 then - // 32-bit load exclusive pair (atomic) - data = Mem[address, dbytes, acctype]; - if BigEndian() then - X[t] = data[datasize-1:elsize]; - X[t2] = data[elsize-1:0]; - else - X[t] = data[elsize-1:0]; - X[t2] = data[datasize-1:elsize]; - else // elsize == 64 - // 64-bit load exclusive pair (not atomic), - // but must be 128-bit aligned - if address != Align(address, dbytes) then - iswrite = FALSE; - secondstage = FALSE; - AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage)); - X[t] = Mem[address + 0, 8, acctype]; - X[t2] = Mem[address + 8, 8, acctype]; - else - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_wide - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_wide - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 00x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand1 = V[n]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, 2*esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - Elem[result, e, 2*esize] = sum[2*esize-1:0]; - - V[d] = result; - -__instruction aarch64_integer_ins_ext_insert_movewide - __encoding aarch64_integer_ins_ext_insert_movewide - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field hw 21 +: 2 - __field imm16 5 +: 16 - __field Rd 0 +: 5 - __opcode 'xxx10010 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer datasize = if sf == '1' then 64 else 32; - bits(16) imm = imm16; - integer pos; - MoveWideOp opcode; - - case opc of - when '00' opcode = MoveWideOp_N; - when '10' opcode = MoveWideOp_Z; - when '11' opcode = MoveWideOp_K; - otherwise UNDEFINED; - - if sf == '0' && hw[1] == '1' then UNDEFINED; - pos = UInt(hw:'0000'); - - __execute - bits(datasize) result; - - if opcode == MoveWideOp_K then - result = X[d]; - else - result = Zeros(); - - result[pos+15:pos] = imm; - if opcode == MoveWideOp_N then - result = NOT(result); - X[d] = result; - -__instruction aarch64_memory_single_general_immediate_signed_post_idx - __encoding aarch64_memory_single_general_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction aarch64_vector_crypto_sha3op_sha1_hash_parity - __encoding aarch64_vector_crypto_sha3op_sha1_hash_parity - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 000xxxxx 000100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if !HaveSHA1Ext() then UNDEFINED; - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) X = V[d]; - bits(32) Y = V[n]; // Note: 32 not 128 bits wide - bits(128) W = V[m]; - bits(32) t; - - for e = 0 to 3 - t = SHAparity(X[63:32], X[95:64], X[127:96]); - Y = Y + ROL(X[31:0], 5) + t + Elem[W, e, 32]; - X[63:32] = ROL(X[63:32], 30); - [Y, X] = ROL(Y : X, 32); - V[d] = X; - -__instruction aarch64_vector_arithmetic_unary_special_recip_int - __encoding aarch64_vector_arithmetic_unary_special_recip_int - __instruction_set A64 - __field Q 30 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 1x100001 110010xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz == '1' then UNDEFINED; - integer esize = 32; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(32) element; - - for e = 0 to elements-1 - element = Elem[operand, e, 32]; - Elem[result, e, 32] = UnsignedRecipEstimate(element); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_element_mul_high_sisd - __encoding aarch64_vector_arithmetic_binary_element_mul_high_sisd - __instruction_set A64 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field op 12 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011111 xxxxxxxx 110xx0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - boolean round = (op == '1'); - - __encoding aarch64_vector_arithmetic_binary_element_mul_high_simd - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field L 21 +: 1 - __field M 20 +: 1 - __field Rm 16 +: 4 - __field op 12 +: 1 - __field H 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001111 xxxxxxxx 110xx0xx xxxxxxxx' - __guard TRUE - __decode - integer idxdsize = if H == '1' then 128 else 64; - integer index; - bit Rmhi; - case size of - when '01' index = UInt(H:L:M); Rmhi = '0'; - when '10' index = UInt(H:L); Rmhi = M; - otherwise UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rmhi:Rm); - - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - boolean round = (op == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(idxdsize) operand2 = V[m]; - bits(datasize) result; - integer round_const = if round then 1 << (esize - 1) else 0; - integer element1; - integer element2; - integer product; - boolean sat; - - element2 = SInt(Elem[operand2, index, esize]); - for e = 0 to elements-1 - element1 = SInt(Elem[operand1, e, esize]); - product = (2 * element1 * element2) + round_const; - // The following only saturates if element1 and element2 equal -(2^(esize-1)) - (Elem[result, e, esize], sat) = SignedSatQ(product >> esize, esize); - if sat then FPSR.QC = '1'; - - V[d] = result; - -__instruction INCP_Z_P_Z__ - __encoding INCP_Z_P_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Zdn 0 +: 5 - __opcode '00100101 xx101100 1000000x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Zdn); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) operand1 = Z[dn]; - bits(PL) operand2 = P[m]; - bits(VL) result; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - for e = 0 to elements-1 - Elem[result, e, esize] = Elem[operand1, e, esize] + count; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_binary_disparate_add_sub_wide - __encoding aarch64_vector_arithmetic_binary_disparate_add_sub_wide - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field o1 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 00x100xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size == '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = 64; - integer part = UInt(Q); - integer elements = datasize DIV esize; - - boolean sub_op = (o1 == '1'); - boolean unsigned = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(2*datasize) operand1 = V[n]; - bits(datasize) operand2 = Vpart[m, part]; - bits(2*datasize) result; - integer element1; - integer element2; - integer sum; - - for e = 0 to elements-1 - element1 = Int(Elem[operand1, e, 2*esize], unsigned); - element2 = Int(Elem[operand2, e, esize], unsigned); - if sub_op then - sum = element1 - element2; - else - sum = element1 + element2; - Elem[result, e, 2*esize] = sum[2*esize-1:0]; - - V[d] = result; - -__instruction ST4B_Z_P_BI_Contiguous - __encoding ST4B_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11100100 0111xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - integer nreg = 4; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..3] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - for r = 0 to nreg-1 - values[r] = Z[(t+r) MOD 32]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Mem[addr, mbytes, AccType_NORMAL] = Elem[values[r], e, esize]; - addr = addr + mbytes; - -__instruction aarch64_memory_atomicops_ld - __encoding aarch64_memory_atomicops_ld - __instruction_set A64 - __field size 30 +: 2 - __field A 23 +: 1 - __field R 22 +: 1 - __field Rs 16 +: 5 - __field opc 12 +: 3 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - - integer t = UInt(Rt); - integer n = UInt(Rn); - integer s = UInt(Rs); - - integer datasize = 8 << UInt(size); - integer regsize = if datasize == 64 then 64 else 32; - AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if R == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - MemAtomicOp op; - case opc of - when '000' op = MemAtomicOp_ADD; - when '001' op = MemAtomicOp_BIC; - when '010' op = MemAtomicOp_EOR; - when '011' op = MemAtomicOp_ORR; - when '100' op = MemAtomicOp_SMAX; - when '101' op = MemAtomicOp_SMIN; - when '110' op = MemAtomicOp_UMAX; - when '111' op = MemAtomicOp_UMIN; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) value; - bits(datasize) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - value = X[s]; - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomic(address, op, value, ldacctype, stacctype); - - if t != 31 then - X[t] = ZeroExtend(data, regsize); - -__instruction aarch64_vector_arithmetic_binary_uniform_shift_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - if S == '0' && size != '11' then UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer round_const = 0; - integer shift; - integer element; - boolean sat; - - for e = 0 to elements-1 - shift = SInt(Elem[operand2, e, esize][7:0]); - if rounding then - round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift - element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift; - if saturating then - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - else - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction FCADD_Z_P_ZZ__ - __encoding FCADD_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field rot 16 +: 1 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100100 xx00000x 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean sub_i = (rot == '0'); - boolean sub_r = (rot == '1'); - - __execute - CheckSVEEnabled(); - integer pairs = VL DIV (2 * esize); - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for p = 0 to pairs-1 - acc_r = Elem[operand1, 2 * p + 0, esize]; - acc_i = Elem[operand1, 2 * p + 1, esize]; - elt2_r = Elem[operand2, 2 * p + 0, esize]; - elt2_i = Elem[operand2, 2 * p + 1, esize]; - if ElemP[mask, 2 * p + 0, esize] == '1' then - if sub_i then elt2_i = FPNeg(elt2_i); - acc_r = FPAdd(acc_r, elt2_i, FPCR); - if ElemP[mask, 2 * p + 1, esize] == '1' then - if sub_r then elt2_r = FPNeg(elt2_r); - acc_i = FPAdd(acc_i, elt2_r, FPCR); - Elem[result, 2 * p + 0, esize] = acc_r; - Elem[result, 2 * p + 1, esize] = acc_i; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_unary_not - __encoding aarch64_vector_arithmetic_unary_not - __instruction_set A64 - __field Q 30 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x101110 00100000 010110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 8; - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 8; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = NOT(element); - - V[d] = result; - -__instruction aarch64_memory_literal_general - __encoding aarch64_memory_literal_general - __instruction_set A64 - __field opc 30 +: 2 - __field imm19 5 +: 19 - __field Rt 0 +: 5 - __opcode 'xx011000 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - MemOp memop = MemOp_LOAD; - boolean signed = FALSE; - integer size; - bits(64) offset; - - case opc of - when '00' - size = 4; - when '01' - size = 8; - when '10' - size = 4; - signed = TRUE; - when '11' - memop = MemOp_PREFETCH; - - offset = SignExtend(imm19:'00', 64); - boolean tag_checked = FALSE; - - __execute - bits(64) address = PC[] + offset; - bits(size*8) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - case memop of - when MemOp_LOAD - data = Mem[address, size, AccType_NORMAL]; - if signed then - X[t] = SignExtend(data, 64); - else - X[t] = data; - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - -__instruction INCD_Z_ZS__ - __encoding INCD_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1111xxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding INCH_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 0111xxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding INCW_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1011xxxx 110000xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - Elem[result, e, esize] = Elem[operand1, e, esize] + (count * imm); - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean test_passed; - - for e = 0 to elements-1 - element = SInt(Elem[operand, e, esize]); - case comparison of - when CompareOp_GT test_passed = element > 0; - when CompareOp_GE test_passed = element >= 0; - when CompareOp_EQ test_passed = element == 0; - when CompareOp_LE test_passed = element <= 0; - when CompareOp_LT test_passed = element < 0; - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction WHILELT_P_P_RR__ - __encoding WHILELT_P_P_RR__ - __instruction_set A64 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field sf 12 +: 1 - __field Rn 5 +: 5 - __field Pd 0 +: 4 - __opcode '00100101 xx1xxxxx 000x01xx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer rsize = 32 << UInt(sf); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Pd); - boolean unsigned = FALSE; - SVECmp op = Cmp_LT; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = Ones(PL); - bits(rsize) operand1 = X[n]; - bits(rsize) operand2 = X[m]; - bits(PL) result; - boolean last = TRUE; - - for e = 0 to elements-1 - boolean cond; - case op of - when Cmp_LT cond = (Int(operand1, unsigned) < Int(operand2, unsigned)); - when Cmp_LE cond = (Int(operand1, unsigned) <= Int(operand2, unsigned)); - - last = last && cond; - ElemP[result, e, esize] = if last then '1' else '0'; - operand1 = operand1 + 1; - - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction INSR_Z_R__ - __encoding INSR_Z_R__ - __instruction_set A64 - __field size 22 +: 2 - __field Rm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000101 xx100100 001110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer dn = UInt(Zdn); - integer m = UInt(Rm); - - __execute - CheckSVEEnabled(); - bits(VL) dest = Z[dn]; - bits(esize) src = X[m]; - Z[dn] = dest[VL-esize-1:0] : src; - -__instruction SQINCW_R_RS_SX - __encoding SQINCW_R_RS_SX - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1010xxxx 111100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQINCW_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1011xxxx 111100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 + (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction DECP_R_P_R__ - __encoding DECP_R_P_R__ - __instruction_set A64 - __field size 22 +: 2 - __field Pm 5 +: 4 - __field Rdn 0 +: 5 - __opcode '00100101 xx101101 1000100x xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer m = UInt(Pm); - integer dn = UInt(Rdn); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) operand1 = X[dn]; - bits(PL) operand2 = P[m]; - integer count = 0; - - for e = 0 to elements-1 - if ElemP[operand2, e, esize] == '1' then - count = count + 1; - - X[dn] = operand1 - count; - -__instruction aarch64_memory_atomicops_cas_pair - __encoding aarch64_memory_atomicops_cas_pair - __instruction_set A64 - __field sz 30 +: 1 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001000 0x1xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveAtomicExt() then UNDEFINED; - if Rs[0] == '1' then UNDEFINED; - if Rt[0] == '1' then UNDEFINED; - - integer n = UInt(Rn); - integer t = UInt(Rt); - integer s = UInt(Rs); - - integer datasize = 32 << UInt(sz); - integer regsize = datasize; - AccType ldacctype = if L == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - AccType stacctype = if o0 == '1' then AccType_ORDEREDATOMICRW else AccType_ATOMICRW; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(2*datasize) comparevalue; - bits(2*datasize) newvalue; - bits(2*datasize) data; - - bits(datasize) s1 = X[s]; - bits(datasize) s2 = X[s+1]; - bits(datasize) t1 = X[t]; - bits(datasize) t2 = X[t+1]; - comparevalue = if BigEndian() then s1:s2 else s2:s1; - newvalue = if BigEndian() then t1:t2 else t2:t1; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - data = MemAtomicCompareAndSwap(address, comparevalue, newvalue, ldacctype, stacctype); - - if BigEndian() then - X[s] = ZeroExtend(data[2*datasize-1:datasize], regsize); - X[s+1] = ZeroExtend(data[datasize-1:0], regsize); - else - X[s] = ZeroExtend(data[datasize-1:0], regsize); - X[s+1] = ZeroExtend(data[2*datasize-1:datasize], regsize); - -__instruction aarch64_float_arithmetic_round_frint - __encoding aarch64_float_arithmetic_round_frint - __instruction_set A64 - __field ftype 22 +: 2 - __field rmode 15 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '00011110 xx1001xx x10000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize; - case ftype of - when '00' datasize = 32; - when '01' datasize = 64; - when '10' UNDEFINED; - when '11' - if HaveFP16Ext() then - datasize = 16; - else - UNDEFINED; - - boolean exact = FALSE; - FPRounding rounding; - case rmode of - when '0xx' rounding = FPDecodeRounding(rmode[1:0]); - when '100' rounding = FPRounding_TIEAWAY; - when '101' UNDEFINED; - when '110' rounding = FPRoundingMode(FPCR); exact = TRUE; - when '111' rounding = FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(datasize) result; - bits(datasize) operand = V[n]; - - result = FPRoundInt(operand, FPCR, rounding, exact); - - V[d] = result; - -__instruction aarch64_memory_single_general_register - __encoding aarch64_memory_single_general_register - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field Rm 16 +: 5 - __field option 13 +: 3 - __field S 12 +: 1 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx1xxxxx xxxx10xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - if option[1] == '0' then UNDEFINED; // sub-word index - ExtendType extend_type = DecodeRegExtend(option); - integer shift = if S == '1' then scale else 0; - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer m = UInt(Rm); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH; - __execute - bits(64) offset = ExtendReg(m, extend_type, shift); - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction BFCVTNT_Z_P_Z_S2BF - __encoding BFCVTNT_Z_P_Z_S2BF - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100100 10001010 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() || !HaveBF16Ext() then UNDEFINED; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV 32; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(32) element = Elem[operand, e, 32]; - if ElemP[mask, e, 32] == '1' then - Elem[result, 2*e+1, 16] = FPConvertBF(element, FPCR); - - Z[d] = result; - -__instruction ORN_P_P_PP_Z - __encoding ORN_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 1000xxxx 01xxxx0x xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = FALSE; - - __encoding ORNS_P_P_PP_Z - __instruction_set A64 - __field Pm 16 +: 4 - __field Pg 10 +: 4 - __field Pn 5 +: 4 - __field Pd 0 +: 4 - __opcode '00100101 1100xxxx 01xxxx0x xxx1xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8; - integer g = UInt(Pg); - integer n = UInt(Pn); - integer m = UInt(Pm); - integer d = UInt(Pd); - boolean setflags = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(PL) operand1 = P[n]; - bits(PL) operand2 = P[m]; - bits(PL) result; - - for e = 0 to elements-1 - bit element1 = ElemP[operand1, e, esize]; - bit element2 = ElemP[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - ElemP[result, e, esize] = element1 OR (NOT element2); - else - ElemP[result, e, esize] = '0'; - - if setflags then - PSTATE.[N,Z,C,V] = PredTest(mask, result, esize); - P[d] = result; - -__instruction MAD_Z_P_ZZZ__ - __encoding MAD_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Za 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 xx0xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - integer a = UInt(Za); - boolean sub_op = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[a]; - bits(VL) result; - - for e = 0 to elements-1 - integer element1 = UInt(Elem[operand1, e, esize]); - integer element2 = UInt(Elem[operand2, e, esize]); - if ElemP[mask, e, esize] == '1' then - integer product = element1 * element2; - if sub_op then - Elem[result, e, esize] = Elem[operand3, e, esize] - product; - else - Elem[result, e, esize] = Elem[operand3, e, esize] + product; - else - Elem[result, e, esize] = Elem[operand1, e, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_transfer_vector_table - __encoding aarch64_vector_transfer_vector_table - __instruction_set A64 - __field Q 30 +: 1 - __field Rm 16 +: 5 - __field len 13 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 000xxxxx 0xxx00xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV 8; - integer regs = UInt(len) + 1; - boolean is_tbl = (op == '0'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) indices = V[m]; - bits(128*regs) table = Zeros(); - bits(datasize) result; - integer index; - - // Create table from registers - for i = 0 to regs - 1 - table[128*i+127:128*i] = V[n]; - n = (n + 1) MOD 32; - - result = if is_tbl then Zeros() else V[d]; - for i = 0 to elements - 1 - index = UInt(Elem[indices, i, 8]); - if index < 16 * regs then - Elem[result, i, 8] = Elem[table, index, 8]; - - V[d] = result; - -__instruction aarch64_float_convert_int - __encoding aarch64_float_convert_int - __instruction_set A64 - __field sf 31 +: 1 - __field ftype 22 +: 2 - __field rmode 19 +: 2 - __field opcode 16 +: 3 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011110 xx1xxxxx 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer intsize = if sf == '1' then 64 else 32; - integer fltsize; - FPConvOp op; - FPRounding rounding; - boolean unsigned; - integer part; - - case ftype of - when '00' - fltsize = 32; - when '01' - fltsize = 64; - when '10' - if opcode[2:1]:rmode != '11 01' then UNDEFINED; - fltsize = 128; - when '11' - if HaveFP16Ext() then - fltsize = 16; - else - UNDEFINED; - - case opcode[2:1]:rmode of - when '00 xx' // FCVT[NPMZ][US] - rounding = FPDecodeRounding(rmode); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '01 00' // [US]CVTF - rounding = FPRoundingMode(FPCR); - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_ItoF; - when '10 00' // FCVTA[US] - rounding = FPRounding_TIEAWAY; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI; - when '11 00' // FMOV - if fltsize != 16 && fltsize != intsize then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 0; - when '11 01' // FMOV D[1] - if intsize != 64 || fltsize != 128 then UNDEFINED; - op = if opcode[0] == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI; - part = 1; - fltsize = 64; // size of D[1] is 64 - when '11 11' // FJCVTZS - if !HaveFJCVTZSExt() then UNDEFINED; - rounding = FPRounding_ZERO; - unsigned = (opcode[0] == '1'); - op = FPConvOp_CVT_FtoI_JS; - otherwise - UNDEFINED; - - __execute - CheckFPAdvSIMDEnabled64(); - - bits(fltsize) fltval; - bits(intsize) intval; - - case op of - when FPConvOp_CVT_FtoI - fltval = V[n]; - intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding); - X[d] = intval; - when FPConvOp_CVT_ItoF - intval = X[n]; - fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding); - V[d] = fltval; - when FPConvOp_MOV_FtoI - fltval = Vpart[n,part]; - intval = ZeroExtend(fltval, intsize); - X[d] = intval; - when FPConvOp_MOV_ItoF - intval = X[n]; - fltval = intval[fltsize-1:0]; - Vpart[d,part] = fltval; - when FPConvOp_CVT_FtoI_JS - bit Z; - fltval = V[n]; - (intval, Z) = FPToFixedJS(fltval, FPCR, TRUE); - PSTATE.[N,Z,C,V] = '0':Z:'00'; - X[d] = intval; - -__instruction aarch64_memory_single_general_immediate_signed_offset_lda_stl - __encoding aarch64_memory_single_general_immediate_signed_offset_lda_stl - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx011001 xx0xxxxx xxxx00xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_ORDERED; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - memop = MemOp_PREFETCH; - if opc[0] == '1' then UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction LD2B_Z_P_BI_Contiguous - __encoding LD2B_Z_P_BI_Contiguous - __instruction_set A64 - __field imm4 16 +: 4 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 0010xxxx 111xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer g = UInt(Pg); - integer esize = 8; - integer offset = SInt(imm4); - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if n == 31 then - CheckSPAlignment(); - if HaveMTEExt() then SetTagCheckedInstruction(FALSE); - base = SP[]; - else - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - base = X[n]; - - addr = base + offset * elements * nreg * mbytes; - for e = 0 to elements-1 - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction CLASTB_Z_P_ZZ__ - __encoding CLASTB_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000101 xx101001 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - boolean isBefore = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - integer last = LastActiveElement(mask, esize); - - if last < 0 then - result = operand1; - else - if !isBefore then - last = last + 1; - if last >= elements then last = 0; - for e = 0 to elements-1 - Elem[result, e, esize] = Elem[operand2, last, esize]; - - Z[dn] = result; - -__instruction aarch64_vector_crypto_sm3_sm3partw2 - __encoding aarch64_vector_crypto_sm3_sm3partw2 - __instruction_set A64 - __field Rm 16 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 011xxxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSM3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) Vd = V[d]; - bits(128) result; - bits(128) tmp; - bits(32) tmp2; - tmp[127:0] = Vn EOR (ROL(Vm[127:96],7):ROL(Vm[95:64],7):ROL(Vm[63:32],7):ROL(Vm[31:0],7)); - result[127:0] = Vd[127:0] EOR tmp[127:0]; - tmp2 = ROL(tmp[31:0],15); - tmp2 = tmp2 EOR ROL(tmp2,15) EOR ROL(tmp2,23); - result[127:96] = result[127:96] EOR tmp2; - V[d]= result; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction SQINCD_R_RS_SX - __encoding SQINCD_R_RS_SX - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1110xxxx 111100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 32; - - __encoding SQINCD_R_RS_X - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Rdn 0 +: 5 - __opcode '00000100 1111xxxx 111100xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Rdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - boolean unsigned = FALSE; - integer ssize = 64; - - __execute - CheckSVEEnabled(); - integer count = DecodePredCount(pat, esize); - bits(ssize) operand1 = X[dn]; - bits(ssize) result; - - integer element1 = Int(operand1, unsigned); - (result, -) = SatQ(element1 + (count * imm), ssize, unsigned); - X[dn] = Extend(result, 64, unsigned); - -__instruction aarch64_vector_crypto_sha3_xar - __encoding aarch64_vector_crypto_sha3_xar - __instruction_set A64 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11001110 100xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSHA3Ext() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) Vm = V[m]; - bits(128) Vn = V[n]; - bits(128) tmp; - tmp = Vn EOR Vm; - V[d] = ROR(tmp[127:64], UInt(imm6)):ROR(tmp[63:0], UInt(imm6)); - -__instruction REVB_Z_Z__ - __encoding REVB_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx100100 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer swsize = 8; - - __encoding REVH_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx100101 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size != '1x' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer swsize = 16; - - __encoding REVW_Z_Z__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '00000101 xx100110 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer swsize = 32; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - bits(esize) element = Elem[operand, e, esize]; - Elem[result, e, esize] = Reverse(element, swsize); - - Z[d] = result; - -__instruction LD1D_Z_P_AI_D - __encoding LD1D_Z_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 101xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Zn); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 64; - boolean unsigned = TRUE; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(VL) base = Z[n]; - bits(64) addr; - bits(PL) mask = P[g]; - bits(VL) result; - bits(msize) data; - constant integer mbytes = msize DIV 8; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + offset * mbytes; - data = Mem[addr, mbytes, AccType_NORMAL]; - Elem[result, e, esize] = Extend(data, esize, unsigned); - else - Elem[result, e, esize] = Zeros(); - - Z[t] = result; - -__instruction aarch64_memory_ordered - __encoding aarch64_memory_ordered - __instruction_set A64 - __field size 30 +: 2 - __field L 22 +: 1 - __field Rs 16 +: 5 - __field o0 15 +: 1 - __field Rt2 10 +: 5 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx001000 1x0xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer t = UInt(Rt); - integer t2 = UInt(Rt2); // ignored by load/store single register - integer s = UInt(Rs); // ignored by all loads and store-release - - AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED; - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer elsize = 8 << UInt(size); - integer regsize = if elsize == 64 then 64 else 32; - integer datasize = elsize; - boolean tag_checked = n != 31; - - __execute - bits(64) address; - bits(datasize) data; - constant integer dbytes = datasize DIV 8; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - case memop of - when MemOp_STORE - data = X[t]; - Mem[address, dbytes, acctype] = data; - - when MemOp_LOAD - data = Mem[address, dbytes, acctype]; - X[t] = ZeroExtend(data, regsize); - -__instruction FMINNM_Z_P_ZZ__ - __encoding FMINNM_Z_P_ZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx000101 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - if ElemP[mask, e, esize] == '1' then - Elem[result, e, esize] = FPMinNum(element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction aarch64_integer_conditional_compare_register - __encoding aarch64_integer_conditional_compare_register - __instruction_set A64 - __field sf 31 +: 1 - __field op 30 +: 1 - __field Rm 16 +: 5 - __field cond 12 +: 4 - __field Rn 5 +: 5 - __field nzcv 0 +: 4 - __opcode 'xx111010 010xxxxx xxxx00xx xxx0xxxx' - __guard TRUE - __decode - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean sub_op = (op == '1'); - bits(4) condition = cond; - bits(4) flags = nzcv; - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bit carry_in = '0'; - - if ConditionHolds(condition) then - if sub_op then - operand2 = NOT(operand2); - carry_in = '1'; - (-, flags) = AddWithCarry(operand1, operand2, carry_in); - PSTATE.[N,Z,C,V] = flags; - -__instruction aarch64_vector_reduce_fp16_max_sisd - __encoding aarch64_vector_reduce_fp16_max_sisd - __instruction_set A64 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01011110 xx110000 111110xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFP16Ext() then UNDEFINED; - - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 16; - if sz == '1' then UNDEFINED; - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX; - - __encoding aarch64_vector_reduce_fp_max_sisd - __instruction_set A64 - __field o1 23 +: 1 - __field sz 22 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01111110 xx110000 111110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer esize = 32 << UInt(sz); - integer datasize = esize * 2; - integer elements = 2; - - ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - V[d] = Reduce(op, operand, esize); - -__instruction FMAD_Z_P_ZZZ__ - __encoding FMAD_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Za 16 +: 5 - __field Pg 10 +: 3 - __field Zm 5 +: 5 - __field Zdn 0 +: 5 - __opcode '01100101 xx1xxxxx 100xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer dn = UInt(Zdn); - integer m = UInt(Zm); - integer a = UInt(Za); - boolean op1_neg = FALSE; - boolean op3_neg = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[dn]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[a]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - bits(esize) element3 = Elem[operand3, e, esize]; - - if ElemP[mask, e, esize] == '1' then - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - else - Elem[result, e, esize] = element1; - - Z[dn] = result; - -__instruction aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd - __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __encoding aarch64_vector_arithmetic_unary_cmp_int_bulk_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 100x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - - CompareOp comparison; - case op:U of - when '00' comparison = CompareOp_GT; - when '01' comparison = CompareOp_GE; - when '10' comparison = CompareOp_EQ; - when '11' comparison = CompareOp_LE; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - boolean test_passed; - - for e = 0 to elements-1 - element = SInt(Elem[operand, e, esize]); - case comparison of - when CompareOp_GT test_passed = element > 0; - when CompareOp_GE test_passed = element >= 0; - when CompareOp_EQ test_passed = element == 0; - when CompareOp_LE test_passed = element <= 0; - when CompareOp_LT test_passed = element < 0; - Elem[result, e, esize] = if test_passed then Ones() else Zeros(); - - V[d] = result; - -__instruction aarch64_vector_transfer_vector_permute_zip - __encoding aarch64_vector_transfer_vector_permute_zip - __instruction_set A64 - __field Q 30 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field op 14 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0x001110 xx0xxxxx 0x1110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer part = UInt(op); - integer pairs = elements DIV 2; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer base = part * pairs; - - for p = 0 to pairs-1 - Elem[result, 2*p+0, esize] = Elem[operand1, base+p, esize]; - Elem[result, 2*p+1, esize] = Elem[operand2, base+p, esize]; - - V[d] = result; - -__instruction aarch64_integer_arithmetic_mul_widening_32_64 - __encoding aarch64_integer_arithmetic_mul_widening_32_64 - __instruction_set A64 - __field U 23 +: 1 - __field Rm 16 +: 5 - __field o0 15 +: 1 - __field Ra 10 +: 5 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '10011011 x01xxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer a = UInt(Ra); - integer destsize = 64; - integer datasize = 32; - boolean sub_op = (o0 == '1'); - boolean unsigned = (U == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = X[m]; - bits(destsize) operand3 = X[a]; - - integer result; - - if sub_op then - result = Int(operand3, unsigned) - (Int(operand1, unsigned) * Int(operand2, unsigned)); - else - result = Int(operand3, unsigned) + (Int(operand1, unsigned) * Int(operand2, unsigned)); - - X[d] = result[63:0]; - -__instruction aarch64_system_monitors - __encoding aarch64_system_monitors - __instruction_set A64 - __field CRm 8 +: 4 - __opcode '11010101 00000011 0011xxxx 01011111' - __guard TRUE - __decode - // CRm field is ignored - - __execute - ClearExclusiveLocal(ProcessorID()); - -__instruction PRFB_I_P_AI_S - __encoding PRFB_I_P_AI_S - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - __opcode '10000100 000xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 0; - integer offset = UInt(imm5); - - __encoding PRFB_I_P_AI_D - __instruction_set A64 - __field imm5 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field prfop 0 +: 4 - __opcode '11000100 000xxxxx 111xxxxx xxx0xxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer level = UInt(prfop[2:1]); - boolean stream = (prfop[0] == '1'); - pref_hint = if prfop[3] == '0' then Prefetch_READ else Prefetch_WRITE; - integer scale = 0; - integer offset = UInt(imm5); - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) base; - bits(64) addr; - base = Z[n]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - addr = ZeroExtend(Elem[base, e, esize], 64) + (offset << scale); - Hint_Prefetch(addr, pref_hint, level, stream); - -__instruction LDFF1SW_Z_P_BZ_D_x32_scaled - __encoding LDFF1SW_Z_P_BZ_D_x32_scaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 0x1xxxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 2; - - __encoding LDFF1SW_Z_P_BZ_D_x32_unscaled - __instruction_set A64 - __field xs 22 +: 1 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 0x0xxxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 32; - boolean unsigned = FALSE; - boolean offs_unsigned = xs == '0'; - integer scale = 0; - - __encoding LDFF1SW_Z_P_BZ_D_64_scaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 011xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 2; - - __encoding LDFF1SW_Z_P_BZ_D_64_unscaled - __instruction_set A64 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '11000101 010xxxxx 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Zm); - integer g = UInt(Pg); - integer esize = 64; - integer msize = 32; - integer offs_size = 64; - boolean unsigned = FALSE; - boolean offs_unsigned = TRUE; - integer scale = 0; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(VL) offset; - bits(PL) mask = P[g]; - bits(VL) result; - bits(VL) orig = Z[t]; - bits(msize) data; - constant integer mbytes = msize DIV 8; - boolean first = TRUE; - boolean fault = FALSE; - boolean faulted = FALSE; - boolean unknown = FALSE; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - offset = Z[m]; - - for e = 0 to elements-1 - if ElemP[mask, e, esize] == '1' then - integer off = Int(Elem[offset, e, esize][offs_size-1:0], offs_unsigned); - addr = base + (off << scale); - if first then - // Mem[] will not return if a fault is detected for the first active element - data = Mem[addr, mbytes, AccType_NORMAL]; - first = FALSE; - else - // MemNF[] will return fault=TRUE if access is not performed for any reason - (data, fault) = MemNF[addr, mbytes, AccType_NONFAULT]; - else - (data, fault) = (Zeros(msize), FALSE); - - // FFR elements set to FALSE following a supressed access/fault - faulted = faulted || fault; - if faulted then - ElemFFR[e, esize] = '0'; - - // Value becomes CONSTRAINED UNPREDICTABLE after an FFR element is FALSE - unknown = unknown || ElemFFR[e, esize] == '0'; - if unknown then - if !fault && ConstrainUnpredictableBool(Unpredictable_SVELDNFDATA) then - Elem[result, e, esize] = Extend(data, esize, unsigned); - elsif ConstrainUnpredictableBool(Unpredictable_SVELDNFZERO) then - Elem[result, e, esize] = Zeros(); - else // merge - Elem[result, e, esize] = Elem[orig, e, esize]; - else - Elem[result, e, esize] = Extend(data, esize, unsigned); - - Z[t] = result; - -__instruction aarch64_integer_arithmetic_rbit - __encoding aarch64_integer_arithmetic_rbit - __instruction_set A64 - __field sf 31 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x1011010 11000000 000000xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer datasize = if sf == '1' then 64 else 32; - - __execute - bits(datasize) operand = X[n]; - bits(datasize) result; - - for i = 0 to datasize-1 - result[datasize-1-i] = operand[i]; - - X[d] = result; - -__instruction aarch64_integer_pac_pacib_dp_1src - __encoding aarch64_integer_pac_pacib_dp_1src - __instruction_set A64 - __field Z 13 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '11011010 11000001 00x001xx xxxxxxxx' - __guard TRUE - __decode - boolean source_is_sp = FALSE; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if !HavePACExt() then - UNDEFINED; - - if Z == '0' then // PACIB - if n == 31 then source_is_sp = TRUE; - else // PACIZB - if n != 31 then UNDEFINED; - - __encoding aarch64_integer_pac_pacib_hint - __instruction_set A64 - __field CRm 8 +: 4 - __field op2 5 +: 3 - __opcode '11010101 00000011 0010xxxx xxx11111' - __guard TRUE - __decode - integer d; - integer n; - boolean source_is_sp = FALSE; - - case CRm:op2 of - when '0011 010' // PACIBZ - d = 30; - n = 31; - when '0011 011' // PACIBSP - d = 30; - source_is_sp = TRUE; - if HaveBTIExt() then - // Check for branch target compatibility between PSTATE.BTYPE - // and implicit branch target of PACIBSP instruction. - SetBTypeCompatible(BTypeCompatible_PACIXSP()); - when '0001 010' // PACIB1716 - d = 17; - n = 16; - when '0001 000' SEE "PACIA"; - when '0001 100' SEE "AUTIA"; - when '0001 110' SEE "AUTIB"; - when '0011 00x' SEE "PACIA"; - when '0011 10x' SEE "AUTIA"; - when '0011 11x' SEE "AUTIB"; - when '0000 111' SEE "XPACLRI"; - otherwise SEE "HINT"; - - __execute - if HavePACExt() then - if source_is_sp then - X[d] = AddPACIB(X[d], SP[]); - else - X[d] = AddPACIB(X[d], X[n]); - -__instruction FCVTZS_Z_P_Z_FP162H - __encoding FCVTZS_Z_P_Z_FP162H - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01011010 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 16; - boolean unsigned = FALSE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZS_Z_P_Z_FP162W - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01011100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 32; - boolean unsigned = FALSE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZS_Z_P_Z_FP162X - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 01011110 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 16; - integer d_esize = 64; - boolean unsigned = FALSE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZS_Z_P_Z_S2W - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 10011100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 32; - boolean unsigned = FALSE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZS_Z_P_Z_S2X - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11011100 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 32; - integer d_esize = 64; - boolean unsigned = FALSE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZS_Z_P_Z_D2W - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11011000 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 32; - boolean unsigned = FALSE; - FPRounding rounding = FPRounding_ZERO; - - __encoding FCVTZS_Z_P_Z_D2X - __instruction_set A64 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zd 0 +: 5 - __opcode '01100101 11011110 101xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer g = UInt(Pg); - integer n = UInt(Zn); - integer d = UInt(Zd); - integer s_esize = 64; - integer d_esize = 64; - boolean unsigned = FALSE; - FPRounding rounding = FPRounding_ZERO; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand = Z[n]; - bits(VL) result = Z[d]; - - for e = 0 to elements-1 - bits(esize) element = Elem[operand, e, esize]; - if ElemP[mask, e, esize] == '1' then - bits(d_esize) res = FPToFixed(element[s_esize-1:0], 0, unsigned, FPCR, rounding); - Elem[result, e, esize] = Extend(res, unsigned); - - Z[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_shift_sisd - __encoding aarch64_vector_arithmetic_binary_uniform_shift_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - if S == '0' && size != '11' then UNDEFINED; - - __encoding aarch64_vector_arithmetic_binary_uniform_shift_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rm 16 +: 5 - __field R 12 +: 1 - __field S 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx1xxxxx 010xx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean unsigned = (U == '1'); - boolean rounding = (R == '1'); - boolean saturating = (S == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand1 = V[n]; - bits(datasize) operand2 = V[m]; - bits(datasize) result; - - integer round_const = 0; - integer shift; - integer element; - boolean sat; - - for e = 0 to elements-1 - shift = SInt(Elem[operand2, e, esize][7:0]); - if rounding then - round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift - element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift; - if saturating then - (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned); - if sat then FPSR.QC = '1'; - else - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction LD2B_Z_P_BR_Contiguous - __encoding LD2B_Z_P_BR_Contiguous - __instruction_set A64 - __field Rm 16 +: 5 - __field Pg 10 +: 3 - __field Rn 5 +: 5 - __field Zt 0 +: 5 - __opcode '10100100 001xxxxx 110xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if Rm == '11111' then UNDEFINED; - integer t = UInt(Zt); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer g = UInt(Pg); - integer esize = 8; - integer nreg = 2; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(64) base; - bits(64) addr; - bits(PL) mask = P[g]; - bits(64) offset = X[m]; - constant integer mbytes = esize DIV 8; - array [0..1] of bits(VL) values; - - if HaveMTEExt() then SetTagCheckedInstruction(TRUE); - - if n == 31 then - CheckSPAlignment(); - base = SP[]; - else - base = X[n]; - - for e = 0 to elements-1 - addr = base + UInt(offset) * mbytes; - for r = 0 to nreg-1 - if ElemP[mask, e, esize] == '1' then - Elem[values[r], e, esize] = Mem[addr, mbytes, AccType_NORMAL]; - else - Elem[values[r], e, esize] = Zeros(); - addr = addr + mbytes; - offset = offset + nreg; - - for r = 0 to nreg-1 - Z[(t+r) MOD 32] = values[r]; - -__instruction aarch64_vector_transfer_vector_insert - __encoding aarch64_vector_transfer_vector_insert - __instruction_set A64 - __field imm5 16 +: 5 - __field imm4 11 +: 4 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01101110 000xxxxx 0xxxx1xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - integer size = LowestSetBit(imm5); - if size > 3 then UNDEFINED; - - integer dst_index = UInt(imm5[4:size+1]); - integer src_index = UInt(imm4[3:size]); - integer idxdsize = if imm4[3] == '1' then 128 else 64; - // imm4[size-1:0] is IGNORED - - integer esize = 8 << size; - - __execute - CheckFPAdvSIMDEnabled64(); - bits(idxdsize) operand = V[n]; - bits(128) result; - - result = V[d]; - Elem[result, dst_index, esize] = Elem[operand, src_index, esize]; - V[d] = result; - -__instruction aarch64_vector_logical - __encoding aarch64_vector_logical - __instruction_set A64 - __field Q 30 +: 1 - __field op 29 +: 1 - __field a 18 +: 1 - __field b 17 +: 1 - __field c 16 +: 1 - __field cmode 12 +: 4 - __field d 9 +: 1 - __field e 8 +: 1 - __field f 7 +: 1 - __field g 6 +: 1 - __field h 5 +: 1 - __field Rd 0 +: 5 - __opcode '0xx01111 00000xxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - integer rd = UInt(Rd); - - integer datasize = if Q == '1' then 128 else 64; - bits(datasize) imm; - bits(64) imm64; - - ImmediateOp operation; - case cmode:op of - when '0xx00' operation = ImmediateOp_MOVI; - when '0xx01' operation = ImmediateOp_MVNI; - when '0xx10' operation = ImmediateOp_ORR; - when '0xx11' operation = ImmediateOp_BIC; - when '10x00' operation = ImmediateOp_MOVI; - when '10x01' operation = ImmediateOp_MVNI; - when '10x10' operation = ImmediateOp_ORR; - when '10x11' operation = ImmediateOp_BIC; - when '110x0' operation = ImmediateOp_MOVI; - when '110x1' operation = ImmediateOp_MVNI; - when '1110x' operation = ImmediateOp_MOVI; - when '11110' operation = ImmediateOp_MOVI; - when '11111' - // FMOV Dn,#imm is in main FP instruction set - if Q == '0' then UNDEFINED; - operation = ImmediateOp_MOVI; - - imm64 = AdvSIMDExpandImm(op, cmode, a:b:c:d:e:f:g:h); - imm = Replicate(imm64, datasize DIV 64); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand; - bits(datasize) result; - - case operation of - when ImmediateOp_MOVI - result = imm; - when ImmediateOp_MVNI - result = NOT(imm); - when ImmediateOp_ORR - operand = V[rd]; - result = operand OR imm; - when ImmediateOp_BIC - operand = V[rd]; - result = operand AND NOT(imm); - - V[rd] = result; - -__instruction DECD_Z_ZS__ - __encoding DECD_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1111xxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 64; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding DECH_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 0111xxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 16; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __encoding DECW_Z_ZS__ - __instruction_set A64 - __field imm4 16 +: 4 - __field pattern 5 +: 5 - __field Zdn 0 +: 5 - __opcode '00000100 1011xxxx 110001xx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - integer esize = 32; - integer dn = UInt(Zdn); - bits(5) pat = pattern; - integer imm = UInt(imm4) + 1; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - integer count = DecodePredCount(pat, esize); - bits(VL) operand1 = Z[dn]; - bits(VL) result; - - for e = 0 to elements-1 - Elem[result, e, esize] = Elem[operand1, e, esize] - (count * imm); - - Z[dn] = result; - -__instruction FNMLA_Z_P_ZZZ__ - __encoding FNMLA_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100101 xx1xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = TRUE; - boolean op3_neg = TRUE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - bits(esize) element3 = Elem[operand3, e, esize]; - - if ElemP[mask, e, esize] == '1' then - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - else - Elem[result, e, esize] = element3; - - Z[da] = result; - -__instruction aarch64_memory_single_general_immediate_signed_post_idx - __encoding aarch64_memory_single_general_immediate_signed_post_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx01xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = TRUE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_signed_pre_idx - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm9 12 +: 9 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111000 xx0xxxxx xxxx11xx xxxxxxxx' - __guard TRUE - __decode - boolean wback = TRUE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = SignExtend(imm9, 64); - - __encoding aarch64_memory_single_general_immediate_unsigned - __instruction_set A64 - __field size 30 +: 2 - __field opc 22 +: 2 - __field imm12 10 +: 12 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode 'xx111001 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - boolean wback = FALSE; - boolean postindex = FALSE; - integer scale = UInt(size); - bits(64) offset = LSL(ZeroExtend(imm12, 64), scale); - - __postdecode - integer n = UInt(Rn); - integer t = UInt(Rt); - AccType acctype = AccType_NORMAL; - MemOp memop; - boolean signed; - integer regsize; - - if opc[1] == '0' then - // store or zero-extending load - memop = if opc[0] == '1' then MemOp_LOAD else MemOp_STORE; - regsize = if size == '11' then 64 else 32; - signed = FALSE; - else - if size == '11' then - UNDEFINED; - else - // sign-extending load - memop = MemOp_LOAD; - if size == '10' && opc[0] == '1' then UNDEFINED; - regsize = if opc[0] == '1' then 32 else 64; - signed = TRUE; - - integer datasize = 8 << scale; - boolean tag_checked = memop != MemOp_PREFETCH && (wback || n != 31); - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - bits(64) address; - bits(datasize) data; - - boolean wb_unknown = FALSE; - boolean rt_unknown = FALSE; - - if memop == MemOp_LOAD && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD); - assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed - when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if memop == MemOp_STORE && wback && n == t && n != 31 then - c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST); - assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP}; - case c of - when Constraint_NONE rt_unknown = FALSE; // value stored is original value - when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN - when Constraint_UNDEF UNDEFINED; - when Constraint_NOP EndOfInstruction(); - - if n == 31 then - if memop != MemOp_PREFETCH then CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - if ! postindex then - address = address + offset; - - case memop of - when MemOp_STORE - if rt_unknown then - data = bits(datasize) UNKNOWN; - else - data = X[t]; - Mem[address, datasize DIV 8, acctype] = data; - - when MemOp_LOAD - data = Mem[address, datasize DIV 8, acctype]; - if signed then - X[t] = SignExtend(data, regsize); - else - X[t] = ZeroExtend(data, regsize); - - when MemOp_PREFETCH - Prefetch(address, t[4:0]); - - if wback then - if wb_unknown then - address = bits(64) UNKNOWN; - elsif postindex then - address = address + offset; - if n == 31 then - SP[] = address; - else - X[n] = address; - -__instruction FMLS_Z_P_ZZZ__ - __encoding FMLS_Z_P_ZZZ__ - __instruction_set A64 - __field size 22 +: 2 - __field Zm 16 +: 5 - __field Pg 10 +: 3 - __field Zn 5 +: 5 - __field Zda 0 +: 5 - __opcode '01100101 xx1xxxxx 001xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveSVE() then UNDEFINED; - if size == '00' then UNDEFINED; - integer esize = 8 << UInt(size); - integer g = UInt(Pg); - integer n = UInt(Zn); - integer m = UInt(Zm); - integer da = UInt(Zda); - boolean op1_neg = TRUE; - boolean op3_neg = FALSE; - - __execute - CheckSVEEnabled(); - integer elements = VL DIV esize; - bits(PL) mask = P[g]; - bits(VL) operand1 = Z[n]; - bits(VL) operand2 = Z[m]; - bits(VL) operand3 = Z[da]; - bits(VL) result; - - for e = 0 to elements-1 - bits(esize) element1 = Elem[operand1, e, esize]; - bits(esize) element2 = Elem[operand2, e, esize]; - bits(esize) element3 = Elem[operand3, e, esize]; - - if ElemP[mask, e, esize] == '1' then - if op1_neg then element1 = FPNeg(element1); - if op3_neg then element3 = FPNeg(element3); - Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR); - else - Elem[result, e, esize] = element3; - - Z[da] = result; - -__instruction aarch64_integer_logical_shiftedreg - __encoding aarch64_integer_logical_shiftedreg - __instruction_set A64 - __field sf 31 +: 1 - __field opc 29 +: 2 - __field shift 22 +: 2 - __field N 21 +: 1 - __field Rm 16 +: 5 - __field imm6 10 +: 6 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'xxx01010 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - integer datasize = if sf == '1' then 64 else 32; - boolean setflags; - LogicalOp op; - case opc of - when '00' op = LogicalOp_AND; setflags = FALSE; - when '01' op = LogicalOp_ORR; setflags = FALSE; - when '10' op = LogicalOp_EOR; setflags = FALSE; - when '11' op = LogicalOp_AND; setflags = TRUE; - - if sf == '0' && imm6[5] == '1' then UNDEFINED; - - ShiftType shift_type = DecodeShift(shift); - integer shift_amount = UInt(imm6); - boolean invert = (N == '1'); - - __execute - bits(datasize) operand1 = X[n]; - bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount); - - if invert then operand2 = NOT(operand2); - - case op of - when LogicalOp_AND result = operand1 AND operand2; - when LogicalOp_ORR result = operand1 OR operand2; - when LogicalOp_EOR result = operand1 EOR operand2; - - if setflags then - PSTATE.[N,Z,C,V] = result[datasize-1]:IsZeroBit(result):'00'; - - X[d] = result; - -__instruction aarch64_memory_vector_single_no_wb - __encoding aarch64_memory_vector_single_no_wb - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 0xx00000 xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = integer UNKNOWN; - boolean wback = FALSE; - boolean tag_checked = wback || n != 31; - - __encoding aarch64_memory_vector_single_post_inc - __instruction_set A64 - __field Q 30 +: 1 - __field L 22 +: 1 - __field R 21 +: 1 - __field Rm 16 +: 5 - __field opcode 13 +: 3 - __field S 12 +: 1 - __field size 10 +: 2 - __field Rn 5 +: 5 - __field Rt 0 +: 5 - __opcode '0x001101 1xxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer n = UInt(Rn); - integer m = UInt(Rm); - boolean wback = TRUE; - boolean tag_checked = wback || n != 31; - - __postdecode - integer scale = UInt(opcode[2:1]); - integer selem = UInt(opcode[0]:R) + 1; - boolean replicate = FALSE; - integer index; - - case scale of - when 3 - // load and replicate - if L == '0' || S == '1' then UNDEFINED; - scale = UInt(size); - replicate = TRUE; - when 0 - index = UInt(Q:S:size); // B[0-15] - when 1 - if size[0] == '1' then UNDEFINED; - index = UInt(Q:S:size[1]); // H[0-7] - when 2 - if size[1] == '1' then UNDEFINED; - if size[0] == '0' then - index = UInt(Q:S); // S[0-3] - else - if S == '1' then UNDEFINED; - index = UInt(Q); // D[0-1] - scale = 3; - - MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE; - integer datasize = if Q == '1' then 128 else 64; - integer esize = 8 << scale; - __execute - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - bits(64) address; - bits(64) offs; - bits(128) rval; - bits(esize) element; - constant integer ebytes = esize DIV 8; - - if n == 31 then - CheckSPAlignment(); - address = SP[]; - else - address = X[n]; - - offs = Zeros(); - if replicate then - // load and replicate to all elements - for s = 0 to selem-1 - element = Mem[address + offs, ebytes, AccType_VEC]; - // replicate to fill 128- or 64-bit register - V[t] = Replicate(element, datasize DIV esize); - offs = offs + ebytes; - t = (t + 1) MOD 32; - else - // load/store one element per register - for s = 0 to selem-1 - rval = V[t]; - if memop == MemOp_LOAD then - // insert into one lane of 128-bit register - Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC]; - V[t] = rval; - else // memop == MemOp_STORE - // extract from one lane of 128-bit register - Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize]; - offs = offs + ebytes; - t = (t + 1) MOD 32; - - if wback then - if m != 31 then - offs = X[m]; - if n == 31 then - SP[] = address + offs; - else - X[n] = address + offs; - -__instruction aarch64_vector_arithmetic_unary_float_round_frint_32_64 - __encoding aarch64_vector_arithmetic_unary_float_round_frint_32_64 - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field sz 22 +: 1 - __field op 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 0x100001 111x10xx xxxxxxxx' - __guard TRUE - __decode - if !HaveFrintExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - - if sz:Q == '10' then UNDEFINED; - integer esize = 32 << UInt(sz); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - integer intsize = if op == '0' then 32 else 64; - FPRounding rounding = if U == '0' then FPRounding_ZERO else FPRoundingMode(FPCR); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - bits(esize) element; - - for e = 0 to elements-1 - element = Elem[operand, e, esize]; - Elem[result, e, esize] = FPRoundIntN(element, FPCR, rounding, intsize); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_unary_diff_neg_int_sisd - __encoding aarch64_vector_arithmetic_unary_diff_neg_int_sisd - __instruction_set A64 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x11110 xx100000 101110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size != '11' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = esize; - integer elements = 1; - boolean neg = (U == '1'); - - __encoding aarch64_vector_arithmetic_unary_diff_neg_int_simd - __instruction_set A64 - __field Q 30 +: 1 - __field U 29 +: 1 - __field size 22 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '0xx01110 xx100000 101110xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - - if size:Q == '110' then UNDEFINED; - integer esize = 8 << UInt(size); - integer datasize = if Q == '1' then 128 else 64; - integer elements = datasize DIV esize; - boolean neg = (U == '1'); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(datasize) operand = V[n]; - bits(datasize) result; - integer element; - - for e = 0 to elements-1 - element = SInt(Elem[operand, e, esize]); - if neg then - element = -element; - else - element = Abs(element); - Elem[result, e, esize] = element[esize-1:0]; - - V[d] = result; - -__instruction aarch64_vector_crypto_aes_round - __encoding aarch64_vector_crypto_aes_round - __instruction_set A64 - __field D 12 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01001110 00101000 010x10xx xxxxxxxx' - __guard TRUE - __decode - integer d = UInt(Rd); - integer n = UInt(Rn); - if !HaveAESExt() then UNDEFINED; - boolean decrypt = (D == '1'); - - __execute - AArch64.CheckFPAdvSIMDEnabled(); - - bits(128) operand1 = V[d]; - bits(128) operand2 = V[n]; - bits(128) result; - result = operand1 EOR operand2; - if decrypt then - result = AESInvSubBytes(AESInvShiftRows(result)); - else - result = AESSubBytes(AESShiftRows(result)); - - V[d] = result; - -__instruction aarch64_vector_arithmetic_binary_uniform_mat_mul_int_mla - __encoding aarch64_vector_arithmetic_binary_uniform_mat_mul_int_mla - __instruction_set A64 - __field U 29 +: 1 - __field Rm 16 +: 5 - __field B 11 +: 1 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode '01x01110 100xxxxx 1010x1xx xxxxxxxx' - __guard TRUE - __decode - if !HaveInt8MatMulExt() then UNDEFINED; - case B:U of - when '00' op1_unsigned = FALSE; op2_unsigned = FALSE; - when '01' op1_unsigned = TRUE; op2_unsigned = TRUE; - when '10' op1_unsigned = TRUE; op2_unsigned = FALSE; - when '11' UNDEFINED; - integer n = UInt(Rn); - integer m = UInt(Rm); - integer d = UInt(Rd); - - __execute - CheckFPAdvSIMDEnabled64(); - bits(128) operand1 = V[n]; - bits(128) operand2 = V[m]; - bits(128) addend = V[d]; - - V[d] = MatMulAdd(addend, operand1, operand2, op1_unsigned, op2_unsigned); - -__instruction aarch64_memory_literal_simdfp - __encoding aarch64_memory_literal_simdfp - __instruction_set A64 - __field opc 30 +: 2 - __field imm19 5 +: 19 - __field Rt 0 +: 5 - __opcode 'xx011100 xxxxxxxx xxxxxxxx xxxxxxxx' - __guard TRUE - __decode - integer t = UInt(Rt); - integer size; - bits(64) offset; - - case opc of - when '00' - size = 4; - when '01' - size = 8; - when '10' - size = 16; - when '11' - UNDEFINED; - - offset = SignExtend(imm19:'00', 64); - boolean tag_checked = FALSE; - - __execute - bits(64) address = PC[] + offset; - bits(size*8) data; - - if HaveMTEExt() then - SetTagCheckedInstruction(tag_checked); - - CheckFPAdvSIMDEnabled64(); - - data = Mem[address, size, AccType_VEC]; - V[t] = data; - -__instruction aarch64_integer_crc - __encoding aarch64_integer_crc - __instruction_set A64 - __field sf 31 +: 1 - __field Rm 16 +: 5 - __field C 12 +: 1 - __field sz 10 +: 2 - __field Rn 5 +: 5 - __field Rd 0 +: 5 - __opcode 'x0011010 110xxxxx 010xxxxx xxxxxxxx' - __guard TRUE - __decode - if !HaveCRCExt() then UNDEFINED; - integer d = UInt(Rd); - integer n = UInt(Rn); - integer m = UInt(Rm); - if sf == '1' && sz != '11' then UNDEFINED; - if sf == '0' && sz == '11' then UNDEFINED; - integer size = 8 << UInt(sz); // 2-bit size field -> 8, 16, 32, 64 - boolean crc32c = (C == '1'); - - __execute - bits(32) acc = X[n]; // accumulator - bits(size) val = X[m]; // input value - bits(32) poly = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)[31:0]; - - bits(32+size) tempacc = BitReverse(acc) : Zeros(size); - bits(size+32) tempval = BitReverse(val) : Zeros(32); - - // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation - X[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly)); - -//////////////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////////////// diff --git a/mra_tools/arch/regs.asl b/mra_tools/arch/regs.asl deleted file mode 100644 index 73a5f7a9..00000000 --- a/mra_tools/arch/regs.asl +++ /dev/null @@ -1,2928 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// Proprietary Notice -// -// This document is protected by copyright and other related rights -// and the practice or implementation of the information contained in -// this document may be protected by one or more patents or pending -// patent applications. No part of this document may be reproduced in any -// form by any means without the express prior written permission of -// Arm. No license, express or implied, by estoppel or otherwise to -// any intellectual property rights is granted by this document unless -// specifically stated. -// -// Your access to the information in this document is conditional upon -// your acceptance that you will not use or permit others to use the -// information for the purposes of determining whether implementations -// infringe any third party patents. -// -// THIS DOCUMENT IS PROVIDED "AS IS". ARM PROVIDES NO REPRESENTATIONS -// AND NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT -// LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY -// QUALITY, NON-INFRINGEMENT OR FITNESS FOR A PARTICULAR PURPOSE WITH -// RESPECT TO THE DOCUMENT. For the avoidance of doubt, Arm makes no -// representation with respect to, and has undertaken no analysis to -// identify or understand the scope and content of, patents, copyrights, -// trade secrets, or other rights. -// -// This document may include technical inaccuracies or typographical -// errors. -// -// TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL ARM BE -// LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION ANY DIRECT, -// INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES, -// HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT -// OF ANY USE OF THIS DOCUMENT, EVEN IF ARM HAS BEEN ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGES. -// -// This document consists solely of commercial items. You shall be -// responsible for ensuring that any use, duplication or disclosure of -// this document complies fully with any relevant export laws and -// regulations to assure that this document or any portion thereof is not -// exported, directly or indirectly, in violation of such export -// laws. Use of the word "partner" in reference to Arm"s customers is not -// intended to create or refer to any partnership relationship with any -// other company. Arm may make changes to this document at any time and -// without notice. -// -// If any of the provisions contained in these terms conflict with -// any of the provisions of any click through or signed written agreement -// covering this document with Arm, then the click through or signed -// written agreement prevails over and supersedes the conflicting -// provisions of these terms. This document may be translated into other -// languages for convenience, and you agree that if there is any conflict -// between the English version of this document and any translation, the -// terms of the English version of the Agreement shall prevail. -// -// The Arm corporate logo and words marked with (R) or (TM) -// are registered trademarks or trademarks of Arm Limited (or its -// subsidiaries) in the US and/or elsewhere. All rights reserved. Other -// brands and names mentioned in this document may be the trademarks of -// their respective owners. Please follow Arm"s trademark usage -// guidelines at -// http://www.arm.com/company/policies/trademarks. -// -// Copyright (C) 2019 Arm Limited (or its affiliates). All rights reserved. -// -// Arm Limited. Company 02557590 registered in England. -// -// 110 Fulbourn Road, Cambridge, England CB1 9NJ. -// -// LES-PRE-20349 -//////////////////////////////////////////////////////////////////////// - -// CPU Interface Interrupt Acknowledge Register -__register 32 { 23:0 INTID } GICC_IAR; - -// Hyp Architectural Feature Trap Register -__register 32 { 31:31 TCPAC, 30:30 TAM, 20:20 TTA, 15:15 TASE, 11:11 TCP11, 10:10 TCP10 } HCPTR; - -// Interrupt Controller Software Generated Interrupt Group 0 Register -__register 64 { 55:48 Aff3, 47:44 RS, 40:40 IRM, 39:32 Aff2, 27:24 INTID, 23:16 Aff1, 15:0 TargetList } ICC_SGI0R; - -// Pointer Authentication Key A for Code (bits[63:0]) -__register 64 { } APGAKeyLo_EL1; - -// Counter Control Register -__register 32 { 17:8 FCREQ, 2:2 SCEN, 1:1 HDBG, 0:0 EN } CNTCR; - -// Activity Monitors Event Counter Registers 1 -array [0..15] of __register 64 { 63:0 ACNT } AMEVCNTR1; - -// Interrupt Controller Running Priority Register -__register 32 { 7:0 Priority } ICC_RPR_EL1; - -// Counter-timer Virtual Timer TimerValue -__register 32 { 31:0 TimerValue } CNTV_TVAL; - -// Data Independent Timing -__register 32 { 24:24 DIT } DIT; - -// External Debug Peripheral Identification Register 2 -__register 32 { 7:4 REVISION, 3:3 JEDEC, 2:0 DES_1 } EDPIDR2; - -// Monitor DCC Status Register -__register 32 { 30:30 RXfull, 29:29 TXfull } MDCCSR_EL0; - -// Hypervisor Configuration Register -__register 64 { 63:60 TWEDEL, 59:59 TWEDEn, 58:58 TID5, 57:57 DCT, 56:56 ATA, 55:55 TTLBOS, 54:54 TTLBIS, 53:53 EnSCXT, 52:52 TOCU, 51:51 AMVOFFEN, 50:50 TICAB, 49:49 TID4, 47:47 FIEN, 46:46 FWB, 45:45 NV2, 44:44 AT, 43:43 NV1, 42:42 NV, 41:41 API, 40:40 APK, 38:38 MIOCNCE, 37:37 TEA, 36:36 TERR, 35:35 TLOR, 34:34 E2H, 33:33 ID, 32:32 CD, 31:31 RW, 30:30 TRVM, 29:29 HCD, 28:28 TDZ, 27:27 TGE, 26:26 TVM, 25:25 TTLB, 24:24 TPU, 23:23 TPCP, 23:23 TPC, 22:22 TSW, 21:21 TACR, 20:20 TIDCP, 19:19 TSC, 18:18 TID3, 17:17 TID2, 16:16 TID1, 15:15 TID0, 14:14 TWE, 13:13 TWI, 12:12 DC, 11:10 BSU, 9:9 FB, 8:8 VSE, 7:7 VI, 6:6 VF, 5:5 AMO, 4:4 IMO, 3:3 FMO, 2:2 PTW, 1:1 SWIO, 0:0 VM } HCR_EL2; - -// Debug Status and Control Register, Internal View -__register 32 { 30:30 RXfull, 29:29 TXfull, 18:18 NS, 17:17 SPNIDdis, 16:16 SPIDdis, 15:15 MDBGen, 12:12 UDCCdis, 5:2 MOE } DBGDSCRint; - -// Auxiliary Fault Status Register 1 (EL2) -__register 32 { } AFSR1_EL2; - -// Reset Management Register (EL1) -__register 32 { 1:1 RR, 0:0 AA64 } RMR_EL1; - -// Secure Debug Control Register -__register 32 { 28:28 MTPME, 27:27 TDCC, 23:23 SCCD, 21:21 EPMAD, 20:20 EDAD, 19:19 TTRF, 18:18 STE, 17:17 SPME, 15:14 SPD } SDCR; - -// Floating-Point Exception Control register -__register 32 { 31:31 EX, 30:30 EN, 29:29 DEX, 28:28 FP2V, 27:27 VV, 26:26 TFV, 10:8 VECITR, 7:7 IDF, 4:4 IXF, 3:3 UFF, 2:2 OFF, 1:1 DZF, 0:0 IOF } FPEXC; - -// Virtual Redistributor Properties Base Address Register -__register 64 { 58:56 OuterCache, 51:12 Physical_Address, 11:10 Shareability, 9:7 InnerCache, 4:0 IDbits, 63:63 Valid, 61:59 Entry_Size, 55:55 Indirect, 54:53 Page_Size, 52:52 Z, 6:0 Size } GICR_VPROPBASER; - -// Architectural Feature Access Control Register -__register 32 { 28:28 TTA, 21:20 FPEN, 17:16 ZEN } CPACR_EL1; - -// Counter-timer Virtual Timer CompareValue register (EL2) -__register 64 { 63:0 CompareValue } CNTHV_CVAL; - -// Performance Monitors Peripheral Identification Register 4 -__register 32 { 7:4 SIZE, 3:0 DES_2 } PMPIDR4; - -// Processor Feature Register 1 -__register 32 { 31:28 GIC, 27:24 Virt_frac, 23:20 Sec_frac, 19:16 GenTimer, 15:12 Virtualization, 11:8 MProgMod, 7:4 Security, 3:0 ProgMod } ID_PFR1; - -// AArch64 Debug Feature Register 1 -__register 64 { } ID_AA64DFR1_EL1; - -// Interrupt Controller Virtual Interrupt Group 0 Enable register -__register 32 { 0:0 Enable } ICV_IGRPEN0_EL1; - -// Hypervisor Fine-Grained Instruction Trap Register -__register 64 { 54:54 DCCVAC, 53:53 SVC_EL1, 52:52 SVC_EL0, 51:51 ERET, 50:50 CPPRCTX, 49:49 DVPRCTX, 48:48 CFPRCTX, 47:47 TLBIVAALE1, 46:46 TLBIVALE1, 45:45 TLBIVAAE1, 44:44 TLBIASIDE1, 43:43 TLBIVAE1, 42:42 TLBIVMALLE1, 41:41 TLBIRVAALE1, 40:40 TLBIRVALE1, 39:39 TLBIRVAAE1, 38:38 TLBIRVAE1, 37:37 TLBIRVAALE1IS, 36:36 TLBIRVALE1IS, 35:35 TLBIRVAAE1IS, 34:34 TLBIRVAE1IS, 33:33 TLBIVAALE1IS, 32:32 TLBIVALE1IS, 31:31 TLBIVAAE1IS, 30:30 TLBIASIDE1IS, 29:29 TLBIVAE1IS, 28:28 TLBIVMALLE1IS, 27:27 TLBIRVAALE1OS, 26:26 TLBIRVALE1OS, 25:25 TLBIRVAAE1OS, 24:24 TLBIRVAE1OS, 23:23 TLBIVAALE1OS, 22:22 TLBIVALE1OS, 21:21 TLBIVAAE1OS, 20:20 TLBIASIDE1OS, 19:19 TLBIVAE1OS, 18:18 TLBIVMALLE1OS, 17:17 ATS1E1WP, 16:16 ATS1E1RP, 15:15 ATS1E0W, 14:14 ATS1E0R, 13:13 ATS1E1W, 12:12 ATS1E1R, 11:11 DCZVA, 10:10 DCCIVAC, 9:9 DCCVADP, 8:8 DCCVAP, 7:7 DCCVAU, 6:6 DCCISW, 5:5 DCCSW, 4:4 DCISW, 3:3 DCIVAC, 2:2 ICIVAU, 1:1 ICIALLU, 0:0 ICIALLUIS } HFGITR_EL2; - -// EL1 Read/Write Software Context Number -__register 64 { } SCXTNUM_EL1; - -// CTI Trigger In Status register -__register 32 { } CTITRIGINSTATUS; - -// LORegion Number (EL1) -__register 64 { 7:0 Num } LORN_EL1; - -// Performance Monitors Overflow Flag Status Clear Register -__register 32 { 31:31 C } PMOVSCLR_EL0; - -// Virtual Deferred Interrupt Status Register -__register 64 { 31:31 A, 24:24 IDS, 23:0 ISS, 15:14 AET, 12:12 ExT, 9:9 LPAE, 5:0 STATUS, 10:10, 3:0 FS } VDISR_EL2; - -// Hyp System Trap Register -__register 32 { } HSTR; - -// Redistributor Implementer Identification Register -__register 32 { 31:24 ProductID, 19:16 Variant, 15:12 Revision, 11:0 Implementer } GICR_IIDR; - -// Counter-timer Virtual Timer CompareValue register (EL2) -__register 64 { 63:0 CompareValue } CNTHV_CVAL_EL2; - -// Hypervisor IPA Fault Address Register -__register 64 { 63:63 NS, 43:40, 39:4 FIPA } HPFAR_EL2; - -// Counter-timer Physical Count register -__register 64 { } CNTPCT; - -// MPAM Memory System Monitor Configure Cache Storage Usage Monitor Control Register -__register 32 { 31:31 EN, 30:28 CAPT_EVNT, 27:27 CAPT_RESET, 26:26 OFLOW_STATUS, 25:25 OFLOW_INTR, 24:24 OFLOW_FRZ, 23:20 SUBTYPE, 17:17 MATCH_PMG, 16:16 MATCH_PARTID, 7:0 TYPE } MSMON_CFG_CSU_CTL; - -// Activity Monitors Control Register -__register 32 { 10:10 HDBG, 17:17 CG1RZ } AMCR; - -// Performance Monitors Overflow Flag Status Register -__register 32 { 31:31 C } PMOVSR; - -// Application Program Status Register -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 19:16 GE } APSR; - -// Performance Monitors Peripheral Identification Register 3 -__register 32 { 7:4 REVAND, 3:0 CMOD } PMPIDR3; - -// CTI Device ID register 2 -__register 32 { } CTIDEVID2; - -// LORegion Start Address (EL1) -__register 64 { 0:0 Valid, 51:48, 47:16 SA } LORSA_EL1; - -// ITS Translation Table Descriptors -array [0..7] of __register 64 { 63:63 Valid, 62:62 Indirect, 61:59 InnerCache, 58:56 Type, 55:53 OuterCache, 52:48 Entry_Size, 47:12 Physical_Address, 11:10 Shareability, 9:8 Page_Size, 7:0 Size } GITS_BASER; - -// Activity Monitors Count Enable Set Register 0 -__register 32 { } AMCNTENSET0; - -// Performance Monitors Event Type Registers -array [0..30] of __register 64 { 31:31 P, 30:30 U, 29:29 NSK, 28:28 NSU, 27:27 NSH, 26:26 M, 25:25 MT, 24:24 SH, 15:10, 9:0 evtCount } PMEVTYPER_EL0; - -// Main ID Register -__register 32 { 31:24 Implementer, 23:20 Variant, 19:16 Architecture, 15:4 PartNum, 3:0 Revision } MIDR_EL1; - -// Counter-timer Physical Timer CompareValue register -__register 64 { 63:0 CompareValue } CNTP_CVAL; - -// Counter-timer Physical Timer TimerValue register -__register 32 { 31:0 TimerValue } CNTP_TVAL; - -// Virtual Machine Interrupt Acknowledge Register -__register 32 { 24:0 INTID } GICV_IAR; - -// Fault-Handling Interrupt Configuration Register 1 -__register 32 { 31:0 DATA } ERRFHICR1; - -// Interrupt Set-Pending Registers -array [1..2] of __register 32 { } GICR_ISPENDRE; - -// Auxiliary ID Register -__register 32 { } AIDR; - -// Saved Program Status Register (EL1) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 DIT, 12:12 SSBS, 22:22 PAN, 21:21 SS, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 25:25 TCO, 23:23 UAO, 11:10 BTYPE, 9:9 D, 15:10, 26:25 IT, 4:4, 4:4, 3:0, 3:0 M } SPSR_EL1; - -// Debug OS Lock Exception Catch Control Register -__register 32 { 31:0 EDECCR } DBGOSECCR; - -// ITS Control Register -__register 32 { 31:31 Quiescent, 7:4 ITS_Number, 1:1 ImDe, 0:0 Enabled } GITS_CTLR; - -// Reset Management Register (EL2) -__register 32 { 1:1 RR, 0:0 AA64 } RMR_EL2; - -// Performance Monitors Interrupt Enable Set register -__register 32 { 31:31 C } PMINTENSET; - -// Hyp Trace Filter Control Register -__register 32 { 6:5 TS, 3:3 CX, 1:1 E2TRE, 0:0 E0HTRE } HTRFCR; - -// AArch32 Media and VFP Feature Register 0 -__register 32 { 31:28 FPRound, 27:24 FPShVec, 23:20 FPSqrt, 19:16 FPDivide, 15:12 FPTrap, 11:8 FPDP, 7:4 FPSP, 3:0 SIMDReg } MVFR0_EL1; - -// Speculative Store Bypass Safe -__register 32 { 12:12 SSBS } SSBS; - -// Saved Program Status Register (IRQ mode) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 J, 23:23 SSBS, 22:22 PAN, 21:21 DIT, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 15:10, 26:25 IT, 4:0 M } SPSR_irq; - -// Cache Size Selection Register -__register 32 { 3:1 Level, 0:0 InD } CSSELR; - -// Interrupt Controller Virtual Active Priorities Group 1 Registers -array [0..3] of __register 64 { } ICV_AP1R_EL1; - -// MPAM Cache Storage Usage Monitor Register -__register 32 { 31:31 NRDY, 30:0 VALUE } MSMON_CSU; - -// Activity Monitors Event Type Registers 0 -array [0..15] of __register 32 { 15:0 evtCount } AMEVTYPER0; - -// AArch64 Memory Model Feature Register 1 -__register 64 { 39:36 ETS, 35:32 TWED, 31:28 XNX, 27:24 SpecSEI, 23:20 PAN, 19:16 LO, 15:12 HPDS, 11:8 VH, 7:4 VMIDBits, 3:0 HAFDBS } ID_AA64MMFR1_EL1; - -// Counter Frequency ID -__register 32 { 31:0 Frequency } CNTFID0; - -// Interrupt Controller Virtual Highest Priority Pending Interrupt Register 0 -__register 32 { 23:0 INTID } ICV_HPPIR0; - -// Interrupt Controller Control Register (EL3) -__register 32 { 19:19 ExtRange, 18:18 RSS, 17:17 nDS, 15:15 A3V, 14:14 SEIS, 13:11 IDbits, 10:8 PRIbits, 6:6 PMHE, 5:5 RM, 4:4 EOImode_EL1NS, 3:3 EOImode_EL1S, 2:2 EOImode_EL3, 1:1 CBPR_EL1NS, 0:0 CBPR_EL1S } ICC_CTLR_EL3; - -// Selected Error Record Address Register -__register 32 { } ERXADDR; - -// Interrupt Controller Virtual Machine Control Register -__register 32 { 31:24 VPMR, 23:21 VBPR0, 20:18 VBPR1, 9:9 VEOIM, 4:4 VCBPR, 3:3 VFIQEn, 2:2 VAckCtl, 1:1 VENG1, 0:0 VENG0 } ICH_VMCR_EL2; - -// MPAM Virtual Partition Mapping Valid Register -__register 64 { } MPAMVPMV_EL2; - -// Interrupt Controller End Of Interrupt Register 1 -__register 32 { 23:0 INTID } ICC_EOIR1; - -// Interrupt Controller Monitor Interrupt Group 1 Enable register -__register 32 { 1:1 EnableGrp1S, 0:0 EnableGrp1NS } ICC_MGRPEN1; - -// CPU Interface End Of Interrupt Register -__register 32 { 23:0 INTID } GICC_EOIR; - -// Error Interrupt Status Register -__register 64 { 5:5 CRIERR, 4:4 CRI, 3:3 ERIERR, 2:2 ERI, 1:1 FHIERR, 0:0 FHI } ERRIRQSR; - -// Virtualization Secure Translation Control Register -__register 32 { 30:30 SA, 29:29 SW, 15:14 TG0, 7:6 SL0, 5:0 T0SZ } VSTCR_EL2; - -// Selected Error Record Miscellaneous Register 3 -__register 64 { } ERXMISC3_EL1; - -// EL0 Read/Write Software Context Number -__register 64 { } SCXTNUM_EL0; - -// PL0 Read/Write Software Thread ID Register -__register 32 { } TPIDRURW; - -// Critical Error Interrupt Configuration Register 2 -__register 32 { 7:7 IRQEN, 6:6 NSMSI, 5:4 SH, 3:0 MemAttr } ERRCRICR2; - -// Clear Secure SPI Pending Register -__register 32 { 12:0 INTID } GICD_CLRSPI_SR; - -// Virtualization Processor ID Register -__register 32 { 31:24 Implementer, 23:20 Variant, 19:16 Architecture, 15:4 PartNum, 3:0 Revision } VPIDR_EL2; - -// Selected Error Record Miscellaneous Register 1 -__register 64 { } ERXMISC1_EL1; - -// AArch32 Memory Model Feature Register 5 -__register 64 { 3:0 ETS } ID_MMFR5_EL1; - -// Tag Fault Status Register (EL1) -__register 64 { 1:1 TF1, 0:0 TF0 } TFSR_EL1; - -// AArch32 Processor Feature Register 1 -__register 32 { 31:28 GIC, 27:24 Virt_frac, 23:20 Sec_frac, 19:16 GenTimer, 15:12 Virtualization, 11:8 MProgMod, 7:4 Security, 3:0 ProgMod } ID_PFR1_EL1; - -// CTI Lock Access Register -__register 32 { 31:0 KEY } CTILAR; - -// Maintenance Interrupt Status Register -__register 32 { 7:7 VGrp1D, 6:6 VGrp1E, 5:5 VGrp0D, 4:4 VGrp0E, 3:3 NP, 2:2 LRENP, 1:1 U, 0:0 EOI } GICH_MISR; - -// Reset Vector Base Address Register (if EL2 and EL3 not implemented) -__register 64 { } RVBAR_EL1; - -// Performance Monitors Machine Identification Register -__register 32 { 7:0 SLOTS } PMMIR; - -// MPAM Memory Bandwidth Proportional Stride Partition Configuration Register -__register 32 { 31:31 EN, 15:0 STRIDEM1 } MPAMCFG_MBW_PROP; - -// Hypervisor Fine-Grained Write Trap Register -__register 64 { 49:49 ERXADDR_EL1, 48:48 ERXPFGCDN_EL1, 47:47 ERXPFGCTL_EL1, 45:45 ERXMISCn_EL1, 44:44 ERXSTATUS_EL1, 43:43 ERXCTLR_EL1, 41:41 ERRSELR_EL1, 39:39 ICC_IGRPENn_EL1, 38:38 VBAR_EL1, 37:37 TTBR1_EL1, 36:36 TTBR0_EL1, 35:35 TPIDR_EL0, 34:34 TPIDRRO_EL0, 33:33 TPIDR_EL1, 32:32 TCR_EL1, 31:31 SCXTNUM_EL0, 30:30 SCXTNUM_EL1, 29:29 SCTLR_EL1, 27:27 PAR_EL1, 24:24 MAIR_EL1, 23:23 LORSA_EL1, 22:22 LORN_EL1, 20:20 LOREA_EL1, 19:19 LORC_EL1, 17:17 FAR_EL1, 16:16 ESR_EL1, 13:13 CSSELR_EL1, 12:12 CPACR_EL1, 11:11 CONTEXTIDR_EL1, 8:8 APIBKey, 7:7 APIAKey, 6:6 APGAKey, 5:5 APDBKey, 4:4 APDAKey, 3:3 AMAIR_EL1, 1:1 AFSR1_EL1, 0:0 AFSR0_EL1 } HFGWTR_EL2; - -// Interrupt Controller Binary Point Register 1 -__register 32 { 2:0 BinaryPoint } ICC_BPR1; - -// Activity Monitors Count Enable Clear Register 1 -__register 32 { } AMCNTENCLR1; - -// Hypervisor Debug Fine-Grained Read Trap Register -__register 64 { 58:58 PMCEIDn_EL0, 57:57 PMUSERENR_EL0, 48:48 TRCVICTLR, 47:47 TRCSTATR, 46:46 TRCSSCSRn, 45:45 TRCSEQSTR, 44:44 TRCPRGCTLR, 43:43 TRCOSLSR, 41:41 TRCIMSPECn, 40:40 TRCID, 37:37 TRCCNTVRn, 36:36 TRCCLAIM, 35:35 TRCAUXCTLR, 34:34 TRCAUTHSTATUS, 33:33 TRC, 32:32 PMSLATFR_EL1, 31:31 PMSIRR_EL1, 30:30 PMSIDR_EL1, 29:29 PMSICR_EL1, 28:28 PMSFCR_EL1, 27:27 PMSEVFR_EL1, 26:26 PMSCR_EL1, 25:25 PMBSR_EL1, 24:24 PMBPTR_EL1, 23:23 PMBLIMITR_EL1, 22:22 PMMIR_EL1, 19:19 PMSELR_EL0, 18:18 PMOVS, 17:17 PMINTEN, 16:16 PMCNTEN, 15:15 PMCCNTR_EL0, 14:14 PMCCFILTR_EL0, 13:13 PMEVTYPERn_EL0, 12:12 PMEVCNTRn_EL0, 11:11 OSDLR_EL1, 10:10 OSECCR_EL1, 9:9 OSLSR_EL1, 7:7 DBGPRCR_EL1, 6:6 DBGAUTHSTATUS_EL1, 5:5 DBGCLAIM, 4:4 MDSCR_EL1, 3:3 DBGWVRn_EL1, 2:2 DBGWCRn_EL1, 1:1 DBGBVRn_EL1, 0:0 DBGBCRn_EL1 } HDFGRTR_EL2; - -// Architectural Feature Access Control Register -__register 32 { 31:31 ASEDIS, 28:28 TRCDIS, 23:22 cp11, 21:20 cp10 } CPACR; - -// Translation Control Register (EL3) -__register 32 { 30:30 TCMA, 29:29 TBID, 28:28 HWU62, 27:27 HWU61, 26:26 HWU60, 25:25 HWU59, 24:24 HPD, 22:22 HD, 21:21 HA, 20:20 TBI, 18:16 PS, 15:14 TG0, 13:12 SH0, 11:10 ORGN0, 9:8 IRGN0, 5:0 T0SZ } TCR_EL3; - -// Debug Breakpoint Value Registers -array [0..15] of __register 32 { 31:0 ContextID, 31:2 VA } DBGBVR; - -// Interrupt Controller Virtual Control Register -__register 32 { 19:19 ExtRange, 18:18 RSS, 15:15 A3V, 14:14 SEIS, 13:11 IDbits, 10:8 PRIbits, 1:1 EOImode, 0:0 CBPR } ICV_CTLR; - -// Hypervisor System Trap Register -__register 32 { } HSTR_EL2; - -// Activity Monitors Event Type Registers 0 -array [0..15] of __register 64 { 15:0 evtCount } AMEVTYPER0_EL0; - -// Generic Error Interrupt Configuration Register -array [0..15] of __register 64 { } ERRIRQCR; - -// Counter-timer Hypervisor Control register -__register 32 { 17:17 EVNTIS, 16:16 EL1NVVCT, 15:15 EL1NVPCT, 14:14 EL1TVCT, 13:13 EL1TVT, 12:12 ECV, 11:11 EL1PTEN, 0:0 EL1PCTEN, 9:9 EL0PTEN, 8:8 EL0VTEN, 7:4 EVNTI, 3:3 EVNTDIR, 2:2 EVNTEN, 1:1 EL0VCTEN, 0:0 EL0PCTEN, 1:1 EL1PCEN } CNTHCTL_EL2; - -// Error Record Control Register -array [0..65534] of __register 64 { 13:13 CI, 11:11 WDUI, 10:10 DUI, 10:10 RDUI, 9:9 WCFI, 8:8 CFI, 8:8 RCFI, 7:7 WUE, 6:6 WFI, 5:5 WUI, 4:4 UE, 4:4 RUE, 3:3 FI, 3:3 RFI, 2:2 UI, 2:2 RUI, 0:0 ED } ERRCTLR; - -// Profiling Buffer ID Register -__register 64 { 5:5 F, 4:4 P, 3:0 Align } PMBIDR_EL1; - -// Error Record Address Register -array [0..65534] of __register 64 { 63:63 NS, 62:62 SI, 61:61 AI, 60:60 VA, 55:0 PADDR } ERRADDR; - -// MPAM Cache Portion Bitmap Partition Configuration Register -__register 32768 { } MPAMCFG_CPBM; - -// OS Lock Data Transfer Register, Receive -__register 32 { } OSDTRRX_EL1; - -// Activity Monitors Implementation Identification Register -__register 32 { 31:20 ProductID, 19:16 Variant, 15:12 Revision, 11:0 Implementer } AMIIDR; - -// MPAM Memory Bandwidth Usage Monitor Capture Register -__register 32 { 31:31 NRDY, 30:0 VALUE } MSMON_MBWU_CAPTURE; - -// Performance Monitors Component Identification Register 1 -__register 32 { 7:4 CLASS, 3:0 PRMBL_1 } PMCIDR1; - -// Debug Saved Program Status Register -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 DIT, 12:12 SSBS, 22:22 PAN, 21:21 SS, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 25:25 TCO, 23:23 UAO, 11:10 BTYPE, 9:9 D, 15:10, 26:25 IT, 4:4, 4:4, 3:0, 3:0 M } DSPSR_EL0; - -// CONTEXTIDR_EL1 Sample Register -__register 32 { 31:0 CONTEXTIDR_EL1 } PMCID1SR; - -// Counter-timer Hyp Physical CompareValue register -__register 64 { 63:0 CompareValue } CNTHP_CVAL; - -// Interrupt Controller Interrupt Priority Mask Register -__register 32 { 7:0 Priority } ICC_PMR_EL1; - -// Auxiliary Memory Attribute Indirection Register 0 -__register 32 { } AMAIR0; - -// Current Cache Size ID Register -__register 32 { 27:13 NumSets, 12:3 Associativity, 2:0 LineSize } CCSIDR_EL1; - -// AArch32 Instruction Set Attribute Register 0 -__register 32 { 27:24 Divide, 23:20 Debug, 19:16 Coproc, 15:12 CmpBranch, 11:8 BitField, 7:4 BitCount, 3:0 Swap } ID_ISAR0_EL1; - -// Performance Monitors Peripheral Identification Register 2 -__register 32 { 7:4 REVISION, 3:3 JEDEC, 2:0 DES_1 } PMPIDR2; - -// MPAM Cache Maximum Capacity Partition Configuration Register -__register 32 { 15:0 MIN } MPAMCFG_MBW_MIN; - -// Interrupt Controller Control Register (EL1) -__register 32 { 19:19 ExtRange, 18:18 RSS, 15:15 A3V, 14:14 SEIS, 13:11 IDbits, 10:8 PRIbits, 6:6 PMHE, 1:1 EOImode, 0:0 CBPR } ICC_CTLR_EL1; - -// Trace Filter Control Register (EL2) -__register 64 { 6:5 TS, 3:3 CX, 1:1 E2TRE, 0:0 E0HTRE } TRFCR_EL2; - -// Hyp Auxiliary Memory Attribute Indirection Register 1 -__register 32 { } HAMAIR1; - -// Trace Filter Control Register -__register 32 { 6:5 TS, 1:1 E1TRE, 0:0 E0TRE } TRFCR; - -// CTI Authentication Status register -__register 32 { 3:2 NSNID, 1:0 NSID } CTIAUTHSTATUS; - -// AArch32 Processor Feature Register 2 -__register 32 { 11:8 RAS_frac, 7:4 SSBS, 3:0 CSV3 } ID_PFR2_EL1; - -// Peripheral Identification Register 3 -__register 32 { 7:4 REVAND, 3:0 CMOD, 7:4 REVISION } ERRPIDR3; - -// Component Identification Register 3 -__register 32 { 7:0 PRMBL_3 } ERRCIDR3; - -// Auxiliary Control Register (EL3) -__register 64 { } ACTLR_EL3; - -// Current Cache Size ID Register 2 -__register 32 { 23:0 NumSets } CCSIDR2; - -// Interrupt Controller Hyp Control Register -__register 32 { 31:27 EOIcount, 14:14 TDIR, 13:13 TSEI, 12:12 TALL1, 11:11 TALL0, 10:10 TC, 8:8 vSGIEOICount, 7:7 VGrp1DIE, 6:6 VGrp1EIE, 5:5 VGrp0DIE, 4:4 VGrp0EIE, 3:3 NPIE, 2:2 LRENPIE, 1:1 UIE, 0:0 En } ICH_HCR_EL2; - -// Interrupt Controller Empty List Register Status Register -__register 32 { } ICH_ELRSR_EL2; - -// Interrupt Group Registers (extended SPI range) -array [0..31] of __register 32 { } GICD_IGROUPRE; - -// Activity Monitors Device Affinity Register 1 -__register 32 { 31:0 MPIDR_EL1hi } AMDEVAFF1; - -// Instruction Fault Status Register -__register 32 { 16:16 FnV, 12:12 ExT, 9:9 LPAE, 5:0 STATUS, 10:10, 3:0 FS } IFSR; - -// Activity Monitors Event Counter Registers 1 -array [0..15] of __register 64 { 63:0 ACNT } AMEVCNTR1_EL0; - -// Virtual Deferred Interrupt Status Register -__register 32 { 31:31 A, 15:14 AET, 12:12 ExT, 9:9 LPAE, 5:0 STATUS, 10:10, 3:0 FS } VDISR; - -// PL0 Read-Only Software Thread ID Register -__register 32 { } TPIDRURO; - -// Counter-timer Virtual Timer Control -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTV_CTL; - -// Redistributor Control Register -__register 32 { 31:31 UWP, 26:26 DPG1S, 25:25 DPG1NS, 24:24 DPG0, 3:3 RWP, 1:1 CES, 0:0 EnableLPIs } GICR_CTLR; - -// Counter-timer Virtual Timer TimerValue register (EL2) -__register 32 { 31:0 TimerValue } CNTHV_TVAL; - -// Sampling Event Filter Register -__register 64 { 63:63, 62:62, 61:61, 60:60, 59:59, 58:58, 57:57, 56:56, 55:55, 54:54, 53:53, 52:52, 51:51, 50:50, 49:49, 48:48, 31:31, 30:30, 29:29, 28:28, 27:27, 26:26, 25:25, 24:24, 18:18, 17:17, 15:15, 14:14, 13:13, 12:12, 11:11, 7:7, 5:5, 3:3, 1:1 E } PMSEVFR_EL1; - -// Implementation Identification Register -__register 32 { 31:20 ProductID, 19:16 Variant, 15:12 Revision, 11:0 Implementer } ERRIIDR; - -// Interrupt Status Register -__register 32 { 8:8 A, 7:7 I, 6:6 F } ISR; - -// Holds the priority of the corresponding interrupt for each extended SPI supported by the GIC. -array [0..255] of __register 32 { 31:24 Priority_offset_3B, 23:16 Priority_offset_2B, 15:8 Priority_offset_1B, 7:0 Priority_offset_0B } GICD_IPRIORITYRE; - -// CPU Interface Status Register -__register 32 { 4:4 ASV, 3:3 WROD, 2:2 RWOD, 1:1 WRD, 0:0 RRD } GICC_STATUSR; - -// MPAM Internal PARTID Narrowing Configuration Register -__register 32 { 16:16 INTERNAL, 15:0 INTPARTID } MPAMCFG_INTPARTID; - -// External Debug Execution Control Register -__register 32 { 2:2 SS, 1:1 RCE, 0:0 OSUCE } EDECR; - -// Profiling Buffer Status/syndrome Register -__register 64 { 31:26 EC, 19:19 DL, 18:18 EA, 17:17 S, 16:16 COLL, 15:0 MSS } PMBSR_EL1; - -// Counter-timer Secure Physical Timer TimerValue register (EL2) -__register 32 { 31:0 TimerValue } CNTHPS_TVAL_EL2; - -// CTI Component Identification Register 3 -__register 32 { 7:0 PRMBL_3 } CTICIDR3; - -// CTI Peripheral Identification Register 3 -__register 32 { 7:4 REVAND, 3:0 CMOD } CTIPIDR3; - -// Instruction Set Attribute Register 6 -__register 32 { 27:24 I8MM, 23:20 BF16, 19:16 SPECRES, 15:12 SB, 11:8 FHM, 7:4 DP, 3:0 JSCVT } ID_ISAR6; - -// CTI Device Affinity register 0 -__register 32 { 31:0 MPIDR_EL1lo } CTIDEVAFF0; - -// AArch32 Secure Debug Enable Register -__register 32 { 1:1 SUNIDEN, 0:0 SUIDEN } SDER32_EL3; - -// Counter-timer Hyp Control register -__register 32 { 17:17 EVNTIS, 7:4 EVNTI, 3:3 EVNTDIR, 2:2 EVNTEN, 1:1 PL1PCEN, 0:0 PL1PCTEN } CNTHCTL; - -// Interrupt Controller Virtual End Of Interrupt Register 1 -__register 32 { 23:0 INTID } ICV_EOIR1_EL1; - -// Performance Monitors Overflow Flag Status Set register -__register 32 { 31:31 C } PMOVSSET_EL0; - -// Debug Self Address Register -__register 64 { } DBGDSAR; - -// Pointer Authentication Key B for Data (bits[63:0]) -__register 64 { } APDBKeyLo_EL1; - -// Counter-timer Virtual Timer CompareValue register -__register 64 { 63:0 CompareValue } CNTV_CVAL; - -// External Debug AArch32 Processor Feature Register -__register 64 { 15:12 EL3, 11:8 EL2, 7:4 PMSA, 3:0 VMSA } EDAA32PFR; - -// Hyp Memory Attribute Indirection Register 0 -__register 32 { } HMAIR0; - -// Saved Program Status Register -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 J, 23:23 SSBS, 22:22 PAN, 21:21 DIT, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 15:10, 26:25 IT, 4:4, 3:0 M } SPSR; - -// Interrupt Group Registers -array [0..31] of __register 32 { } GICD_IGROUPR; - -// External Debug Power/Reset Control Register -__register 32 { 1:1 CWRR, 0:0 CORENPDRQ, 3:3 COREPURQ } EDPRCR; - -// Virtual Machine Aliased Interrupt Acknowledge Register -__register 32 { 24:0 INTID } GICV_AIAR; - -// Non-secure Access Control Registers -array [0..63] of __register 32 { } GICD_NSACR; - -// Statistical Profiling Control Register (EL2) -__register 64 { 7:6 PCT, 5:5 TS, 4:4 PA, 3:3 CX, 1:1 E2SPE, 0:0 E0HSPE } PMSCR_EL2; - -// Counter-timer Hypervisor Physical Timer Control register -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTHP_CTL_EL2; - -// Profiling Buffer Limit Address Register -__register 64 { 63:12 LIMIT, 2:1 FM, 0:0 E } PMBLIMITR_EL1; - -// Activity Monitors Event Counter Virtual Offset Registers 1 -array [0..15] of __register 64 { } AMEVCNTVOFF1_EL2; - -// Memory Model Feature Register 5 -__register 32 { 3:0 ETS } ID_MMFR5; - -// Memory Model Feature Register 4 -__register 32 { 31:28 EVT, 27:24 CCIDX, 23:20 LSM, 19:16 HPDS, 15:12 CnP, 11:8 XNX, 7:4 AC2, 3:0 SpecSEI } ID_MMFR4; - -// Activity Monitors Count Enable Clear Register 0 -__register 32 { } AMCNTENCLR0; - -// Interrupt Clear-Enable Registers -array [0..31] of __register 32 { } GICD_ICENABLERE; - -// Interrupt Configuration Register 1 -__register 32 { } GICR_ICFGR1; - -// Counter-timer Virtual Timer Control register -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTV_CTL_EL0; - -// Interrupt Controller Virtual Binary Point Register 0 -__register 32 { 2:0 BinaryPoint } ICV_BPR0_EL1; - -// Saved Program Status Register (FIQ mode) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 J, 23:23 SSBS, 22:22 PAN, 21:21 DIT, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 15:10, 26:25 IT, 4:0 M } SPSR_fiq; - -// Hyp Configuration Register 2 -__register 32 { 22:22 TTLBIS, 20:20 TOCU, 18:18 TICAB, 17:17 TID4, 6:6 MIOCNCE, 5:5 TEA, 4:4 TERR, 1:1 ID, 0:0 CD } HCR2; - -// Data Fault Address Register -__register 32 { } DFAR; - -// Debug CLAIM Tag Clear register -__register 32 { 7:0 CLAIM } DBGCLAIMCLR; - -// Hyp Software Thread ID Register -__register 32 { } HTPIDR; - -// Pointer Authentication Key B for Data (bits[127:64]) -__register 64 { } APDBKeyHi_EL1; - -// Hypervisor Control Register -__register 32 { 31:27 EOICount, 7:7 VGrp1DIE, 6:6 VGrp1EIE, 5:5 VGrp0DIE, 4:4 VGrp0EIE, 3:3 NPIE, 2:2 LRENPIE, 1:1 UIE, 0:0 En } GICH_HCR; - -// Floating-point Status Register -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 QC, 7:7 IDC, 4:4 IXC, 3:3 UFC, 2:2 OFC, 1:1 DZC, 0:0 IOC } FPSR; - -// Interrupt Priority Registers -array [0..7] of __register 32 { 31:24 Priority_offset_3B, 23:16 Priority_offset_2B, 15:8 Priority_offset_1B, 7:0 Priority_offset_0B } GICR_IPRIORITYR; - -// Fault Address Register (EL1) -__register 64 { } FAR_EL1; - -// Activity Monitors Event Counter Virtual Offset Registers 0 -array [0..15] of __register 64 { } AMEVCNTVOFF0_EL2; - -// Performance Monitors Count Enable Set register -__register 32 { 31:31 C } PMCNTENSET_EL0; - -// Interrupt Controller Virtual Interrupt Group 0 Enable register -__register 32 { 0:0 Enable } ICV_IGRPEN0; - -// Performance Monitors Count Enable Clear register -__register 32 { 31:31 C } PMCNTENCLR_EL0; - -// Virtualization Processor ID Register -__register 32 { 31:24 Implementer, 23:20 Variant, 19:16 Architecture, 15:4 PartNum, 3:0 Revision } VPIDR; - -// Selected Error Record Control Register -__register 32 { } ERXCTLR; - -// Report maximum PARTID and PMG Register -__register 32 { 23:16 PMGmax, 15:0 PARTIDmax } GICR_MPAMIDR; - -// Performance Monitors Control Register -__register 32 { 7:7 LP, 6:6 LC, 5:5 DP, 4:4 X, 3:3 D, 2:2 C, 1:1 P, 0:0 E, 31:24 IMP, 23:16 IDCODE, 15:11 N } PMCR_EL0; - -// MPAM Virtual PARTID Mapping Register 2 -__register 64 { 63:48 PhyPARTID11, 47:32 PhyPARTID10, 31:16 PhyPARTID9, 15:0 PhyPARTID8 } MPAMVPM2_EL2; - -// Floating-Point Exception Control register -__register 32 { 31:31 EX, 30:30 EN, 29:29 DEX, 28:28 FP2V, 27:27 VV, 26:26 TFV, 10:8 VECITR, 7:7 IDF, 4:4 IXF, 3:3 UFF, 2:2 OFF, 1:1 DZF, 0:0 IOF } FPEXC32_EL2; - -// Debug OS Lock Status Register -__register 32 { 2:2 nTT, 1:1 OSLK, 3:3, 0:0 OSLM } DBGOSLSR; - -// Performance Monitors Selected Event Count Register -__register 32 { } PMXEVCNTR_EL0; - -// Hyp Memory Attribute Indirection Register 1 -__register 32 { } HMAIR1; - -// Peripheral Identification Register 4 -__register 32 { 7:4 SIZE, 3:0 DES_2 } ERRPIDR4; - -// Instruction Set Attribute Register 5 -__register 32 { 31:28 VCMA, 27:24 RDM, 19:16 CRC32, 15:12 SHA2, 11:8 SHA1, 7:4 AES, 3:0 SEVL } ID_ISAR5; - -// Memory Model Feature Register 3 -__register 32 { 31:28 Supersec, 27:24 CMemSz, 23:20 CohWalk, 19:16 PAN, 15:12 MaintBcst, 11:8 BPMaint, 7:4 CMaintSW, 3:0 CMaintVA } ID_MMFR3; - -// Selected Error Record Control Register -__register 64 { } ERXCTLR_EL1; - -// Interrupt Controller Interrupt Acknowledge Register 1 -__register 32 { 23:0 INTID } ICC_IAR1; - -// Performance Monitors Interrupt Enable Set register -__register 32 { 31:31 C } PMINTENSET_EL1; - -// Error Group Status Register -__register 64 { } ERRGSR; - -// External Debug Component Identification Register 1 -__register 32 { 7:4 CLASS, 3:0 PRMBL_1 } EDCIDR1; - -// AArch32 Secure Debug Enable Register -__register 32 { 1:1 SUNIDEN, 0:0 SUIDEN } SDER32_EL2; - -// Activity Monitors Component Identification Register 2 -__register 32 { 7:0 PRMBL_2 } AMCIDR2; - -// Interrupt Set-Active Registers -array [1..2] of __register 32 { } GICR_ISACTIVERE; - -// Instruction Set Attribute Register 0 -__register 32 { 27:24 Divide, 23:20 Debug, 19:16 Coproc, 15:12 CmpBranch, 11:8 BitField, 7:4 BitCount, 3:0 Swap } ID_ISAR0; - -// Interrupt Controller Alias Software Generated Interrupt Group 1 Register -__register 64 { 55:48 Aff3, 47:44 RS, 40:40 IRM, 39:32 Aff2, 27:24 INTID, 23:16 Aff1, 15:0 TargetList } ICC_ASGI1R; - -// Set PARTID and PMG Register -__register 32 { 23:16 PMG, 15:0 PARTID } GICR_PARTIDR; - -// System Control Register (EL3) -__register 64 { 44:44 DSSBS, 43:43 ATA, 41:40 TCF, 37:37 ITFSB, 36:36 BT, 31:31 EnIA, 30:30 EnIB, 27:27 EnDA, 25:25 EE, 22:22 EIS, 21:21 IESB, 19:19 WXN, 13:13 EnDB, 12:12 I, 11:11 EOS, 6:6 nAA, 3:3 SA, 2:2 C, 1:1 A, 0:0 M } SCTLR_EL3; - -// OS Lock Status Register -__register 32 { 2:2 nTT, 1:1 OSLK, 3:3, 0:0 OSLM } OSLSR_EL1; - -// MPAM Long Memory Bandwidth Usage Monitor Capture Register -__register 64 { 63:63 NRDY, 62:0 VALUE } MSMON_MBWU_L_CAPTURE; - -// Interrupt Controller Deactivate Interrupt Register -__register 32 { 23:0 INTID } ICC_DIR; - -// CTI Peripheral Identification Register 2 -__register 32 { 7:4 REVISION, 3:3 JEDEC, 2:0 DES_1 } CTIPIDR2; - -// Pointer Authentication Key A for Instruction (bits[127:64]) -__register 64 { } APIAKeyHi_EL1; - -// Translation Control Register (EL2) -__register 64 { 30:30 TCMA, 29:29 TBID, 28:28 HWU62, 27:27 HWU61, 26:26 HWU60, 25:25 HWU59, 24:24 HPD, 40:40 HD, 39:39 HA, 20:20 TBI, 18:16 PS, 15:14 TG0, 13:12 SH0, 11:10 ORGN0, 9:8 IRGN0, 5:0 T0SZ, 58:58 TCMA1, 57:57 TCMA0, 56:56 E0PD1, 55:55 E0PD0, 54:54 NFD1, 53:53 NFD0, 52:52 TBID1, 51:51 TBID0, 50:50 HWU162, 49:49 HWU161, 48:48 HWU160, 47:47 HWU159, 46:46 HWU062, 45:45 HWU061, 44:44 HWU060, 43:43 HWU059, 42:42 HPD1, 41:41 HPD0, 38:38 TBI1, 37:37 TBI0, 36:36 AS, 34:32 IPS, 31:30 TG1, 29:28 SH1, 27:26 ORGN1, 25:24 IRGN1, 23:23 EPD1, 22:22 A1, 21:16 T1SZ, 7:7 EPD0 } TCR_EL2; - -// Auxiliary Fault Status Register 1 (EL1) -__register 32 { } AFSR1_EL1; - -// AArch64 Memory Model Feature Register 2 -__register 64 { 63:60 E0PD, 59:56 EVT, 55:52 BBM, 51:48 TTL, 43:40 FWB, 39:36 IDS, 35:32 AT, 31:28 ST, 27:24 NV, 23:20 CCIDX, 19:16 VARange, 15:12 IESB, 11:8 LSM, 7:4 UAO, 3:0 CnP } ID_AA64MMFR2_EL1; - -// Exception Syndrome Register (EL2) -__register 32 { 31:26 EC, 25:25 IL, 24:0 ISS } ESR_EL2; - -// Counter-timer Physical Timer TimerValue register (EL2) -__register 32 { 31:0 TimerValue } CNTHP_TVAL_EL2; - -// Counter ID registers -array [0..11] of __register 32 { } CounterID; - -// MPAM Long Memory Bandwidth Usage Monitor Register -__register 64 { 63:63 NRDY, 62:0 VALUE } MSMON_MBWU_L; - -// AArch64 Auxiliary Feature Register 0 -__register 64 { } ID_AA64AFR0_EL1; - -// Virtual Machine Aliased Highest Priority Pending Interrupt Register -__register 32 { 24:0 INTID } GICV_AHPPIR; - -// CTI Input Trigger to Output Channel Enable registers -array [0..31] of __register 32 { } CTIINEN; - -// Fault-Handling Interrupt Configuration Register 2 -__register 32 { 7:7 IRQEN, 6:6 NSMSI, 5:4 SH, 3:0 MemAttr } ERRFHICR2; - -// Interrupt Priority Registers -array [0..254] of __register 32 { 31:24 Priority_offset_3B, 23:16 Priority_offset_2B, 15:8 Priority_offset_1B, 7:0 Priority_offset_0B } GICD_IPRIORITYR; - -// Performance Monitors Cycle Count Register -__register 64 { 63:0 CCNT } PMCCNTR_EL0; - -// CTI Device Architecture register -__register 32 { 31:21 ARCHITECT, 20:20 PRESENT, 19:16 REVISION, 15:0 ARCHID } CTIDEVARCH; - -// Virtualization Multiprocessor ID Register -__register 64 { 39:32 Aff3, 30:30 U, 24:24 MT, 23:16 Aff2, 15:8 Aff1, 7:0 Aff0 } VMPIDR_EL2; - -// Hypervisor Debug Fine-Grained Write Trap Register -__register 64 { 57:57 PMUSERENR_EL0, 49:49 TRFCR_EL1, 48:48 TRCVICTLR, 46:46 TRCSSCSRn, 45:45 TRCSEQSTR, 44:44 TRCPRGCTLR, 42:42 TRCOSLAR, 41:41 TRCIMSPECn, 37:37 TRCCNTVRn, 36:36 TRCCLAIM, 35:35 TRCAUXCTLR, 33:33 TRC, 32:32 PMSLATFR_EL1, 31:31 PMSIRR_EL1, 29:29 PMSICR_EL1, 28:28 PMSFCR_EL1, 27:27 PMSEVFR_EL1, 26:26 PMSCR_EL1, 25:25 PMBSR_EL1, 24:24 PMBPTR_EL1, 23:23 PMBLIMITR_EL1, 21:21 PMCR_EL0, 20:20 PMSWINC_EL0, 19:19 PMSELR_EL0, 18:18 PMOVS, 17:17 PMINTEN, 16:16 PMCNTEN, 15:15 PMCCNTR_EL0, 14:14 PMCCFILTR_EL0, 13:13 PMEVTYPERn_EL0, 12:12 PMEVCNTRn_EL0, 11:11 OSDLR_EL1, 10:10 OSECCR_EL1, 8:8 OSLAR_EL1, 7:7 DBGPRCR_EL1, 5:5 DBGCLAIM, 4:4 MDSCR_EL1, 3:3 DBGWVRn_EL1, 2:2 DBGWCRn_EL1, 1:1 DBGBVRn_EL1, 0:0 DBGBCRn_EL1 } HDFGWTR_EL2; - -// Debug Power Control Register -__register 32 { 0:0 CORENPDRQ } DBGPRCR; - -// Interrupt Controller Hyp Active Priorities Group 0 Registers -array [0..3] of __register 64 { } ICH_AP0R_EL2; - -// Activity Monitors Device Affinity Register 0 -__register 32 { 31:0 MPIDR_EL1lo } AMDEVAFF0; - -// OS Lock Data Transfer Register, Transmit -__register 32 { } OSDTRTX_EL1; - -// External Debug Processor Status Register -__register 32 { 11:11 SDR, 10:10 SPMAD, 9:9 EPMAD, 8:8 SDAD, 7:7 EDAD, 6:6 DLK, 5:5 OSLK, 4:4 HALTED, 3:3 SR, 2:2 R, 1:1 SPD, 0:0 PU } EDPRSR; - -// Activity Monitors Device Architecture Register -__register 32 { 31:21 ARCHITECT, 20:20 PRESENT, 19:16 REVISION, 15:0 ARCHID } AMDEVARCH; - -// Interrupt Controller Type Register 2 -__register 32 { 7:7 VIL, 4:0 VID } GICD_TYPER2; - -// Program Counter Sample Register -__register 64 { 63:63 NS, 62:61 EL, 55:32, 31:0 PCSample } PMPCSR; - -// Activity Monitors Device Type Register -__register 32 { 7:4 SUB, 3:0 MAJOR } AMDEVTYPE; - -// Processor Feature Register 0 -__register 32 { 31:28 RAS, 27:24 DIT, 23:20 AMU, 19:16 CSV2, 15:12 State3, 11:8 State2, 7:4 State1, 3:0 State0 } ID_PFR0; - -// Current Exception Level -__register 64 { 3:2 EL } CurrentEL; - -// CONTEXTIDR_EL2 Sample Register -__register 32 { 31:0 CONTEXTIDR_EL2 } PMCID2SR; - -// AArch64 Processor Feature Register 0 -__register 64 { 63:60 CSV3, 59:56 CSV2, 51:48 DIT, 47:44 AMU, 43:40 MPAM, 39:36 SEL2, 35:32 SVE, 31:28 RAS, 27:24 GIC, 23:20 AdvSIMD, 19:16 FP, 15:12 EL3, 11:8 EL2, 7:4 EL1, 3:0 EL0 } ID_AA64PFR0_EL1; - -// CTI Peripheral Identification Register 4 -__register 32 { 7:4 SIZE, 3:0 DES_2 } CTIPIDR4; - -// MPAM Resource Monitoring Identification Register -__register 32 { 31:31 HAS_LOCAL_CAPT_EVNT, 17:17 MSMON_MBWU, 16:16 MSMON_CSU } MPAMF_MSMON_IDR; - -// Interrupt Controller Alias Software Generated Interrupt Group 1 Register -__register 64 { 55:48 Aff3, 47:44 RS, 40:40 IRM, 39:32 Aff2, 27:24 INTID, 23:16 Aff1, 15:0 TargetList } ICC_ASGI1R_EL1; - -// Interrupt Controller Deactivate Virtual Interrupt Register -__register 32 { 23:0 INTID } ICV_DIR; - -// Cache Type Register -__register 32 { 37:32 TminLine, 29:29 DIC, 28:28 IDC, 27:24 CWG, 23:20 ERG, 19:16 DminLine, 15:14 L1Ip, 3:0 IminLine } CTR_EL0; - -// Performance Monitors Common Event Identification register 0 -__register 64 { } PMCEID0_EL0; - -// Virtual Machine CPU Interface Identification Register -__register 32 { 31:20 ProductID, 19:16 Architecture_version, 15:12 Revision, 11:0 Implementer } GICV_IIDR; - -// CPU Interface Deactivate Interrupt Register -__register 32 { 23:0 INTID } GICC_DIR; - -// Interrupt Controller Deactivate Interrupt Register -__register 32 { 23:0 INTID } ICC_DIR_EL1; - -// MPAM Virtual PARTID Mapping Register 4 -__register 64 { 63:48 PhyPARTID19, 47:32 PhyPARTID18, 31:16 PhyPARTID17, 15:0 PhyPARTID16 } MPAMVPM4_EL2; - -// Virtual Nested Control Register -__register 64 { 63:53 RESS, 52:12 BADDR } VNCR_EL2; - -// Performance Monitors Event Counter Selection Register -__register 32 { 4:0 SEL } PMSELR; - -// Debug Watchpoint Control Registers -array [0..15] of __register 64 { 28:24 MASK, 20:20 WT, 19:16 LBN, 15:14 SSC, 13:13 HMC, 12:5 BAS, 4:3 LSC, 2:1 PAC, 0:0 E } DBGWCR_EL1; - -// Interrupt Controller Virtual Interrupt Acknowledge Register 1 -__register 32 { 23:0 INTID } ICV_IAR1; - -// Selected Error Record Control Register 2 -__register 32 { } ERXCTLR2; - -// Counter-timer Virtual Count register -__register 64 { } CNTVCT; - -// Redistributor Invalidate LPI Register -__register 64 { 63:63 V, 47:32 vPEID, 31:0 INTID } GICR_INVLPIR; - -// CTI CLAIM Tag Set register -__register 32 { } CTICLAIMSET; - -// MPAM3 Register (EL3) -__register 64 { 63:63 MPAMEN, 62:62 TRAPLOWER, 61:61 SDEFLT, 60:60 FORCE_NS, 47:40 PMG_D, 39:32 PMG_I, 31:16 PARTID_D, 15:0 PARTID_I } MPAM3_EL3; - -// Virtualization Secure Translation Table Base Register -__register 64 { 47:1 BADDR, 0:0 CnP } VSTTBR_EL2; - -// Error Record ID Register -__register 64 { 15:0 NUM } ERRIDR_EL1; - -// System Control Register -__register 32 { 31:31 DSSBS, 30:30 TE, 29:29 AFE, 28:28 TRE, 25:25 EE, 23:23 SPAN, 20:20 UWXN, 19:19 WXN, 18:18 nTWE, 16:16 nTWI, 13:13 V, 12:12 I, 10:10 EnRCTX, 8:8 SED, 7:7 ITD, 6:6 UNK, 5:5 CP15BEN, 4:4 LSMAOE, 3:3 nTLSMD, 2:2 C, 1:1 A, 0:0 M } SCTLR; - -// Device Affinity Register -__register 64 { 39:32 Aff3, 31:31 F0V, 30:30 U, 24:24 MT, 23:16 Aff2, 15:8 Aff1, 7:0 Aff0 } ERRDEVAFF; - -// Activity Monitors Peripheral Identification Register 1 -__register 32 { 7:4 DES_0, 3:0 PART_1 } AMPIDR1; - -// Hyp Translation Table Base Register -__register 64 { 47:1 BADDR, 0:0 CnP } HTTBR; - -// Error Reporting Status Register -__register 32 { 3:3 WROD, 2:2 RWOD, 1:1 WRD, 0:0 RRD } GICR_STATUSR; - -// CTI Channel Gate Enable register -__register 32 { } CTIGATE; - -// AArch64 Processor Feature Register 1 -__register 64 { 19:16 MPAM_frac, 15:12 RAS_frac, 11:8 MTE, 7:4 SSBS, 3:0 BT } ID_AA64PFR1_EL1; - -// CTI Channel In Status register -__register 32 { } CTICHINSTATUS; - -// MPAM Virtual PARTID Mapping Register 5 -__register 64 { 63:48 PhyPARTID23, 47:32 PhyPARTID22, 31:16 PhyPARTID21, 15:0 PhyPARTID20 } MPAMVPM5_EL2; - -// CTI Peripheral Identification Register 1 -__register 32 { 7:4 DES_0, 3:0 PART_1 } CTIPIDR1; - -// Interrupt Controller Virtual Binary Point Register 0 -__register 32 { 2:0 BinaryPoint } ICV_BPR0; - -// Interrupt Controller List Registers -array [0..15] of __register 32 { 31:30 State, 29:29 HW, 28:28 Group, 23:16 Priority, 12:0 pINTID } ICH_LRC; - -// Interrupt Controller Empty List Register Status Register -__register 32 { } ICH_ELRSR; - -// Critical Error Interrupt Configuration Register 0 -__register 64 { 55:2 ADDR } ERRCRICR0; - -// Interrupt Priority Registers (extended PPI range) -array [8..23] of __register 32 { 31:24 Priority_offset_3B, 23:16 Priority_offset_2B, 15:8 Priority_offset_1B, 7:0 Priority_offset_0B } GICR_IPRIORITYRE; - -// MPAM Features Identification Register -__register 64 { 59:56 RIS_MAX, 39:39 HAS_ESR, 38:38 HAS_EXTD_ESR, 37:37 NO_IMPL_MSMON, 36:36 NO_IMPL_PART, 32:32 HAS_RIS, 31:31 HAS_PARTID_NRW, 30:30 HAS_MSMON, 29:29 HAS_IMPL_IDR, 28:28 EXT, 27:27 HAS_PRI_PART, 26:26 HAS_MBW_PART, 25:25 HAS_CPOR_PART, 24:24 HAS_CCAP_PART, 23:16 PMG_MAX, 15:0 PARTID_MAX } MPAMF_IDR; - -// AArch32 Instruction Set Attribute Register 6 -__register 32 { 27:24 I8MM, 23:20 BF16, 19:16 SPECRES, 15:12 SB, 11:8 FHM, 7:4 DP, 3:0 JSCVT } ID_ISAR6_EL1; - -// Virtual Machine Control Register -__register 32 { 31:24 VPMR, 23:21 VBPR0, 20:18 VBPR1, 9:9 VEOIM, 4:4 VCBPR, 3:3 VFIQEn, 2:2 VAckCtl, 1:1 VENG1, 0:0 VENG0 } GICH_VMCR; - -// Auxiliary Memory Attribute Indirection Register 1 -__register 32 { } AMAIR1; - -// Counter-timer Virtual Timer Control register (EL2) -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTHV_CTL_EL2; - -// Pseudo-fault Generation Control Register -array [0..65534] of __register 64 { 31:31 CDNEN, 30:30 R, 12:12 MV, 11:11 AV, 10:10 PN, 9:9 ER, 8:8 CI, 7:6 CE, 5:5 DE, 4:4 UEO, 3:3 UER, 2:2 UEU, 1:1 UC, 0:0 OF } ERRPFGCTL; - -// Memory Attribute Indirection Register 1 -__register 32 { } MAIR1; - -// OS Double Lock Register -__register 32 { 0:0 DLK } OSDLR_EL1; - -// Counter-timer Virtual Timer TimerValue Register (EL2) -__register 32 { 31:0 TimerValue } CNTHV_TVAL_EL2; - -// Translation Table Base Register 0 (EL1) -__register 64 { 63:48 ASID, 47:1 BADDR, 0:0 CnP } TTBR0_EL1; - -// Monitor DCC Interrupt Enable Register -__register 32 { 30:30 RX, 29:29 TX } MDCCINT_EL1; - -// Counter-timer Physical Timer Control register -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTP_CTL_EL0; - -// Selected Error Record Miscellaneous Register 0 -__register 64 { } ERXMISC0_EL1; - -// MPAM Partition Configuration Selection Register -__register 32 { 27:24 RIS, 16:16 INTERNAL, 15:0 PARTID_SEL } MPAMCFG_PART_SEL; - -// Performance Monitors Cycle Counter Filter Register -__register 32 { 31:31 P, 30:30 U, 29:29 NSK, 28:28 NSU, 27:27 NSH, 26:26 M, 24:24 SH } PMCCFILTR_EL0; - -// CTI CLAIM Tag Clear register -__register 32 { } CTICLAIMCLR; - -// Auxiliary Data Fault Status Register -__register 32 { } ADFSR; - -// Redistributor Type Register -__register 64 { 63:32 Affinity_Value, 31:27 PPInum, 26:26 VSGI, 25:24 CommonLPIAff, 23:8 Processor_Number, 7:7 RVPEID, 6:6 MPAM, 5:5 DPGS, 4:4 Last, 3:3 DirectLPI, 2:2 Dirty, 1:1 VLPIS, 0:0 PLPIS } GICR_TYPER; - -// Counter-timer Physical Timer Control register -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTP_CTL; - -// MPAM Hypervisor Control Register (EL2) -__register 64 { 31:31 TRAP_MPAMIDR_EL1, 8:8 GSTAPP_PLK, 1:1 EL1_VPMEN, 0:0 EL0_VPMEN } MPAMHCR_EL2; - -// Performance Monitors Component Identification Register 3 -__register 32 { 7:0 PRMBL_3 } PMCIDR3; - -// Interrupt Configuration Registers -array [0..63] of __register 32 { } GICD_ICFGR; - -// Debug Data Transfer Register, Transmit -__register 32 { } DBGDTRTXint; - -// EL3 Software Thread ID Register -__register 64 { } TPIDR_EL3; - -// Interrupt Controller Virtual Interrupt Acknowledge Register 0 -__register 32 { 23:0 INTID } ICV_IAR0; - -// Error Record Feature Register -array [0..65534] of __register 64 { 54:53 CE, 52:52 DE, 51:51 UEO, 50:50 UER, 49:49 UEU, 48:48 UC, 31:31 FRX, 25:24 TS, 23:22 CI, 21:20 INJ, 19:18 CEO, 17:16 DUI, 15:15 RP, 14:12 CEC, 11:10 CFI, 9:8 UE, 7:6 FI, 5:4 UI, 1:0 ED } ERRFR; - -// ITS Translation Register -__register 32 { 31:0 EventID } GITS_TRANSLATER; - -// MPAM2 Register (EL2) -__register 64 { 63:63 MPAMEN, 58:58 TIDR, 49:49 TRAPMPAM0EL1, 48:48 TRAPMPAM1EL1, 47:40 PMG_D, 39:32 PMG_I, 31:16 PARTID_D, 15:0 PARTID_I } MPAM2_EL2; - -// Debug Breakpoint Control Registers -array [0..15] of __register 32 { 23:20 BT, 19:16 LBN, 15:14 SSC, 13:13 HMC, 8:5 BAS, 2:1 PMC, 0:0 E } DBGBCR; - -// MPAM Virtual PARTID Mapping Register 0 -__register 64 { 63:48 PhyPARTID3, 47:32 PhyPARTID2, 31:16 PhyPARTID1, 15:0 PhyPARTID0 } MPAMVPM0_EL2; - -// Peripheral Identification Register 2 -__register 32 { 7:4 REVISION, 3:3 JEDEC, 2:0 DES_1, 7:4 PART_2 } ERRPIDR2; - -// Random Allocation Tag Seed Register. -__register 32 { 23:8 SEED, 3:0 TAG } RGSR_EL1; - -// Media and VFP Feature Register 1 -__register 32 { 31:28 SIMDFMAC, 27:24 FPHP, 23:20 SIMDHP, 19:16 SIMDSP, 15:12 SIMDInt, 11:8 SIMDLS, 7:4 FPDNaN, 3:0 FPFtZ } MVFR1; - -// Debug Vector Catch Register -__register 32 { 31:31 NSF, 30:30 NSI, 28:28 NSD, 27:27 NSP, 26:26 NSS, 25:25 NSU, 15:15 MF, 14:14 MI, 12:12 MD, 11:11 MP, 10:10 MS, 7:7 SF, 6:6 SI, 4:4 SD, 3:3 SP, 2:2 SS, 1:1 SU, 7:7 F, 6:6 I, 4:4 D, 3:3 P, 2:2 S, 1:1 U } DBGVCR; - -// Activity Monitors Configuration Register -__register 64 { 31:28 NCG, 24:24 HDBG, 13:8 SIZE, 7:0 N } AMCFGR_EL0; - -// Performance Monitors Software Increment register -__register 32 { } PMSWINC; - -// Stack Pointer (EL2) -__register 64 { } SP_EL2; - -// Saved Program Status Register (Hyp mode) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 J, 23:23 SSBS, 22:22 PAN, 21:21 DIT, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 15:10, 26:25 IT, 4:0 M } SPSR_hyp; - -// Deferred Interrupt Status Register -__register 32 { 31:31 A, 15:14 AET, 9:9 EA, 5:0 DFSC, 12:12 ExT, 9:9 LPAE, 5:0 STATUS, 10:10, 3:0 FS } DISR; - -// Activity Monitors Event Type Registers 1 -array [0..15] of __register 64 { 15:0 evtCount } AMEVTYPER1_EL0; - -// Interrupt Clear-Pending Register 0 -__register 32 { } GICR_ICPENDR0; - -// ITS Type Register -__register 64 { 43:43 nID, 42:41 SVPET, 40:40 VMAPP, 39:39 VSGI, 38:38 MPAM, 37:37 VMOVP, 36:36 CIL, 35:32 CIDbits, 31:24 HCC, 19:19 PTA, 18:18 SEIS, 17:13 Devbits, 12:8 ID_bits, 7:4 ITT_entry_size, 2:2 CCT, 1:1 Virtual, 0:0 Physical } GITS_TYPER; - -// Interrupt Controller Software Generated Interrupt Group 0 Register -__register 64 { 55:48 Aff3, 47:44 RS, 40:40 IRM, 39:32 Aff2, 27:24 INTID, 23:16 Aff1, 15:0 TargetList } ICC_SGI0R_EL1; - -// Interrupt Controller Virtual Interrupt Acknowledge Register 1 -__register 32 { 23:0 INTID } ICV_IAR1_EL1; - -// Error Record Primary Status Register -array [0..65534] of __register 64 { 31:31 AV, 30:30 V, 29:29 UE, 28:28 ER, 27:27 OF, 26:26 MV, 25:24 CE, 23:23 DE, 22:22 PN, 21:20 UET, 19:19 CI, 15:8 IERR, 7:0 SERR } ERRSTATUS; - -// MPAM Virtual PARTID Mapping Register 1 -__register 64 { 63:48 PhyPARTID7, 47:32 PhyPARTID6, 31:16 PhyPARTID5, 15:0 PhyPARTID4 } MPAMVPM1_EL2; - -// Pointer Authentication Key A for Instruction (bits[63:0]) -__register 64 { } APIAKeyLo_EL1; - -// Instruction Set Attribute Register 2 -__register 32 { 31:28 Reversal, 27:24 PSR_AR, 23:20 MultU, 19:16 MultS, 15:12 Mult, 11:8 MultiAccessInt, 7:4 MemHint, 3:0 LoadStore } ID_ISAR2; - -// Performance Monitors Interrupt Enable Clear register -__register 32 { 31:31 C } PMINTENCLR_EL1; - -// Secure Configuration Register -__register 64 { 35:35 AMVOFFEN, 33:30 TWEDEL, 29:29 TWEDEn, 28:28 ECVEn, 27:27 FGTEn, 26:26 ATA, 25:25 EnSCXT, 21:21 FIEN, 20:20 NMEA, 19:19 EASE, 18:18 EEL2, 17:17 API, 16:16 APK, 15:15 TERR, 14:14 TLOR, 13:13 TWE, 12:12 TWI, 11:11 ST, 10:10 RW, 9:9 SIF, 8:8 HCE, 7:7 SMD, 3:3 EA, 2:2 FIQ, 1:1 IRQ, 0:0 NS } SCR_EL3; - -// MPAM Error Status Register -__register 64 { 35:32 RIS, 31:31 OVRWR, 27:24 ERRCODE, 23:16 PMG, 15:0 PARTID_MON } MPAMF_ESR; - -// MPAM Features Cache Portion Partitioning ID register -__register 32 { 15:0 CPBM_WD } MPAMF_CPOR_IDR; - -// Interrupt Controller End Of Interrupt Register 1 -__register 32 { 23:0 INTID } ICC_EOIR1_EL1; - -// CTI Component Identification Register 0 -__register 32 { 7:0 PRMBL_0 } CTICIDR0; - -// System Control Register (EL1) -__register 64 { 49:46 TWEDEL, 45:45 TWEDEn, 44:44 DSSBS, 43:43 ATA, 42:42 ATA0, 41:40 TCF, 39:38 TCF0, 37:37 ITFSB, 36:36 BT1, 35:35 BT0, 31:31 EnIA, 30:30 EnIB, 29:29 LSMAOE, 28:28 nTLSMD, 27:27 EnDA, 26:26 UCI, 25:25 EE, 24:24 E0E, 23:23 SPAN, 22:22 EIS, 21:21 IESB, 20:20 TSCXT, 19:19 WXN, 18:18 nTWE, 16:16 nTWI, 15:15 UCT, 14:14 DZE, 13:13 EnDB, 12:12 I, 11:11 EOS, 10:10 EnRCTX, 9:9 UMA, 8:8 SED, 7:7 ITD, 6:6 nAA, 5:5 CP15BEN, 4:4 SA0, 3:3 SA, 2:2 C, 1:1 A, 0:0 M } SCTLR_EL1; - -// External Debug Peripheral Identification Register 3 -__register 32 { 7:4 REVAND, 3:0 CMOD } EDPIDR3; - -// Debug Data Transfer Register, Receive -__register 32 { } DBGDTRRX_EL0; - -// External Debug Device ID register 0 -__register 32 { 27:24 AuxRegs, 7:4 DebugPower, 3:0 PCSample } EDDEVID; - -// MPAM Bandwidth Portion Bitmap Partition Configuration Register -__register 4096 { } MPAMCFG_MBW_PBM; - -// Activity Monitors User Enable Register -__register 32 { 0:0 EN } AMUSERENR; - -// Interrupt Controller Virtual Interrupt Group 1 Enable register -__register 32 { 0:0 Enable } ICV_IGRPEN1_EL1; - -// MPAM Monitor Instance Selection Register -__register 32 { 27:24 RIS, 15:0 MON_SEL } MSMON_CFG_MON_SEL; - -// Memory Attribute Indirection Register 0 -__register 32 { } MAIR0; - -// Pointer Authentication Key B for Instruction (bits[127:64]) -__register 64 { } APIBKeyHi_EL1; - -// Context ID Register (EL2) -__register 32 { 31:0 PROCID } CONTEXTIDR_EL2; - -// Counter-timer Frequency register -__register 32 { } CNTFRQ; - -// Counter-timer Access Control Registers -array [0..7] of __register 32 { 5:5 RWPT, 4:4 RWVT, 3:3 RVOFF, 2:2 RFRQ, 1:1 RVCT, 0:0 RPCT } CNTACR; - -// Interrupt Clear-Enable Registers -array [1..2] of __register 32 { } GICR_ICENABLERE; - -// Counter-timer Secure Virtual Timer TimerValue register (EL2) -__register 32 { 31:0 TimerValue } CNTHVS_TVAL_EL2; - -// Selected Error Record Feature Register -__register 32 { } ERXFR; - -// Virtual Machine End Of Interrupt Register -__register 32 { 24:0 INTID } GICV_EOIR; - -// MPAM Features Secure Identification Register -__register 32 { 23:16 S_PMG_MAX, 15:0 S_PARTID_MAX } MPAMF_SIDR; - -// Jazelle Main Configuration Register -__register 32 { } JMCR; - -// Interrupt Controller System Register Enable register (EL2) -__register 32 { 3:3 Enable, 2:2 DIB, 1:1 DFB, 0:0 SRE } ICC_SRE_EL2; - -// MPAM Memory Bandwidth Usage Monitor Register -__register 32 { 31:31 NRDY, 30:0 VALUE } MSMON_MBWU; - -// Interrupt Controller Virtual End Of Interrupt Register 0 -__register 32 { 23:0 INTID } ICV_EOIR0; - -// Interrupt Controller End of Interrupt Status Register -__register 32 { } ICH_EISR_EL2; - -// Activity Monitors Peripheral Identification Register 3 -__register 32 { 7:4 REVAND, 3:0 CMOD } AMPIDR3; - -// Debug Breakpoint Value Registers -array [0..15] of __register 64 { 31:0 ContextID, 63:32 ContextID2, 63:53, 52:49 RESS, 52:49, 48:2 VA, 47:40, 47:40, 39:32, 39:32 VMID } DBGBVR_EL1; - -// Pointer Authentication Key A for Data (bits[127:64]) -__register 64 { } APDAKeyHi_EL1; - -// Context ID Register -__register 32 { 31:0 PROCID, 7:0 ASID } CONTEXTIDR; - -// Auxiliary Fault Status Register 0 (EL1) -__register 32 { } AFSR0_EL1; - -// CTI Device Type register -__register 32 { 7:4 SUB, 3:0 MAJOR } CTIDEVTYPE; - -// Set Secure SPI Pending Register -__register 32 { 12:0 INTID } GICD_SETSPI_SR; - -// Counter-timer Secure Physical Timer CompareValue Register (EL2) -__register 64 { 63:0 CompareValue } CNTHPS_CVAL; - -// Debug CLAIM Tag Set register -__register 32 { 7:0 CLAIM } DBGCLAIMSET; - -// Selected Error Record Miscellaneous Register 3 -__register 32 { } ERXMISC3; - -// Auxiliary ID Register -__register 32 { } AIDR_EL1; - -// Interrupt Controller Virtual Machine Control Register -__register 32 { 31:24 VPMR, 23:21 VBPR0, 20:18 VBPR1, 9:9 VEOIM, 4:4 VCBPR, 3:3 VFIQEn, 2:2 VAckCtl, 1:1 VENG1, 0:0 VENG0 } ICH_VMCR; - -// Hypervisor Auxiliary Control Register -__register 32 { } HACR_EL2; - -// External Debug Component Identification Register 2 -__register 32 { 7:0 PRMBL_2 } EDCIDR2; - -// Activity Monitors Count Enable Set Register 1 -__register 32 { } AMCNTENSET1; - -// CTI Application Pulse register -__register 32 { } CTIAPPPULSE; - -// Sampling Interval Reload Register -__register 64 { 31:8 INTERVAL, 0:0 RND } PMSIRR_EL1; - -// Tag Control Register. -__register 64 { 16:16 RRND, 15:0 Exclude } GCR_EL1; - -// Fault Address Register (EL3) -__register 64 { } FAR_EL3; - -// Jazelle ID Register -__register 32 { } JIDR; - -// SVE Control Register for EL3 -__register 64 { 3:0 LEN } ZCR_EL3; - -// Processor Feature Register 2 -__register 32 { 11:8 RAS_frac, 7:4 SSBS, 3:0 CSV3 } ID_PFR2; - -// Empty List Register Status Register -__register 32 { } GICH_ELRSR; - -// Vector Base Address Register -__register 32 { } VBAR; - -// Interrupt Controller End of Interrupt Status Register -__register 32 { } ICH_EISR; - -// User Access Override -__register 32 { 23:23 UAO } UAO; - -// Multiprocessor Affinity Register -__register 32 { 31:31 M, 30:30 U, 24:24 MT, 23:16 Aff2, 15:8 Aff1, 7:0 Aff0 } MPIDR; - -// Counter-timer Hyp Physical Timer Control register -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTHP_CTL; - -// Error Recovery Interrupt Configuration Register 0 -__register 64 { 55:2 ADDR } ERRERICR0; - -// Trace Filter Control Register (EL1) -__register 64 { 6:5 TS, 1:1 E1TRE, 0:0 E0TRE } TRFCR_EL1; - -// Performance Monitors Event Counter Selection Register -__register 32 { 4:0 SEL } PMSELR_EL0; - -// Activity Monitors Counter Group Configuration Register -__register 32 { 15:8 CG1NC, 7:0 CG0NC } AMCGCR; - -// PL1 Software Thread ID Register -__register 32 { } TPIDRPRW; - -// Interrupt Controller Interrupt Group 1 Enable register -__register 32 { 0:0 Enable } ICC_IGRPEN1; - -// Interrupt Controller Active Priorities Group 1 Registers -array [0..3] of __register 32 { } ICC_AP1R; - -// CTI Device ID register 1 -__register 32 { } CTIDEVID1; - -// Virtual Machine Aliased End Of Interrupt Register -__register 32 { 24:0 INTID } GICV_AEOIR; - -// AArch32 Auxiliary Feature Register 0 -__register 32 { } ID_AFR0_EL1; - -// Translation Table Base Register 0 (EL3) -__register 64 { 47:1 BADDR, 0:0 CnP } TTBR0_EL3; - -// External Debug Watchpoint Address Register -__register 64 { } EDWAR; - -// MPAM Features Cache Capacity Partitioning ID register -__register 32 { 5:0 CMAX_WD } MPAMF_CCAP_IDR; - -// Interrupt Status Register -__register 32 { 8:8 A, 7:7 I, 6:6 F } ISR_EL1; - -// Interrupt Controller Control Register -__register 32 { 19:19 ExtRange, 18:18 RSS, 15:15 A3V, 14:14 SEIS, 13:11 IDbits, 10:8 PRIbits, 6:6 PMHE, 1:1 EOImode, 0:0 CBPR } ICC_CTLR; - -// Counter-timer Self-Synchronized Virtual Count register -__register 64 { } CNTVCTSS_EL0; - -// Sampling Profiling ID Register -__register 64 { 19:16 CountSize, 15:12 MaxSize, 11:8 Interval, 5:5 ERnd, 4:4 LDS, 3:3 ArchInst, 2:2 FL, 1:1 FT, 0:0 FE } PMSIDR_EL1; - -// Secure Configuration Register -__register 32 { 15:15 TERR, 13:13 TWE, 12:12 TWI, 9:9 SIF, 8:8 HCE, 7:7 SCD, 6:6 nET, 5:5 AW, 4:4 FW, 3:3 EA, 2:2 FIQ, 1:1 IRQ, 0:0 NS } SCR; - -// CPU Interface Highest Priority Pending Interrupt Register -__register 32 { 23:0 INTID } GICC_HPPIR; - -// Interrupt Controller Virtual Highest Priority Pending Interrupt Register 0 -__register 32 { 23:0 INTID } ICV_HPPIR0_EL1; - -// ITS Command Queue Descriptor -__register 64 { 63:63 Valid, 61:59 InnerCache, 55:53 OuterCache, 51:12 Physical_Address, 11:10 Shareability, 7:0 Size } GITS_CBASER; - -// Interrupt Controller List Registers -array [0..15] of __register 64 { 63:62 State, 61:61 HW, 60:60 Group, 55:48 Priority, 44:32 pINTID, 31:0 vINTID } ICH_LR_EL2; - -// Hyp Data Fault Address Register -__register 32 { } HDFAR; - -// Activity Monitors Count Enable Clear Register 1 -__register 64 { } AMCNTENCLR1_EL0; - -// LORegionID (EL1) -__register 64 { 23:16 LD, 7:0 LR } LORID_EL1; - -// Interrupt Controller Highest Priority Pending Interrupt Register 1 -__register 32 { 23:0 INTID } ICC_HPPIR1; - -// Interrupt Group Registers -array [1..2] of __register 32 { } GICR_IGROUPRE; - -// LORegion Control (EL1) -__register 64 { 9:2 DS, 0:0 EN } LORC_EL1; - -// Interrupt configuration registers -array [2..5] of __register 32 { } GICR_ICFGRE; - -// Interrupt Controller Deactivate Virtual Interrupt Register -__register 32 { 23:0 INTID } ICV_DIR_EL1; - -// Debug Watchpoint Control Registers -array [0..15] of __register 32 { 28:24 MASK, 20:20 WT, 19:16 LBN, 15:14 SSC, 13:13 HMC, 12:5 BAS, 4:3 LSC, 2:1 PAC, 0:0 E } DBGWCR; - -// SVE Feature ID register 0 -__register 64 { 59:56 F64MM, 55:52 F32MM, 47:44 I8MM, 23:20 BF16, 3:0 SVEver } ID_AA64ZFR0_EL1; - -// Tag Fault Status Register (EL2) -__register 64 { 1:1 TF1, 0:0 TF0 } TFSR_EL2; - -// Instruction Set Attribute Register 3 -__register 32 { 31:28 T32EE, 27:24 TrueNOP, 23:20 T32Copy, 19:16 TabBranch, 15:12 SynchPrim, 11:8 SVC, 7:4 SIMD, 3:0 Saturate } ID_ISAR3; - -// Error Record Miscellaneous Register 3 -array [0..65534] of __register 64 { 63:0 TS } ERRMISC3; - -// Domain Access Control Register -__register 32 { } DACR; - -// AArch32 Instruction Set Attribute Register 5 -__register 32 { 31:28 VCMA, 27:24 RDM, 19:16 CRC32, 15:12 SHA2, 11:8 SHA1, 7:4 AES, 3:0 SEVL } ID_ISAR5_EL1; - -// AArch64 Instruction Set Attribute Register 0 -__register 64 { 63:60 RNDR, 59:56 TLB, 55:52 TS, 51:48 FHM, 47:44 DP, 43:40 SM4, 39:36 SM3, 35:32 SHA3, 31:28 RDM, 23:20 Atomic, 19:16 CRC32, 15:12 SHA2, 11:8 SHA1, 7:4 AES } ID_AA64ISAR0_EL1; - -// Floating-Point Status and Control Register -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 QC, 26:26 AHP, 25:25 DN, 24:24 FZ, 23:22 RMode, 21:20 Stride, 19:19 FZ16, 18:16 Len, 15:15 IDE, 12:12 IXE, 11:11 UFE, 10:10 OFE, 9:9 DZE, 8:8 IOE, 7:7 IDC, 4:4 IXC, 3:3 UFC, 2:2 OFC, 1:1 DZC, 0:0 IOC } FPSCR; - -// Interrupt Clear-Enable Register 0 -__register 32 { } GICR_ICENABLER0; - -// External Debug Device Architecture register -__register 32 { 31:21 ARCHITECT, 20:20 PRESENT, 19:16 REVISION, 15:12 ARCHVER, 11:0 ARCHPART } EDDEVARCH; - -// Redistributor LPI Pending Table Base Address Register -__register 64 { 62:62 PTZ, 58:56 OuterCache, 51:16 Physical_Address, 11:10 Shareability, 9:7 InnerCache } GICR_PENDBASER; - -// Component Identification Register 0 -__register 32 { 7:0 PRMBL_0 } ERRCIDR0; - -// Selected Error Record Address Register 2 -__register 32 { } ERXADDR2; - -// Distributor Implementer Identification Register -__register 32 { 31:24 ProductID, 19:16 Variant, 15:12 Revision, 11:0 Implementer } GICD_IIDR; - -// Debug Feature Register 0 -__register 32 { 31:28 TraceFilt, 27:24 PerfMon, 23:20 MProfDbg, 11:8 MMapDbg, 7:4 CopSDbg, 3:0 CopDbg } ID_DFR0; - -// Interrupt Controller Virtual Interrupt Priority Mask Register -__register 32 { 7:0 Priority } ICV_PMR; - -// Counter Frequency IDs, n > 0 -array [1..1003] of __register 32 { 31:0 Frequency } CNTFID; - -// SVE Control Register for EL2 -__register 64 { 3:0 LEN } ZCR_EL2; - -// Sampling Interval Counter Register -__register 64 { 63:56 ECOUNT, 31:0 COUNT } PMSICR_EL1; - -// Report maximum PARTID and PMG Register -__register 32 { 23:16 PMGmax, 15:0 PARTIDmax } GITS_MPAMIDR; - -// Debug Device ID register 1 -__register 32 { 3:0 PCSROffset } DBGDEVID1; - -// Selected Error Record Miscellaneous Register 7 -__register 32 { } ERXMISC7; - -// Component Identification Register 2 -__register 32 { 7:0 PRMBL_2 } ERRCIDR2; - -// Interrupt Controller Hyp Active Priorities Group 1 Registers -array [0..3] of __register 32 { } ICH_AP1R; - -// Performance Monitors Common Event Identification register 0 -__register 32 { } PMCEID0; - -// Virtual SError Exception Syndrome Register -__register 32 { 15:14 AET, 12:12 ExT } VDFSR; - -// Performance Monitors Common Event Identification register 1 -__register 32 { } PMCEID1; - -// Interrupt Clear-Enable Registers -array [0..31] of __register 32 { } GICD_ICENABLER; - -// Monitor Debug Configuration Register (EL2) -__register 32 { 28:28 MTPME, 27:27 TDCC, 26:26 HLP, 23:23 HCCD, 19:19 TTRF, 17:17 HPMD, 14:14 TPMS, 13:12 E2PB, 11:11 TDRA, 10:10 TDOSA, 9:9 TDA, 8:8 TDE, 7:7 HPME, 6:6 TPM, 5:5 TPMCR, 4:0 HPMN } MDCR_EL2; - -// Interrupt Controller Binary Point Register 0 -__register 32 { 2:0 BinaryPoint } ICC_BPR0_EL1; - -// Activity Monitors Counter Group Configuration Register -__register 64 { 15:8 CG1NC, 7:0 CG0NC } AMCGCR_EL0; - -// Debug Status and Control Register, External View -__register 32 { 31:31 TFO, 30:30 RXfull, 29:29 TXfull, 27:27 RXO, 26:26 TXU, 23:22 INTdis, 21:21 TDA, 19:19 SC2, 18:18 NS, 17:17 SPNIDdis, 16:16 SPIDdis, 15:15 MDBGen, 14:14 HDE, 12:12 UDCCdis, 6:6 ERR, 5:2 MOE } DBGDSCRext; - -// Counter-timer Secure Virtual Timer CompareValue Register (EL2) -__register 64 { 63:0 CompareValue } CNTHVS_CVAL; - -// Interrupt Controller Highest Priority Pending Interrupt Register 1 -__register 32 { 23:0 INTID } ICC_HPPIR1_EL1; - -// Instruction Fault Status Register (EL2) -__register 32 { 16:16 FnV, 12:12 ExT, 9:9 LPAE, 5:0 STATUS, 10:10, 3:0 FS } IFSR32_EL2; - -// Virtual Machine Aliased Binary Point Register -__register 32 { 2:0 Binary_Point } GICV_ABPR; - -// Interrupt Set-Enable Register 0 -__register 32 { } GICR_ISENABLER0; - -// Exception Link Register (EL3) -__register 64 { } ELR_EL3; - -// List Registers -array [0..15] of __register 32 { 31:31 HW, 30:30 Group, 29:28 State, 27:23 Priority, 19:10 pINTID, 9:0 vINTID } GICH_LR; - -// Redistributor Properties Base Address Register -__register 64 { 58:56 OuterCache, 51:12 Physical_Address, 11:10 Shareability, 9:7 InnerCache, 4:0 IDbits } GICR_PROPBASER; - -// Data Fault Status Register -__register 32 { 16:16 FnV, 15:14 AET, 13:13 CM, 12:12 ExT, 11:11 WnR, 9:9 LPAE, 7:4 Domain, 5:0 STATUS, 10:10, 3:0 FS } DFSR; - -// Debug CLAIM Tag Set register -__register 32 { 7:0 CLAIM } DBGCLAIMSET_EL1; - -// Translation Table Base Register 1 -__register 64 { 31:7 TTB1, 5:5 NOS, 4:3 RGN, 2:2 IMP, 1:1 S, 55:48 ASID, 47:1 BADDR, 0:0 CnP, 6:6, 0:0 IRGN } TTBR1; - -// Auxiliary Control Register -__register 32 { } ACTLR; - -// Saved Program Status Register (EL3) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 DIT, 12:12 SSBS, 22:22 PAN, 21:21 SS, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 25:25 TCO, 23:23 UAO, 11:10 BTYPE, 9:9 D, 15:10, 26:25 IT, 4:4, 4:4, 3:0, 3:0 M } SPSR_EL3; - -// Counter Status Register -__register 32 { 31:8 FCACK, 1:1 DBGH } CNTSR; - -// Interrupt Controller Virtual End Of Interrupt Register 1 -__register 32 { 23:0 INTID } ICV_EOIR1; - -// Debug OS Lock Data Transfer Register, Transmit -__register 32 { } DBGDTRTXext; - -// Performance Monitors Selected Event Type Register -__register 32 { } PMXEVTYPER_EL0; - -// Counter-timer Secure Physical Timer TimerValue Register (EL2) -__register 32 { 31:0 TimerValue } CNTHPS_TVAL; - -// Hyp Syndrome Register -__register 32 { 31:26 EC, 25:25 IL, 24:0 ISS } HSR; - -// Virtualization Multiprocessor ID Register -__register 32 { 31:31 M, 30:30 U, 24:24 MT, 23:16 Aff2, 15:8 Aff1, 7:0 Aff0 } VMPIDR; - -// Debug Data Transfer Register, Transmit -__register 32 { } DBGDTRTX_EL0; - -// Interrupt Controller Hyp Active Priorities Group 0 Registers -array [0..3] of __register 32 { } ICH_AP0R; - -// External Debug Device Type register -__register 32 { 7:4 SUB, 3:0 MAJOR } EDDEVTYPE; - -// Interrupt Group Modifier Registers -array [0..31] of __register 32 { } GICD_IGRPMODR; - -// SGI Clear-Pending Registers -array [0..3] of __register 32 { } GICD_CPENDSGIR; - -// Activity Monitors Peripheral Identification Register 0 -__register 32 { 7:0 PART_0 } AMPIDR0; - -// Interrupt Controller Active Priorities Group 1 Registers -array [0..3] of __register 64 { } ICC_AP1R_EL1; - -// Redistributor Synchronize Register -__register 32 { 0:0 Busy } GICR_SYNCR; - -// Interrupt Controller Maintenance Interrupt State Register -__register 32 { 7:7 VGrp1D, 6:6 VGrp1E, 5:5 VGrp0D, 4:4 VGrp0E, 3:3 NP, 2:2 LRENP, 1:1 U, 0:0 EOI } ICH_MISR_EL2; - -// AArch32 Instruction Set Attribute Register 2 -__register 32 { 31:28 Reversal, 27:24 PSR_AR, 23:20 MultU, 19:16 MultS, 15:12 Mult, 11:8 MultiAccessInt, 7:4 MemHint, 3:0 LoadStore } ID_ISAR2_EL1; - -// Interrupt Routing Registers (Extended SPI Range) -array [0..1023] of __register 64 { 39:32 Aff3, 31:31 Interrupt_Routing_Mode, 23:16 Aff2, 15:8 Aff1, 7:0 Aff0 } GICD_IROUTERE; - -// Virtual Machine Control Register -__register 32 { 9:9 EOImode, 4:4 CBPR, 3:3 FIQEn, 2:2 AckCtl, 1:1 EnableGrp1, 0:0 EnableGrp0 } GICV_CTLR; - -// Error Record ID Register -__register 32 { 15:0 NUM } ERRIDR; - -// Condition Flags -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V } NZCV; - -// Interrupt Clear-Active Registers (extended SPI range) -array [0..31] of __register 32 { } GICD_ICACTIVERE; - -// Interrupt Controller Interrupt Priority Mask Register -__register 32 { 7:0 Priority } ICC_PMR; - -// CTI Component Identification Register 2 -__register 32 { 7:0 PRMBL_2 } CTICIDR2; - -// System Control Register (EL2) -__register 64 { 44:44 DSSBS, 43:43 ATA, 41:40 TCF, 37:37 ITFSB, 36:36 BT, 31:31 EnIA, 30:30 EnIB, 27:27 EnDA, 25:25 EE, 22:22 EIS, 21:21 IESB, 19:19 WXN, 13:13 EnDB, 12:12 I, 11:11 EOS, 6:6 nAA, 3:3 SA, 2:2 C, 1:1 A, 0:0 M, 49:46 TWEDEL, 45:45 TWEDEn, 42:42 ATA0, 39:38 TCF0, 36:36 BT1, 35:35 BT0, 29:29 LSMAOE, 28:28 nTLSMD, 26:26 UCI, 24:24 E0E, 23:23 SPAN, 20:20 TSCXT, 18:18 nTWE, 16:16 nTWI, 15:15 UCT, 14:14 DZE, 10:10 EnRCTX, 8:8 SED, 7:7 ITD, 5:5 CP15BEN, 4:4 SA0 } SCTLR_EL2; - -// Interrupt Set-Pending Register 0 -__register 32 { } GICR_ISPENDR0; - -// Non-secure Access Control Registers -array [0..63] of __register 32 { } GICD_NSACRE; - -// Virtual Type Register -__register 32 { 31:29 PRIbits, 28:26 PREbits, 25:23 IDbits, 22:22 SEIS, 21:21 A3V, 4:0 ListRegs } GICH_VTR; - -// Translation Table Base Control Register 2 -__register 32 { 18:18 HWU162, 17:17 HWU161, 16:16 HWU160, 15:15 HWU159, 14:14 HWU062, 13:13 HWU061, 12:12 HWU060, 11:11 HWU059, 10:10 HPD1, 9:9 HPD0 } TTBCR2; - -// Activity Monitors Peripheral Identification Register 4 -__register 32 { 7:4 SIZE, 3:0 DES_2 } AMPIDR4; - -// Hypervisor Fine-Grained Read Trap Register -__register 64 { 49:49 ERXADDR_EL1, 48:48 ERXPFGCDN_EL1, 47:47 ERXPFGCTL_EL1, 46:46 ERXPFGF_EL1, 45:45 ERXMISCn_EL1, 44:44 ERXSTATUS_EL1, 43:43 ERXCTLR_EL1, 42:42 ERXFR_EL1, 41:41 ERRSELR_EL1, 40:40 ERRIDR_EL1, 39:39 ICC_IGRPENn_EL1, 38:38 VBAR_EL1, 37:37 TTBR1_EL1, 36:36 TTBR0_EL1, 35:35 TPIDR_EL0, 34:34 TPIDRRO_EL0, 33:33 TPIDR_EL1, 32:32 TCR_EL1, 31:31 SCXTNUM_EL0, 30:30 SCXTNUM_EL1, 29:29 SCTLR_EL1, 28:28 REVIDR_EL1, 27:27 PAR_EL1, 26:26 MPIDR_EL1, 25:25 MIDR_EL1, 24:24 MAIR_EL1, 23:23 LORSA_EL1, 22:22 LORN_EL1, 21:21 LORID_EL1, 20:20 LOREA_EL1, 19:19 LORC_EL1, 18:18 ISR_EL1, 17:17 FAR_EL1, 16:16 ESR_EL1, 15:15 DCZID_EL0, 14:14 CTR_EL0, 13:13 CSSELR_EL1, 12:12 CPACR_EL1, 11:11 CONTEXTIDR_EL1, 10:10 CLIDR_EL1, 9:9 CCSIDR_EL1, 8:8 APIBKey, 7:7 APIAKey, 6:6 APGAKey, 5:5 APDBKey, 4:4 APDAKey, 3:3 AMAIR_EL1, 2:2 AIDR_EL1, 1:1 AFSR1_EL1, 0:0 AFSR0_EL1 } HFGRTR_EL2; - -// Counter Count Value register -__register 64 { 63:0 CountValue } CNTCV; - -// Component Identification Register 1 -__register 32 { 7:4 CLASS, 3:0 PRMBL_1 } ERRCIDR1; - -// Physical Address Register -__register 64 { 39:12 PA, 11:11 LPAE, 10:10 NOS, 9:9 NS, 8:7 SH, 1:1 SS, 0:0 F, 63:56 ATTR, 9:9 FSTAGE, 8:8 S2WLK, 6:1 FST, 6:4 Inner, 3:2 Outer, 6:6, 5:1 FS } PAR; - -// Instruction Set Attribute Register 4 -__register 32 { 31:28 SWP_frac, 27:24 PSR_M, 23:20 SynchPrim_frac, 19:16 Barrier, 15:12 SMC, 11:8 Writeback, 7:4 WithShifts, 3:0 Unpriv } ID_ISAR4; - -// Activity Monitors Configuration Register -__register 32 { 31:28 NCG, 24:24 HDBG, 13:8 SIZE, 7:0 N } AMCFGR; - -// Performance Monitors Cycle Count Filter Register -__register 32 { 31:31 P, 30:30 U, 29:29 NSK, 28:28 NSU, 27:27 NSH } PMCCFILTR; - -// CPU Interface Identification Register -__register 32 { 31:20 ProductID, 19:16 Architecture_version, 15:12 Revision, 11:0 Implementer } GICC_IIDR; - -// MPAM1 Register (EL1) -__register 64 { 63:63 MPAMEN, 60:60 FORCED_NS, 47:40 PMG_D, 39:32 PMG_I, 31:16 PARTID_D, 15:0 PARTID_I } MPAM1_EL1; - -// Interrupt Controller Software Generated Interrupt Group 1 Register -__register 64 { 55:48 Aff3, 47:44 RS, 40:40 IRM, 39:32 Aff2, 27:24 INTID, 23:16 Aff1, 15:0 TargetList } ICC_SGI1R; - -// Context ID Register (EL1) -__register 32 { 31:0 PROCID } CONTEXTIDR_EL1; - -// Debug Link Register -__register 32 { } DLR; - -// Statistical Profiling Control Register (EL1) -__register 64 { 7:6 PCT, 5:5 TS, 4:4 PA, 3:3 CX, 1:1 E1SPE, 0:0 E0SPE } PMSCR_EL1; - -// Monitor Debug Configuration Register (EL3) -__register 32 { 28:28 MTPME, 27:27 TDCC, 23:23 SCCD, 21:21 EPMAD, 20:20 EDAD, 19:19 TTRF, 18:18 STE, 17:17 SPME, 16:16 SDD, 15:14 SPD32, 13:12 NSPB, 10:10 TDOSA, 9:9 TDA, 6:6 TPM } MDCR_EL3; - -// External Debug Component Identification Register 3 -__register 32 { 7:0 PRMBL_3 } EDCIDR3; - -// Interrupt Controller System Register Enable register -__register 32 { 2:2 DIB, 1:1 DFB, 0:0 SRE } ICC_SRE; - -// Interrupt Controller Interrupt Group 1 Enable register (EL3) -__register 32 { 1:1 EnableGrp1S, 0:0 EnableGrp1NS } ICC_IGRPEN1_EL3; - -// Normal Memory Remap Register -__register 32 { } NMRR; - -// EL2 Software Thread ID Register -__register 64 { } TPIDR_EL2; - -// Interrupt Group Register 0 -__register 32 { } GICR_IGROUPR0; - -// Error Record Miscellaneous Register 0 -array [0..65534] of __register 64 { 39:39 OF, 38:32 CEC, 47:47 OFO, 46:40 CECO, 39:39 OFR, 38:32 CECR } ERRMISC0; - -// CPU Interface Aliased Interrupt Acknowledge Register -__register 32 { 23:0 INTID } GICC_AIAR; - -// Hyp Vector Base Address Register -__register 32 { } HVBAR; - -// Reseeded Random Number -__register 64 { 63:0 RNDRRS } RNDRRS; - -// Redistributor virtual SGI pending state request register -__register 32 { 15:0 vPEID } GICR_VSGIR; - -// Interrupt Group Modifier Registers -array [1..2] of __register 32 { } GICR_IGRPMODRE; - -// Performance Monitors Selected Event Count Register -__register 32 { } PMXEVCNTR; - -// Selected Error Record Feature Register -__register 64 { } ERXFR_EL1; - -// CTI External Multiplexer Control register -__register 32 { } ASICCTL; - -// MPAM Virtual PARTID Mapping Register 3 -__register 64 { 63:48 PhyPARTID15, 47:32 PhyPARTID14, 31:16 PhyPARTID13, 15:0 PhyPARTID12 } MPAMVPM3_EL2; - -// Debug Feature Register 1 -__register 64 { 3:0 MTPMU } ID_DFR1_EL1; - -// External Debug Integration mode Control register -__register 32 { 0:0 IME } EDITCTRL; - -// Selected Error Record Miscellaneous Register 2 -__register 64 { } ERXMISC2_EL1; - -// External Debug Virtual Context Sample Register -__register 32 { 31:31 NS, 30:30 E2, 29:29 E3, 28:28 HV, 31:0 CONTEXTIDR_EL2, 15:8, 7:0 VMID } EDVIDSR; - -// Fault Address Register (EL2) -__register 64 { } FAR_EL2; - -// Hyp Translation Control Register -__register 32 { 28:28 HWU62, 27:27 HWU61, 26:26 HWU60, 25:25 HWU59, 24:24 HPD, 13:12 SH0, 11:10 ORGN0, 9:8 IRGN0, 2:0 T0SZ } HTCR; - -// Hyp Auxiliary Configuration Register -__register 32 { } HACR; - -// FCSE Process ID register -__register 32 { } FCSEIDR; - -// Performance Monitors Component Identification Register 0 -__register 32 { 7:0 PRMBL_0 } PMCIDR0; - -// Debug Breakpoint Extended Value Registers -array [0..15] of __register 32 { 31:0 ContextID2, 15:8, 7:0 VMID } DBGBXVR; - -// Virtual SError Exception Syndrome Register -__register 64 { 15:14 AET, 12:12 ExT, 24:24 IDS, 23:0 ISS } VSESR_EL2; - -// External Debug Auxiliary Control Register -__register 32 { } EDACR; - -// Interrupt Controller Maintenance Interrupt State Register -__register 32 { 7:7 VGrp1D, 6:6 VGrp1E, 5:5 VGrp0D, 4:4 VGrp0E, 3:3 NP, 2:2 LRENP, 1:1 U, 0:0 EOI } ICH_MISR; - -// Architectural Feature Trap Register (EL2) -__register 32 { 31:31 TCPAC, 30:30 TAM, 20:20 TTA, 21:20 FPEN, 17:16 ZEN, 10:10 TFP, 8:8 TZ } CPTR_EL2; - -// Performance Monitors Component Identification Register 2 -__register 32 { 7:0 PRMBL_2 } PMCIDR2; - -// LORegion End Address (EL1) -__register 64 { 51:48, 47:16 EA } LOREA_EL1; - -// Hyp Configuration Register -__register 32 { 30:30 TRVM, 29:29 HCD, 27:27 TGE, 26:26 TVM, 25:25 TTLB, 24:24 TPU, 23:23 TPC, 22:22 TSW, 21:21 TAC, 20:20 TIDCP, 19:19 TSC, 18:18 TID3, 17:17 TID2, 16:16 TID1, 15:15 TID0, 14:14 TWE, 13:13 TWI, 12:12 DC, 11:10 BSU, 9:9 FB, 8:8 VA, 7:7 VI, 6:6 VF, 5:5 AMO, 4:4 IMO, 3:3 FMO, 2:2 PTW, 1:1 SWIO, 0:0 VM } HCR; - -// Performance Monitors Lock Access Register -__register 32 { 31:0 KEY } PMLAR; - -// Interrupt Controller System Register Enable register (EL3) -__register 32 { 3:3 Enable, 2:2 DIB, 1:1 DFB, 0:0 SRE } ICC_SRE_EL3; - -// Interrupt Controller Virtual Highest Priority Pending Interrupt Register 1 -__register 32 { 23:0 INTID } ICV_HPPIR1; - -// Performance Monitors Peripheral Identification Register 0 -__register 32 { 7:0 PART_0 } PMPIDR0; - -// Sampling Latency Filter Register -__register 64 { 11:0 MINLAT } PMSLATFR_EL1; - -// ITS Read Register -__register 64 { 19:5 Offset, 0:0 Stalled } GITS_CREADR; - -// Interrupt Controller Hyp System Register Enable register -__register 32 { 3:3 Enable, 2:2 DIB, 1:1 DFB, 0:0 SRE } ICC_HSRE; - -// MPAM Capture Event Generation Register -__register 32 { 1:1 ALL, 0:0 NOW } MSMON_CAPT_EVNT; - -// EL0 Read-Only Software Thread ID Register -__register 64 { } TPIDRRO_EL0; - -// Virtualization Translation Control Register -__register 32 { 28:28 HWU62, 27:27 HWU61, 26:26 HWU60, 25:25 HWU59, 13:12 SH0, 11:10 ORGN0, 9:8 IRGN0, 7:6 SL0, 4:4 S, 3:0 T0SZ } VTCR; - -// DCC Interrupt Enable Register -__register 32 { 30:30 RX, 29:29 TX } DBGDCCINT; - -// Debug Saved Program Status Register -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 DIT, 23:23 SSBS, 22:22 PAN, 21:21 SS, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 15:10, 26:25 IT, 4:0 M } DSPSR; - -// Profiling Buffer Write Pointer Register -__register 64 { 63:0 PTR } PMBPTR_EL1; - -// Debug Authentication Status register -__register 32 { 7:6 SNID, 5:4 SID, 3:2 NSNID, 1:0 NSID } DBGAUTHSTATUS; - -// Counter-timer Frequency register -__register 32 { } CNTFRQ_EL0; - -// Interrupt Set-Active Registers (extended SPI range) -array [0..31] of __register 32 { } GICD_ISACTIVERE; - -// Report ITS's affinity. -__register 32 { 31:24 Aff3, 23:16 Aff2, 15:8 Aff1 } GITS_MPIDR; - -// VMID Sample Register -__register 32 { 15:8, 7:0 VMID } PMVIDSR; - -// Interrupt Controller Virtual Running Priority Register -__register 32 { 7:0 Priority } ICV_RPR; - -// Activity Monitors Event Type Registers 1 -array [0..15] of __register 32 { 15:0 evtCount } AMEVTYPER1; - -// Main ID Register -__register 32 { 31:24 Implementer, 23:20 Variant, 19:16 Architecture, 15:4 PartNum, 3:0 Revision } MIDR; - -// Selected Error Record Feature Register 2 -__register 32 { } ERXFR2; - -// Data Cache Zero ID register -__register 32 { 4:4 DZP, 3:0 BS } DCZID_EL0; - -// Error Record Select Register -__register 32 { 15:0 SEL } ERRSELR; - -// MPAM Implementation-Specific Partitioning Feature Identification Register -__register 32 { } MPAMF_IMPL_IDR; - -// Performance Monitors Common Event Identification register 3 -__register 32 { } PMCEID3; - -// Media and VFP Feature Register 2 -__register 32 { 7:4 FPMisc, 3:0 SIMDMisc } MVFR2; - -// Debug Watchpoint Value Registers -array [0..15] of __register 64 { 63:53, 52:49 RESS, 52:49, 48:2 VA } DBGWVR_EL1; - -// Exception Link Register (Hyp mode) -__register 32 { } ELR_hyp; - -// Floating-point Control Register -__register 32 { 26:26 AHP, 25:25 DN, 24:24 FZ, 23:22 RMode, 21:20 Stride, 19:19 FZ16, 18:16 Len, 15:15 IDE, 12:12 IXE, 11:11 UFE, 10:10 OFE, 9:9 DZE, 8:8 IOE } FPCR; - -// Performance Monitors Lock Status Register -__register 32 { 2:2 nTT, 1:1 SLK, 0:0 SLI } PMLSR; - -// CTI Application Trigger Set register -__register 32 { } CTIAPPSET; - -// Stack Pointer (EL0) -__register 64 { } SP_EL0; - -// Vector Base Address Register (EL2) -__register 64 { } VBAR_EL2; - -// Interrupt Configuration Registers (Extended SPI Range) -array [0..63] of __register 32 { } GICD_ICFGRE; - -// Selected Error Record Miscellaneous Register 1 -__register 32 { } ERXMISC1; - -// AArch64 Instruction Set Attribute Register 1 -__register 64 { 55:52 I8MM, 51:48 DGH, 47:44 BF16, 43:40 SPECRES, 39:36 SB, 35:32 FRINTTS, 31:28 GPI, 27:24 GPA, 23:20 LRCPC, 19:16 FCMA, 15:12 JSCVT, 11:8 API, 7:4 APA, 3:0 DPB } ID_AA64ISAR1_EL1; - -// Virtual Machine Highest Priority Pending Interrupt Register -__register 32 { 24:0 INTID } GICV_HPPIR; - -// Debug Vector Catch Register -__register 32 { 31:31 NSF, 30:30 NSI, 28:28 NSD, 27:27 NSP, 26:26 NSS, 25:25 NSU, 7:7 SF, 6:6 SI, 4:4 SD, 3:3 SP, 2:2 SS, 1:1 SU, 7:7 F, 6:6 I, 4:4 D, 3:3 P, 2:2 S, 1:1 U } DBGVCR32_EL2; - -// Sampling Filter Control Register -__register 64 { 18:18 ST, 17:17 LD, 16:16 B, 2:2 FL, 1:1 FT, 0:0 FE } PMSFCR_EL1; - -// Performance Monitors Configuration Register -__register 32 { 31:28 NCG, 19:19 UEN, 18:18 WT, 17:17 NA, 16:16 EX, 15:15 CCD, 14:14 CC, 13:8 SIZE, 7:0 N } PMCFGR; - -// Interrupt Controller Virtual Binary Point Register 1 -__register 32 { 2:0 BinaryPoint } ICV_BPR1_EL1; - -// Performance Monitors Interrupt Enable Clear register -__register 32 { 31:31 C } PMINTENCLR; - -// Stack Pointer (EL1) -__register 64 { } SP_EL1; - -// Performance Monitors Overflow Flag Status Set register -__register 32 { 31:31 C } PMOVSSET; - -// Interrupt Set-Active Registers -array [0..31] of __register 32 { } GICD_ISACTIVER; - -// Selected Pseudo-fault Generation Countdown register -__register 64 { } ERXPFGCDN_EL1; - -// SVE Control Register for EL1 -__register 64 { 3:0 LEN } ZCR_EL1; - -// Debug Data Transfer Register, half-duplex -__register 64 { 63:32 HighWord, 31:0 LowWord } DBGDTR_EL0; - -// Performance Monitors Count Enable Set register -__register 32 { 31:31 C } PMCNTENSET; - -// Interrupt Controller Highest Priority Pending Interrupt Register 0 -__register 32 { 23:0 INTID } ICC_HPPIR0; - -// Translation Table Base Register 1 (EL2) -__register 64 { 63:48 ASID, 47:1 BADDR, 0:0 CnP } TTBR1_EL2; - -// Debug OS Lock Data Transfer Register, Receive, External View -__register 32 { } DBGDTRRXext; - -// Performance Monitors User Enable Register -__register 32 { 3:3 ER, 2:2 CR, 1:1 SW, 0:0 EN } PMUSERENR; - -// Pseudo-fault Generation Countdown Register -array [0..65534] of __register 64 { 31:0 CDN } ERRPFGCDN; - -// Selected Error Record Miscellaneous Register 4 -__register 32 { } ERXMISC4; - -// Hyp Auxiliary Control Register -__register 32 { } HACTLR; - -// MPAM0 Register (EL1) -__register 64 { 47:40 PMG_D, 39:32 PMG_I, 31:16 PARTID_D, 15:0 PARTID_I } MPAM0_EL1; - -// Hyp Auxiliary Instruction Fault Status Register -__register 32 { } HAIFSR; - -// External Debug Instruction Transfer Register -__register 32 { 31:16 T32Second, 15:0 T32First } EDITR; - -// Counter-timer Physical Timer CompareValue register (EL2) -__register 64 { 63:0 CompareValue } CNTHP_CVAL_EL2; - -// Device Architecture Register -__register 32 { 31:21 ARCHITECT, 20:20 PRESENT, 19:16 REVISION, 15:12 ARCHVER, 11:0 ARCHPART } ERRDEVARCH; - -// Hypervisor Activity Monitors Fine-Grained Read Trap Register -__register 64 { 49:49 AMEVTYPER115_EL0, 48:48 AMEVCNTR115_EL0, 47:47 AMEVTYPER114_EL0, 46:46 AMEVCNTR114_EL0, 45:45 AMEVTYPER113_EL0, 44:44 AMEVCNTR113_EL0, 43:43 AMEVTYPER112_EL0, 42:42 AMEVCNTR112_EL0, 41:41 AMEVTYPER111_EL0, 40:40 AMEVCNTR111_EL0, 39:39 AMEVTYPER110_EL0, 38:38 AMEVCNTR110_EL0, 37:37 AMEVTYPER19_EL0, 36:36 AMEVCNTR19_EL0, 35:35 AMEVTYPER18_EL0, 34:34 AMEVCNTR18_EL0, 33:33 AMEVTYPER17_EL0, 32:32 AMEVCNTR17_EL0, 31:31 AMEVTYPER16_EL0, 30:30 AMEVCNTR16_EL0, 29:29 AMEVTYPER15_EL0, 28:28 AMEVCNTR15_EL0, 27:27 AMEVTYPER14_EL0, 26:26 AMEVCNTR14_EL0, 25:25 AMEVTYPER13_EL0, 24:24 AMEVCNTR13_EL0, 23:23 AMEVTYPER12_EL0, 22:22 AMEVCNTR12_EL0, 21:21 AMEVTYPER11_EL0, 20:20 AMEVCNTR11_EL0, 19:19 AMEVTYPER10_EL0, 18:18 AMEVCNTR10_EL0, 17:17 AMCNTEN1, 0:0 AMCNTEN0 } HAFGRTR_EL2; - -// Memory Model Feature Register 1 -__register 32 { 31:28 BPred, 27:24 L1TstCln, 23:20 L1Uni, 19:16 L1Hvd, 15:12 L1UniSW, 11:8 L1HvdSW, 7:4 L1UniVA, 3:0 L1HvdVA } ID_MMFR1; - -// Auxiliary Memory Attribute Indirection Register (EL2) -__register 64 { } AMAIR_EL2; - -// Translation Table Base Control Register -__register 32 { 31:31 EAE, 5:5 PD1, 4:4 PD0, 2:0 N, 29:28 SH1, 27:26 ORGN1, 25:24 IRGN1, 23:23 EPD1, 22:22 A1, 18:16 T1SZ, 13:12 SH0, 11:10 ORGN0, 9:8 IRGN0, 7:7 EPD0, 6:6 T2E, 2:0 T0SZ } TTBCR; - -// External Debug Processor Feature Register -__register 64 { 47:44 AMU, 39:36 SEL2, 35:32 SVE, 27:24 GIC, 23:20 AdvSIMD, 19:16 FP, 15:12 EL3, 11:8 EL2, 7:4 EL1, 3:0 EL0 } EDPFR; - -// Interrupt Controller Monitor System Register Enable register -__register 32 { 3:3 Enable, 2:2 DIB, 1:1 DFB, 0:0 SRE } ICC_MSRE; - -// Activity Monitors User Enable Register -__register 64 { 0:0 EN } AMUSERENR_EL0; - -// Error Record Select Register -__register 64 { 15:0 SEL } ERRSELR_EL1; - -// Interrupt Set-Active Register 0 -__register 32 { } GICR_ISACTIVER0; - -// AArch32 Memory Model Feature Register 1 -__register 32 { 31:28 BPred, 27:24 L1TstCln, 23:20 L1Uni, 19:16 L1Hvd, 15:12 L1UniSW, 11:8 L1HvdSW, 7:4 L1UniVA, 3:0 L1HvdVA } ID_MMFR1_EL1; - -// Counter Scale Register -__register 32 { 31:0 ScaleVal } CNTSCR; - -// AArch32 Instruction Set Attribute Register 1 -__register 32 { 31:28 Jazelle, 27:24 Interwork, 23:20 Immediate, 19:16 IfThen, 15:12 Extend, 11:8 Except_AR, 7:4 Except, 3:0 Endian } ID_ISAR1_EL1; - -// Debug ROM Address Register -__register 64 { 1:0 Valid, 47:12 ROMADDR } DBGDRAR; - -// Activity Monitors Event Counter Registers 0 -array [0..15] of __register 64 { 63:0 ACNT } AMEVCNTR0_EL0; - -// External Debug Lock Access Register -__register 32 { 31:0 KEY } EDLAR; - -// Counter-timer Virtual Offsets -array [0..7] of __register 64 { } CNTVOFF; - -// Privileged Access Never -__register 32 { 22:22 PAN } PAN; - -// Monitor Debug ROM Address Register -__register 64 { 1:0 Valid, 51:48, 47:12 ROMADDR } MDRAR_EL1; - -// Non-Secure Access Control Register -__register 32 { 20:20 NSTRCDIS, 15:15 NSASEDIS, 11:11 cp11, 10:10 cp10 } NSACR; - -// Current Program Status Register -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 23:23 SSBS, 22:22 PAN, 21:21 DIT, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 3:0 M } CPSR; - -// Monitor Vector Base Address Register -__register 32 { 4:0 Reserved } MVBAR; - -// Performance Monitors User Enable Register -__register 32 { 3:3 ER, 2:2 CR, 1:1 SW, 0:0 EN } PMUSERENR_EL0; - -// External Debug Exception Catch Control Register -__register 32 { } EDECCR; - -// External Debug Component Identification Register 0 -__register 32 { 7:0 PRMBL_0 } EDCIDR0; - -// Activity Monitors Count Enable Set Register 1 -__register 64 { } AMCNTENSET1_EL0; - -// External Debug Peripheral Identification Register 4 -__register 32 { 7:4 SIZE, 3:0 DES_2 } EDPIDR4; - -// AArch32 Debug Feature Register 0 -__register 32 { 31:28 TraceFilt, 27:24 PerfMon, 23:20 MProfDbg, 11:8 MMapDbg, 7:4 CopSDbg, 3:0 CopDbg } ID_DFR0_EL1; - -// EL0 Read/Write Software Thread ID Register -__register 64 { } TPIDR_EL0; - -// Activity Monitors Event Counter Registers 0 -array [0..15] of __register 64 { 63:0 ACNT } AMEVCNTR0; - -// Secure Debug Enable Register -__register 32 { 1:1 SUNIDEN, 0:0 SUIDEN } SDER; - -// Hyp IPA Fault Address Register -__register 32 { 31:4 FIPA } HPFAR; - -// Counter-timer Timer ID Register -__register 32 { } CNTTIDR; - -// Interrupt Controller Monitor Control Register -__register 32 { 19:19 ExtRange, 18:18 RSS, 17:17 nDS, 15:15 A3V, 14:14 SEIS, 13:11 IDbits, 10:8 PRIbits, 6:6 PMHE, 5:5 RM, 4:4 EOImode_EL1NS, 3:3 EOImode_EL1S, 2:2 EOImode_EL3, 1:1 CBPR_EL1NS, 0:0 CBPR_EL1S } ICC_MCTLR; - -// CTI Peripheral Identification Register 0 -__register 32 { 7:0 PART_0 } CTIPIDR0; - -// Debug Power Control Register -__register 32 { 0:0 CORENPDRQ } DBGPRCR_EL1; - -// Interrupt Controller VGIC Type Register -__register 32 { 31:29 PRIbits, 28:26 PREbits, 25:23 IDbits, 22:22 SEIS, 21:21 A3V, 20:20 nV4, 19:19 TDS, 4:0 ListRegs } ICH_VTR_EL2; - -// Interrupt Controller Hyp Active Priorities Group 1 Registers -array [0..3] of __register 64 { } ICH_AP1R_EL2; - -// CPU Interface Running Priority Register -__register 32 { 7:0 Priority } GICC_RPR; - -// Counter-timer Kernel Control register -__register 32 { 17:17 EVNTIS, 9:9 EL0PTEN, 8:8 EL0VTEN, 7:4 EVNTI, 3:3 EVNTDIR, 2:2 EVNTEN, 1:1 EL0VCTEN, 0:0 EL0PCTEN } CNTKCTL_EL1; - -// Counter-timer Virtual Count register -__register 64 { } CNTVCT_EL0; - -// EL2 Read/Write Software Context Number -__register 64 { } SCXTNUM_EL2; - -// ITS Identification Register -__register 32 { 31:24 ProductID, 19:16 Variant, 15:12 Revision, 11:0 Implementer } GITS_IIDR; - -// Counter-timer Virtual Timer Control register (EL2) -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTHV_CTL; - -// CTI Lock Status Register -__register 32 { 2:2 nTT, 1:1 SLK, 0:0 SLI } CTILSR; - -// End Interrupt Status Register -__register 32 { } GICH_EISR; - -// Interrupt Controller VGIC Type Register -__register 32 { 31:29 PRIbits, 28:26 PREbits, 25:23 IDbits, 22:22 SEIS, 21:21 A3V, 20:20 nV4, 19:19 TDS, 4:0 ListRegs } ICH_VTR; - -// AArch64 Memory Model Feature Register 0 -__register 64 { 63:60 ECV, 59:56 FGT, 47:44 ExS, 43:40 TGran4_2, 39:36 TGran64_2, 35:32 TGran16_2, 31:28 TGran4, 27:24 TGran64, 23:20 TGran16, 19:16 BigEndEL0, 15:12 SNSMem, 11:8 BigEnd, 7:4 ASIDBits, 3:0 PARange } ID_AA64MMFR0_EL1; - -// Interrupt Clear-Pending Registers -array [0..31] of __register 32 { } GICD_ICPENDR; - -// Virtual Machine Deactivate Interrupt Register -__register 32 { 24:0 INTID } GICV_DIR; - -// Debug Link Register -__register 64 { } DLR_EL0; - -// Translation Table Base Register 1 (EL1) -__register 64 { 63:48 ASID, 47:1 BADDR, 0:0 CnP } TTBR1_EL1; - -// Performance Monitors Common Event Identification register 1 -__register 64 { } PMCEID1_EL0; - -// SGI Set-Pending Registers -array [0..3] of __register 32 { } GICD_SPENDSGIR; - -// Peripheral Identification Register 0 -__register 32 { 7:0 PART_0 } ERRPIDR0; - -// Exception Link Register (EL2) -__register 64 { } ELR_EL2; - -// Hyp Auxiliary Control Register 2 -__register 32 { } HACTLR2; - -// Activity Monitors Counter Group 1 Identification Register -__register 64 { } AMCG1IDR_EL0; - -// MPAM Memory System Monitor Configure Memory Bandwidth Usage Monitor Filter Register -__register 32 { 23:16 PMG, 15:0 PARTID } MSMON_CFG_MBWU_FLT; - -// Vector Base Address Register (EL3) -__register 64 { } VBAR_EL3; - -// Software Generated Interrupt Register -__register 32 { 25:24 TargetListFilter, 23:16 CPUTargetList, 15:15 NSATT, 3:0 INTID } GICD_SGIR; - -// Pointer Authentication Key A for Code (bits[127:64]) -__register 64 { } APGAKeyHi_EL1; - -// CTI Trigger Out Status register -__register 32 { } CTITRIGOUTSTATUS; - -// Interrupt Controller Virtual Active Priorities Group 0 Registers -array [0..3] of __register 64 { } ICV_AP0R_EL1; - -// Performance Monitors Event Count Registers -array [0..30] of __register 32 { } PMEVCNTR; - -// Auxiliary Memory Attribute Indirection Register (EL3) -__register 64 { } AMAIR_EL3; - -// Debug OS Double Lock Register -__register 32 { 0:0 DLK } DBGOSDLR; - -// Interrupt Controller End Of Interrupt Register 0 -__register 32 { 23:0 INTID } ICC_EOIR0; - -// Counter-timer Secure Virtual Timer Control Register (EL2) -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTHVS_CTL; - -// Primary Region Remap Register -__register 32 { 19:19 NS1, 18:18 NS0, 17:17 DS1, 16:16 DS0 } PRRR; - -// Instruction Set Attribute Register 1 -__register 32 { 31:28 Jazelle, 27:24 Interwork, 23:20 Immediate, 19:16 IfThen, 15:12 Extend, 11:8 Except_AR, 7:4 Except, 3:0 Endian } ID_ISAR1; - -// Reset Vector Base Address Register -__register 32 { } RVBAR; - -// External Debug Device Affinity register 0 -__register 32 { 31:0 MPIDR_EL1lo } EDDEVAFF0; - -// Auxiliary Control Register (EL1) -__register 64 { } ACTLR_EL1; - -// Counter-timer Self-Synchronized Virtual Count register -__register 64 { } CNTVCTSS; - -// Selected Error Record Primary Status Register -__register 64 { } ERXSTATUS_EL1; - -// Reset Management Register -__register 32 { 1:1 RR, 0:0 AA64 } RMR; - -// ITS Write Register -__register 64 { 19:5 Offset, 0:0 Retry } GITS_CWRITER; - -// Cache Size Selection Register -__register 32 { 4:4 TnD, 3:1 Level, 0:0 InD } CSSELR_EL1; - -// CPU Interface Aliased Binary Point Register -__register 32 { 2:0 Binary_Point } GICC_ABPR; - -// Redistributor virtual SGI pending state register -__register 32 { 31:31 Busy, 15:0 Pending } GICR_VSGIPENDR; - -// Translation Table Base Register 0 -__register 64 { 31:7 TTB0, 5:5 NOS, 4:3 RGN, 2:2 IMP, 1:1 S, 55:48 ASID, 47:1 BADDR, 0:0 CnP, 0:0, 6:6 IRGN } TTBR0; - -// Interrupt Configuration Register 0 -__register 32 { } GICR_ICFGR0; - -// Redistributor Wake Register -__register 32 { 2:2 ChildrenAsleep, 1:1 ProcessorSleep } GICR_WAKER; - -// Selected Error Record Miscellaneous Register 2 -__register 32 { } ERXMISC2; - -// Exception Syndrome Register (EL1) -__register 32 { 31:26 EC, 25:25 IL, 24:0 ISS } ESR_EL1; - -// CTI Device ID register 0 -__register 32 { 25:24 INOUT, 21:16 NUMCHAN, 13:8 NUMTRIG, 4:0 EXTMUXNUM } CTIDEVID; - -// Performance Monitors Peripheral Identification Register 1 -__register 32 { 7:4 DES_0, 3:0 PART_1 } PMPIDR1; - -// Counter-timer EL0 Access Control Register -__register 32 { 9:9 EL0PTEN, 8:8 EL0VTEN, 1:1 EL0VCTEN, 0:0 EL0PCTEN } CNTEL0ACR; - -// Counter-timer Physical Offset register -__register 64 { } CNTPOFF_EL2; - -// Activity Monitors Count Enable Set Register 0 -__register 64 { } AMCNTENSET0_EL0; - -// Device Configuration Register -__register 32 { 15:0 NUM } ERRDEVID; - -// Interrupt Controller Type Register -__register 32 { 31:27 ESPI_range, 26:26 RSS, 25:25 No1N, 24:24 A3V, 23:19 IDbits, 18:18 DVIS, 17:17 LPIS, 16:16 MBIS, 15:11 num_LPIs, 10:10 SecurityExtn, 8:8 ESPI, 7:5 CPUNumber, 4:0 ITLinesNumber } GICD_TYPER; - -// External Debug Device Affinity register 1 -__register 32 { 31:0 MPIDR_EL1hi } EDDEVAFF1; - -// Interrupt Controller Hyp Control Register -__register 32 { 31:27 EOIcount, 14:14 TDIR, 13:13 TSEI, 12:12 TALL1, 11:11 TALL0, 10:10 TC, 8:8 vSGIEOICount, 7:7 VGrp1DIE, 6:6 VGrp1EIE, 5:5 VGrp0DIE, 4:4 VGrp0EIE, 3:3 NPIE, 2:2 LRENPIE, 1:1 UIE, 0:0 En } ICH_HCR; - -// Instruction Fault Address Register -__register 32 { } IFAR; - -// Domain Access Control Register -__register 32 { } DACR32_EL2; - -// Interrupt Clear-Active Register 0 -__register 32 { } GICR_ICACTIVER0; - -// Memory Attribute Indirection Register (EL2) -__register 64 { } MAIR_EL2; - -// CTI Integration mode Control register -__register 32 { 0:0 IME } CTIITCTRL; - -// Interrupt Controller Interrupt Acknowledge Register 1 -__register 32 { 23:0 INTID } ICC_IAR1_EL1; - -// MPAM Memory Bandwidth Partitioning Identification Register -__register 32 { 28:16 BWPBM_WD, 14:14 WINDWR, 13:13 HAS_PROP, 12:12 HAS_PBM, 11:11 HAS_MAX, 10:10 HAS_MIN, 5:0 BWA_WD } MPAMF_MBW_IDR; - -// Activity Monitors Component Identification Register 3 -__register 32 { 7:0 PRMBL_3 } AMCIDR3; - -// MPAM Implementation Identification Register -__register 32 { 31:20 ProductID, 19:16 Variant, 15:12 Revision, 11:0 Implementer } MPAMF_IIDR; - -// Memory Model Feature Register 2 -__register 32 { 31:28 HWAccFlg, 27:24 WFIStall, 23:20 MemBarr, 19:16 UniTLB, 15:12 HvdTLB, 11:8 L1HvdRng, 7:4 L1HvdBG, 3:0 L1HvdFG } ID_MMFR2; - -// Tag Fault Status Register (EL0). -__register 64 { 1:1 TF1, 0:0 TF0 } TFSRE0_EL1; - -// Error Record Miscellaneous Register 1 -array [0..65534] of __register 64 { } ERRMISC1; - -// Pointer Authentication Key A for Data (bits[63:0]) -__register 64 { } APDAKeyLo_EL1; - -// Interrupt Set-Enable Registers -array [0..31] of __register 32 { } GICD_ISENABLERE; - -// CTI Input Channel to Output Trigger Enable registers -array [0..31] of __register 32 { } CTIOUTEN; - -// Interrupt Controller Binary Point Register 1 -__register 32 { 2:0 BinaryPoint } ICC_BPR1_EL1; - -// Hyp Debug Control Register -__register 32 { 28:28 MTPME, 27:27 TDCC, 26:26 HLP, 23:23 HCCD, 19:19 TTRF, 17:17 HPMD, 11:11 TDRA, 10:10 TDOSA, 9:9 TDA, 8:8 TDE, 7:7 HPME, 6:6 TPM, 5:5 TPMCR, 4:0 HPMN } HDCR; - -// Interrupt Controller Interrupt Group 0 Enable register -__register 32 { 0:0 Enable } ICC_IGRPEN0; - -// External Debug Reserve Control Register -__register 32 { 4:4 CBRRQ, 3:3 CSPA, 2:2 CSE } EDRCR; - -// Counter-timer Virtual Offset register -__register 64 { } CNTVOFF_EL2; - -// MPAM Memory Bandwidth Partitioning Window Width Configuration Register -__register 32 { 23:8 US_INT, 7:0 US_FRAC } MPAMCFG_MBW_WINWD; - -// MPAM Architecture Identification Register -__register 32 { 7:4 ArchMajorRev, 3:0 ArchMinorRev } MPAMF_AIDR; - -// Interrupt Controller Interrupt Group 0 Enable register -__register 32 { 0:0 Enable } ICC_IGRPEN0_EL1; - -// Media and VFP Feature Register 0 -__register 32 { 31:28 FPRound, 27:24 FPShVec, 23:20 FPSqrt, 19:16 FPDivide, 15:12 FPTrap, 11:8 FPDP, 7:4 FPSP, 3:0 SIMDReg } MVFR0; - -// MPAM Cache Storage Usage Monitor Capture Register -__register 32 { 31:31 NRDY, 30:0 VALUE } MSMON_CSU_CAPTURE; - -// Tag Fault Status Register (EL3) -__register 64 { 0:0 TF0 } TFSR_EL3; - -// Multiple tag transfer ID register -__register 64 { 3:0 BS } GMID_EL1; - -// CPU Interface Aliased End Of Interrupt Register -__register 32 { 23:0 INTID } GICC_AEOIR; - -// MPAM Cache Maximum Capacity Partition Configuration Register -__register 32 { 15:0 CMAX } MPAMCFG_CMAX; - -// Interrupt Controller Virtual Control Register -__register 32 { 19:19 ExtRange, 18:18 RSS, 15:15 A3V, 14:14 SEIS, 13:11 IDbits, 10:8 PRIbits, 1:1 EOImode, 0:0 CBPR } ICV_CTLR_EL1; - -// Memory Model Feature Register 0 -__register 32 { 31:28 InnerShr, 27:24 FCSE, 23:20 AuxReg, 19:16 TCM, 15:12 ShareLvl, 11:8 OuterShr, 7:4 PMSA, 3:0 VMSA } ID_MMFR0; - -// Hyp Instruction Fault Address Register -__register 32 { } HIFAR; - -// Performance Monitors Event Type Registers -array [0..30] of __register 32 { 31:31 P, 30:30 U, 29:29 NSK, 28:28 NSU, 27:27 NSH, 25:25 MT, 15:10, 9:0 evtCount } PMEVTYPER; - -// Distributor Control Register -__register 32 { 31:31 RWP, 7:7 E1NWF, 6:6 DS, 4:4 ARE_NS, 4:4 ARE_S, 2:2 EnableGrp1S, 1:1 EnableGrp1NS, 0:0 EnableGrp0, 1:1 EnableGrp1A, 1:1 EnableGrp1, 4:4 ARE } GICD_CTLR; - -// Auxiliary Control Register (EL2) -__register 64 { } ACTLR_EL2; - -// Counter-timer Secure Virtual Timer CompareValue register (EL2) -__register 64 { 63:0 CompareValue } CNTHVS_CVAL_EL2; - -// Performance Monitors Common Event Identification register 2 -__register 32 { } PMCEID2; - -// Auxiliary Fault Status Register 0 (EL2) -__register 32 { } AFSR0_EL2; - -// Reset Vector Base Address Register (if EL3 not implemented) -__register 64 { } RVBAR_EL2; - -// AArch32 Memory Model Feature Register 3 -__register 32 { 31:28 Supersec, 27:24 CMemSz, 23:20 CohWalk, 19:16 PAN, 15:12 MaintBcst, 11:8 BPMaint, 7:4 CMaintSW, 3:0 CMaintVA } ID_MMFR3_EL1; - -// MPAM Virtual PARTID Mapping Register 6 -__register 64 { 63:48 PhyPARTID27, 47:32 PhyPARTID26, 31:16 PhyPARTID25, 15:0 PhyPARTID24 } MPAMVPM6_EL2; - -// AArch64 Debug Feature Register 0 -__register 64 { 51:48 MTPMU, 43:40 TraceFilt, 39:36 DoubleLock, 35:32 PMSVer, 31:28 CTX_CMPs, 23:20 WRPs, 15:12 BRPs, 11:8 PMUVer, 7:4 TraceVer, 3:0 DebugVer } ID_AA64DFR0_EL1; - -// Pseudo-fault Generation Feature Register -array [0..65534] of __register 64 { 30:30 R, 29:29 SYN, 12:12 MV, 11:11 AV, 10:10 PN, 9:9 ER, 8:8 CI, 7:6 CE, 5:5 DE, 4:4 UEO, 3:3 UER, 2:2 UEU, 1:1 UC, 0:0 OF } ERRPFGF; - -// Critical Error Interrupt Configuration Register 1 -__register 32 { 31:0 DATA } ERRCRICR1; - -// Active Priorities Registers -array [0..3] of __register 32 { } GICH_APR; - -// Counter-timer Virtual Timer TimerValue register -__register 32 { 31:0 TimerValue } CNTV_TVAL_EL0; - -// Jazelle OS Control Register -__register 32 { } JOSCR; - -// Activity Monitors Peripheral Identification Register 2 -__register 32 { 7:4 REVISION, 3:3 JEDEC, 2:0 DES_1 } AMPIDR2; - -// AArch32 Instruction Set Attribute Register 4 -__register 32 { 31:28 SWP_frac, 27:24 PSR_M, 23:20 SynchPrim_frac, 19:16 Barrier, 15:12 SMC, 11:8 Writeback, 7:4 WithShifts, 3:0 Unpriv } ID_ISAR4_EL1; - -// External Debug Peripheral Identification Register 0 -__register 32 { 7:0 PART_0 } EDPIDR0; - -// Physical Address Register -__register 64 { 63:56 ATTR, 9:9 NS, 8:7 SH, 0:0 F, 9:9 S, 8:8 PTW, 6:1 FST, 51:48, 47:12 PA } PAR_EL1; - -// Hyp Reset Management Register -__register 32 { 1:1 RR, 0:0 AA64 } HRMR; - -// Interrupt Controller Software Generated Interrupt Group 1 Register -__register 64 { 55:48 Aff3, 47:44 RS, 40:40 IRM, 39:32 Aff2, 27:24 INTID, 23:16 Aff1, 15:0 TargetList } ICC_SGI1R_EL1; - -// Interrupt Controller Running Priority Register -__register 32 { 7:0 Priority } ICC_RPR; - -// Debug Device ID register 0 -__register 32 { 31:28 CIDMask, 27:24 AuxRegs, 23:20 DoubleLock, 19:16 VirtExtns, 15:12 VectorCatch, 11:8 BPAddrMask, 7:4 WPAddrMask, 3:0 PCSample } DBGDEVID; - -// Interrupt Controller Virtual Active Priorities Group 0 Registers -array [0..3] of __register 32 { } ICV_AP0R; - -// Debug Feature Register 1 -__register 32 { 3:0 MTPMU } ID_DFR1; - -// Reset Management Register (EL3) -__register 32 { 1:1 RR, 0:0 AA64 } RMR_EL3; - -// Virtualization Translation Table Base Register -__register 64 { 47:1 BADDR, 0:0 CnP, 63:56, 55:48 VMID } VTTBR_EL2; - -// Multiprocessor Affinity Register -__register 64 { 39:32 Aff3, 30:30 U, 24:24 MT, 23:16 Aff2, 15:8 Aff1, 7:0 Aff0 } MPIDR_EL1; - -// Performance Monitors Machine Identification Register -__register 64 { 7:0 SLOTS } PMMIR_EL1; - -// Interrupt Controller Active Priorities Group 0 Registers -array [0..3] of __register 32 { } ICC_AP0R; - -// CPU Interface Non-secure Active Priorities Registers -array [0..3] of __register 32 { } GICC_NSAPR; - -// Virtual Machine Binary Point Register -__register 32 { 2:0 Binary_Point } GICV_BPR; - -// External Debug Event Status Register -__register 32 { 2:2 SS, 1:1 RC, 0:0 OSUC } EDESR; - -// Debug Watchpoint Value Registers -array [0..15] of __register 32 { 31:2 VA } DBGWVR; - -// OS Lock Access Register -__register 32 { 0:0 OSLK } OSLAR_EL1; - -// Interrupt Controller Interrupt Acknowledge Register 0 -__register 32 { 23:0 INTID } ICC_IAR0; - -// MPAM Memory Bandwidth Maximum Partition Configuration Register -__register 32 { 31:31 HARDLIM, 15:0 MAX } MPAMCFG_MBW_MAX; - -// Performance Monitors Integration mode Control register -__register 32 { 0:0 IME } PMITCTRL; - -// Debug CLAIM Tag Clear register -__register 32 { 7:0 CLAIM } DBGCLAIMCLR_EL1; - -// Debug ID Register -__register 32 { 31:28 WRPs, 27:24 BRPs, 23:20 CTX_CMPs, 19:16 Version, 14:14 nSUHD_imp, 12:12 SE_imp } DBGDIDR; - -// Exception Link Register (EL1) -__register 64 { } ELR_EL1; - -// CPU Interface Control Register -__register 32 { 10:10 EOImodeNS, 8:8 IRQBypDisGrp1, 7:7 FIQBypDisGrp1, 1:1 EnableGrp1, 9:9 EOImodeS, 6:6 IRQBypDisGrp0, 5:5 FIQBypDisGrp0, 4:4 CBPR, 3:3 FIQEn, 0:0 EnableGrp0, 9:9 EOImode } GICC_CTLR; - -// Performance Monitors Control Register -__register 32 { 31:24 IMP, 23:16 IDCODE, 15:11 N, 7:7 LP, 6:6 LC, 5:5 DP, 4:4 X, 3:3 D, 2:2 C, 1:1 P, 0:0 E } PMCR; - -// Random Number -__register 64 { 63:0 RNDR } RNDR; - -// Memory Attribute Indirection Register (EL3) -__register 64 { } MAIR_EL3; - -// Saved Program Status Register (Undefined mode) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 J, 23:23 SSBS, 22:22 PAN, 21:21 DIT, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 15:10, 26:25 IT, 4:0 M } SPSR_und; - -// Counter-timer Physical Timer CompareValue register -__register 64 { 63:0 CompareValue } CNTP_CVAL_EL0; - -// Interrupt Controller Virtual Interrupt Acknowledge Register 0 -__register 32 { 23:0 INTID } ICV_IAR0_EL1; - -// Performance Monitors Device Affinity register 1 -__register 32 { 31:0 MPIDR_EL1hi } PMDEVAFF1; - -// Debug OS Lock Access Register -__register 32 { 31:0 OSLA } DBGOSLAR; - -// Stack Pointer Select -__register 64 { 0:0 SP } SPSel; - -// Exception Syndrome Register (EL3) -__register 32 { 31:26 EC, 25:25 IL, 24:0 ISS } ESR_EL3; - -// Interrupt Controller List Registers -array [0..15] of __register 32 { 31:0 vINTID } ICH_LR; - -// Virtual Redistributor LPI Pending Table Base Address Register -__register 64 { 63:63 Valid, 62:62 IDAI, 61:61 PendingLast, 60:60 Dirty, 58:56 OuterCache, 51:16 Physical_Address, 11:10 Shareability, 9:7 InnerCache, 62:62 Doorbell, 59:59 VGrp0En, 58:58 VGrp1En, 15:0 vPEID } GICR_VPENDBASER; - -// Interrupt Set-Pending Registers -array [0..31] of __register 32 { } GICD_ISPENDR; - -// AArch32 Media and VFP Feature Register 1 -__register 32 { 31:28 SIMDFMAC, 27:24 FPHP, 23:20 SIMDHP, 19:16 SIMDSP, 15:12 SIMDInt, 11:8 SIMDLS, 7:4 FPDNaN, 3:0 FPFtZ } MVFR1_EL1; - -// Cache Type Register -__register 32 { 29:29 DIC, 28:28 IDC, 27:24 CWG, 23:20 ERG, 19:16 DminLine, 15:14 L1Ip, 3:0 IminLine } CTR; - -// Virtualization Translation Control Register -__register 32 { 30:30 NSA, 29:29 NSW, 28:28 HWU62, 27:27 HWU61, 26:26 HWU60, 25:25 HWU59, 22:22 HD, 21:21 HA, 19:19 VS, 18:16 PS, 15:14 TG0, 13:12 SH0, 11:10 ORGN0, 9:8 IRGN0, 7:6 SL0, 5:0 T0SZ } VTCR_EL2; - -// Set PARTID and PMG Register -__register 32 { 23:16 PMG, 15:0 PARTID } GITS_PARTIDR; - -// Saved Program Status Register (Supervisor mode) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 J, 23:23 SSBS, 22:22 PAN, 21:21 DIT, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 15:10, 26:25 IT, 4:0 M } SPSR_svc; - -// Vector Base Address Register (EL1) -__register 64 { } VBAR_EL1; - -// Auxiliary Fault Status Register 1 (EL3) -__register 32 { } AFSR1_EL3; - -// Performance Monitors Event Count Registers -array [0..30] of __register 64 { } PMEVCNTR_EL0; - -// CTI Output Trigger Acknowledge register -__register 32 { } CTIINTACK; - -// MPAM Features Memory Bandwidth Usage Monitoring ID register -__register 32 { 31:31 HAS_CAPTURE, 30:30 HAS_LONG, 29:29 LWD, 20:16 SCALE, 15:0 NUM_MON } MPAMF_MBWUMON_IDR; - -// Counter-timer Secure Virtual Timer Control register (EL2) -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTHVS_CTL_EL2; - -// Performance Monitors Cycle Count Register -__register 64 { 63:0 CCNT } PMCCNTR; - -// Counter-timer Physical Secure Timer Control register -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTPS_CTL_EL1; - -// ITS SGI Register -__register 64 { 47:32 vPEID, 3:0 vINTID } GITS_SGIR; - -// Selected Error Record Miscellaneous Register 5 -__register 32 { } ERXMISC5; - -// Fault-Handling Interrupt Configuration Register 0 -__register 64 { 55:2 ADDR } ERRFHICR0; - -// External Debug Lock Status Register -__register 32 { 2:2 nTT, 1:1 SLK, 0:0 SLI } EDLSR; - -// Performance Monitors Device Type register -__register 32 { 7:4 SUB, 3:0 MAJOR } PMDEVTYPE; - -// Floating-Point System ID register -__register 32 { 31:24 Implementer, 23:23 SW, 22:16 Subarchitecture, 15:8 PartNum, 7:4 Variant, 3:0 Revision } FPSID; - -// External Debug Feature Register -__register 64 { 43:40 TraceFilt, 31:28 CTX_CMPs, 23:20 WRPs, 15:12 BRPs, 11:8 PMUVer, 7:4 TraceVer } EDDFR; - -// CPU Interface Priority Mask Register -__register 32 { 7:0 Priority } GICC_PMR; - -// Interrupt Routing Registers -array [32..1019] of __register 64 { 39:32 Aff3, 31:31 Interrupt_Routing_Mode, 23:16 Aff2, 15:8 Aff1, 7:0 Aff0 } GICD_IROUTER; - -// CPU Interface Aliased Highest Priority Pending Interrupt Register -__register 32 { 23:0 INTID } GICC_AHPPIR; - -// Saved Program Status Register (Monitor mode) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 J, 23:23 SSBS, 22:22 PAN, 21:21 DIT, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 15:10, 26:25 IT, 4:0 M } SPSR_mon; - -// Reset Vector Base Address Register (if EL3 implemented) -__register 64 { } RVBAR_EL3; - -// Debug Authentication Status register -__register 32 { 7:6 SNID, 5:4 SID, 3:2 NSNID, 1:0 NSID } DBGAUTHSTATUS_EL1; - -// Counter-timer Self-Synchronized Physical Count register -__register 64 { } CNTPCTSS_EL0; - -// Peripheral Identification Register 1 -__register 32 { 7:4 DES_0, 3:0 PART_1 } ERRPIDR1; - -// Interrupt Set-Enable Registers -array [0..31] of __register 32 { } GICD_ISENABLER; - -// Interrupt Clear-Active Registers -array [1..2] of __register 32 { } GICR_ICACTIVERE; - -// MPAM Error Control Register -__register 32 { 0:0 INTEN } MPAMF_ECR; - -// Hyp Auxiliary Data Fault Status Register -__register 32 { } HADFSR; - -// Auxiliary Memory Attribute Indirection Register (EL1) -__register 64 { } AMAIR_EL1; - -// TLB Type Register -__register 32 { 0:0 nU } TLBTR; - -// Redistributor Invalidate All Register -__register 64 { 47:32 V } GICR_INVALLR; - -// Interrupt Clear-Pending Registers (extended SPI range) -array [0..31] of __register 32 { } GICD_ICPENDRE; - -// Interrupt Controller End Of Interrupt Register 0 -__register 32 { 23:0 INTID } ICC_EOIR0_EL1; - -// MPAM Features Cache Storage Usage Monitoring ID register -__register 32 { 31:31 HAS_CAPTURE, 15:0 NUM_MON } MPAMF_CSUMON_IDR; - -// Performance Monitors Device Architecture register -__register 32 { 31:21 ARCHITECT, 20:20 PRESENT, 19:16 REVISION, 15:0 ARCHID } PMDEVARCH; - -// AArch32 Memory Model Feature Register 4 -__register 32 { 31:28 EVT, 27:24 CCIDX, 23:20 LSM, 19:16 HPDS, 15:12 CnP, 11:8 XNX, 7:4 AC2, 3:0 SpecSEI } ID_MMFR4_EL1; - -// Interrupt Group Modifier Registers (extended SPI range) -array [0..31] of __register 32 { } GICD_IGRPMODRE; - -// Stack Pointer (EL3) -__register 64 { } SP_EL3; - -// Monitor Debug System Control Register -__register 32 { 31:31 TFO, 30:30 RXfull, 29:29 TXfull, 27:27 RXO, 26:26 TXU, 23:22 INTdis, 21:21 TDA, 19:19 SC2, 15:15 MDE, 14:14 HDE, 13:13 KDE, 12:12 TDCC, 6:6 ERR, 0:0 SS } MDSCR_EL1; - -// Pointer Authentication Key B for Instruction (bits[63:0]) -__register 64 { } APIBKeyLo_EL1; - -// Selected Error Record Miscellaneous Register 0 -__register 32 { } ERXMISC0; - -// AArch32 Memory Model Feature Register 2 -__register 32 { 31:28 HWAccFlg, 27:24 WFIStall, 23:20 MemBarr, 19:16 UniTLB, 15:12 HvdTLB, 11:8 L1HvdRng, 7:4 L1HvdBG, 3:0 L1HvdFG } ID_MMFR2_EL1; - -// Auxiliary Control Register 2 -__register 32 { } ACTLR2; - -// Current Cache Size ID Register 2 -__register 32 { 23:0 NumSets } CCSIDR2_EL1; - -// Interrupt Group Modifier Register 0 -__register 32 { } GICR_IGRPMODR0; - -// Interrupt Controller Highest Priority Pending Interrupt Register 0 -__register 32 { 23:0 INTID } ICC_HPPIR0_EL1; - -// MPAM Virtual PARTID Mapping Register 7 -__register 64 { 63:48 PhyPARTID31, 47:32 PhyPARTID30, 31:16 PhyPARTID29, 15:0 PhyPARTID28 } MPAMVPM7_EL2; - -// Debug Data Transfer Register, Receive -__register 32 { } DBGDTRRXint; - -// MPAM Memory System Monitor Configure Cache Storage Usage Monitor Filter Register -__register 32 { 23:16 PMG, 15:0 PARTID } MSMON_CFG_CSU_FLT; - -// Performance Monitors Selected Event Type Register -__register 32 { } PMXEVTYPER; - -// Cache Level ID Register -__register 32 { 31:30 ICB, 29:27 LoUU, 26:24 LoC, 23:21 LoUIS } CLIDR; - -// Performance Monitors Authentication Status register -__register 32 { 7:6 SNID, 5:4 SID, 3:2 NSNID, 1:0 NSID } PMAUTHSTATUS; - -// MPAM Priority Partitioning Identification Register -__register 32 { 25:20 DSPRI_WD, 17:17 DSPRI_0_IS_LOW, 16:16 HAS_DSPRI, 9:4 INTPRI_WD, 1:1 INTPRI_0_IS_LOW, 0:0 HAS_INTPRI } MPAMF_PRI_IDR; - -// Counter-timer Secure Physical Timer Control Register (EL2) -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTHPS_CTL; - -// Saved Program Status Register (EL2) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 DIT, 12:12 SSBS, 22:22 PAN, 21:21 SS, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 25:25 TCO, 23:23 UAO, 11:10 BTYPE, 9:9 D, 15:10, 26:25 IT, 4:4, 4:4, 3:0, 3:0 M } SPSR_EL2; - -// Interrupt Controller Active Priorities Group 0 Registers -array [0..3] of __register 64 { } ICC_AP0R_EL1; - -// Activity Monitors Component Identification Register 0 -__register 32 { 7:0 PRMBL_0 } AMCIDR0; - -// Tag Check Override -__register 64 { 25:25 TCO } TCO; - -// External Debug Status and Control Register -__register 32 { 31:31 TFO, 30:30 RXfull, 29:29 TXfull, 28:28 ITO, 27:27 RXO, 26:26 TXU, 25:25 PipeAdv, 24:24 ITE, 23:22 INTdis, 21:21 TDA, 20:20 MA, 19:19 SC2, 18:18 NS, 16:16 SDD, 14:14 HDE, 13:10 RW, 9:8 EL, 7:7 A, 6:6 ERR, 5:0 STATUS } EDSCR; - -// Counter-timer Physical Secure Timer CompareValue register -__register 64 { 63:0 CompareValue } CNTPS_CVAL_EL1; - -// AArch32 Instruction Set Attribute Register 3 -__register 32 { 31:28 T32EE, 27:24 TrueNOP, 23:20 T32Copy, 19:16 TabBranch, 15:12 SynchPrim, 11:8 SVC, 7:4 SIMD, 3:0 Saturate } ID_ISAR3_EL1; - -// Set Non-secure SPI Pending Register -__register 32 { 12:0 INTID } GICD_SETSPI_NSR; - -// Set LPI Pending Register -__register 64 { 31:0 pINTID } GICR_SETLPIR; - -// Activity Monitors Control Register -__register 64 { 17:17 CG1RZ, 10:10 HDBG } AMCR_EL0; - -// External Debug Peripheral Identification Register 1 -__register 32 { 7:4 DES_0, 3:0 PART_1 } EDPIDR1; - -// Saved Program Status Register (Abort mode) -__register 32 { 31:31 N, 30:30 Z, 29:29 C, 28:28 V, 27:27 Q, 24:24 J, 23:23 SSBS, 22:22 PAN, 21:21 DIT, 20:20 IL, 19:16 GE, 9:9 E, 8:8 A, 7:7 I, 6:6 F, 5:5 T, 15:10, 26:25 IT, 4:0 M } SPSR_abt; - -// Clear LPI Pending Register -__register 64 { 31:0 pINTID } GICR_CLRLPIR; - -// Interrupt Set-Pending Registers (extended SPI range) -array [0..31] of __register 32 { } GICD_ISPENDRE; - -// External Debug Device ID register 2 -__register 32 { } EDDEVID2; - -// Non-secure Access Control Register -__register 32 { } GICR_NSACR; - -// Counter-timer Physical Count register -__register 64 { } CNTPCT_EL0; - -// Translation Control Register (EL1) -__register 64 { 58:58 TCMA1, 57:57 TCMA0, 56:56 E0PD1, 55:55 E0PD0, 54:54 NFD1, 53:53 NFD0, 52:52 TBID1, 51:51 TBID0, 50:50 HWU162, 49:49 HWU161, 48:48 HWU160, 47:47 HWU159, 46:46 HWU062, 45:45 HWU061, 44:44 HWU060, 43:43 HWU059, 42:42 HPD1, 41:41 HPD0, 40:40 HD, 39:39 HA, 38:38 TBI1, 37:37 TBI0, 36:36 AS, 34:32 IPS, 31:30 TG1, 29:28 SH1, 27:26 ORGN1, 25:24 IRGN1, 23:23 EPD1, 22:22 A1, 21:16 T1SZ, 15:14 TG0, 13:12 SH0, 11:10 ORGN0, 9:8 IRGN0, 7:7 EPD0, 5:0 T0SZ } TCR_EL1; - -// CPU Interface Active Priorities Registers -array [0..3] of __register 32 { } GICC_APR; - -// AArch32 Media and VFP Feature Register 2 -__register 32 { 7:4 FPMisc, 3:0 SIMDMisc } MVFR2_EL1; - -// CPU Interface Binary Point Register -__register 32 { 2:0 Binary_Point } GICC_BPR; - -// Counter-timer Secure Virtual Timer TimerValue Register (EL2) -__register 32 { 31:0 TimerValue } CNTHVS_TVAL; - -// CTI Component Identification Register 1 -__register 32 { 7:4 CLASS, 3:0 PRMBL_1 } CTICIDR1; - -// Current Cache Size ID Register -__register 32 { 12:3 Associativity, 2:0 LineSize, 27:13 NumSets } CCSIDR; - -// Selected Pseudo-fault Generation Control register -__register 64 { } ERXPFGCTL_EL1; - -// CTI Device Affinity register 1 -__register 32 { 31:0 MPIDR_EL1hi } CTIDEVAFF1; - -// Error Reporting Status Register -__register 32 { 3:3 WROD, 2:2 RWOD, 1:1 WRD, 0:0 RRD } GICD_STATUSR; - -// Interrupt Controller Virtual Running Priority Register -__register 32 { 7:0 Priority } ICV_RPR_EL1; - -// Memory Attribute Indirection Register (EL1) -__register 64 { } MAIR_EL1; - -// TCM Type Register -__register 32 { } TCMTR; - -// Counter-timer Non-secure Access Register -__register 32 { } CNTNSAR; - -// Interrupt Controller Binary Point Register 0 -__register 32 { 2:0 BinaryPoint } ICC_BPR0; - -// MPAM Memory System Monitor Configure Memory Bandwidth Usage Monitor Control Register -__register 32 { 31:31 EN, 30:28 CAPT_EVNT, 27:27 CAPT_RESET, 26:26 OFLOW_STATUS, 25:25 OFLOW_INTR, 24:24 OFLOW_FRZ, 23:20 SUBTYPE, 19:19 SCLEN, 17:17 MATCH_PMG, 16:16 MATCH_PARTID, 15:15 OFLOW_STATUS_L, 14:14 OFLOW_INTR_L, 7:0 TYPE } MSMON_CFG_MBWU_CTL; - -// CTI Channel Out Status register -__register 32 { } CTICHOUTSTATUS; - -// Virtualization Translation Table Base Register -__register 64 { 55:48 VMID, 47:1 BADDR, 0:0 CnP } VTTBR; - -// OS Lock Exception Catch Control Register -__register 32 { 31:0 EDECCR } OSECCR_EL1; - -// Interrupt Controller Virtual Binary Point Register 1 -__register 32 { 2:0 BinaryPoint } ICV_BPR1; - -// Performance Monitors Count Enable Clear register -__register 32 { 31:31 C } PMCNTENCLR; - -// Cache Level ID Register -__register 64 { 32:30 ICB, 29:27 LoUU, 26:24 LoC, 23:21 LoUIS } CLIDR_EL1; - -// Selected Error Record Address Register -__register 64 { } ERXADDR_EL1; - -// Virtual Machine Error Reporting Status Register -__register 32 { 3:3 WROD, 2:2 RWOD, 1:1 WRD, 0:0 RRD } GICV_STATUSR; - -// MPAM ID Register (EL1) -__register 64 { 61:61 HAS_SDEFLT, 60:60 HAS_FORCE_NS, 58:58 HAS_TIDR, 39:32 PMG_MAX, 20:18 VPMR_MAX, 17:17 HAS_HCR, 15:0 PARTID_MAX } MPAMIDR_EL1; - -// Debug Breakpoint Control Registers -array [0..15] of __register 64 { 23:20 BT, 19:16 LBN, 15:14 SSC, 13:13 HMC, 8:5 BAS, 2:1 PMC, 0:0 E } DBGBCR_EL1; - -// Counter-timer Physical Timer TimerValue register -__register 32 { 31:0 TimerValue } CNTP_TVAL_EL0; - -// Counter-timer Self-Synchronized Physical Count register -__register 64 { } CNTPCTSS; - -// AArch32 Processor Feature Register 0 -__register 32 { 31:28 RAS, 27:24 DIT, 23:20 AMU, 19:16 CSV2, 15:12 State3, 11:8 State2, 7:4 State1, 3:0 State0 } ID_PFR0_EL1; - -// Error Record Miscellaneous Register 2 -array [0..65534] of __register 64 { } ERRMISC2; - -// EL1 Software Thread ID Register -__register 64 { } TPIDR_EL1; - -// Interrupt Controller Interrupt Acknowledge Register 0 -__register 32 { 23:0 INTID } ICC_IAR0_EL1; - -// Interrupt Controller Interrupt Group 1 Enable register -__register 32 { 0:0 Enable } ICC_IGRPEN1_EL1; - -// EL3 Read/Write Software Context Number -__register 64 { } SCXTNUM_EL3; - -// Virtual Machine Running Priority Register -__register 32 { 7:0 Priority } GICV_RPR; - -// Interrupt Controller System Register Enable register (EL1) -__register 32 { 2:2 DIB, 1:1 DFB, 0:0 SRE } ICC_SRE_EL1; - -// AArch64 Auxiliary Feature Register 1 -__register 64 { } ID_AA64AFR1_EL1; - -// Counter-timer Hyp Physical Timer TimerValue register -__register 32 { 31:0 TimerValue } CNTHP_TVAL; - -// Counter Identification Register -__register 32 { 3:0 CNTSC } CNTID; - -// Auxiliary Feature Register 0 -__register 32 { } ID_AFR0; - -// CTI Device Control register -__register 32 { 1:1 RCE, 0:0 OSUCE } CTIDEVCTL; - -// Interrupt Controller Virtual Active Priorities Group 1 Registers -array [0..3] of __register 32 { } ICV_AP1R; - -// External Debug Context ID Sample Register -__register 32 { 31:0 CONTEXTIDR } EDCIDSR; - -// Debug Watchpoint Fault Address Register -__register 32 { } DBGWFAR; - -// Interrupt Processor Targets Registers -array [0..254] of __register 32 { 31:24 CPU_targets_offset_3B, 23:16 CPU_targets_offset_2B, 15:8 CPU_targets_offset_1B, 7:0 CPU_targets_offset_0B } GICD_ITARGETSR; - -// MPAM PARTID Narrowing ID register -__register 32 { 15:0 INTPARTID_MAX } MPAMF_PARTID_NRW_IDR; - -// Selected Error Record Miscellaneous Register 6 -__register 32 { } ERXMISC6; - -// Hyp System Control Register -__register 32 { 31:31 DSSBS, 30:30 TE, 25:25 EE, 19:19 WXN, 12:12 I, 8:8 SED, 7:7 ITD, 5:5 CP15BEN, 4:4 LSMAOE, 3:3 nTLSMD, 2:2 C, 1:1 A, 0:0 M } HSCTLR; - -// Auxiliary Instruction Fault Status Register -__register 32 { } AIFSR; - -// Revision ID Register -__register 32 { } REVIDR_EL1; - -// External Debug Program Counter Sample Register -__register 64 { 63:63 NS, 62:61 EL } EDPCSR; - -// Performance Monitors Device ID register -__register 32 { 3:0 PCSample } PMDEVID; - -// Performance Monitors Device Affinity register 0 -__register 32 { 31:0 MPIDR_EL1lo } PMDEVAFF0; - -// Virtual Machine Active Priorities Registers -array [0..3] of __register 32 { } GICV_APR; - -// Performance Monitors Software Increment register -__register 32 { } PMSWINC_EL0; - -// Auxiliary Fault Status Register 0 (EL3) -__register 32 { } AFSR0_EL3; - -// Error Recovery Interrupt Configuration Register 1 -__register 32 { 31:0 DATA } ERRERICR1; - -// Error Recovery Interrupt Configuration Register 2 -__register 32 { 7:7 IRQEN, 6:6 NSMSI, 5:4 SH, 3:0 MemAttr } ERRERICR2; - -// Virtual Machine Priority Mask Register -__register 32 { 7:0 Priority } GICV_PMR; - -// Interrupt Controller Virtual Highest Priority Pending Interrupt Register 1 -__register 32 { 23:0 INTID } ICV_HPPIR1_EL1; - -// Activity Monitors Count Enable Clear Register 0 -__register 64 { } AMCNTENCLR0_EL0; - -// Interrupt Clear-Pending Registers -array [1..2] of __register 32 { } GICR_ICPENDRE; - -// Interrupt Set-Enable Registers -array [1..2] of __register 32 { } GICR_ISENABLERE; - -// External Debug Device ID register 1 -__register 32 { 3:0 PCSROffset } EDDEVID1; - -// CTI Application Trigger Clear register -__register 32 { } CTIAPPCLEAR; - -// Interrupt Mask Bits -__register 32 { 9:9 D, 8:8 A, 7:7 I, 6:6 F } DAIF; - -// Debug Device ID register 2 -__register 32 { } DBGDEVID2; - -// Hyp Auxiliary Memory Attribute Indirection Register 0 -__register 32 { } HAMAIR0; - -// Counter-timer Kernel Control register -__register 32 { 17:17 EVNTIS, 9:9 PL0PTEN, 8:8 PL0VTEN, 7:4 EVNTI, 3:3 EVNTDIR, 2:2 EVNTEN, 1:1 PL0VCTEN, 0:0 PL0PCTEN } CNTKCTL; - -// Counter-timer Physical Secure Timer TimerValue register -__register 32 { 31:0 TimerValue } CNTPS_TVAL_EL1; - -// Clear Non-secure SPI Pending Register -__register 32 { 12:0 INTID } GICD_CLRSPI_NSR; - -// Interrupt Controller Virtual Interrupt Group 1 Enable register -__register 32 { 0:0 Enable } ICV_IGRPEN1; - -// Selected Pseudo-fault Generation Feature register -__register 64 { } ERXPFGF_EL1; - -// Deferred Interrupt Status Register -__register 64 { 31:31 A, 24:24 IDS, 12:10 AET, 9:9 EA, 5:0 DFSC, 23:0 ISS } DISR_EL1; - -// Selected Error Record Primary Status Register -__register 32 { } ERXSTATUS; - -// Interrupt Clear-Active Registers -array [0..31] of __register 32 { } GICD_ICACTIVER; - -// MPAM Priority Partition Configuration Register -__register 32 { 31:16 DSPRI, 15:0 INTPRI } MPAMCFG_PRI; - -// Activity Monitors Component Identification Register 1 -__register 32 { 7:4 CLASS, 3:0 PRMBL_1 } AMCIDR1; - -// Revision ID Register -__register 32 { } REVIDR; - -// Counter-timer Virtual Timer CompareValue register -__register 64 { 63:0 CompareValue } CNTV_CVAL_EL0; - -// Counter-timer Secure Physical Timer CompareValue register (EL2) -__register 64 { 63:0 CompareValue } CNTHPS_CVAL_EL2; - -// Architectural Feature Trap Register (EL3) -__register 32 { 31:31 TCPAC, 30:30 TAM, 20:20 TTA, 10:10 TFP, 8:8 EZ } CPTR_EL3; - -// CTI Control register -__register 32 { 0:0 GLBEN } CTICONTROL; - -// Counter-timer Secure Physical Timer Control register (EL2) -__register 32 { 2:2 ISTATUS, 1:1 IMASK, 0:0 ENABLE } CNTHPS_CTL_EL2; - -// AArch32 Memory Model Feature Register 0 -__register 32 { 31:28 InnerShr, 27:24 FCSE, 23:20 AuxReg, 19:16 TCM, 15:12 ShareLvl, 11:8 OuterShr, 7:4 PMSA, 3:0 VMSA } ID_MMFR0_EL1; - -// Interrupt Controller Virtual Interrupt Priority Mask Register -__register 32 { 7:0 Priority } ICV_PMR_EL1; - -// Interrupt Controller Virtual End Of Interrupt Register 0 -__register 32 { 23:0 INTID } ICV_EOIR0_EL1; - -// Translation Table Base Register 0 (EL2) -__register 64 { 63:48 ASID, 47:1 BADDR, 0:0 CnP } TTBR0_EL2; - diff --git a/mra_tools/support/aes.asl b/mra_tools/support/aes.asl deleted file mode 100644 index 68889e14..00000000 --- a/mra_tools/support/aes.asl +++ /dev/null @@ -1,34 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Functions to support AES -// -// The following functions are not defined in the current -// XML release but are necessary to build a working simulator -//////////////////////////////////////////////////////////////// - -bits(128) AESInvMixColumns(bits (128) op) - assert FALSE; - return Zeros(128); - -bits(128) AESInvShiftRows(bits(128) op) - assert FALSE; - return Zeros(128); - -bits(128) AESInvSubBytes(bits(128) op) - assert FALSE; - return Zeros(128); - -bits(128) AESMixColumns(bits (128) op) - assert FALSE; - return Zeros(128); - -bits(128) AESShiftRows(bits(128) op) - assert FALSE; - return Zeros(128); - -bits(128) AESSubBytes(bits(128) op) - assert FALSE; - return Zeros(128); - -//////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////// diff --git a/mra_tools/support/barriers.asl b/mra_tools/support/barriers.asl deleted file mode 100644 index 5072abcc..00000000 --- a/mra_tools/support/barriers.asl +++ /dev/null @@ -1,29 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Functions to perform barrier operations -// -// The following functions are not defined in the current -// XML release but are necessary to build a working simulator -//////////////////////////////////////////////////////////////// - -DataMemoryBarrier(MBReqDomain domain, MBReqTypes types) - return; - -DataSynchronizationBarrier(MBReqDomain domain, MBReqTypes types) - return; - -ErrorSynchronizationBarrier(MBReqDomain domain, MBReqTypes types) - return; - -InstructionSynchronizationBarrier() - return; - -ProfilingSynchronizationBarrier() - return; - -SynchronizeContext() - return; - -//////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////// - diff --git a/mra_tools/support/debug.asl b/mra_tools/support/debug.asl deleted file mode 100644 index 896d32dc..00000000 --- a/mra_tools/support/debug.asl +++ /dev/null @@ -1,41 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Functions to support debug features -// -// The following functions are not defined in the current -// XML release but are necessary to build a working simulator -//////////////////////////////////////////////////////////////// - -CTI_SetEventLevel(CrossTriggerIn id, signal level) - assert FALSE; - -CTI_SignalEvent(CrossTriggerIn id) - assert FALSE; - -DisableITRAndResumeInstructionPrefetch() - assert FALSE; - -boolean HaltingStep_DidNotStep() - assert FALSE; - return FALSE; - -boolean HaltingStep_SteppedEX() - assert FALSE; - return FALSE; - -ResetExternalDebugRegisters(boolean cold_reset) - assert FALSE; - -boolean SoftwareStep_DidNotStep() - assert FALSE; - return FALSE; - -boolean SoftwareStep_SteppedEX() - assert FALSE; - return FALSE; - -StopInstructionPrefetchAndEnableITR() - assert FALSE; - -//////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////// diff --git a/mra_tools/support/feature.asl b/mra_tools/support/feature.asl deleted file mode 100644 index 4a53744f..00000000 --- a/mra_tools/support/feature.asl +++ /dev/null @@ -1,60 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Feature support -//////////////////////////////////////////////////////////////// - -boolean HaveAnyAArch32() - // return boolean IMPLEMENTATION_DEFINED; - return TRUE; - -boolean HighestELUsingAArch32() - if !HaveAnyAArch32() then return FALSE; - // return boolean IMPLEMENTATION_DEFINED; // e.g. CFG32SIGNAL == HIGH - return FALSE; - -boolean HaveEL(bits(2) el) - if el IN {EL1,EL0} then - return TRUE; // EL1 and EL0 must exist - // return boolean IMPLEMENTATION_DEFINED; - return TRUE; - -boolean IsSecureBelowEL3() - if HaveEL(EL3) then - return SCR_GEN[].NS == '0'; - elsif HaveEL(EL2) then - return FALSE; - else - // TRUE if processor is Secure or FALSE if Non-secure; - // return boolean IMPLEMENTATION_DEFINED; - return FALSE; - -boolean HasArchVersion(ArchVersion version) - // return version == ARMv8p0 || boolean IMPLEMENTATION_DEFINED; - return version IN {ARMv8p0, ARMv8p1, ARMv8p2, ARMv8p3, - ARMv8p4, ARMv8p5, ARMv8p6}; - -boolean HaveAArch32EL(bits(2) el) - // Return TRUE if Exception level 'el' supports AArch32 in this implementation - if !HaveEL(el) then - return FALSE; // The Exception level is not implemented - elsif !HaveAnyAArch32() then - return FALSE; // No Exception level can use AArch32 - elsif HighestELUsingAArch32() then - return TRUE; // All Exception levels are using AArch32 - elsif el == HighestEL() then - return FALSE; // The highest Exception level is using AArch64 - elsif el == EL0 then - return TRUE; // EL0 must support using AArch32 if any AArch32 - // return boolean IMPLEMENTATION_DEFINED; - return TRUE; - -boolean Have16bitVMID() - // return HaveEL(EL2) && boolean IMPLEMENTATION_DEFINED; - return HaveEL(EL2); - -boolean HaveFP16Ext() - // return boolean IMPLEMENTATION_DEFINED; - return TRUE; - -//////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////// diff --git a/mra_tools/support/fetchdecode.asl b/mra_tools/support/fetchdecode.asl deleted file mode 100644 index 394ccbb0..00000000 --- a/mra_tools/support/fetchdecode.asl +++ /dev/null @@ -1,254 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Functions to support instruction fetch/decode -// -// The following functions are not defined in the current -// XML release but are necessary to build a working simulator -//////////////////////////////////////////////////////////////// - -EndOfInstruction() - __ExceptionTaken(); - - -boolean __Sleeping; - -EnterLowPowerState() - __Sleeping = TRUE; - -ExitLowPowerState() - __Sleeping = FALSE; - -__ResetExecuteState() - __Sleeping = FALSE; - -ExecuteA64(bits(32) instr) - __decode A64 instr; - -ExecuteA32(bits(32) instr) - __decode A32 instr; - -ExecuteT32(bits(16) hw1, bits(16) hw2) - __decode T32 (hw1 : hw2); - -ExecuteT16(bits(16) instr) - __decode T16 instr; - -// Implementation of BranchTo and BranchToAddr modified so that we can -// tell that a branch was taken - this is essential for implementing -// PC advance correctly. - -boolean __BranchTaken; - -BranchTo(bits(N) target, BranchType branch_type) - __BranchTaken = TRUE; // extra line added - Hint_Branch(branch_type); - if N == 32 then - assert UsingAArch32(); - _PC = ZeroExtend(target); - else - assert N == 64 && !UsingAArch32(); - _PC = AArch64.BranchAddr(target[63:0]); - return; - -BranchToAddr(bits(N) target, BranchType branch_type) - __BranchTaken = TRUE; // extra line added - Hint_Branch(branch_type); - if N == 32 then - assert UsingAArch32(); - _PC = ZeroExtend(target); - else - assert N == 64 && !UsingAArch32(); - _PC = target[63:0]; - return; - -enumeration __InstrEnc { __A64, __A32, __T16, __T32 }; - -bits(32) __ThisInstr; -__InstrEnc __ThisInstrEnc; -bits(4) __currentCond; - - -__SetThisInstrDetails(__InstrEnc enc, bits(32) opcode, bits(4) cond) - __ThisInstrEnc = enc; - __ThisInstr = opcode; - __currentCond = cond; - return; - -bits(32) ThisInstr() - return __ThisInstr; - -// Length in bits of instruction -integer ThisInstrLength() - return if __ThisInstrEnc == __T16 then 16 else 32; - -bits(4) AArch32.CurrentCond() - return __currentCond; - -bits(N) ThisInstrAddr() - return _PC[0 +: N]; - -bits(N) NextInstrAddr() - return (_PC + (ThisInstrLength() DIV 8))[N-1:0]; - -(__InstrEnc, bits(32)) __FetchInstr(bits(64) pc) - __InstrEnc enc; - bits(32) instr; - - CheckSoftwareStep(); - - if PSTATE.nRW == '0' then - AArch64.CheckPCAlignment(); - enc = __A64; - instr = AArch64.MemSingle[pc, 4, AccType_IFETCH, TRUE]; - AArch64.CheckIllegalState(); - else - AArch32.CheckPCAlignment(); - if PSTATE.T == '1' then - hw1 = AArch32.MemSingle[pc[31:0], 2, AccType_IFETCH, TRUE]; - isT16 = UInt(hw1[15:11]) < UInt('11101'); - if isT16 then - enc = __T16; - instr = Zeros(16) : hw1; - else - hw2 = AArch32.MemSingle[pc[31:0]+2, 2, AccType_IFETCH, TRUE]; - enc = __T32; - instr = hw1 : hw2; - else - enc = __A32; - instr = AArch32.MemSingle[pc[31:0], 4, AccType_IFETCH, TRUE]; - AArch32.CheckIllegalState(); - - return (enc, instr); - -__DecodeExecute(__InstrEnc enc, bits(32) instr) - case enc of - when __A64 - ExecuteA64(instr); - when __A32 - ExecuteA32(instr); - when __T16 - ExecuteT16(instr[15:0]); - when __T32 - ExecuteT32(instr[31:16], instr[15:0]); - return; - -// Default condition for an instruction with encoding 'enc'. -// This may be overridden for instructions with explicit condition field. -bits(4) __DefaultCond(__InstrEnc enc) - if enc IN {__A64, __A32} || PSTATE.IT[3:0] == Zeros(4) then - cond = 0xE[3:0]; - else - cond = PSTATE.IT[7:4]; - return cond; - -__InstructionExecute() - try - __BranchTaken = FALSE; - bits(64) pc = ThisInstrAddr(); - (enc, instr) = __FetchInstr(pc); - __SetThisInstrDetails(enc, instr, __DefaultCond(enc)); - __DecodeExecute(enc, instr); - - catch exn - // Do not catch UNPREDICTABLE or internal errors - when IsSEE(exn) || IsUNDEFINED(exn) - if UsingAArch32() then - if ConditionHolds(AArch32.CurrentCond()) then - AArch32.UndefinedFault(); - else - AArch64.UndefinedFault(); - - when IsExceptionTaken(exn) - // Do nothing - assert TRUE; // todo: this is a bodge around lack of support for empty statements - - if !__BranchTaken then - _PC = (_PC + (ThisInstrLength() DIV 8))[63:0]; - - boolean itExecuted = __ThisInstrEnc == __T16 && __ThisInstr[15:0] IN '1011 1111 xxxx xxxx' && __ThisInstr[3:0] != '0000'; - if PSTATE.nRW == '1' && PSTATE.T == '1' && !itExecuted then - AArch32.ITAdvance(); - - return; - -//////////////////////////////////////////////////////////////// -// The following functions define the IMPLEMENTATION_DEFINED behaviour -// of this execution -//////////////////////////////////////////////////////////////// - -boolean __IMPDEF_boolean(string x) - if x == "Condition valid for trapped T32" then return TRUE; - elsif x == "Has Dot Product extension" then return TRUE; - elsif x == "Has RAS extension" then return TRUE; - elsif x == "Has SHA512 and SHA3 Crypto instructions" then return TRUE; - elsif x == "Has SM3 and SM4 Crypto instructions" then return TRUE; - elsif x == "Has basic Crypto instructions" then return TRUE; - elsif x == "Have CRC extension" then return TRUE; - elsif x == "Report I-cache maintenance fault in IFSR" then return TRUE; - elsif x == "Reserved Control Space EL0 Trapped" then return TRUE; - elsif x == "Translation fault on misprogrammed contiguous bit" then return TRUE; - elsif x == "UNDEF unallocated CP15 access at NS EL0" then return TRUE; - elsif x == "UNDEF unallocated CP15 access at NS EL0" then return TRUE; - - return FALSE; - -integer __IMPDEF_integer(string x) - if x == "Maximum Physical Address Size" then return 52; - elsif x == "Maximum Virtual Address Size" then return 56; - - return 0; - -bits(N) __IMPDEF_bits(integer N, string x) - if x == "0 or 1" then return Zeros(N); - elsif x == "FPEXC.EN value when TGE==1 and RW==0" then return Zeros(N); - elsif x == "reset vector address" then return Zeros(N); - - return Zeros(N); - -MemoryAttributes __IMPDEF_MemoryAttributes(string x) - return MemoryAttributes UNKNOWN; - -// todo: implement defaults for these behaviours -// IMPLEMENTATION_DEFINED "floating-point trap handling"; -// IMPLEMENTATION_DEFINED "signal slave-generated error"; - -//////////////////////////////////////////////////////////////// -// The following functions are required by my simulator: -// - __TopLevel(): take one atomic step -// - __setPC(): set PC to particular value (used after loading an ELF file) -// - __getPC(): read current value of PC (used to support breakpointing) -// - __conditionPassed: set if executing a conditional instruction -// - __CycleEnd(): deprecated hook called after every instruction execution -// - __ModeString(): generate summary of current mode (used to support tracing) -//////////////////////////////////////////////////////////////// - -__TakeColdReset() - PSTATE.nRW = '0'; // boot into A64 mode - PSTATE.SS = '0'; - __ResetInterruptState(); - __ResetMemoryState(); - __ResetExecuteState(); - AArch64.TakeReset(TRUE); - -__TopLevel() - __InstructionExecute(); - -__setPC(integer x) - _PC = x[63:0]; - return; - -integer __getPC() - return UInt(_PC); - -boolean __conditionPassed; - -__CycleEnd() - return; - -// Function used to generate summary of current state of processor -// (used when generating debug traces) -string __ModeString() - return ""; - -//////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////// diff --git a/mra_tools/support/hints.asl b/mra_tools/support/hints.asl deleted file mode 100644 index ef2711db..00000000 --- a/mra_tools/support/hints.asl +++ /dev/null @@ -1,31 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Functions to implement hint instructions -// -// The following functions are not defined in the current -// XML release but are necessary to build a working simulator -//////////////////////////////////////////////////////////////// - -Hint_Branch(BranchType hint) - return; - -Hint_Prefetch(bits(64) address, PrefetchHint hint, integer target, boolean stream) - return; - -Hint_PreloadDataForWrite(bits(32) address) - return; - -Hint_PreloadData(bits(32) address) - return; - -Hint_PreloadDataForWrite(bits(32) address) - return; - -Hint_PreloadInstr(bits(32) address) - return; - -Hint_Yield() - return; - -//////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////// diff --git a/mra_tools/support/interrupts.asl b/mra_tools/support/interrupts.asl deleted file mode 100644 index ceaeda73..00000000 --- a/mra_tools/support/interrupts.asl +++ /dev/null @@ -1,55 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Functions to support interrupts and System Errors -// -// The following functions are not defined in the current -// XML release but are necessary to build a working simulator -//////////////////////////////////////////////////////////////// - -boolean __PendingPhysicalSError; -boolean __PendingInterrupt; - -__ResetInterruptState() - __PendingPhysicalSError = FALSE; - __PendingInterrupt = FALSE; - -boolean InterruptPending() - return __PendingInterrupt; - -SendEvent() - assert FALSE; - -SetInterruptRequestLevel(InterruptID id, signal level) - assert FALSE; - -AArch32.SErrorSyndrome AArch32.PhysicalSErrorSyndrome() - assert FALSE; - AArch32.SErrorSyndrome r; - r.AET = Zeros(2); - r.ExT = Zeros(1); - return r; - -bits(25) AArch64.PhysicalSErrorSyndrome(boolean implicit_esb) - assert FALSE; - return Zeros(25); - -__SetPendingPhysicalSError() - __PendingPhysicalSError = TRUE; - return; - -ClearPendingPhysicalSError() - __PendingPhysicalSError = FALSE; - return; - -boolean SErrorPending() - // todo: can there be a pending virtual SError? - return __PendingPhysicalSError; - -TakeUnmaskedPhysicalSErrorInterrupts(boolean iesb_req) - assert FALSE; - -TakeUnmaskedSErrorInterrupts() - assert FALSE; - -//////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////// diff --git a/mra_tools/support/memory.asl b/mra_tools/support/memory.asl deleted file mode 100644 index 648fa9bd..00000000 --- a/mra_tools/support/memory.asl +++ /dev/null @@ -1,109 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Functions to support exclusive memory accesses -// -// The following functions are not defined in the current -// XML release but are necessary to build a working simulator -//////////////////////////////////////////////////////////////// - -__RAM(52) __Memory; - -boolean __ExclusiveLocal; - -__ResetMemoryState() - __InitRAM(52, 1, __Memory, Zeros(8)); // zero memory on reset - __ExclusiveLocal = FALSE; - -__ELFWriteMemory(bits(64) address, bits(8) val) - __WriteRAM(52, 1, __Memory, address[0 +: 52], val); - return; - -bits(8*size) _Mem[AddressDescriptor desc, integer size, AccessDescriptor accdesc] - assert size IN {1, 2, 4, 8, 16}; - bits(52) address = desc.paddress.address; - assert address == Align(address, size); - return __ReadRAM(52, size, __Memory, address); - -_Mem[AddressDescriptor desc, integer size, AccessDescriptor accdesc] = bits(8*size) value - assert size IN {1, 2, 4, 8, 16}; - bits(52) address = desc.paddress.address; - assert address == Align(address, size); - - if address == 0x13000000[51:0] then // TUBE - if UInt(value) == 0x4 then - print("Program exited by writing ^D to TUBE\n"); - __abort(); - else - putchar(UInt(value[7:0])); - else - __WriteRAM(52, size, __Memory, address, value); - return; - -ClearExclusiveLocal(integer processorid) - __ExclusiveLocal = FALSE; - return; - -MarkExclusiveLocal(FullAddress paddress, integer processorid, integer size) - __ExclusiveLocal = FALSE; - -boolean IsExclusiveLocal(FullAddress paddress, integer processorid, integer size) - return __ExclusiveLocal; - - -boolean AArch32.IsExclusiveVA(bits(32) address, integer processorid, integer size) - assert FALSE; - return FALSE; - -AArch32.MarkExclusiveVA(bits(32) address, integer processorid, integer size) - assert FALSE; - -boolean AArch64.IsExclusiveVA(bits(64) address, integer processorid, integer size) - assert FALSE; - return FALSE; - -AArch64.MarkExclusiveVA(bits(64) address, integer processorid, integer size) - assert FALSE; - -ClearExclusiveByAddress(FullAddress paddress, integer processorid, integer size) - assert TRUE; // todo - -bit ExclusiveMonitorsStatus() - assert FALSE; - return '0'; // '0' indicates success - -boolean IsExclusiveGlobal(FullAddress paddress, integer processorid, integer size) - assert FALSE; - return FALSE; - -MarkExclusiveGlobal(FullAddress paddress, integer processorid, integer size) - assert FALSE; - -integer ProcessorID() - return 0; - -bits(4) _MemTag[AddressDescriptor desc] - assert FALSE; - return Zeros(4); - -_MemTag[AddressDescriptor desc] = bits(4) value - assert FALSE; - return; - -boolean IsNonTagCheckedInstruction() - assert FALSE; - return FALSE; - -SetNotTagCheckedInstruction(boolean unchecked) - assert FALSE; - return; - -bits(4) _ChooseRandomNonExcludedTag(bits(16) exclude) - assert FALSE; - return Zeros(4); - -(bits(64), integer) ImpDefTagArrayStartAndCount(bits(64) address) - assert FALSE; - return (Zeros(64), 0); - -//////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////// diff --git a/mra_tools/support/stubs.asl b/mra_tools/support/stubs.asl deleted file mode 100644 index 2a6bd7e9..00000000 --- a/mra_tools/support/stubs.asl +++ /dev/null @@ -1,113 +0,0 @@ -//////////////////////////////////////////////////////////////// -// Miscellaneous stub functions -// -// The following functions are not defined in the current -// XML release. -//////////////////////////////////////////////////////////////// - -AArch32.ResetControlRegisters(boolean cold_reset) - assert FALSE; - -AArch32.ResetSystemRegisters(boolean cold_reset) - assert FALSE; - -AArch64.ResetControlRegisters(boolean cold_reset) - return; - -AArch64.ResetSystemRegisters(boolean cold_reset) - return; - -ResetExternalDebugRegisters(boolean cold_reset) - return; - - -bits(64) AArch32.SysRegRead64(integer cp_num, bits(32) instr) - assert FALSE; - return Zeros(64); - -boolean AArch32.SysRegReadCanWriteAPSR(integer cp_num, bits(32) instr) - assert FALSE; - return FALSE; - -bits(32) AArch32.SysRegRead(integer cp_num, bits(32) instr) - assert FALSE; - return Zeros(32); - -bits(64) AArch32.SysRegRead64(integer cp_num, bits(32) instr) - assert FALSE; - return Zeros(64); - -AArch32.SysRegWrite(integer cp_num, bits(32) instr, bits(32) val) - assert FALSE; - -AArch32.SysRegWrite64(integer cp_num, bits(32) instr, bits(64) val) - assert FALSE; - -AArch32.SysRegWrite64(integer cp_num, bits(32) instr, bits(64) val) - assert FALSE; - -(boolean, bits(2)) AArch64.CheckAdvSIMDFPSystemRegisterTraps(bits(2) op0, bits(3) op1, bits(4) crn, bits(4) crm, bits(3) op2, bit read) - assert FALSE; - return (FALSE, '00'); - -(boolean, bits(2)) AArch64.CheckAdvSIMDFPSystemRegisterTraps(bits(2) op0, bits(3) op1, bits(4) crn, bits(4) crm, bits(3) op2, bit read) - assert FALSE; - return (FALSE, '00'); - -(boolean, bits(2)) AArch64.CheckSystemRegisterTraps(bits(2) op0, bits(3) op1, bits(4) crn, bits(4) crm, bits(3) op2, bit read) - assert FALSE; - return (FALSE, '00'); - -boolean AArch64.CheckUnallocatedSystemAccess(bits(2) op0, bits(3) op1, bits(4) crn, bits(4) crm, bits(3) op2, bit read) - assert FALSE; - return FALSE; - -bits(64) AArch64.SysInstrWithResult(integer op0, integer op1, integer crn, integer crm, integer op2) - assert FALSE; - return Zeros(64); - -AArch64.SysInstr(integer op0, integer op1, integer crn, integer crm, integer op2, bits(64) val) - assert FALSE; - -bits(64) AArch64.SysInstrWithResult(integer op0, integer op1, integer crn, integer crm, integer op2) - assert FALSE; - return Zeros(64); - -AArch64.SysRegWrite(integer op0, integer op1, integer crn, integer crm, integer op2, bits(64) val) - assert FALSE; - -bits(64) System_Get(integer op0, integer op1, integer crn, integer crm, integer op2) - assert FALSE; - return Zeros(64); - -boolean CP14DebugInstrDecode(bits(32) instr) - assert FALSE; - return FALSE; - -boolean CP14JazelleInstrDecode(bits(32) instr) - assert FALSE; - return FALSE; - -boolean CP14TraceInstrDecode(bits(32) instr) - assert FALSE; - return FALSE; - -boolean CP15InstrDecode(bits(32) instr) - assert FALSE; - return FALSE; - -bits(11) LSInstructionSyndrome() - assert FALSE; - return Zeros(11); - -boolean RemapRegsHaveResetValues() - assert FALSE; - return FALSE; - -UndefinedFault() - assert FALSE; - return; - -//////////////////////////////////////////////////////////////// -// End -//////////////////////////////////////////////////////////////// diff --git a/mra_tools/types.asl b/mra_tools/types.asl deleted file mode 100644 index f2e82cbb..00000000 --- a/mra_tools/types.asl +++ /dev/null @@ -1,35 +0,0 @@ -type CPACRType = typeof(CPACR_EL1); -type CNTKCTLType = typeof(CNTKCTL_EL1); -type ESRType = typeof(ESR_EL1); -type FPCRType = typeof(FPCR); -type MAIRType = typeof(MAIR_EL1); -type SCRType = typeof(SCR_EL3); -type SCTLRType = typeof(SCTLR_EL1); - -// The following appear to be missing from the XML -// The following is not necessarily correct - but it lets us keep going -__register 32 { 31:31 EAE, 5:5 PD1, 4:4 PD0, 2:0 N, 29:28 SH1, 27:26 ORGN1, 25:24 IRGN1, 23:23 EPD1, 22:22 A1, 18:16 T1SZ, 13:12 SH0, 11:10 ORGN0, 9:8 IRGN0, 7:7 EPD0, 6:6 T2E, 2:0 T0SZ } TTBCR_S; -__register 32 { 0+:24 PC, 29+:2 EL, 31 NS } EDPCSRhi; - -bits(64) AArch64.SysRegRead(integer op0, integer op1, integer crn, integer crm, integer op2); -AArch64.SysRegWrite(integer op0, integer op1, integer crn, integer crm, integer op2, bits(64) val); -TraceSynchronizationBarrier(); -UndefinedFault(); -ReservedEncoding(); - -boolean IRQPending(); -boolean FIQPending(); - -constant integer LOG2_TAG_GRANULE=4; -constant integer TAG_GRANULE=2 ^ LOG2_TAG_GRANULE; -// These declarations have to be manually inserted into arch.asl after extraction. -// Insert them before the declaration of MemTag. -// bits(4) _MemTag[AddressDescriptor desc]; -// _MemTag[AddressDescriptor desc] = bits(4) value; -boolean IsNonTagCheckedInstruction(); -SetNotTagCheckedInstruction(boolean unchecked); -bits(4) _ChooseRandomNonExcludedTag(bits(16) exclude); -(bits(64), integer) ImpDefTagArrayStartAndCount(bits(64) address); - -signal HIDEN; -signal HNIDEN; diff --git a/coverage.sh b/scripts/coverage.sh similarity index 73% rename from coverage.sh rename to scripts/coverage.sh index 8036c20e..39ccc1b7 100755 --- a/coverage.sh +++ b/scripts/coverage.sh @@ -7,9 +7,7 @@ INSTRUCTION_GROUPS+=' aarch64_vector_arithmetic_unary(?!.*_(fp|float))' INSTRUCTION_GROUPS+=' aarch64_vector_arithmetic_binary(?!.*_(fp|float|complex|r?sqrt|bf|recp))' INSTRUCTION_GROUPS+=' aarch64_memory_.+_general.*' INSTRUCTION_GROUPS+=' aarch64_memory_atomicops_.*' -ASL_FILES="prelude.asl ./mra_tools/arch/regs.asl ./mra_tools/types.asl ./mra_tools/arch/arch.asl ./mra_tools/arch/arch_instrs.asl ./mra_tools/arch/arch_decode.asl ./mra_tools/support/aes.asl ./mra_tools/support/barriers.asl ./mra_tools/support/debug.asl ./mra_tools/support/feature.asl ./mra_tools/support/hints.asl ./mra_tools/support/interrupts.asl ./mra_tools/support/memory.asl ./mra_tools/support/stubs.asl ./mra_tools/support/fetchdecode.asl" -ASL_FILES+=" tests/override.asl" -ASL_FILES+=" tests/override.prj" +ASL_FILES="cpus/armv8.6.cpu" COVERAGE_DIR="./tests/coverage" COVERAGE_TEMP=$(mktemp -d) diff --git a/scripts/stash.sh b/scripts/stash.sh new file mode 100755 index 00000000..d40fc556 --- /dev/null +++ b/scripts/stash.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Expects to be run from asl-interpreter directory + +TARGET="cpus/armv8.6.cpu" + +echo "Extracting MRA specs" +rm -rf mra_tools +git clone https://github.com/alastairreid/mra_tools.git +cd mra_tools && mkdir -p v8.6 && cd v8.6 +wget https://developer.arm.com/-/media/developer/products/architecture/armv8-a-architecture/2019-12/SysReg_xml_v86A-2019-12.tar.gz +wget https://developer.arm.com/-/media/developer/products/architecture/armv8-a-architecture/2019-12/A64_ISA_xml_v86A-2019-12.tar.gz +wget https://developer.arm.com/-/media/developer/products/architecture/armv8-a-architecture/2019-12/AArch32_ISA_xml_v86A-2019-12.tar.gz +tar zxf A64_ISA_xml_v86A-2019-12.tar.gz +tar zxf AArch32_ISA_xml_v86A-2019-12.tar.gz +tar zxf SysReg_xml_v86A-2019-12.tar.gz +cd .. +make all + +echo "Marshalling to $TARGET" +cd .. +ASL_FILES="prelude.asl" +ASL_FILES+=" mra_tools/arch/regs.asl" +ASL_FILES+=" mra_tools/types.asl" +ASL_FILES+=" mra_tools/arch/arch.asl" +ASL_FILES+=" mra_tools/arch/arch_instrs.asl" +ASL_FILES+=" mra_tools/arch/arch_decode.asl" +ASL_FILES+=" mra_tools/support/aes.asl" +ASL_FILES+=" mra_tools/support/barriers.asl" +ASL_FILES+=" mra_tools/support/debug.asl" +ASL_FILES+=" mra_tools/support/feature.asl" +ASL_FILES+=" mra_tools/support/hints.asl" +ASL_FILES+=" mra_tools/support/interrupts.asl" +ASL_FILES+=" mra_tools/support/memory.asl" +ASL_FILES+=" mra_tools/support/stubs.asl" +ASL_FILES+=" mra_tools/support/fetchdecode.asl" +ASL_FILES+=" tests/override.asl" +ASL_FILES+=" tests/override.prj" +echo ":stash $TARGET" | dune exec asli $ASL_FILES