__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_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_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_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_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 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 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_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_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_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 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 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_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_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_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_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_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 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 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_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_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_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 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_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 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 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_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 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_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_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 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 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 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 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_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_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 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 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 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 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 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 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 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 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 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 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_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_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 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_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 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 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_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 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_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_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_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 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 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 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_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 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 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_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_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_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_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 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_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 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 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 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 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 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_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_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 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 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 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_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 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 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 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_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_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_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 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 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 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_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 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 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 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 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 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 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 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_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 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 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 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 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 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 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 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_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 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_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 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 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 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 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 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_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 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 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 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 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 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_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 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 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 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 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 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 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_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_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_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 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 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_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 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_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_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_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 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 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 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 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 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 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 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_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_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_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 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_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_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_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 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 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_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_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 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_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_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_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 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 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_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_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 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_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 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 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_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_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 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 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 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 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 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_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_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_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 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 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_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_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_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_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 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_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 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 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 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_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 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_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 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_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_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_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 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 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_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_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 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_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 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 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_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_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 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 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_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 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 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 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 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 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 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 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 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_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_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 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 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 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 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 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_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_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 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 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_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 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_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_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_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 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 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 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_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 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 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 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_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_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_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 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_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 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 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 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 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_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_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_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_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_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 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_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 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 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 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 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 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 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_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_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_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 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 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 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 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_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 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 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 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_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_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_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 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 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_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_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 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 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 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_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 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 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 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 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_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_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 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 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 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 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_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 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 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 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 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_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_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_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 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 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 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_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 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 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_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 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 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 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 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_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_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_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 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 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 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 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 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 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 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_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_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_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 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 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 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 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 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_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_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 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_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_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_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_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_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_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 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 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 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 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 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_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 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_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 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 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 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 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 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_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_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 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 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 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_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_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_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_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_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_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_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 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_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 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 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 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_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_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 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_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_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 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_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 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 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 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_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_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 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 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 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 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 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_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_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_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 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 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_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_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_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 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_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 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_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 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 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_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_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_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_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_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 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 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_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 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 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_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 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_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 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 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 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 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_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 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 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 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 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_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_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 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 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 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_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 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_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 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 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_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 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_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_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_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 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_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 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_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_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 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 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 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 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_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_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_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_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_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 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 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 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 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 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_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 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 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 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_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_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_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 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_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 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 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_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 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 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 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 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 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_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_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 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 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 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 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 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 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_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_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 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 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 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_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 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_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_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_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 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_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_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_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 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_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_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_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 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 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 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_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_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 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 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 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 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 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 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_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_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_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 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_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 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_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_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 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 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 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 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_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 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 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_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_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 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 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 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_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 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 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 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 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_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 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_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 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 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 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 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 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 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_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_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_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_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_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 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_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 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 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_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 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 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_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 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 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_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 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_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_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 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 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 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 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 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_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_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_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_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 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 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 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 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 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_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 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 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 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_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_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_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 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 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_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 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 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 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_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 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 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 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_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 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_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_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_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_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_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_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 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 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_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 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 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 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 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 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_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_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_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_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 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_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 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_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_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_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_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_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_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_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_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 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_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 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 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 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_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_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 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 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 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 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_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 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 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_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_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 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 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 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_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 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_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 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 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 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_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_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 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 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 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 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 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_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_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_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 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 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 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 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 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_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 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_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_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_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 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 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 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_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_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_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_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 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_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 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 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_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 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 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 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_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 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 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 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 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 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_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_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_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 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_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 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 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 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 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 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 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 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_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 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 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 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 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_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_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_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_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 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 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 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_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_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_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 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_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_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_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_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_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 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 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 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 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 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 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 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 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 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_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 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_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_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_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_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 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 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 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 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 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 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_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 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_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 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 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_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 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 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_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 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_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_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_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 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 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_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 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_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 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_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 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 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 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 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_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_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 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_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_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_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 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_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_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_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 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_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 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_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 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 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_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 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 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_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_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_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_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 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 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 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 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_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 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 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 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 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_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 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 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 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_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_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_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 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 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_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 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 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_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 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 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_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 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_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 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_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 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 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 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 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_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_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_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 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 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 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 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 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_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_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 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_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_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_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 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_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_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_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_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_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 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 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 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_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_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 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_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_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 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 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 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_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_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 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 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 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 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 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_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_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_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_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_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_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_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_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 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_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_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_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 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 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 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_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 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 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_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_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_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_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_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 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 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_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_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_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 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_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 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 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_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_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_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_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 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 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 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_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_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 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 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 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_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_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 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_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 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 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_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_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 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_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 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 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 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_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 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_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 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 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_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 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 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 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 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_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_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 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 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 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_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 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_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_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_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_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 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_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 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 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_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 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 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 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 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 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 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 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 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_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 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 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 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_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 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_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 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 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 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 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 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_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 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 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 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 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 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_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 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 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 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_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 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 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_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 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_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_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_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 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 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_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 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_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 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 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 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 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 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 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 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_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 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_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_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_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 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_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 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 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 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_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_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_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 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_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_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_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_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 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 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 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 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_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_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_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_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 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 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 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 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_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 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 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_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_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 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 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_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_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 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 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_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_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 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_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_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_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_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_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 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 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_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_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 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 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_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_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 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_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 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 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 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_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_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 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_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_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 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 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 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_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_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 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_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_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_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 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 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 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_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 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 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_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 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 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 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 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 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_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_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_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_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_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_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_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 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 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_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 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 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 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 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_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_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_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 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_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_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 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_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 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 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 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 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 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_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_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_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_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_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 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 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 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 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 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 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 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; //////////////////////////////////////////////////////////////////////// // End ////////////////////////////////////////////////////////////////////////