(* arm8 - generated by L3 - Wed Oct 11 10:50:34 2017 *) structure arm8 :> arm8 = struct structure Map = MutableMap (* ------------------------------------------------------------------------- Type declarations ------------------------------------------------------------------------- *) type ProcState = { C: bool, EL: BitsN.nbit, N: bool, SPS: bool, V: bool, Z: bool } type TCR_EL1 = { TBI0: bool, TBI1: bool, tcr_el1'rst: BitsN.nbit } type TCR_EL2_EL3 = { TBI: bool, tcr_el2_el3'rst: BitsN.nbit } type SCTLRType = { A: bool, E0E: bool, EE: bool, SA: bool, SA0: bool, sctlrtype'rst: BitsN.nbit } datatype BranchType = BranchType_CALL | BranchType_ERET | BranchType_DBGEXIT | BranchType_RET | BranchType_JMP | BranchType_EXCEPTION | BranchType_UNKNOWN datatype AccType = AccType_NORMAL | AccType_VEC | AccType_STREAM | AccType_VECSTREAM | AccType_ATOMIC | AccType_ORDERED | AccType_UNPRIV | AccType_IFETCH | AccType_PTW | AccType_DC | AccType_IC | AccType_AT datatype ShiftType = ShiftType_LSL | ShiftType_LSR | ShiftType_ASR | ShiftType_ROR datatype ExtendType = ExtendType_UXTB | ExtendType_UXTH | ExtendType_UXTW | ExtendType_UXTX | ExtendType_SXTB | ExtendType_SXTH | ExtendType_SXTW | ExtendType_SXTX datatype LogicalOp = LogicalOp_AND | LogicalOp_ORR | LogicalOp_EOR datatype MemOp = MemOp_LOAD | MemOp_STORE | MemOp_PREFETCH datatype MemBarrierOp = MemBarrierOp_DSB | MemBarrierOp_DMB | MemBarrierOp_ISB datatype MoveWideOp = MoveWideOp_N | MoveWideOp_Z | MoveWideOp_K datatype RevOp = RevOp_RBIT | RevOp_REV16 | RevOp_REV32 | RevOp_REV64 datatype SystemHintOp = SystemHintOp_NOP | SystemHintOp_YIELD | SystemHintOp_WFE | SystemHintOp_WFI | SystemHintOp_SEV | SystemHintOp_SEVL datatype PSTATEField = PSTATEField_DAIFSet | PSTATEField_DAIFClr | PSTATEField_SP datatype System = ExceptionReturn | HypervisorCall of BitsN.nbit | MoveImmediateProcState of PSTATEField * BitsN.nbit | MoveSystemRegister of bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))) | SecureMonitorCall of BitsN.nbit | SupervisorCall of BitsN.nbit | SystemInstruction of BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (bool * BitsN.nbit)))) datatype Debug = Breakpoint of BitsN.nbit | DebugRestore | DebugSwitch of BitsN.nbit | Halt of BitsN.nbit datatype LoadStore = LoadLiteral''32 of BitsN.nbit * (MemOp * (bool * (BitsN.nbit * BitsN.nbit))) | LoadLiteral''64 of BitsN.nbit * (MemOp * (bool * (BitsN.nbit * BitsN.nbit))) | LoadStoreAcquire''16 of BitsN.nbit * (MemOp * (AccType * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))) | LoadStoreAcquire''32 of BitsN.nbit * (MemOp * (AccType * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))) | LoadStoreAcquire''64 of BitsN.nbit * (MemOp * (AccType * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))) | LoadStoreAcquire''8 of BitsN.nbit * (MemOp * (AccType * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))) | LoadStoreAcquirePair''128 of BitsN.nbit * (MemOp * (AccType * (bool * (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))) | LoadStoreAcquirePair''64 of BitsN.nbit * (MemOp * (AccType * (bool * (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))) | LoadStoreImmediate''16 of BitsN.nbit * (bool * (MemOp * (AccType * (bool * (bool * (bool * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))))))) | LoadStoreImmediate''32 of BitsN.nbit * (bool * (MemOp * (AccType * (bool * (bool * (bool * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))))))) | LoadStoreImmediate''64 of BitsN.nbit * (bool * (MemOp * (AccType * (bool * (bool * (bool * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))))))) | LoadStoreImmediate''8 of BitsN.nbit * (bool * (MemOp * (AccType * (bool * (bool * (bool * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))))))) | LoadStorePair''32 of BitsN.nbit * (MemOp * (AccType * (bool * (bool * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))))) | LoadStorePair''64 of BitsN.nbit * (MemOp * (AccType * (bool * (bool * (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))))) | LoadStoreRegister''16 of BitsN.nbit * (bool * (MemOp * (bool * (BitsN.nbit * (ExtendType * (Nat.nat * (BitsN.nbit * BitsN.nbit))))))) | LoadStoreRegister''32 of BitsN.nbit * (bool * (MemOp * (bool * (BitsN.nbit * (ExtendType * (Nat.nat * (BitsN.nbit * BitsN.nbit))))))) | LoadStoreRegister''64 of BitsN.nbit * (bool * (MemOp * (bool * (BitsN.nbit * (ExtendType * (Nat.nat * (BitsN.nbit * BitsN.nbit))))))) | LoadStoreRegister''8 of BitsN.nbit * (bool * (MemOp * (bool * (BitsN.nbit * (ExtendType * (Nat.nat * (BitsN.nbit * BitsN.nbit))))))) datatype Branch = BranchConditional of BitsN.nbit * BitsN.nbit | BranchImmediate of BitsN.nbit * BranchType | BranchRegister of BitsN.nbit * BranchType | CompareAndBranch''32 of BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit)) | CompareAndBranch''64 of BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit)) | TestBitAndBranch''32 of BitsN.nbit * (BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit))) | TestBitAndBranch''64 of BitsN.nbit * (BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit))) datatype CRCExt = CRC''16 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | CRC''32 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | CRC''64 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | CRC''8 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) datatype Data = AddSubCarry''32 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))) | AddSubCarry''64 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))) | AddSubExtendRegister''32 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (ExtendType * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))) | AddSubExtendRegister''64 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (ExtendType * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))) | AddSubImmediate''32 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))) | AddSubImmediate''64 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))) | AddSubShiftedRegister''32 of BitsN.nbit * (bool * (bool * (ShiftType * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))) | AddSubShiftedRegister''64 of BitsN.nbit * (bool * (bool * (ShiftType * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))) | BitfieldMove''32 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (BitsN.nbit * (Nat.nat * (Nat.nat * (BitsN.nbit * BitsN.nbit))))))) | BitfieldMove''64 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (BitsN.nbit * (Nat.nat * (Nat.nat * (BitsN.nbit * BitsN.nbit))))))) | ConditionalCompareImmediate''32 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * ((bool * (bool * (bool * bool))) * BitsN.nbit)))) | ConditionalCompareImmediate''64 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * ((bool * (bool * (bool * bool))) * BitsN.nbit)))) | ConditionalCompareRegister''32 of BitsN.nbit * (bool * (BitsN.nbit * ((bool * (bool * (bool * bool))) * (BitsN.nbit * BitsN.nbit)))) | ConditionalCompareRegister''64 of BitsN.nbit * (bool * (BitsN.nbit * ((bool * (bool * (bool * bool))) * (BitsN.nbit * BitsN.nbit)))) | ConditionalSelect''32 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))) | ConditionalSelect''64 of BitsN.nbit * (bool * (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))) | CountLeading''32 of BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit)) | CountLeading''64 of BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit)) | Division''32 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | Division''64 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | ExtractRegister''32 of BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | ExtractRegister''64 of BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | LogicalImmediate''32 of BitsN.nbit * (LogicalOp * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))) | LogicalImmediate''64 of BitsN.nbit * (LogicalOp * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))) | LogicalShiftedRegister''32 of BitsN.nbit * (LogicalOp * (bool * (bool * (ShiftType * (Nat.nat * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))) | LogicalShiftedRegister''64 of BitsN.nbit * (LogicalOp * (bool * (bool * (ShiftType * (Nat.nat * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))) | MoveWide''32 of BitsN.nbit * (MoveWideOp * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | MoveWide''64 of BitsN.nbit * (MoveWideOp * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | MultiplyAddSub''32 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))) | MultiplyAddSub''64 of BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))) | MultiplyAddSubLong of bool * (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))) | MultiplyHigh of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)) | Reverse''32 of BitsN.nbit * (RevOp * (BitsN.nbit * BitsN.nbit)) | Reverse''64 of BitsN.nbit * (RevOp * (BitsN.nbit * BitsN.nbit)) | Shift''32 of BitsN.nbit * (ShiftType * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) | Shift''64 of BitsN.nbit * (ShiftType * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))) datatype instruction = Address of bool * (BitsN.nbit * BitsN.nbit) | Branch of Branch | CRCExt of CRCExt | ClearExclusive of BitsN.nbit | Data of Data | Debug of Debug | Hint of SystemHintOp | LoadStore of LoadStore | MemoryBarrier of MemBarrierOp * BitsN.nbit | Reserved | System of System | Unallocated datatype MachineCode = ARM8 of BitsN.nbit | BadCode of string datatype maybe_instruction = FAIL of string | OK of instruction | PENDING of string * instruction | WORD of BitsN.nbit (* ------------------------------------------------------------------------- Casting maps (for enumerated types) ------------------------------------------------------------------------- *) structure Cast = struct fun natToBranchType x = case Nat.toInt x of 0 => BranchType_CALL | 1 => BranchType_ERET | 2 => BranchType_DBGEXIT | 3 => BranchType_RET | 4 => BranchType_JMP | 5 => BranchType_EXCEPTION | 6 => BranchType_UNKNOWN | _ => raise Fail "natToBranchType" fun natToAccType x = case Nat.toInt x of 0 => AccType_NORMAL | 1 => AccType_VEC | 2 => AccType_STREAM | 3 => AccType_VECSTREAM | 4 => AccType_ATOMIC | 5 => AccType_ORDERED | 6 => AccType_UNPRIV | 7 => AccType_IFETCH | 8 => AccType_PTW | 9 => AccType_DC | 10 => AccType_IC | 11 => AccType_AT | _ => raise Fail "natToAccType" fun natToShiftType x = case Nat.toInt x of 0 => ShiftType_LSL | 1 => ShiftType_LSR | 2 => ShiftType_ASR | 3 => ShiftType_ROR | _ => raise Fail "natToShiftType" fun natToExtendType x = case Nat.toInt x of 0 => ExtendType_UXTB | 1 => ExtendType_UXTH | 2 => ExtendType_UXTW | 3 => ExtendType_UXTX | 4 => ExtendType_SXTB | 5 => ExtendType_SXTH | 6 => ExtendType_SXTW | 7 => ExtendType_SXTX | _ => raise Fail "natToExtendType" fun natToLogicalOp x = case Nat.toInt x of 0 => LogicalOp_AND | 1 => LogicalOp_ORR | 2 => LogicalOp_EOR | _ => raise Fail "natToLogicalOp" fun natToMemOp x = case Nat.toInt x of 0 => MemOp_LOAD | 1 => MemOp_STORE | 2 => MemOp_PREFETCH | _ => raise Fail "natToMemOp" fun natToMemBarrierOp x = case Nat.toInt x of 0 => MemBarrierOp_DSB | 1 => MemBarrierOp_DMB | 2 => MemBarrierOp_ISB | _ => raise Fail "natToMemBarrierOp" fun natToMoveWideOp x = case Nat.toInt x of 0 => MoveWideOp_N | 1 => MoveWideOp_Z | 2 => MoveWideOp_K | _ => raise Fail "natToMoveWideOp" fun natToRevOp x = case Nat.toInt x of 0 => RevOp_RBIT | 1 => RevOp_REV16 | 2 => RevOp_REV32 | 3 => RevOp_REV64 | _ => raise Fail "natToRevOp" fun natToSystemHintOp x = case Nat.toInt x of 0 => SystemHintOp_NOP | 1 => SystemHintOp_YIELD | 2 => SystemHintOp_WFE | 3 => SystemHintOp_WFI | 4 => SystemHintOp_SEV | 5 => SystemHintOp_SEVL | _ => raise Fail "natToSystemHintOp" fun natToPSTATEField x = case Nat.toInt x of 0 => PSTATEField_DAIFSet | 1 => PSTATEField_DAIFClr | 2 => PSTATEField_SP | _ => raise Fail "natToPSTATEField" fun BranchTypeToNat x = case x of BranchType_CALL => 0 | BranchType_ERET => 1 | BranchType_DBGEXIT => 2 | BranchType_RET => 3 | BranchType_JMP => 4 | BranchType_EXCEPTION => 5 | BranchType_UNKNOWN => 6 fun AccTypeToNat x = case x of AccType_NORMAL => 0 | AccType_VEC => 1 | AccType_STREAM => 2 | AccType_VECSTREAM => 3 | AccType_ATOMIC => 4 | AccType_ORDERED => 5 | AccType_UNPRIV => 6 | AccType_IFETCH => 7 | AccType_PTW => 8 | AccType_DC => 9 | AccType_IC => 10 | AccType_AT => 11 fun ShiftTypeToNat x = case x of ShiftType_LSL => 0 | ShiftType_LSR => 1 | ShiftType_ASR => 2 | ShiftType_ROR => 3 fun ExtendTypeToNat x = case x of ExtendType_UXTB => 0 | ExtendType_UXTH => 1 | ExtendType_UXTW => 2 | ExtendType_UXTX => 3 | ExtendType_SXTB => 4 | ExtendType_SXTH => 5 | ExtendType_SXTW => 6 | ExtendType_SXTX => 7 fun LogicalOpToNat x = case x of LogicalOp_AND => 0 | LogicalOp_ORR => 1 | LogicalOp_EOR => 2 fun MemOpToNat x = case x of MemOp_LOAD => 0 | MemOp_STORE => 1 | MemOp_PREFETCH => 2 fun MemBarrierOpToNat x = case x of MemBarrierOp_DSB => 0 | MemBarrierOp_DMB => 1 | MemBarrierOp_ISB => 2 fun MoveWideOpToNat x = case x of MoveWideOp_N => 0 | MoveWideOp_Z => 1 | MoveWideOp_K => 2 fun RevOpToNat x = case x of RevOp_RBIT => 0 | RevOp_REV16 => 1 | RevOp_REV32 => 2 | RevOp_REV64 => 3 fun SystemHintOpToNat x = case x of SystemHintOp_NOP => 0 | SystemHintOp_YIELD => 1 | SystemHintOp_WFE => 2 | SystemHintOp_WFI => 3 | SystemHintOp_SEV => 4 | SystemHintOp_SEVL => 5 fun PSTATEFieldToNat x = case x of PSTATEField_DAIFSet => 0 | PSTATEField_DAIFClr => 1 | PSTATEField_SP => 2 fun BranchTypeToString x = case x of BranchType_CALL => "BranchType_CALL" | BranchType_ERET => "BranchType_ERET" | BranchType_DBGEXIT => "BranchType_DBGEXIT" | BranchType_RET => "BranchType_RET" | BranchType_JMP => "BranchType_JMP" | BranchType_EXCEPTION => "BranchType_EXCEPTION" | BranchType_UNKNOWN => "BranchType_UNKNOWN" fun AccTypeToString x = case x of AccType_NORMAL => "AccType_NORMAL" | AccType_VEC => "AccType_VEC" | AccType_STREAM => "AccType_STREAM" | AccType_VECSTREAM => "AccType_VECSTREAM" | AccType_ATOMIC => "AccType_ATOMIC" | AccType_ORDERED => "AccType_ORDERED" | AccType_UNPRIV => "AccType_UNPRIV" | AccType_IFETCH => "AccType_IFETCH" | AccType_PTW => "AccType_PTW" | AccType_DC => "AccType_DC" | AccType_IC => "AccType_IC" | AccType_AT => "AccType_AT" fun ShiftTypeToString x = case x of ShiftType_LSL => "ShiftType_LSL" | ShiftType_LSR => "ShiftType_LSR" | ShiftType_ASR => "ShiftType_ASR" | ShiftType_ROR => "ShiftType_ROR" fun ExtendTypeToString x = case x of ExtendType_UXTB => "ExtendType_UXTB" | ExtendType_UXTH => "ExtendType_UXTH" | ExtendType_UXTW => "ExtendType_UXTW" | ExtendType_UXTX => "ExtendType_UXTX" | ExtendType_SXTB => "ExtendType_SXTB" | ExtendType_SXTH => "ExtendType_SXTH" | ExtendType_SXTW => "ExtendType_SXTW" | ExtendType_SXTX => "ExtendType_SXTX" fun LogicalOpToString x = case x of LogicalOp_AND => "LogicalOp_AND" | LogicalOp_ORR => "LogicalOp_ORR" | LogicalOp_EOR => "LogicalOp_EOR" fun MemOpToString x = case x of MemOp_LOAD => "MemOp_LOAD" | MemOp_STORE => "MemOp_STORE" | MemOp_PREFETCH => "MemOp_PREFETCH" fun MemBarrierOpToString x = case x of MemBarrierOp_DSB => "MemBarrierOp_DSB" | MemBarrierOp_DMB => "MemBarrierOp_DMB" | MemBarrierOp_ISB => "MemBarrierOp_ISB" fun MoveWideOpToString x = case x of MoveWideOp_N => "MoveWideOp_N" | MoveWideOp_Z => "MoveWideOp_Z" | MoveWideOp_K => "MoveWideOp_K" fun RevOpToString x = case x of RevOp_RBIT => "RevOp_RBIT" | RevOp_REV16 => "RevOp_REV16" | RevOp_REV32 => "RevOp_REV32" | RevOp_REV64 => "RevOp_REV64" fun SystemHintOpToString x = case x of SystemHintOp_NOP => "SystemHintOp_NOP" | SystemHintOp_YIELD => "SystemHintOp_YIELD" | SystemHintOp_WFE => "SystemHintOp_WFE" | SystemHintOp_WFI => "SystemHintOp_WFI" | SystemHintOp_SEV => "SystemHintOp_SEV" | SystemHintOp_SEVL => "SystemHintOp_SEVL" fun PSTATEFieldToString x = case x of PSTATEField_DAIFSet => "PSTATEField_DAIFSet" | PSTATEField_DAIFClr => "PSTATEField_DAIFClr" | PSTATEField_SP => "PSTATEField_SP" fun stringToBranchType x = case x of "BranchType_CALL" => BranchType_CALL | "BranchType_ERET" => BranchType_ERET | "BranchType_DBGEXIT" => BranchType_DBGEXIT | "BranchType_RET" => BranchType_RET | "BranchType_JMP" => BranchType_JMP | "BranchType_EXCEPTION" => BranchType_EXCEPTION | "BranchType_UNKNOWN" => BranchType_UNKNOWN | _ => raise Fail "stringToBranchType" fun stringToAccType x = case x of "AccType_NORMAL" => AccType_NORMAL | "AccType_VEC" => AccType_VEC | "AccType_STREAM" => AccType_STREAM | "AccType_VECSTREAM" => AccType_VECSTREAM | "AccType_ATOMIC" => AccType_ATOMIC | "AccType_ORDERED" => AccType_ORDERED | "AccType_UNPRIV" => AccType_UNPRIV | "AccType_IFETCH" => AccType_IFETCH | "AccType_PTW" => AccType_PTW | "AccType_DC" => AccType_DC | "AccType_IC" => AccType_IC | "AccType_AT" => AccType_AT | _ => raise Fail "stringToAccType" fun stringToShiftType x = case x of "ShiftType_LSL" => ShiftType_LSL | "ShiftType_LSR" => ShiftType_LSR | "ShiftType_ASR" => ShiftType_ASR | "ShiftType_ROR" => ShiftType_ROR | _ => raise Fail "stringToShiftType" fun stringToExtendType x = case x of "ExtendType_UXTB" => ExtendType_UXTB | "ExtendType_UXTH" => ExtendType_UXTH | "ExtendType_UXTW" => ExtendType_UXTW | "ExtendType_UXTX" => ExtendType_UXTX | "ExtendType_SXTB" => ExtendType_SXTB | "ExtendType_SXTH" => ExtendType_SXTH | "ExtendType_SXTW" => ExtendType_SXTW | "ExtendType_SXTX" => ExtendType_SXTX | _ => raise Fail "stringToExtendType" fun stringToLogicalOp x = case x of "LogicalOp_AND" => LogicalOp_AND | "LogicalOp_ORR" => LogicalOp_ORR | "LogicalOp_EOR" => LogicalOp_EOR | _ => raise Fail "stringToLogicalOp" fun stringToMemOp x = case x of "MemOp_LOAD" => MemOp_LOAD | "MemOp_STORE" => MemOp_STORE | "MemOp_PREFETCH" => MemOp_PREFETCH | _ => raise Fail "stringToMemOp" fun stringToMemBarrierOp x = case x of "MemBarrierOp_DSB" => MemBarrierOp_DSB | "MemBarrierOp_DMB" => MemBarrierOp_DMB | "MemBarrierOp_ISB" => MemBarrierOp_ISB | _ => raise Fail "stringToMemBarrierOp" fun stringToMoveWideOp x = case x of "MoveWideOp_N" => MoveWideOp_N | "MoveWideOp_Z" => MoveWideOp_Z | "MoveWideOp_K" => MoveWideOp_K | _ => raise Fail "stringToMoveWideOp" fun stringToRevOp x = case x of "RevOp_RBIT" => RevOp_RBIT | "RevOp_REV16" => RevOp_REV16 | "RevOp_REV32" => RevOp_REV32 | "RevOp_REV64" => RevOp_REV64 | _ => raise Fail "stringToRevOp" fun stringToSystemHintOp x = case x of "SystemHintOp_NOP" => SystemHintOp_NOP | "SystemHintOp_YIELD" => SystemHintOp_YIELD | "SystemHintOp_WFE" => SystemHintOp_WFE | "SystemHintOp_WFI" => SystemHintOp_WFI | "SystemHintOp_SEV" => SystemHintOp_SEV | "SystemHintOp_SEVL" => SystemHintOp_SEVL | _ => raise Fail "stringToSystemHintOp" fun stringToPSTATEField x = case x of "PSTATEField_DAIFSet" => PSTATEField_DAIFSet | "PSTATEField_DAIFClr" => PSTATEField_DAIFClr | "PSTATEField_SP" => PSTATEField_SP | _ => raise Fail "stringToPSTATEField" end (* ------------------------------------------------------------------------- Record update functions ------------------------------------------------------------------------- *) fun ProcState_C_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') = {C = x', EL = EL, N = N, SPS = SPS, V = V, Z = Z}: ProcState fun ProcState_EL_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') = {C = C, EL = x', N = N, SPS = SPS, V = V, Z = Z}: ProcState fun ProcState_N_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') = {C = C, EL = EL, N = x', SPS = SPS, V = V, Z = Z}: ProcState fun ProcState_SPS_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') = {C = C, EL = EL, N = N, SPS = x', V = V, Z = Z}: ProcState fun ProcState_V_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') = {C = C, EL = EL, N = N, SPS = SPS, V = x', Z = Z}: ProcState fun ProcState_Z_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') = {C = C, EL = EL, N = N, SPS = SPS, V = V, Z = x'}: ProcState fun TCR_EL1_TBI0_rupd ({TBI0, TBI1, tcr_el1'rst}: TCR_EL1, x') = {TBI0 = x', TBI1 = TBI1, tcr_el1'rst = tcr_el1'rst}: TCR_EL1 fun TCR_EL1_TBI1_rupd ({TBI0, TBI1, tcr_el1'rst}: TCR_EL1, x') = {TBI0 = TBI0, TBI1 = x', tcr_el1'rst = tcr_el1'rst}: TCR_EL1 fun TCR_EL1_tcr_el1'rst_rupd ({TBI0, TBI1, tcr_el1'rst}: TCR_EL1, x') = {TBI0 = TBI0, TBI1 = TBI1, tcr_el1'rst = x'}: TCR_EL1 fun TCR_EL2_EL3_TBI_rupd ({TBI, tcr_el2_el3'rst}: TCR_EL2_EL3, x') = {TBI = x', tcr_el2_el3'rst = tcr_el2_el3'rst}: TCR_EL2_EL3 fun TCR_EL2_EL3_tcr_el2_el3'rst_rupd ({TBI, tcr_el2_el3'rst} : TCR_EL2_EL3, x') = {TBI = TBI, tcr_el2_el3'rst = x'}: TCR_EL2_EL3 fun SCTLRType_A_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst} : SCTLRType, x') = {A = x', E0E = E0E, EE = EE, SA = SA, SA0 = SA0, sctlrtype'rst = sctlrtype'rst}: SCTLRType fun SCTLRType_E0E_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst} : SCTLRType, x') = {A = A, E0E = x', EE = EE, SA = SA, SA0 = SA0, sctlrtype'rst = sctlrtype'rst}: SCTLRType fun SCTLRType_EE_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst} : SCTLRType, x') = {A = A, E0E = E0E, EE = x', SA = SA, SA0 = SA0, sctlrtype'rst = sctlrtype'rst}: SCTLRType fun SCTLRType_SA_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst} : SCTLRType, x') = {A = A, E0E = E0E, EE = EE, SA = x', SA0 = SA0, sctlrtype'rst = sctlrtype'rst}: SCTLRType fun SCTLRType_SA0_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst} : SCTLRType, x') = {A = A, E0E = E0E, EE = EE, SA = SA, SA0 = x', sctlrtype'rst = sctlrtype'rst}: SCTLRType fun SCTLRType_sctlrtype'rst_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst} : SCTLRType, x') = {A = A, E0E = E0E, EE = EE, SA = SA, SA0 = SA0, sctlrtype'rst = x'} : SCTLRType (* ------------------------------------------------------------------------- Exceptions ------------------------------------------------------------------------- *) exception ALIGNMENT_FAULT exception ASSERT of string exception UNDEFINED_FAULT of string (* ------------------------------------------------------------------------- Global variables (state) ------------------------------------------------------------------------- *) val MEM = ref (Map.mkMap(SOME 18446744073709551616,BitsN.B(0x0,8))) : (BitsN.nbit Map.map) ref val PC = ref (BitsN.B(0x0,64)): BitsN.nbit ref val PSTATE = ref ({C = false, EL = BitsN.B(0x0,2), N = false, SPS = false, V = false, Z = false}): ProcState ref val REG = ref (Map.mkMap(SOME 32,BitsN.B(0x0,64))) : (BitsN.nbit Map.map) ref val SCTLR_EL1 = ref ({A = false, E0E = false, EE = false, SA = false, SA0 = false, sctlrtype'rst = BitsN.B(0x0,27)}): SCTLRType ref val SCTLR_EL2 = ref ({A = false, E0E = false, EE = false, SA = false, SA0 = false, sctlrtype'rst = BitsN.B(0x0,27)}): SCTLRType ref val SCTLR_EL3 = ref ({A = false, E0E = false, EE = false, SA = false, SA0 = false, sctlrtype'rst = BitsN.B(0x0,27)}): SCTLRType ref val SP_EL0 = ref (BitsN.B(0x0,64)): BitsN.nbit ref val SP_EL1 = ref (BitsN.B(0x0,64)): BitsN.nbit ref val SP_EL2 = ref (BitsN.B(0x0,64)): BitsN.nbit ref val SP_EL3 = ref (BitsN.B(0x0,64)): BitsN.nbit ref val TCR_EL1 = ref ({TBI0 = false, TBI1 = false, tcr_el1'rst = BitsN.B(0x0,62)}) : TCR_EL1 ref val TCR_EL2 = ref ({TBI = false, tcr_el2_el3'rst = BitsN.B(0x0,31)}) : TCR_EL2_EL3 ref val TCR_EL3 = ref ({TBI = false, tcr_el2_el3'rst = BitsN.B(0x0,31)}) : TCR_EL2_EL3 ref val branch_hint = ref (NONE): (BranchType option) ref (* ------------------------------------------------------------------------- Main specification ------------------------------------------------------------------------- *) local fun tuple'32 [t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16, t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30, t31] = (t0, (t1, (t2, (t3, (t4, (t5, (t6, (t7, (t8, (t9, (t10, (t11, (t12, (t13, (t14, (t15, (t16, (t17, (t18, (t19, (t20, (t21, (t22, (t23, (t24,(t25,(t26,(t27,(t28,(t29,(t30,t31))))))))))))))))))))))))))))))) | tuple'32 (_: bool list) = raise Fail "tuple'32" in val boolify'32 = tuple'32 o BitsN.toList end fun rec'TCR_EL1 x = {TBI0 = BitsN.bit(x,37), TBI1 = BitsN.bit(x,38), tcr_el1'rst = BitsN.@@(BitsN.bits(36,0) x,BitsN.bits(63,39) x)}; fun reg'TCR_EL1 x = case x of {TBI0 = TBI0, TBI1 = TBI1, tcr_el1'rst = tcr_el1'rst} => BitsN.concat [BitsN.bits(24,0) tcr_el1'rst,BitsN.fromBit TBI1, BitsN.fromBit TBI0,BitsN.bits(61,25) tcr_el1'rst]; fun write'rec'TCR_EL1 (_,x) = reg'TCR_EL1 x; fun write'reg'TCR_EL1 (_,x) = rec'TCR_EL1 x; fun rec'TCR_EL2_EL3 x = {TBI = BitsN.bit(x,20), tcr_el2_el3'rst = BitsN.@@(BitsN.bits(19,0) x,BitsN.bits(31,21) x)}; fun reg'TCR_EL2_EL3 x = case x of {TBI = TBI, tcr_el2_el3'rst = tcr_el2_el3'rst} => BitsN.concat [BitsN.bits(10,0) tcr_el2_el3'rst,BitsN.fromBit TBI, BitsN.bits(30,11) tcr_el2_el3'rst]; fun write'rec'TCR_EL2_EL3 (_,x) = reg'TCR_EL2_EL3 x; fun write'reg'TCR_EL2_EL3 (_,x) = rec'TCR_EL2_EL3 x; fun rec'SCTLRType x = {A = BitsN.bit(x,1), E0E = BitsN.bit(x,24), EE = BitsN.bit(x,25), SA = BitsN.bit(x,3), SA0 = BitsN.bit(x,4), sctlrtype'rst = BitsN.concat [BitsN.bits(0,0) x,BitsN.bits(2,2) x,BitsN.bits(23,5) x, BitsN.bits(31,26) x]}; fun reg'SCTLRType x = case x of {A = A, E0E = E0E, EE = EE, SA = SA, SA0 = SA0, sctlrtype'rst = sctlrtype'rst} => BitsN.concat [BitsN.bits(5,0) sctlrtype'rst,BitsN.fromBit EE, BitsN.fromBit E0E,BitsN.bits(24,6) sctlrtype'rst, BitsN.fromBit SA0,BitsN.fromBit SA, BitsN.bits(25,25) sctlrtype'rst,BitsN.fromBit A, BitsN.bits(26,26) sctlrtype'rst]; fun write'rec'SCTLRType (_,x) = reg'SCTLRType x; fun write'reg'SCTLRType (_,x) = rec'SCTLRType x; fun X N n = if n = (BitsN.B(0x1F,5)) then BitsN.BV(0x0,N) else BitsN.fromNat(BitsN.toNat(Map.lookup((!REG),BitsN.toNat n)),N); fun write'X N (value,n) = if not(n = (BitsN.B(0x1F,5))) then REG := (Map.update ((!REG),BitsN.toNat n,BitsN.fromNat(BitsN.toNat value,64))) else (); fun SP N = let val sp = if not(#SPS((!PSTATE) : ProcState)) then (!SP_EL0) else case #EL((!PSTATE) : ProcState) of BitsN.B(0x0,_) => (!SP_EL0) | BitsN.B(0x1,_) => (!SP_EL1) | BitsN.B(0x2,_) => (!SP_EL2) | BitsN.B(0x3,_) => (!SP_EL3) | _ => raise General.Bind in BitsN.fromNat(BitsN.toNat sp,N) end; fun write'SP N value = let val v = BitsN.fromNat(BitsN.toNat value,64) in if not(#SPS((!PSTATE) : ProcState)) then SP_EL0 := v else case #EL((!PSTATE) : ProcState) of BitsN.B(0x0,_) => SP_EL0 := v | BitsN.B(0x1,_) => SP_EL1 := v | BitsN.B(0x2,_) => SP_EL2 := v | BitsN.B(0x3,_) => SP_EL3 := v | _ => raise General.Bind end; fun TranslationRegime () = if not((#EL((!PSTATE) : ProcState)) = (BitsN.B(0x0,2))) then #EL((!PSTATE) : ProcState) else BitsN.B(0x1,2); fun SCTLR () = let val regime = TranslationRegime () in case regime of BitsN.B(0x1,_) => (!SCTLR_EL1) | BitsN.B(0x2,_) => (!SCTLR_EL2) | BitsN.B(0x3,_) => (!SCTLR_EL3) | BitsN.B(0x0,_) => {A = false, E0E = false, EE = false, SA = false, SA0 = false, sctlrtype'rst = BitsN.B(0x0,27)} | _ => raise General.Bind end; fun Hint_Branch branch_type = branch_hint := (Option.SOME branch_type); fun BranchTo (target0,branch_type) = let val target = ref target0 in ( Hint_Branch branch_type ; case #EL((!PSTATE) : ProcState) of BitsN.B(0x0,_) => ( if (BitsN.bit((!target),55)) andalso (#TBI1((!TCR_EL1) : TCR_EL1)) then target := (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0xFF,8))) else () ; if (not(BitsN.bit((!target),55))) andalso (#TBI0((!TCR_EL1) : TCR_EL1)) then target := (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0x0,8))) else () ) | BitsN.B(0x1,_) => ( if (BitsN.bit((!target),55)) andalso (#TBI1((!TCR_EL1) : TCR_EL1)) then target := (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0xFF,8))) else () ; if (not(BitsN.bit((!target),55))) andalso (#TBI0((!TCR_EL1) : TCR_EL1)) then target := (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0x0,8))) else () ) | BitsN.B(0x2,_) => if #TBI((!TCR_EL2) : TCR_EL2_EL3) then target := (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0x0,8))) else () | BitsN.B(0x3,_) => if #TBI((!TCR_EL3) : TCR_EL2_EL3) then target := (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0x0,8))) else () | _ => raise General.Bind ; PC := (!target) ) end; fun Align N (w,n) = BitsN.fromNat(Nat.*(n,Nat.div(BitsN.toNat w,n)),N); fun Aligned N (w,n) = w = (Align N (w,n)); fun CheckSPAlignment () = let val sp = SP 64 val stack_align_check = if (#EL((!PSTATE) : ProcState)) = (BitsN.B(0x0,2)) then #SA0((!SCTLR_EL1) : SCTLRType) else #SA((SCTLR ()) : SCTLRType) in if stack_align_check andalso (not(Aligned 64 (sp,16))) then raise ALIGNMENT_FAULT else () end; fun CheckAlignment (address,(size,(acctype,iswrite))) = if (not(Aligned 64 (address,size))) andalso ((acctype = AccType_ATOMIC) orelse ((acctype = AccType_ORDERED) orelse (#A((SCTLR ()) : SCTLRType)))) then raise ALIGNMENT_FAULT else (); fun BigEndian () = if (#EL((!PSTATE) : ProcState)) = (BitsN.B(0x0,2)) then #E0E((!SCTLR_EL1) : SCTLRType) else #EE((SCTLR ()) : SCTLRType); fun ByteList l = case l of [] => [] | b0 :: (b1 :: (b2 :: (b3 :: (b4 :: (b5 :: (b6 :: (v7 :: rest))))))) => [b0,b1,b2,b3,b4,b5,b6,v7] :: (ByteList rest) | rest => [rest]; fun BigEndianReverse l = List.concat(List.rev(ByteList l)); fun Mem N (address,(size,acctype)) = ( CheckAlignment(address,(size,(acctype,false))) ; let val value = ref [] in ( L3.for (0,Nat.-(size,1), fn i => value := ((BitsN.toBitstring (Map.lookup ((!MEM), BitsN.toNat(BitsN.+(address,BitsN.fromNat(i,64)))))) @ (!value))) ; BitsN.fromBitstring (if BigEndian () then BigEndianReverse (!value) else (!value),N) ) end ); fun write'Mem N (value,(address,(size,acctype))) = ( CheckAlignment(address,(size,(acctype,true))) ; let val value = if BigEndian () then BigEndianReverse(BitsN.toBitstring value) else BitsN.toBitstring value in L3.for (0,Nat.-(size,1), fn i => let val x = BitsN.+(address,BitsN.fromNat(i,64)) in MEM := (Map.update ((!MEM),BitsN.toNat x, BitsN.fromBitstring (Bitstring.bits(Nat.+(Nat.*(8,i),7),Nat.*(8,i)) value,8))) end) end ); fun ConditionTest (cond,(N,(Z,(C,V)))) = let val result = case BitsN.bits(3,1) cond of BitsN.B(0x0,_) => Z | BitsN.B(0x1,_) => C | BitsN.B(0x2,_) => N | BitsN.B(0x3,_) => V | BitsN.B(0x4,_) => C andalso (not Z) | BitsN.B(0x5,_) => N = V | BitsN.B(0x6,_) => (N = V) andalso (not Z) | BitsN.B(0x7,_) => true | _ => raise General.Bind in if (BitsN.bit(cond,0)) andalso (not(cond = (BitsN.B(0xF,4)))) then not result else result end; fun ConditionHolds cond = ConditionTest (cond, (#N((!PSTATE) : ProcState), (#Z((!PSTATE) : ProcState), (#C((!PSTATE) : ProcState),#V((!PSTATE) : ProcState))))); fun Ones n = L3.padLeft(true,(n,[])); fun Zeros n = L3.padLeft(false,(n,[])); fun Replicate N l = BitsN.fromBitstring (Bitstring.replicate (l,Nat.div(BitsN.size(BitsN.BV(0x0,N)),L3.length l)),N); fun HighestSetBit N w = if w = (BitsN.BV(0x0,N)) then IntInf.~ 1 else BitsN.toInt(BitsN.log2 w); fun CountLeadingZeroBits N w = Nat.fromInt (IntInf.- (IntInf.-(Nat.toInt(BitsN.size(BitsN.BV(0x0,N))),1), HighestSetBit N w)); fun CountLeadingSignBits N w = Nat.- (CountLeadingZeroBits N (BitsN.?? (BitsN.>>+(w,1), BitsN.&&(w,BitsN.~(BitsN.#>>(BitsN.BV(0x1,N),1))))),1); fun Poly32Mod2_loop (i,(data,poly)) = if Nat.<(i,32) then data else let val data = if Bitstring.bit(data,i) then (Bitstring.bits(Nat.-(L3.length data,1),i) data) @ (Bitstring.?? (Bitstring.bits(Nat.-(i,1),0) data, L3.padRight(false,(i,poly)))) else data in Poly32Mod2_loop(Nat.-(i,1),(data,poly)) end; fun Poly32Mod2 (data,poly) = BitsN.fromBitstring (Bitstring.bits(31,0) (Poly32Mod2_loop (Nat.-(L3.length data,1),(data,BitsN.toBitstring poly))),32); fun AddWithCarry N (x,(y,carry_in)) = let val unsigned_sum = Nat.+(Nat.+(BitsN.toNat x,BitsN.toNat y),Nat.fromBool carry_in) val signed_sum = IntInf.+ (IntInf.+(BitsN.toInt x,BitsN.toInt y),IntExtra.fromBool carry_in) val result = BitsN.fromNat(unsigned_sum,N) val n = BitsN.msb result val z = result = (BitsN.BV(0x0,N)) val c = not((BitsN.toNat result) = unsigned_sum) val v = not((BitsN.toInt result) = signed_sum) in (result,(n,(z,(c,v)))) end; fun SetTheFlags (setflags,(n,(z,(c,v)))) = if setflags then ( PSTATE := (ProcState_N_rupd((!PSTATE),n)) ; PSTATE := (ProcState_Z_rupd((!PSTATE),z)) ; PSTATE := (ProcState_C_rupd((!PSTATE),c)) ; PSTATE := (ProcState_V_rupd((!PSTATE),v)) ) else (); fun DecodeShift sh = (Cast.natToShiftType o BitsN.toNat) sh; fun ShiftValue N (value,(ty,amount)) = case ty of ShiftType_LSL => BitsN.<<(value,amount) | ShiftType_LSR => BitsN.>>+(value,amount) | ShiftType_ASR => BitsN.>>(value,amount) | ShiftType_ROR => BitsN.#>>(value,amount); fun ShiftReg N (reg,(ty,amount)) = ShiftValue N (X N reg,(ty,amount)); fun ExtendWord (M,N) (w,signed) = if signed then BitsN.signExtend N w else BitsN.zeroExtend N w; fun Extend N (l,unsigned) = if unsigned orelse (not(List.hd l)) then BitsN.fromBitstring(l,N) else BitsN.fromBitstring (L3.padLeft(true,(BitsN.size(BitsN.BV(0x0,N)),l)),N); fun DecodeRegExtend ext = (Cast.natToExtendType o BitsN.toNat) ext; fun ExtendValue N (value,(ty,sh)) = let val value = BitsN.toBitstring value val (unsigned,len) = case ty of ExtendType_SXTB => (false,8) | ExtendType_SXTH => (false,16) | ExtendType_SXTW => (false,32) | ExtendType_SXTX => (false,64) | ExtendType_UXTB => (true,8) | ExtendType_UXTH => (true,16) | ExtendType_UXTW => (true,32) | ExtendType_UXTX => (true,64) val len = Nat.min(len,Nat.-(BitsN.size(BitsN.BV(0x0,N)),sh)) in Extend N (Bitstring.<<(Bitstring.bits(Nat.-(len,1),0) value,sh),unsigned) end; fun ExtendReg N (reg,(ty,sh)) = ExtendValue N (X N reg,(ty,sh)); fun DecodeBitMasks M (immN,(imms,(immr,immediate))) = let val len = HighestSetBit 7 (BitsN.@@(immN,BitsN.~ imms)) in if IntInf.<(len,1) then NONE else let val len = Nat.fromInt len val levels = BitsN.fromBitstring(Ones len,6) val S = BitsN.&&(imms,levels) val R = BitsN.&&(immr,levels) in if immediate andalso (S = levels) then NONE else let val diff = BitsN.toBitstring(BitsN.-(S,R)) val esize = Nat.pow(2,len) val d = Bitstring.bits(Nat.-(len,1),0) diff val welem = L3.padLeft(false,(esize,Ones(Nat.+(BitsN.toNat S,1)))) val telem = L3.padLeft (false,(esize,Ones(Nat.+(Bitstring.toNat d,1)))) val wmask = Replicate M (Bitstring.#>>(welem,BitsN.toNat R)) val tmask = Replicate M telem in Option.SOME(wmask,tmask) end end end; fun dfn'Address (page,(imm,d)) = let val base = ref (!PC) in ( if page then base := (BitsN.bitFieldInsert(11,0) ((!base),BitsN.B(0x0,12))) else () ; write'X 64 (BitsN.+((!base),imm),d) ) end; fun dfn'AddSubCarry N (sf,(sub_op,(setflags,(m,(n,d))))) = let val operand1 = X N n val operand2 = X N m val operand2 = if sub_op then BitsN.~ operand2 else operand2 val (result,nzcv) = AddWithCarry N (operand1,(operand2,#C((!PSTATE) : ProcState))) in ( SetTheFlags(setflags,nzcv); write'X N (result,d) ) end; fun dfn'AddSubExtendRegister N (sf,(sub_op,(setflags,(m,(extend_type,(imm3,(n,d))))))) = let val operand1 = if n = (BitsN.B(0x1F,5)) then SP N else X N n val operand2 = ExtendReg N (m,(extend_type,BitsN.toNat imm3)) val (operand2,carry_in) = if sub_op then (BitsN.~ operand2,true) else (operand2,false) val (result,nzcv) = AddWithCarry N (operand1,(operand2,carry_in)) in ( SetTheFlags(setflags,nzcv) ; if (d = (BitsN.B(0x1F,5))) andalso (not setflags) then write'SP N result else write'X N (result,d) ) end; fun dfn'AddSubImmediate N (sf,(sub_op,(setflags,(imm,(n,d))))) = let val operand1 = if n = (BitsN.B(0x1F,5)) then SP N else X N n val operand2 = imm val (operand2,carry_in) = if sub_op then (BitsN.~ operand2,true) else (operand2,false) val (result,nzcv) = AddWithCarry N (operand1,(operand2,carry_in)) in ( SetTheFlags(setflags,nzcv) ; if (d = (BitsN.B(0x1F,5))) andalso (not setflags) then write'SP N result else write'X N (result,d) ) end; fun dfn'AddSubShiftedRegister N (sf,(sub_op,(setflags,(shift_type,(m,(imm,(n,d))))))) = let val operand1 = X N n val operand2 = ShiftReg N (m,(shift_type,BitsN.toNat imm)) val (operand2,carry_in) = if sub_op then (BitsN.~ operand2,true) else (operand2,false) val (result,nzcv) = AddWithCarry N (operand1,(operand2,carry_in)) in ( SetTheFlags(setflags,nzcv); write'X N (result,d) ) end; fun dfn'LogicalImmediate N (sf,(opc,(setflags,(imm,(n,d))))) = let val operand1 = X N n val operand2 = imm val result = case opc of LogicalOp_AND => BitsN.&&(operand1,operand2) | LogicalOp_ORR => BitsN.||(operand1,operand2) | LogicalOp_EOR => BitsN.??(operand1,operand2) in ( SetTheFlags (setflags, (BitsN.msb result,(result = (BitsN.BV(0x0,N)),(false,false)))) ; if (d = (BitsN.B(0x1F,5))) andalso (not setflags) then write'SP N result else write'X N (result,d) ) end; fun dfn'LogicalShiftedRegister N (sf,(opc,(invert,(setflags,(shift_type,(shift_amount,(m,(n,d)))))))) = let val operand1 = X N n val operand2 = ShiftReg N (m,(shift_type,shift_amount)) val operand2 = if invert then BitsN.~ operand2 else operand2 val result = case opc of LogicalOp_AND => BitsN.&&(operand1,operand2) | LogicalOp_ORR => BitsN.||(operand1,operand2) | LogicalOp_EOR => BitsN.??(operand1,operand2) in ( SetTheFlags (setflags, (BitsN.msb result,(result = (BitsN.BV(0x0,N)),(false,false)))) ; write'X N (result,d) ) end; fun dfn'Shift N (sf,(shift_type,(m,(n,d)))) = let val operand2 = X N m val result = ShiftReg N (n, (shift_type, Nat.mod(BitsN.toNat operand2,BitsN.size(BitsN.BV(0x0,N))))) in write'X N (result,d) end; fun dfn'MoveWide N (sf,(opcode,(hw,(imm,d)))) = let val pos = BitsN.toNat(BitsN.@@(hw,BitsN.B(0x0,4))) in let val result = ref (if opcode = MoveWideOp_K then X N d else BitsN.BV(0x0,N)) in ( let val h = Nat.+(pos,15) in result := (BitsN.bitFieldInsert(h,pos) ((!result),imm)) end ; let val result = if opcode = MoveWideOp_N then BitsN.~ (!result) else (!result) in write'X N (result,d) end ) end end; fun dfn'BitfieldMove N (sf,(inzero,(extend,(wmask,(tmask,(R,(S,(n,d)))))))) = let val dst = if inzero then BitsN.BV(0x0,N) else X N d val src = X N n val bot = BitsN.|| (BitsN.&&(dst,BitsN.~ wmask),BitsN.&&(BitsN.#>>(src,R),wmask)) val top = if extend then Replicate N (Bitstring.fromBool(BitsN.bit(src,S))) else dst in write'X N (BitsN.||(BitsN.&&(top,BitsN.~ tmask),BitsN.&&(bot,tmask)),d) end; fun dfn'ConditionalCompareImmediate N (sf,(sub_op,(imm,(cond,(nzcv,n))))) = let val operand1 = X N n val operand2 = imm in if ConditionHolds cond then let val (operand2,carry_in) = if sub_op then (BitsN.~ operand2,true) else (operand2,false) val (_,flags) = AddWithCarry N (operand1,(operand2,carry_in)) in SetTheFlags(true,flags) end else SetTheFlags(true,nzcv) end; fun dfn'ConditionalCompareRegister N (sf,(sub_op,(cond,(nzcv,(m,n))))) = let val operand1 = X N n val operand2 = X N m in if ConditionHolds cond then let val (operand2,carry_in) = if sub_op then (BitsN.~ operand2,true) else (operand2,false) val (_,flags) = AddWithCarry N (operand1,(operand2,carry_in)) in SetTheFlags(true,flags) end else SetTheFlags(true,nzcv) end; fun dfn'ConditionalSelect N (sf,(else_inv,(else_inc,(cond,(m,(n,d)))))) = let val operand1 = X N n val operand2 = X N m in let val result = ref (BitsN.fromNat(0,N)) in ( if ConditionHolds cond then result := operand1 else ( result := operand2 ; if else_inv then result := (BitsN.~ (!result)) else () ; if else_inc then result := (BitsN.+((!result),BitsN.BV(0x1,N))) else () ) ; write'X N ((!result),d) ) end end; fun dfn'CountLeading N (sf,(count_clz,(n,d))) = let val operand1 = X N n val result = if count_clz then CountLeadingZeroBits N operand1 else CountLeadingSignBits N operand1 in write'X N (BitsN.fromNat(result,N),d) end; fun dfn'ExtractRegister N (sf,(imms,(m,(n,d)))) = let val lsb = BitsN.toNat imms val operand1 = X N n val operand2 = X N m val concat = (BitsN.toBitstring operand1) @ (BitsN.toBitstring operand2) val result = BitsN.fromBitstring(Bitstring.>>+(concat,lsb),N) in write'X N (result,d) end; fun dfn'Division N (sf,(unsigned,(m,(n,d)))) = let val operand1 = X N n val operand2 = X N m val result = if operand2 = (BitsN.BV(0x0,N)) then BitsN.BV(0x0,N) else if unsigned then BitsN.div(operand1,operand2) else BitsN.quot(operand1,operand2) in write'X N (result,d) end; fun dfn'MultiplyAddSub N (sf,(sub_op,(m,(a,(n,d))))) = let val operand1 = X N n val operand2 = X N m val operand3 = X N a val result = if sub_op then BitsN.-(operand3,BitsN.*(operand1,operand2)) else BitsN.+(operand3,BitsN.*(operand1,operand2)) in write'X N (result,d) end; fun dfn'MultiplyAddSubLong (sub_op,(signed,(m,(a,(n,d))))) = let val operand1 = X 32 n val operand2 = X 32 m val operand3 = X 64 a val product = BitsN.* (ExtendWord (32,64) (operand1,signed), ExtendWord (32,64) (operand2,signed)) val result = if sub_op then BitsN.-(operand3,product) else BitsN.+(operand3,product) in write'X 64 (result,d) end; fun dfn'MultiplyHigh (signed,(m,(n,d))) = let val operand1 = X 64 n val operand2 = X 64 m val result = BitsN.* (ExtendWord (64,128) (operand1,signed), ExtendWord (64,128) (operand2,signed)) in write'X 64 (BitsN.bits(127,64) result,d) end; fun dfn'Reverse N (sf,(op',(n,d))) = if (BitsN.size(BitsN.BV(0x0,N))) = 32 then let val v = X 32 n val result = case op' of RevOp_RBIT => BitsN.reverse v | RevOp_REV16 => BitsN.concat [BitsN.bits(23,16) v,BitsN.bits(31,24) v, BitsN.bits(7,0) v,BitsN.bits(15,8) v] | RevOp_REV32 => BitsN.concat [BitsN.bits(7,0) v,BitsN.bits(15,8) v, BitsN.bits(23,16) v,BitsN.bits(31,24) v] | RevOp_REV64 => BitsN.B(0x0,32) in write'X 32 (result,d) end else let val v = X 64 n val result = case op' of RevOp_RBIT => BitsN.reverse v | RevOp_REV16 => BitsN.concat [BitsN.bits(55,48) v,BitsN.bits(63,56) v, BitsN.bits(39,32) v,BitsN.bits(47,40) v, BitsN.bits(23,16) v,BitsN.bits(31,24) v, BitsN.bits(7,0) v,BitsN.bits(15,8) v] | RevOp_REV32 => BitsN.concat [BitsN.bits(39,32) v,BitsN.bits(47,40) v, BitsN.bits(55,48) v,BitsN.bits(63,56) v, BitsN.bits(7,0) v,BitsN.bits(15,8) v,BitsN.bits(23,16) v, BitsN.bits(31,24) v] | RevOp_REV64 => BitsN.concat [BitsN.bits(7,0) v,BitsN.bits(15,8) v,BitsN.bits(23,16) v, BitsN.bits(31,24) v,BitsN.bits(39,32) v, BitsN.bits(47,40) v,BitsN.bits(55,48) v, BitsN.bits(63,56) v] in write'X 64 (result,d) end; fun dfn'CRC N (sz,(crc32c,(m,(n,d)))) = let val acc = X 32 n val val' = X N m val poly = if crc32c then BitsN.B(0x1EDC6F41,32) else BitsN.B(0x4C11DB7,32) val tempacc = (List.rev(BitsN.toBitstring acc)) @ (Zeros(BitsN.size(BitsN.BV(0x0,N)))) val tempval = (List.rev(BitsN.toBitstring val')) @ (Zeros 32) in write'X 32 (BitsN.reverse(Poly32Mod2(Bitstring.??(tempacc,tempval),poly)),d) end; fun dfn'BranchConditional (offset,cond) = if ConditionHolds cond then BranchTo(BitsN.+((!PC),offset),BranchType_JMP) else (); fun dfn'BranchImmediate (offset,branch_type) = ( if branch_type = BranchType_CALL then write'X 64 (BitsN.+((!PC),BitsN.B(0x4,64)),BitsN.B(0x1E,5)) else () ; BranchTo(BitsN.+((!PC),offset),branch_type) ); fun dfn'BranchRegister (n,branch_type) = let val target = X 64 n in ( if branch_type = BranchType_CALL then write'X 64 (BitsN.+((!PC),BitsN.B(0x4,64)),BitsN.B(0x1E,5)) else () ; BranchTo(target,branch_type) ) end; fun dfn'CompareAndBranch N (sf,(iszero,(offset,t))) = let val operand1 = X N t in if operand1 = (BitsN.BV(0x0,N)) then BranchTo(BitsN.+((!PC),offset),BranchType_JMP) else () end; fun dfn'TestBitAndBranch N (sf,(bit_pos,(bit_val,(offset,t)))) = let val operand1 = X N t in if (BitsN.bit(operand1,BitsN.toNat bit_pos)) = bit_val then BranchTo(BitsN.+((!PC),offset),BranchType_JMP) else () end; fun LoadStoreSingle N (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,t))))))))))) = ( if (n = (BitsN.B(0x1F,5))) andalso (not(memop = MemOp_PREFETCH)) then CheckSPAlignment () else () ; let val address = if n = (BitsN.B(0x1F,5)) then SP 64 else X 64 n val address = if postindex then address else BitsN.+(address,offset) in ( case memop of MemOp_STORE => let val data = if rt_unknown then BitsN.fromNat(0,N) else X N t val x = (address,(Nat.div(BitsN.size(BitsN.BV(0x0,N)),8),acctype)) in write'Mem N (data,x) end | MemOp_LOAD => let val data = Mem N (address,(Nat.div(BitsN.size(BitsN.BV(0x0,N)),8),acctype)) in if regsize_word then write'X 32 (ExtendWord (32,32) (data,signed),t) else write'X 64 (ExtendWord (64,64) (data,signed),t) end | MemOp_PREFETCH => () ; if wback then let val address = if wb_unknown then BitsN.B(0x0,64) else if postindex then BitsN.+(address,offset) else address in if n = (BitsN.B(0x1F,5)) then write'SP 64 address else write'X 64 (address,n) end else () ) end ); fun dfn'LoadStoreImmediate N (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown,(wback,(postindex,(unsigned_offset,(offset,(n,t)))))))))))) = LoadStoreSingle N (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,t))))))))))); fun dfn'LoadStoreRegister N (size,(regsize_word,(memop,(signed,(m,(extend_type,(shift,(n,t)))))))) = let val offset = ExtendReg 64 (m,(extend_type,shift)) in LoadStoreSingle N (size, (regsize_word, (memop, (AccType_NORMAL, (signed,(false,(false,(false,(false,(offset,(n,t))))))))))) end; fun dfn'LoadStorePair N (size, (memop, (acctype, (signed, (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,(t,t2))))))))))) = let val dbytes = Nat.div(BitsN.size(BitsN.BV(0x0,N)),8) in ( if n = (BitsN.B(0x1F,5)) then CheckSPAlignment () else () ; let val address = if n = (BitsN.B(0x1F,5)) then SP 64 else X 64 n val address = if postindex then address else BitsN.+(address,offset) in ( case memop of MemOp_STORE => let val data1 = if rt_unknown andalso (t = n) then BitsN.fromNat(0,N) else X N t val data2 = if rt_unknown andalso (t2 = n) then BitsN.fromNat(0,N) else X N t2 in ( let val x = (address,(dbytes,acctype)) in write'Mem N (data1,x) end ; let val x = (BitsN.+(address,BitsN.fromNat(dbytes,64)), (dbytes,acctype)) in write'Mem N (data2,x) end ) end | MemOp_LOAD => let val (data1,data2) = if rt_unknown then (BitsN.fromNat(0,N),BitsN.fromNat(0,N)) else (Mem N (address,(dbytes,acctype)), Mem N (BitsN.+(address,BitsN.fromNat(dbytes,64)), (dbytes,acctype))) in if signed then ( write'X 64 (ExtendWord (64,64) (data1,signed),t) ; write'X 64 (ExtendWord (64,64) (data2,signed),t2) ) else ( write'X N (data1,t); write'X N (data2,t2) ) end | _ => () ; if wback then let val address = if wb_unknown then BitsN.B(0x0,64) else if postindex then BitsN.+(address,offset) else address in if n = (BitsN.B(0x1F,5)) then write'SP 64 address else write'X 64 (address,n) end else () ) end ) end; fun ExclusiveMonitorPass (address,n) = false; fun SetExclusiveMonitors (address,n) = (); val ExclusiveMonitorStatus = BitsN.B(0x0,1) fun dfn'LoadStoreAcquire N (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(s,(n,t)))))))) = let val dbytes = Nat.div(BitsN.size(BitsN.BV(0x0,N)),8) in ( if n = (BitsN.B(0x1F,5)) then CheckSPAlignment () else () ; let val address = if n = (BitsN.B(0x1F,5)) then SP 64 else if rn_unknown then BitsN.B(0x0,64) else X 64 n in case memop of MemOp_STORE => let val data = if rt_unknown then BitsN.fromNat(0,N) else X N t in if excl then if ExclusiveMonitorPass(address,dbytes) then ( let val x = (address,(dbytes,acctype)) in write'Mem N (data,x) end ; let val status = ExclusiveMonitorStatus in write'X 32 (BitsN.fromNat(BitsN.toNat status,32),s) end ) else write'X 32 (BitsN.B(0x1,32),s) else let val x = (address,(dbytes,acctype)) in write'Mem N (data,x) end end | MemOp_LOAD => ( if excl then SetExclusiveMonitors(address,dbytes) else () ; let val data = Mem N (address,(dbytes,acctype)) in if (BitsN.size(BitsN.BV(0x0,N))) = 64 then write'X N (data,t) else write'X 32 (BitsN.fromNat(BitsN.toNat data,32),t) end ) | _ => () end ) end; fun dfn'LoadStoreAcquirePair N (size,(memop,(acctype,(rn_unknown,(rt_unknown,(s,(n,(t,t2)))))))) = let val dbytes = Nat.div(BitsN.size(BitsN.BV(0x0,N)),8) in ( if n = (BitsN.B(0x1F,5)) then CheckSPAlignment () else () ; let val address = if n = (BitsN.B(0x1F,5)) then SP 64 else if rn_unknown then BitsN.B(0x0,64) else X 64 n in case memop of MemOp_STORE => let val data = if rt_unknown then BitsN.fromNat(0,N) else if (BitsN.size(BitsN.BV(0x0,N))) = 64 then if BigEndian () then BitsN.fromNat (BitsN.toNat(BitsN.@@(X 32 t,X 32 t2)),N) else BitsN.fromNat (BitsN.toNat(BitsN.@@(X 32 t2,X 32 t)),N) else if BigEndian () then BitsN.fromNat (BitsN.toNat(BitsN.@@(X 64 t,X 64 t2)),N) else BitsN.fromNat (BitsN.toNat(BitsN.@@(X 64 t2,X 64 t)),N) in if ExclusiveMonitorPass(address,dbytes) then ( let val x = (address,(dbytes,acctype)) in write'Mem N (data,x) end ; let val status = ExclusiveMonitorStatus in write'X 32 (BitsN.fromNat(BitsN.toNat status,32),s) end ) else write'X 32 (BitsN.B(0x1,32),s) end | MemOp_LOAD => ( SetExclusiveMonitors(address,dbytes) ; if rt_unknown then if (BitsN.size(BitsN.BV(0x0,N))) = 64 then write'X 32 (BitsN.B(0x0,32),t) else write'X 64 (BitsN.B(0x0,64),t) else if (BitsN.size(BitsN.BV(0x0,N))) = 64 then let val data = Mem N (address,(dbytes,acctype)) in if BigEndian () then ( write'X 32 (BitsN.bits(63,32) data,t) ; write'X 32 (BitsN.bits(31,0) data,t2) ) else ( write'X 32 (BitsN.bits(31,0) data,t) ; write'X 32 (BitsN.bits(63,32) data,t2) ) end else ( if not(Aligned 64 (address,dbytes)) then raise ALIGNMENT_FAULT else () ; write'X 64 (Mem 64 (address,(8,acctype)),t) ; write'X 64 (Mem 64 (BitsN.+(address,BitsN.B(0x8,64)),(8,acctype)),t2) ) ) | _ => () end ) end; fun dfn'LoadLiteral N (size,(memop,(signed,(offset,t)))) = let val address = BitsN.+((!PC),offset) in case memop of MemOp_LOAD => let val data = Mem N (address, (Nat.div(BitsN.size(BitsN.BV(0x0,N)),8),AccType_NORMAL)) in write'X 64 (ExtendWord (64,64) (data,signed),t) end | _ => () end; fun dfn'MemoryBarrier (op',crm) = raise UNDEFINED_FAULT "MemoryBarrier"; fun dfn'ClearExclusive imm = raise UNDEFINED_FAULT "ClearExclusive"; fun dfn'Hint op' = if op' = SystemHintOp_NOP then () else raise UNDEFINED_FAULT "Hint"; fun dfn'Breakpoint imm = raise UNDEFINED_FAULT "Breakpoint"; fun dfn'DebugSwitch target_level = raise UNDEFINED_FAULT "DebugSwitch"; fun dfn'DebugRestore () = raise UNDEFINED_FAULT "DebugRestore"; fun dfn'Halt imm16 = raise UNDEFINED_FAULT "Halt"; fun dfn'SystemInstruction (sys_op1,(sys_op2,(sys_crn,(sys_crm,(has_result,t))))) = raise UNDEFINED_FAULT "System"; fun dfn'MoveSystemRegister (read,(sys_op0,(sys_op1,(sys_op2,(sys_crn,(sys_crm,t)))))) = raise UNDEFINED_FAULT "MoveSystemRegister"; fun dfn'MoveImmediateProcState (field,operand) = raise UNDEFINED_FAULT "MoveImmediateProcState"; fun dfn'SupervisorCall imm16 = raise UNDEFINED_FAULT "SupervisorCall"; fun dfn'HypervisorCall imm16 = raise UNDEFINED_FAULT "HypervisorCall"; fun dfn'SecureMonitorCall imm16 = raise UNDEFINED_FAULT "SecureMonitorCall"; fun dfn'ExceptionReturn () = raise UNDEFINED_FAULT "ExceptionReturn"; fun dfn'Unallocated () = raise UNDEFINED_FAULT "Unallocated"; fun dfn'Reserved () = raise UNDEFINED_FAULT "Reserved"; fun Run v0 = case v0 of Reserved => dfn'Reserved () | Unallocated => dfn'Unallocated () | Address v81 => dfn'Address v81 | ClearExclusive v82 => dfn'ClearExclusive v82 | Hint v83 => dfn'Hint v83 | MemoryBarrier v84 => dfn'MemoryBarrier v84 | Branch v1 => (case v1 of BranchConditional v2 => dfn'BranchConditional v2 | BranchImmediate v3 => dfn'BranchImmediate v3 | BranchRegister v4 => dfn'BranchRegister v4 | CompareAndBranch''32 v5 => dfn'CompareAndBranch 32 v5 | CompareAndBranch''64 v6 => dfn'CompareAndBranch 64 v6 | TestBitAndBranch''32 v7 => dfn'TestBitAndBranch 32 v7 | TestBitAndBranch''64 v8 => dfn'TestBitAndBranch 64 v8) | CRCExt v9 => (case v9 of CRC''16 v10 => dfn'CRC 16 v10 | CRC''32 v11 => dfn'CRC 32 v11 | CRC''64 v12 => dfn'CRC 64 v12 | CRC''8 v13 => dfn'CRC 8 v13) | Data v14 => (case v14 of AddSubCarry''32 v15 => dfn'AddSubCarry 32 v15 | AddSubCarry''64 v16 => dfn'AddSubCarry 64 v16 | AddSubExtendRegister''32 v17 => dfn'AddSubExtendRegister 32 v17 | AddSubExtendRegister''64 v18 => dfn'AddSubExtendRegister 64 v18 | AddSubImmediate''32 v19 => dfn'AddSubImmediate 32 v19 | AddSubImmediate''64 v20 => dfn'AddSubImmediate 64 v20 | AddSubShiftedRegister''32 v21 => dfn'AddSubShiftedRegister 32 v21 | AddSubShiftedRegister''64 v22 => dfn'AddSubShiftedRegister 64 v22 | BitfieldMove''32 v23 => dfn'BitfieldMove 32 v23 | BitfieldMove''64 v24 => dfn'BitfieldMove 64 v24 | ConditionalCompareImmediate''32 v25 => dfn'ConditionalCompareImmediate 32 v25 | ConditionalCompareImmediate''64 v26 => dfn'ConditionalCompareImmediate 64 v26 | ConditionalCompareRegister''32 v27 => dfn'ConditionalCompareRegister 32 v27 | ConditionalCompareRegister''64 v28 => dfn'ConditionalCompareRegister 64 v28 | ConditionalSelect''32 v29 => dfn'ConditionalSelect 32 v29 | ConditionalSelect''64 v30 => dfn'ConditionalSelect 64 v30 | CountLeading''32 v31 => dfn'CountLeading 32 v31 | CountLeading''64 v32 => dfn'CountLeading 64 v32 | Division''32 v33 => dfn'Division 32 v33 | Division''64 v34 => dfn'Division 64 v34 | ExtractRegister''32 v35 => dfn'ExtractRegister 32 v35 | ExtractRegister''64 v36 => dfn'ExtractRegister 64 v36 | LogicalImmediate''32 v37 => dfn'LogicalImmediate 32 v37 | LogicalImmediate''64 v38 => dfn'LogicalImmediate 64 v38 | LogicalShiftedRegister''32 v39 => dfn'LogicalShiftedRegister 32 v39 | LogicalShiftedRegister''64 v40 => dfn'LogicalShiftedRegister 64 v40 | MoveWide''32 v41 => dfn'MoveWide 32 v41 | MoveWide''64 v42 => dfn'MoveWide 64 v42 | MultiplyAddSub''32 v43 => dfn'MultiplyAddSub 32 v43 | MultiplyAddSub''64 v44 => dfn'MultiplyAddSub 64 v44 | MultiplyAddSubLong v45 => dfn'MultiplyAddSubLong v45 | MultiplyHigh v46 => dfn'MultiplyHigh v46 | Reverse''32 v47 => dfn'Reverse 32 v47 | Reverse''64 v48 => dfn'Reverse 64 v48 | Shift''32 v49 => dfn'Shift 32 v49 | Shift''64 v50 => dfn'Shift 64 v50) | Debug v51 => (case v51 of DebugRestore => dfn'DebugRestore () | Breakpoint v52 => dfn'Breakpoint v52 | DebugSwitch v53 => dfn'DebugSwitch v53 | Halt v54 => dfn'Halt v54) | LoadStore v55 => (case v55 of LoadLiteral''32 v56 => dfn'LoadLiteral 32 v56 | LoadLiteral''64 v57 => dfn'LoadLiteral 64 v57 | LoadStoreAcquire''16 v58 => dfn'LoadStoreAcquire 16 v58 | LoadStoreAcquire''32 v59 => dfn'LoadStoreAcquire 32 v59 | LoadStoreAcquire''64 v60 => dfn'LoadStoreAcquire 64 v60 | LoadStoreAcquire''8 v61 => dfn'LoadStoreAcquire 8 v61 | LoadStoreAcquirePair''128 v62 => dfn'LoadStoreAcquirePair 128 v62 | LoadStoreAcquirePair''64 v63 => dfn'LoadStoreAcquirePair 64 v63 | LoadStoreImmediate''16 v64 => dfn'LoadStoreImmediate 16 v64 | LoadStoreImmediate''32 v65 => dfn'LoadStoreImmediate 32 v65 | LoadStoreImmediate''64 v66 => dfn'LoadStoreImmediate 64 v66 | LoadStoreImmediate''8 v67 => dfn'LoadStoreImmediate 8 v67 | LoadStorePair''32 v68 => dfn'LoadStorePair 32 v68 | LoadStorePair''64 v69 => dfn'LoadStorePair 64 v69 | LoadStoreRegister''16 v70 => dfn'LoadStoreRegister 16 v70 | LoadStoreRegister''32 v71 => dfn'LoadStoreRegister 32 v71 | LoadStoreRegister''64 v72 => dfn'LoadStoreRegister 64 v72 | LoadStoreRegister''8 v73 => dfn'LoadStoreRegister 8 v73) | System v74 => (case v74 of ExceptionReturn => dfn'ExceptionReturn () | HypervisorCall v75 => dfn'HypervisorCall v75 | MoveImmediateProcState v76 => dfn'MoveImmediateProcState v76 | MoveSystemRegister v77 => dfn'MoveSystemRegister v77 | SecureMonitorCall v78 => dfn'SecureMonitorCall v78 | SupervisorCall v79 => dfn'SupervisorCall v79 | SystemInstruction v80 => dfn'SystemInstruction v80); fun DecodeLogicalOp opc = case opc of BitsN.B(0x0,_) => (LogicalOp_AND,false) | BitsN.B(0x1,_) => (LogicalOp_ORR,false) | BitsN.B(0x2,_) => (LogicalOp_EOR,false) | BitsN.B(0x3,_) => (LogicalOp_AND,true) | _ => raise General.Bind; val NoOperation = Hint SystemHintOp_NOP fun LoadStoreRegister (size,(regsize_word,(memop,(signed,(m,(extend_type,(shift,(n,t)))))))) = let val a = (regsize_word,(memop,(signed,(m,(extend_type,(shift,(n,t))))))) in case size of BitsN.B(0x0,_) => LoadStore(LoadStoreRegister''8(BitsN.B(0x0,8),a)) | BitsN.B(0x1,_) => LoadStore(LoadStoreRegister''16(BitsN.B(0x1,16),a)) | BitsN.B(0x2,_) => LoadStore(LoadStoreRegister''32(BitsN.B(0x2,32),a)) | BitsN.B(0x3,_) => LoadStore(LoadStoreRegister''64(BitsN.B(0x3,64),a)) | _ => raise General.Bind end; fun LoadStoreImmediateN (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown,(wback,(postindex,(unsigned_offset,(offset,(n,t)))))))))))) = let val a = (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(unsigned_offset,(offset,(n,t))))))))))) in case size of BitsN.B(0x0,_) => LoadStore(LoadStoreImmediate''8(BitsN.B(0x0,8),a)) | BitsN.B(0x1,_) => LoadStore(LoadStoreImmediate''16(BitsN.B(0x1,16),a)) | BitsN.B(0x2,_) => LoadStore(LoadStoreImmediate''32(BitsN.B(0x2,32),a)) | BitsN.B(0x3,_) => LoadStore(LoadStoreImmediate''64(BitsN.B(0x3,64),a)) | _ => raise General.Bind end; fun LoadStoreImmediate (size, (opc,(acctype,(wback,(postindex,(unsigned_offset,(offset,(Rn,Rt)))))))) = let val (memop,(regsize_word,signed)) = if not(BitsN.bit(opc,1)) then (if BitsN.bit(opc,0) then MemOp_LOAD else MemOp_STORE, (not(size = (BitsN.B(0x3,2))),false)) else if size = (BitsN.B(0x3,2)) then (MemOp_PREFETCH,(false,false)) else (MemOp_LOAD,(BitsN.bit(opc,0),true)) val wb_unknown = false val rt_unknown = false in if (memop = MemOp_LOAD) andalso (wback andalso ((Rn = Rt) andalso (not(Rn = (BitsN.B(0x1F,5)))))) then case (L3.K(BitsN.B(0x0,2))) "LoadImmediate unpredictable" of BitsN.B(0x0,_) => let val wback = false in LoadStoreImmediateN (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback, (postindex,(unsigned_offset,(offset,(Rn,Rt)))))))))))) end | BitsN.B(0x1,_) => let val wb_unknown = true in LoadStoreImmediateN (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback, (postindex,(unsigned_offset,(offset,(Rn,Rt)))))))))))) end | BitsN.B(0x2,_) => Unallocated | BitsN.B(0x3,_) => NoOperation | _ => raise General.Bind else if (memop = MemOp_STORE) andalso (wback andalso ((Rn = Rt) andalso (not(Rn = (BitsN.B(0x1F,5)))))) then case (L3.K(BitsN.B(0x0,2))) "StoreImmediate unpredictable" of BitsN.B(0x0,_) => LoadStoreImmediateN (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback, (postindex,(unsigned_offset,(offset,(Rn,Rt)))))))))))) | BitsN.B(0x1,_) => let val rt_unknown = true in LoadStoreImmediateN (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback, (postindex,(unsigned_offset,(offset,(Rn,Rt)))))))))))) end | BitsN.B(0x2,_) => Unallocated | BitsN.B(0x3,_) => NoOperation | _ => raise General.Bind else LoadStoreImmediateN (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(unsigned_offset,(offset,(Rn,Rt)))))))))))) end; fun LoadStorePairN (sf, (memop, (acctype, (signed, (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,(t,t2))))))))))) = let val a = (memop, (acctype, (signed, (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,(t,t2)))))))))) in if sf = (BitsN.B(0x1,1)) then LoadStore(LoadStorePair''64(BitsN.B(0x1,64),a)) else LoadStore(LoadStorePair''32(BitsN.B(0x0,32),a)) end; fun LoadStorePair (sf, (memop,(acctype,(signed,(wback,(postindex,(offset,(Rn,(Rt,Rt2))))))))) = let val wb_unknown = false val rt_unknown = false in if (memop = MemOp_LOAD) andalso (wback andalso (((Rn = Rt) orelse (Rn = Rt2)) andalso (not(Rn = (BitsN.B(0x1F,5)))))) then case (L3.K(BitsN.B(0x0,2))) "LoadPair unpredictable" of BitsN.B(0x0,_) => let val wback = false in LoadStorePairN (sf, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(offset,(Rn,(Rt,Rt2))))))))))) end | BitsN.B(0x1,_) => let val wb_unknown = true in LoadStorePairN (sf, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(offset,(Rn,(Rt,Rt2))))))))))) end | BitsN.B(0x2,_) => Unallocated | BitsN.B(0x3,_) => NoOperation | _ => raise General.Bind else if (memop = MemOp_STORE) andalso (wback andalso (((Rn = Rt) orelse (Rn = Rt2)) andalso (not(Rn = (BitsN.B(0x1F,5)))))) then case (L3.K(BitsN.B(0x0,2))) "StorePair unpredictable" of BitsN.B(0x0,_) => LoadStorePairN (sf, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(offset,(Rn,(Rt,Rt2))))))))))) | BitsN.B(0x1,_) => let val rt_unknown = true in LoadStorePairN (sf, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(offset,(Rn,(Rt,Rt2))))))))))) end | BitsN.B(0x2,_) => Unallocated | BitsN.B(0x3,_) => NoOperation | _ => raise General.Bind else if (memop = MemOp_LOAD) andalso (Rt = Rt2) then case (L3.K(BitsN.B(0x0,2))) "LoadPair Rt = Rt2 unpredictable" of BitsN.B(0x0,_) => let val rt_unknown = true in LoadStorePairN (sf, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(offset,(Rn,(Rt,Rt2))))))))))) end | BitsN.B(0x1,_) => Unallocated | _ => NoOperation else LoadStorePairN (sf, (memop, (acctype, (signed, (wb_unknown, (rt_unknown,(wback,(postindex,(offset,(Rn,(Rt,Rt2))))))))))) end; fun LoadStoreAcquireN (size, (memop, (acctype,(excl,(pair,(rn_unknown,(rt_unknown,(s,(n,(t,t2)))))))))) = if pair then let val a = (memop,(acctype,(rn_unknown,(rt_unknown,(s,(n,(t,t2))))))) in if size = (BitsN.B(0x2,2)) then LoadStore(LoadStoreAcquirePair''64(BitsN.B(0x2,64),a)) else LoadStore(LoadStoreAcquirePair''128(BitsN.B(0x3,128),a)) end else let val a = (memop,(acctype,(excl,(rn_unknown,(rt_unknown,(s,(n,t))))))) in case size of BitsN.B(0x0,_) => LoadStore(LoadStoreAcquire''8(BitsN.B(0x0,8),a)) | BitsN.B(0x1,_) => LoadStore(LoadStoreAcquire''16(BitsN.B(0x1,16),a)) | BitsN.B(0x2,_) => LoadStore(LoadStoreAcquire''32(BitsN.B(0x2,32),a)) | BitsN.B(0x3,_) => LoadStore(LoadStoreAcquire''64(BitsN.B(0x3,64),a)) | _ => raise General.Bind end; fun LoadStoreAcquire (size,(memop,(acctype,(excl,(pair,(Rs,(Rn,(Rt,Rt2)))))))) = let val (rt_unknown,(rn_unknown,ast)) = if (memop = MemOp_LOAD) andalso (pair andalso (Rt = Rt2)) then case (L3.K(BitsN.B(0x0,2))) "LoadAcquire unpredictable" of BitsN.B(0x0,_) => (true,(false,NONE)) | BitsN.B(0x1,_) => (false,(false,Option.SOME Unallocated)) | _ => (false,(false,Option.SOME NoOperation)) else (false,(false,NONE)) val (rt_unknown,(rn_unknown,ast)) = if ((memop = MemOp_STORE) andalso (excl andalso (Rs = Rt))) orelse (pair andalso (Rs = Rt2)) then case (L3.K(BitsN.B(0x0,2))) "StoreAcquire Rs = Rt unpredictable" of BitsN.B(0x0,_) => (true,(rn_unknown,ast)) | BitsN.B(0x1,_) => (rt_unknown,(rn_unknown,ast)) | BitsN.B(0x2,_) => (rt_unknown,(rn_unknown,Option.SOME Unallocated)) | BitsN.B(0x3,_) => (rt_unknown,(rn_unknown,Option.SOME NoOperation)) | _ => raise General.Bind else (rt_unknown,(rn_unknown,ast)) val (rt_unknown,(rn_unknown,ast)) = if (memop = MemOp_STORE) andalso (excl andalso ((Rs = Rn) andalso (not(Rn = (BitsN.B(0x1F,5)))))) then case (L3.K(BitsN.B(0x0,2))) "StoreAcquire Rs = Rn unpredictable" of BitsN.B(0x0,_) => (rt_unknown,(true,ast)) | BitsN.B(0x1,_) => (rt_unknown,(rn_unknown,ast)) | BitsN.B(0x2,_) => (rt_unknown,(rn_unknown,Option.SOME Unallocated)) | BitsN.B(0x3,_) => (rt_unknown,(rn_unknown,Option.SOME NoOperation)) | _ => raise General.Bind else (rt_unknown,(rn_unknown,ast)) in case ast of Option.SOME i => i | NONE => LoadStoreAcquireN (size, (memop, (acctype, (excl,(pair,(rn_unknown,(rt_unknown,(Rs,(Rn,(Rt,Rt2)))))))))) end; fun Decode w = case boolify'32 w of (op'0, (immlo'1, (immlo'0, (true, (false, (false, (false, (false, (immhi'18, (immhi'17, (immhi'16, (immhi'15, (immhi'14, (immhi'13, (immhi'12, (immhi'11, (immhi'10, (immhi'9, (immhi'8, (immhi'7, (immhi'6, (immhi'5, (immhi'4, (immhi'3, (immhi'2, (immhi'1, (immhi'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val immhi = BitsN.fromBitstring ([immhi'18,immhi'17,immhi'16,immhi'15,immhi'14,immhi'13, immhi'12,immhi'11,immhi'10,immhi'9,immhi'8,immhi'7,immhi'6, immhi'5,immhi'4,immhi'3,immhi'2,immhi'1,immhi'0],19) val immlo = BitsN.fromBitstring([immlo'1,immlo'0],2) val page = (not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)) val imm = if page then BitsN.signExtend 64 (BitsN.concat[immhi,immlo,BitsN.B(0x0,12)]) else BitsN.signExtend 64 (BitsN.@@(immhi,immlo)) in Address (page,(imm,BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))) end | (_, (op'0, (S'0, (false, (true, (false, (true, (true, (true, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (imm6'5, (imm6'4, (imm6'3, (imm6'2, (imm6'1, (imm6'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Reserved | (false, (op'0, (S'0, (false, (true, (false, (true, (true, (shift'1, (shift'0, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (imm6'5, (imm6'4, (imm6'3, (imm6'2, (imm6'1, (imm6'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val imm6 = BitsN.fromBitstring ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],6) in if BitsN.bit(imm6,5) then Reserved else Data (AddSubShiftedRegister''32 (BitsN.B(0x0,32), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([S'0],1)), (DecodeShift(BitsN.fromBitstring([shift'1,shift'0],2)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (imm6, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))) end | (true, (op'0, (S'0, (false, (true, (false, (true, (true, (shift'1, (shift'0, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (imm6'5, (imm6'4, (imm6'3, (imm6'2, (imm6'1, (imm6'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (AddSubShiftedRegister''64 (BitsN.B(0x1,64), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([S'0],1)), (DecodeShift(BitsN.fromBitstring([shift'1,shift'0],2)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],6), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))) | (false, (op'0, (S'0, (false, (true, (false, (true, (true, (false, (false, (true, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (option'2, (option'1, (option'0, (imm3'2, (imm3'1, (imm3'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val imm3 = BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3) in if BitsN.>+(imm3,BitsN.B(0x4,3)) then Reserved else Data (AddSubExtendRegister''32 (BitsN.B(0x0,32), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([S'0],1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (DecodeRegExtend (BitsN.fromBitstring ([option'2,option'1,option'0],3)), (imm3, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))) end | (true, (op'0, (S'0, (false, (true, (false, (true, (true, (false, (false, (true, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (option'2, (option'1, (option'0, (imm3'2, (imm3'1, (imm3'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val imm3 = BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3) in if BitsN.>+(imm3,BitsN.B(0x4,3)) then Reserved else Data (AddSubExtendRegister''64 (BitsN.B(0x1,64), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([S'0],1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (DecodeRegExtend (BitsN.fromBitstring ([option'2,option'1,option'0],3)), (imm3, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))) end | (_, (op'0, (S'0, (true, (false, (false, (false, (true, (true, (_, (imm12'11, (imm12'10, (imm12'9, (imm12'8, (imm12'7, (imm12'6, (imm12'5, (imm12'4, (imm12'3, (imm12'2, (imm12'1, (imm12'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Reserved | (false, (op'0, (S'0, (true, (false, (false, (false, (true, (shift'1, (shift'0, (imm12'11, (imm12'10, (imm12'9, (imm12'8, (imm12'7, (imm12'6, (imm12'5, (imm12'4, (imm12'3, (imm12'2, (imm12'1, (imm12'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val imm12 = BitsN.fromBitstring ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,imm12'6,imm12'5, imm12'4,imm12'3,imm12'2,imm12'1,imm12'0],12) val imm = if (BitsN.fromBitstring([shift'1,shift'0],2)) = (BitsN.B(0x0,2)) then BitsN.fromNat(BitsN.toNat imm12,32) else BitsN.<<(BitsN.fromNat(BitsN.toNat imm12,32),12) in Data (AddSubImmediate''32 (BitsN.B(0x0,32), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([S'0],1)), (imm, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) end | (true, (op'0, (S'0, (true, (false, (false, (false, (true, (shift'1, (shift'0, (imm12'11, (imm12'10, (imm12'9, (imm12'8, (imm12'7, (imm12'6, (imm12'5, (imm12'4, (imm12'3, (imm12'2, (imm12'1, (imm12'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val imm12 = BitsN.fromBitstring ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,imm12'6,imm12'5, imm12'4,imm12'3,imm12'2,imm12'1,imm12'0],12) val imm = if (BitsN.fromBitstring([shift'1,shift'0],2)) = (BitsN.B(0x0,2)) then BitsN.fromNat(BitsN.toNat imm12,64) else BitsN.<<(BitsN.fromNat(BitsN.toNat imm12,64),12) in Data (AddSubImmediate''64 (BitsN.B(0x1,64), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([S'0],1)), (imm, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) end | (false, (op'0, (S'0, (true, (true, (false, (true, (false, (false, (false, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (false, (false, (false, (false, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (AddSubCarry''32 (BitsN.B(0x0,32), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([S'0],1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) | (true, (op'0, (S'0, (true, (true, (false, (true, (false, (false, (false, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (false, (false, (false, (false, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (AddSubCarry''64 (BitsN.B(0x1,64), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([S'0],1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) | (false, (opc'1, (opc'0, (false, (true, (false, (true, (false, (shift'1, (shift'0, (N'0, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (imm6'5, (imm6'4, (imm6'3, (imm6'2, (imm6'1, (imm6'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val imm6 = BitsN.fromBitstring ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],6) in if BitsN.bit(imm6,5) then Reserved else let val invert = (BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x1,1)) val (opc,setflags) = DecodeLogicalOp(BitsN.fromBitstring([opc'1,opc'0],2)) in Data (LogicalShiftedRegister''32 (BitsN.B(0x0,32), (opc, (invert, (setflags, (DecodeShift (BitsN.fromBitstring([shift'1,shift'0],2)), (BitsN.toNat imm6, (BitsN.fromBitstring ([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring ([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring ([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))))) end end | (true, (opc'1, (opc'0, (false, (true, (false, (true, (false, (shift'1, (shift'0, (N'0, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (imm6'5, (imm6'4, (imm6'3, (imm6'2, (imm6'1, (imm6'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val invert = (BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x1,1)) val (opc,setflags) = DecodeLogicalOp(BitsN.fromBitstring([opc'1,opc'0],2)) in Data (LogicalShiftedRegister''64 (BitsN.B(0x1,64), (opc, (invert, (setflags, (DecodeShift(BitsN.fromBitstring([shift'1,shift'0],2)), (BitsN.toNat (BitsN.fromBitstring ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],6)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))))) end | (false, (opc'1, (opc'0, (true, (false, (false, (true, (false, (false, (true, (immr'5, (immr'4, (immr'3, (immr'2, (immr'1, (immr'0, (imms'5, (imms'4, (imms'3, (imms'2, (imms'1, (imms'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Reserved | (false, (opc'1, (opc'0, (true, (false, (false, (true, (false, (false, (N'0, (immr'5, (immr'4, (immr'3, (immr'2, (immr'1, (immr'0, (imms'5, (imms'4, (imms'3, (imms'2, (imms'1, (imms'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => (case DecodeBitMasks 32 (BitsN.fromBitstring([N'0],1), (BitsN.fromBitstring ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6), (BitsN.fromBitstring ([immr'5,immr'4,immr'3,immr'2,immr'1,immr'0],6),true))) of Option.SOME(imm,_) => let val (opc,setflags) = DecodeLogicalOp(BitsN.fromBitstring([opc'1,opc'0],2)) in Data (LogicalImmediate''32 (BitsN.B(0x0,32), (opc, (setflags, (imm, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) end | NONE => Reserved) | (true, (opc'1, (opc'0, (true, (false, (false, (true, (false, (false, (N'0, (immr'5, (immr'4, (immr'3, (immr'2, (immr'1, (immr'0, (imms'5, (imms'4, (imms'3, (imms'2, (imms'1, (imms'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => (case DecodeBitMasks 64 (BitsN.fromBitstring([N'0],1), (BitsN.fromBitstring ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6), (BitsN.fromBitstring ([immr'5,immr'4,immr'3,immr'2,immr'1,immr'0],6),true))) of Option.SOME(imm,_) => let val (opc,setflags) = DecodeLogicalOp(BitsN.fromBitstring([opc'1,opc'0],2)) in Data (LogicalImmediate''64 (BitsN.B(0x1,64), (opc, (setflags, (imm, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) end | NONE => Reserved) | (false, (false, (false, (true, (true, (false, (true, (false, (true, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (false, (true, (false, (op2'1, (op2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (Shift''32 (BitsN.B(0x0,32), (DecodeShift(BitsN.fromBitstring([op2'1,op2'0],2)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))) | (true, (false, (false, (true, (true, (false, (true, (false, (true, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (false, (true, (false, (op2'1, (op2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (Shift''64 (BitsN.B(0x1,64), (DecodeShift(BitsN.fromBitstring([op2'1,op2'0],2)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))) | (false, (opc'1, (opc'0, (true, (false, (false, (true, (false, (true, (true, (_, (imm16'15, (imm16'14, (imm16'13, (imm16'12, (imm16'11, (imm16'10, (imm16'9, (imm16'8, (imm16'7, (imm16'6, (imm16'5, (imm16'4, (imm16'3, (imm16'2, (imm16'1, (imm16'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Unallocated | (sf'0, (false, (true, (true, (false, (false, (true, (false, (true, (hw'1, (hw'0, (imm16'15, (imm16'14, (imm16'13, (imm16'12, (imm16'11, (imm16'10, (imm16'9, (imm16'8, (imm16'7, (imm16'6, (imm16'5, (imm16'4, (imm16'3, (imm16'2, (imm16'1, (imm16'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Unallocated | (sf'0, (opc'1, (opc'0, (true, (false, (false, (true, (false, (true, (hw'1, (hw'0, (imm16'15, (imm16'14, (imm16'13, (imm16'12, (imm16'11, (imm16'10, (imm16'9, (imm16'8, (imm16'7, (imm16'6, (imm16'5, (imm16'4, (imm16'3, (imm16'2, (imm16'1, (imm16'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val Rd = BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5) val imm16 = BitsN.fromBitstring ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10, imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3, imm16'2,imm16'1,imm16'0],16) val hw = BitsN.fromBitstring([hw'1,hw'0],2) val opcode = case BitsN.fromBitstring([opc'1,opc'0],2) of BitsN.B(0x0,_) => MoveWideOp_N | BitsN.B(0x2,_) => MoveWideOp_Z | BitsN.B(0x3,_) => MoveWideOp_K | BitsN.B(0x1,_) => MoveWideOp_K | _ => raise General.Bind in if (BitsN.fromBitstring([sf'0],1)) = (BitsN.B(0x1,1)) then Data(MoveWide''64(BitsN.B(0x1,64),(opcode,(hw,(imm16,Rd))))) else Data(MoveWide''32(BitsN.B(0x0,32),(opcode,(hw,(imm16,Rd))))) end | (_, (true, (true, (true, (false, (false, (true, (true, (false, (N'0, (immr'5, (immr'4, (immr'3, (immr'2, (immr'1, (immr'0, (imms'5, (imms'4, (imms'3, (imms'2, (imms'1, (imms'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Unallocated | (false, (opc'1, (opc'0, (true, (false, (false, (true, (true, (false, (N'0, (immr'5, (immr'4, (immr'3, (immr'2, (immr'1, (immr'0, (imms'5, (imms'4, (imms'3, (imms'2, (imms'1, (imms'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val imms = BitsN.fromBitstring ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6) val immr = BitsN.fromBitstring ([immr'5,immr'4,immr'3,immr'2,immr'1,immr'0],6) val N = BitsN.fromBitstring([N'0],1) in if (N = (BitsN.B(0x1,1))) orelse ((BitsN.bit(immr,5)) orelse (BitsN.bit(imms,5))) then Reserved else let val (inzero,extend) = case BitsN.fromBitstring([opc'1,opc'0],2) of BitsN.B(0x0,_) => (true,true) | BitsN.B(0x1,_) => (false,false) | BitsN.B(0x2,_) => (true,false) | _ => (false,false) in case DecodeBitMasks 32 (N,(imms,(immr,false))) of Option.SOME(wmask,tmask) => Data (BitfieldMove''32 (BitsN.B(0x0,32), (inzero, (extend, (wmask, (tmask, (BitsN.toNat immr, (BitsN.toNat imms, (BitsN.fromBitstring ([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring ([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))))) | NONE => Reserved end end | (true, (opc'1, (opc'0, (true, (false, (false, (true, (true, (false, (N'0, (immr'5, (immr'4, (immr'3, (immr'2, (immr'1, (immr'0, (imms'5, (imms'4, (imms'3, (imms'2, (imms'1, (imms'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val imms = BitsN.fromBitstring ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6) val immr = BitsN.fromBitstring ([immr'5,immr'4,immr'3,immr'2,immr'1,immr'0],6) val N = BitsN.fromBitstring([N'0],1) in if N = (BitsN.B(0x0,1)) then Reserved else let val (inzero,extend) = case BitsN.fromBitstring([opc'1,opc'0],2) of BitsN.B(0x0,_) => (true,true) | BitsN.B(0x1,_) => (false,false) | BitsN.B(0x2,_) => (true,false) | _ => (false,false) in case DecodeBitMasks 64 (N,(imms,(immr,false))) of Option.SOME(wmask,tmask) => Data (BitfieldMove''64 (BitsN.B(0x1,64), (inzero, (extend, (wmask, (tmask, (BitsN.toNat immr, (BitsN.toNat imms, (BitsN.fromBitstring ([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring ([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))))) | NONE => Reserved end end | (false, (op'0, (true, (true, (true, (false, (true, (false, (false, (true, (false, (imm5'4, (imm5'3, (imm5'2, (imm5'1, (imm5'0, (cond'3, (cond'2, (cond'1, (cond'0, (true, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(false,(n'0,(z'0,(c'0,v'0))))))))))))))))))))))))))))))) => let val nzcv = ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([n'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([z'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([c'0],1)), (not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([v'0],1))))) in Data (ConditionalCompareImmediate''32 (BitsN.B(0x0,32), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), (BitsN.fromNat (BitsN.toNat (BitsN.fromBitstring ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5)),32), (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4), (nzcv,BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5))))))) end | (true, (op'0, (true, (true, (true, (false, (true, (false, (false, (true, (false, (imm5'4, (imm5'3, (imm5'2, (imm5'1, (imm5'0, (cond'3, (cond'2, (cond'1, (cond'0, (true, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(false,(n'0,(z'0,(c'0,v'0))))))))))))))))))))))))))))))) => let val nzcv = ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([n'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([z'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([c'0],1)), (not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([v'0],1))))) in Data (ConditionalCompareImmediate''64 (BitsN.B(0x1,64), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), (BitsN.fromNat (BitsN.toNat (BitsN.fromBitstring ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5)),64), (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4), (nzcv,BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5))))))) end | (false, (op'0, (true, (true, (true, (false, (true, (false, (false, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (cond'3, (cond'2, (cond'1, (cond'0, (false, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(false,(n'0,(z'0,(c'0,v'0))))))))))))))))))))))))))))))) => let val nzcv = ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([n'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([z'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([c'0],1)), (not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([v'0],1))))) in Data (ConditionalCompareRegister''32 (BitsN.B(0x0,32), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4), (nzcv, (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5))))))) end | (true, (op'0, (true, (true, (true, (false, (true, (false, (false, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (cond'3, (cond'2, (cond'1, (cond'0, (false, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(false,(n'0,(z'0,(c'0,v'0))))))))))))))))))))))))))))))) => let val nzcv = ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([n'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([z'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([c'0],1)), (not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([v'0],1))))) in Data (ConditionalCompareRegister''64 (BitsN.B(0x1,64), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4), (nzcv, (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5))))))) end | (false, (op'0, (false, (true, (true, (false, (true, (false, (true, (false, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (cond'3, (cond'2, (cond'1, (cond'0, (false, (o2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (ConditionalSelect''32 (BitsN.B(0x0,32), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([o2'0],1)), (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))) | (true, (op'0, (false, (true, (true, (false, (true, (false, (true, (false, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (cond'3, (cond'2, (cond'1, (cond'0, (false, (o2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (ConditionalSelect''64 (BitsN.B(0x1,64), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([o2'0],1)), (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))) | (false, (true, (false, (true, (true, (false, (true, (false, (true, (true, (false, (false, (false, (false, (false, (false, (false, (false, (false, (true, (false, (op'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (CountLeading''32 (BitsN.B(0x0,32), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))) | (true, (true, (false, (true, (true, (false, (true, (false, (true, (true, (false, (false, (false, (false, (false, (false, (false, (false, (false, (true, (false, (op'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (CountLeading''64 (BitsN.B(0x1,64), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))) | (false, (false, (false, (true, (false, (false, (true, (true, (true, (N'0, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (imms'5, (imms'4, (imms'3, (imms'2, (imms'1, (imms'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => let val imms = BitsN.fromBitstring ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6) in if not((BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x0,1))) then Unallocated else if BitsN.bit(imms,5) then Reserved else Data (ExtractRegister''32 (BitsN.B(0x0,32), (imms, (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))) end | (true, (false, (false, (true, (false, (false, (true, (true, (true, (N'0, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (imms'5, (imms'4, (imms'3, (imms'2, (imms'1, (imms'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => (if not((BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x1,1))) then Unallocated else Data (ExtractRegister''64 (BitsN.B(0x1,64), (BitsN.fromBitstring ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) | (false, (false, (false, (true, (true, (false, (true, (false, (true, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (false, (false, (false, (true, (o1'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (Division''32 (BitsN.B(0x0,32), ((BitsN.fromBitstring([o1'0],1)) = (BitsN.B(0x0,1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))) | (true, (false, (false, (true, (true, (false, (true, (false, (true, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (false, (false, (false, (true, (o1'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (Division''64 (BitsN.B(0x1,64), ((BitsN.fromBitstring([o1'0],1)) = (BitsN.B(0x0,1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))) | (false, (false, (false, (true, (true, (false, (true, (true, (false, (false, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (o0'0, (Ra'4, (Ra'3, (Ra'2, (Ra'1, (Ra'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (MultiplyAddSub''32 (BitsN.B(0x0,32), ((BitsN.fromBitstring([o0'0],1)) = (BitsN.B(0x1,1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Ra'4,Ra'3,Ra'2,Ra'1,Ra'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) | (true, (false, (false, (true, (true, (false, (true, (true, (false, (false, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (o0'0, (Ra'4, (Ra'3, (Ra'2, (Ra'1, (Ra'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (MultiplyAddSub''64 (BitsN.B(0x1,64), ((BitsN.fromBitstring([o0'0],1)) = (BitsN.B(0x1,1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Ra'4,Ra'3,Ra'2,Ra'1,Ra'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) | (true, (false, (false, (true, (true, (false, (true, (true, (U'0, (false, (true, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (o0'0, (Ra'4, (Ra'3, (Ra'2, (Ra'1, (Ra'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (MultiplyAddSubLong ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([o0'0],1)), ((BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x0,1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Ra'4,Ra'3,Ra'2,Ra'1,Ra'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))) | (true, (false, (false, (true, (true, (false, (true, (true, (U'0, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (_, (_, (_, (_, (_, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (MultiplyHigh ((BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x0,1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))) | (false, (true, (false, (true, (true, (false, (true, (false, (true, (true, (false, (false, (false, (false, (false, (false, (false, (false, (false, (false, (true, (true, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Unallocated | (false, (true, (false, (true, (true, (false, (true, (false, (true, (true, (false, (false, (false, (false, (false, (false, (false, (false, (false, (false, (opc'1, (opc'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (Reverse''32 (BitsN.B(0x0,32), ((Cast.natToRevOp o BitsN.toNat) (BitsN.fromBitstring([opc'1,opc'0],2)), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))) | (true, (true, (false, (true, (true, (false, (true, (false, (true, (true, (false, (false, (false, (false, (false, (false, (false, (false, (false, (false, (opc'1, (opc'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => Data (Reverse''64 (BitsN.B(0x1,64), ((Cast.natToRevOp o BitsN.toNat) (BitsN.fromBitstring([opc'1,opc'0],2)), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))) | (false, (false, (false, (true, (true, (false, (true, (false, (true, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (true, (false, (C'0, (false, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => CRCExt (CRC''8 (BitsN.B(0x0,8), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([C'0],1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))) | (false, (false, (false, (true, (true, (false, (true, (false, (true, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (true, (false, (C'0, (false, (true, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => CRCExt (CRC''16 (BitsN.B(0x1,16), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([C'0],1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))) | (false, (false, (false, (true, (true, (false, (true, (false, (true, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (true, (false, (C'0, (true, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => CRCExt (CRC''32 (BitsN.B(0x2,32), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([C'0],1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))) | (true, (false, (false, (true, (true, (false, (true, (false, (true, (true, (false, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (true, (false, (C'0, (true, (true, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) => CRCExt (CRC''64 (BitsN.B(0x3,64), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([C'0],1)), (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))) | (false, (true, (false, (true, (false, (true, (false, (false, (imm19'18, (imm19'17, (imm19'16, (imm19'15, (imm19'14, (imm19'13, (imm19'12, (imm19'11, (imm19'10, (imm19'9, (imm19'8, (imm19'7, (imm19'6, (imm19'5, (imm19'4, (imm19'3, (imm19'2, (imm19'1, (imm19'0, (false,(cond'3,(cond'2,(cond'1,cond'0))))))))))))))))))))))))))))))) => Branch (BranchConditional (BitsN.signExtend 64 (BitsN.@@ (BitsN.fromBitstring ([imm19'18,imm19'17,imm19'16,imm19'15,imm19'14, imm19'13,imm19'12,imm19'11,imm19'10,imm19'9,imm19'8, imm19'7,imm19'6,imm19'5,imm19'4,imm19'3,imm19'2, imm19'1,imm19'0],19),BitsN.B(0x0,2))), BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4))) | (op'0, (false, (false, (true, (false, (true, (imm26'25, (imm26'24, (imm26'23, (imm26'22, (imm26'21, (imm26'20, (imm26'19, (imm26'18, (imm26'17, (imm26'16, (imm26'15, (imm26'14, (imm26'13, (imm26'12, (imm26'11, (imm26'10, (imm26'9, (imm26'8, (imm26'7, (imm26'6, (imm26'5, (imm26'4, (imm26'3,(imm26'2,(imm26'1,imm26'0))))))))))))))))))))))))))))))) => let val branch_type = if (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x1,1)) then BranchType_CALL else BranchType_JMP in Branch (BranchImmediate (BitsN.signExtend 64 (BitsN.@@ (BitsN.fromBitstring ([imm26'25,imm26'24,imm26'23,imm26'22,imm26'21, imm26'20,imm26'19,imm26'18,imm26'17,imm26'16, imm26'15,imm26'14,imm26'13,imm26'12,imm26'11, imm26'10,imm26'9,imm26'8,imm26'7,imm26'6,imm26'5, imm26'4,imm26'3,imm26'2,imm26'1,imm26'0],26), BitsN.B(0x0,2))),branch_type)) end | (true, (true, (false, (true, (false, (true, (true, (false, (false, (false, (false, (true, (true, (true, (true, (true, (false, (false, (false, (false, (false, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1, (Rn'0,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) => Branch (BranchRegister (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BranchType_JMP)) | (true, (true, (false, (true, (false, (true, (true, (false, (false, (false, (true, (true, (true, (true, (true, (true, (false, (false, (false, (false, (false, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1, (Rn'0,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) => Branch (BranchRegister (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BranchType_CALL)) | (true, (true, (false, (true, (false, (true, (true, (false, (false, (true, (false, (true, (true, (true, (true, (true, (false, (false, (false, (false, (false, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1, (Rn'0,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) => Branch (BranchRegister (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BranchType_RET)) | (true, (true, (false, (true, (false, (true, (true, (false, (false, (_, (_, (true, (true, (true, (true, (true, (false, (false, (false, (false, (false, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1, (Rn'0,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) => Unallocated | (sf'0, (false, (true, (true, (false, (true, (false, (op'0, (imm19'18, (imm19'17, (imm19'16, (imm19'15, (imm19'14, (imm19'13, (imm19'12, (imm19'11, (imm19'10, (imm19'9, (imm19'8, (imm19'7, (imm19'6, (imm19'5, (imm19'4, (imm19'3, (imm19'2, (imm19'1, (imm19'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => let val Rt = BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5) val iszero = (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x0,1)) val offset = BitsN.signExtend 64 (BitsN.@@ (BitsN.fromBitstring ([imm19'18,imm19'17,imm19'16,imm19'15,imm19'14,imm19'13, imm19'12,imm19'11,imm19'10,imm19'9,imm19'8,imm19'7, imm19'6,imm19'5,imm19'4,imm19'3,imm19'2,imm19'1,imm19'0], 19),BitsN.B(0x0,2))) in if (BitsN.fromBitstring([sf'0],1)) = (BitsN.B(0x1,1)) then Branch (CompareAndBranch''64 (BitsN.B(0x1,64),(iszero,(offset,Rt)))) else Branch (CompareAndBranch''32(BitsN.B(0x0,32),(iszero,(offset,Rt)))) end | (sf'0, (false, (true, (true, (false, (true, (true, (op'0, (b40'4, (b40'3, (b40'2, (b40'1, (b40'0, (imm14'13, (imm14'12, (imm14'11, (imm14'10, (imm14'9, (imm14'8, (imm14'7, (imm14'6, (imm14'5, (imm14'4, (imm14'3, (imm14'2, (imm14'1, (imm14'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => let val Rt = BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5) val sf = BitsN.fromBitstring([sf'0],1) val bit_pos = BitsN.@@ (sf,BitsN.fromBitstring([b40'4,b40'3,b40'2,b40'1,b40'0],5)) val bit_val = (not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1)) val offset = BitsN.signExtend 64 (BitsN.@@ (BitsN.fromBitstring ([imm14'13,imm14'12,imm14'11,imm14'10,imm14'9,imm14'8, imm14'7,imm14'6,imm14'5,imm14'4,imm14'3,imm14'2, imm14'1,imm14'0],14),BitsN.B(0x0,2))) in if sf = (BitsN.B(0x1,1)) then Branch (TestBitAndBranch''64 (BitsN.B(0x1,64),(bit_pos,(bit_val,(offset,Rt))))) else Branch (TestBitAndBranch''32 (BitsN.B(0x0,32),(bit_pos,(bit_val,(offset,Rt))))) end | (true, (false, (true, (true, (true, (false, (false, (false, (true, (true, (false, (imm9'8, (imm9'7, (imm9'6, (imm9'5, (imm9'4, (imm9'3, (imm9'2, (imm9'1, (imm9'0, (_, (_, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (true, (false, (true, (true, (true, (false, (false, (true, (true, (true, (imm12'11, (imm12'10, (imm12'9, (imm12'8, (imm12'7, (imm12'6, (imm12'5, (imm12'4, (imm12'3, (imm12'2, (imm12'1, (imm12'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (true, (true, (true, (true, (true, (false, (false, (false, (true, (true, (false, (imm9'8, (imm9'7, (imm9'6, (imm9'5, (imm9'4, (imm9'3, (imm9'2, (imm9'1, (imm9'0, (_, (_, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (true, (true, (true, (true, (true, (false, (false, (false, (true, (_, (false, (imm9'8, (imm9'7, (imm9'6, (imm9'5, (imm9'4, (imm9'3, (imm9'2, (imm9'1, (imm9'0, (true, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (size'1, (size'0, (true, (true, (true, (false, (false, (false, (opc'1, (opc'0, (false, (imm9'8, (imm9'7, (imm9'6, (imm9'5, (imm9'4, (imm9'3, (imm9'2, (imm9'1, (imm9'0, (P'0, (true, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => let val wback = true val postindex = (BitsN.fromBitstring([P'0],1)) = (BitsN.B(0x0,1)) val offset = BitsN.signExtend 64 (BitsN.fromBitstring ([imm9'8,imm9'7,imm9'6,imm9'5,imm9'4,imm9'3,imm9'2,imm9'1, imm9'0],9)) val acctype = AccType_NORMAL in LoadStoreImmediate (BitsN.fromBitstring([size'1,size'0],2), (BitsN.fromBitstring([opc'1,opc'0],2), (acctype, (wback, (postindex, (false, (offset, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5))))))))) end | (size'1, (size'0, (true, (true, (true, (false, (false, (false, (opc'1, (opc'0, (false, (imm9'8, (imm9'7, (imm9'6, (imm9'5, (imm9'4, (imm9'3, (imm9'2, (imm9'1, (imm9'0, (U'0, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => let val wback = false val postindex = false val offset = BitsN.signExtend 64 (BitsN.fromBitstring ([imm9'8,imm9'7,imm9'6,imm9'5,imm9'4,imm9'3,imm9'2,imm9'1, imm9'0],9)) val acctype = if (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1)) then AccType_UNPRIV else AccType_NORMAL in LoadStoreImmediate (BitsN.fromBitstring([size'1,size'0],2), (BitsN.fromBitstring([opc'1,opc'0],2), (acctype, (wback, (postindex, (false, (offset, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5))))))))) end | (size'1, (size'0, (true, (true, (true, (false, (false, (true, (opc'1, (opc'0, (imm12'11, (imm12'10, (imm12'9, (imm12'8, (imm12'7, (imm12'6, (imm12'5, (imm12'4, (imm12'3, (imm12'2, (imm12'1, (imm12'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => let val size = BitsN.fromBitstring([size'1,size'0],2) val wback = false val postindex = false val offset = BitsN.<< (BitsN.zeroExtend 64 (BitsN.fromBitstring ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,imm12'6, imm12'5,imm12'4,imm12'3,imm12'2,imm12'1,imm12'0],12)), BitsN.toNat size) val acctype = AccType_NORMAL in LoadStoreImmediate (size, (BitsN.fromBitstring([opc'1,opc'0],2), (acctype, (wback, (postindex, (true, (offset, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5))))))))) end | (true, (_, (true, (true, (true, (false, (false, (false, (true, (true, (true, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (option'2, (option'1, (option'0, (S'0, (true, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (size'1, (size'0, (true, (true, (true, (false, (false, (false, (opc'1, (opc'0, (true, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (false, (false, (_, (S'0, (true, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Reserved | (size'1, (size'0, (true, (true, (true, (false, (false, (false, (opc'1, (opc'0, (true, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (true, (false, (_, (S'0, (true, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Reserved | (size'1, (size'0, (true, (true, (true, (false, (false, (false, (opc'1, (opc'0, (true, (Rm'4, (Rm'3, (Rm'2, (Rm'1, (Rm'0, (option'2, (option'1, (option'0, (S'0, (true, (false, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => let val opc = BitsN.fromBitstring([opc'1,opc'0],2) val size = BitsN.fromBitstring([size'1,size'0],2) val scale = BitsN.toNat size val extend_type = DecodeRegExtend (BitsN.fromBitstring([option'2,option'1,option'0],3)) val shift = if (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1)) then scale else 0 val (memop,(regsize_word,signed)) = if not(BitsN.bit(opc,1)) then (if BitsN.bit(opc,0) then MemOp_LOAD else MemOp_STORE, (not(size = (BitsN.B(0x3,2))),false)) else if size = (BitsN.B(0x3,2)) then (MemOp_PREFETCH,(false,false)) else (MemOp_LOAD,(BitsN.bit(opc,0),true)) in LoadStoreRegister (size, (regsize_word, (memop, (signed, (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5), (extend_type, (shift, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5))))))))) end | (opc'1, (opc'0, (false, (true, (true, (false, (false, (false, (imm19'18, (imm19'17, (imm19'16, (imm19'15, (imm19'14, (imm19'13, (imm19'12, (imm19'11, (imm19'10, (imm19'9, (imm19'8, (imm19'7, (imm19'6, (imm19'5, (imm19'4, (imm19'3, (imm19'2, (imm19'1, (imm19'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => let val Rt = BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5) val offset = BitsN.signExtend 64 (BitsN.@@ (BitsN.fromBitstring ([imm19'18,imm19'17,imm19'16,imm19'15,imm19'14,imm19'13, imm19'12,imm19'11,imm19'10,imm19'9,imm19'8,imm19'7, imm19'6,imm19'5,imm19'4,imm19'3,imm19'2,imm19'1,imm19'0], 19),BitsN.B(0x0,2))) in case BitsN.fromBitstring([opc'1,opc'0],2) of BitsN.B(0x0,_) => LoadStore (LoadLiteral''32 (BitsN.B(0x0,32),(MemOp_LOAD,(false,(offset,Rt))))) | BitsN.B(0x1,_) => LoadStore (LoadLiteral''64 (BitsN.B(0x1,64),(MemOp_LOAD,(false,(offset,Rt))))) | BitsN.B(0x2,_) => LoadStore (LoadLiteral''32 (BitsN.B(0x2,32),(MemOp_LOAD,(true,(offset,Rt))))) | BitsN.B(0x3,_) => LoadStore (LoadLiteral''32 (BitsN.B(0x3,32),(MemOp_PREFETCH,(false,(offset,Rt))))) | _ => raise General.Bind end | (_, (true, (true, (false, (true, (false, (false, (_, (_, (false, (imm7'6, (imm7'5, (imm7'4, (imm7'3, (imm7'2, (imm7'1, (imm7'0, (Rt2'4, (Rt2'3, (Rt2'2, (Rt2'1, (Rt2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (true, (true, (true, (false, (true, (false, (false, (_, (_, (_, (imm7'6, (imm7'5, (imm7'4, (imm7'3, (imm7'2, (imm7'1, (imm7'0, (Rt2'4, (Rt2'3, (Rt2'2, (Rt2'1, (Rt2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (sf'0, (S'0, (true, (false, (true, (false, (false, (false, (false, (L'0, (imm7'6, (imm7'5, (imm7'4, (imm7'3, (imm7'2, (imm7'1, (imm7'0, (Rt2'4, (Rt2'3, (Rt2'2, (Rt2'1, (Rt2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (sf'0, (S'0, (true, (false, (true, (false, (false, (P'0, (W'0, (L'0, (imm7'6, (imm7'5, (imm7'4, (imm7'3, (imm7'2, (imm7'1, (imm7'0, (Rt2'4, (Rt2'3, (Rt2'2, (Rt2'1, (Rt2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => let val sf = BitsN.fromBitstring([sf'0],1) val wback = (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1)) val signed = (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1)) val postindex = (BitsN.fromBitstring([P'0],1)) = (BitsN.B(0x0,1)) val nontemporal = (not(wback orelse signed)) andalso postindex val postindex = (not nontemporal) andalso postindex val acctype = if nontemporal then AccType_STREAM else AccType_NORMAL val scale = Nat.+(2,BitsN.toNat sf) val offset = BitsN.<< (BitsN.signExtend 64 (BitsN.fromBitstring ([imm7'6,imm7'5,imm7'4,imm7'3,imm7'2,imm7'1,imm7'0],7)), scale) val memop = if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1)) then MemOp_LOAD else MemOp_STORE in LoadStorePair (sf, (memop, (acctype, (signed, (wback, (postindex, (offset, (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), (BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5), BitsN.fromBitstring([Rt2'4,Rt2'3,Rt2'2,Rt2'1,Rt2'0],5)))))))))) end | (size'1, (size'0, (false, (false, (true, (false, (false, (false, (true, (L'0, (false, (Rs'4, (Rs'3, (Rs'2, (Rs'1, (Rs'0, (false, (Rt2'4, (Rt2'3, (Rt2'2, (Rt2'1, (Rt2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (size'1, (size'0, (false, (false, (true, (false, (false, (false, (true, (L'0, (true, (Rs'4, (Rs'3, (Rs'2, (Rs'1, (Rs'0, (_, (Rt2'4, (Rt2'3, (Rt2'2, (Rt2'1, (Rt2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (false, (_, (false, (false, (true, (false, (false, (false, (o2'0, (L'0, (true, (Rs'4, (Rs'3, (Rs'2, (Rs'1, (Rs'0, (o0'0, (Rt2'4, (Rt2'3, (Rt2'2, (Rt2'1, (Rt2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => Unallocated | (size'1, (size'0, (false, (false, (true, (false, (false, (false, (o2'0, (L'0, (o1'0, (Rs'4, (Rs'3, (Rs'2, (Rs'1, (Rs'0, (o0'0, (Rt2'4, (Rt2'3, (Rt2'2, (Rt2'1, (Rt2'0, (Rn'4, (Rn'3, (Rn'2, (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => let val memop = if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1)) then MemOp_LOAD else MemOp_STORE val acctype = if (BitsN.fromBitstring([o0'0],1)) = (BitsN.B(0x1,1)) then AccType_ORDERED else AccType_ATOMIC val excl = (BitsN.fromBitstring([o2'0],1)) = (BitsN.B(0x0,1)) val pair = (BitsN.fromBitstring([o1'0],1)) = (BitsN.B(0x1,1)) in LoadStoreAcquire (BitsN.fromBitstring([size'1,size'0],2), (memop, (acctype, (excl, (pair, (BitsN.fromBitstring([Rs'4,Rs'3,Rs'2,Rs'1,Rs'0],5), (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5), (BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5), BitsN.fromBitstring([Rt2'4,Rt2'3,Rt2'2,Rt2'1,Rt2'0],5))))))))) end | (true, (true, (false, (true, (false, (true, (false, (true, (false, (false, (L'0, (true, (o0'0, (op1'2, (op1'1, (op1'0, (CRn'3, (CRn'2, (CRn'1, (CRn'0, (CRm'3, (CRm'2, (CRm'1, (CRm'0, (op2'2, (op2'1, (op2'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => System (MoveSystemRegister ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([L'0],1)), (BitsN.+ (BitsN.B(0x2,3), BitsN.fromNat(BitsN.toNat(BitsN.fromBitstring([o0'0],1)),3)), (BitsN.fromBitstring([op1'2,op1'1,op1'0],3), (BitsN.fromBitstring([op2'2,op2'1,op2'0],3), (BitsN.fromBitstring([CRn'3,CRn'2,CRn'1,CRn'0],4), (BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4), BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5)))))))) | (true, (true, (false, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (false, (false, (false, (false, (true, (false, (false, (CRm'3, (CRm'2, (CRm'1, (CRm'0, (true, (false,(true,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) => System (MoveImmediateProcState (PSTATEField_SP,BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4))) | (true, (true, (false, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (false, (true, (true, (false, (true, (false, (false, (CRm'3, (CRm'2, (CRm'1, (CRm'0, (true, (true,(false,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) => System (MoveImmediateProcState (PSTATEField_DAIFSet, BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4))) | (true, (true, (false, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (false, (true, (true, (false, (true, (false, (false, (CRm'3, (CRm'2, (CRm'1, (CRm'0, (true, (true,(true,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) => System (MoveImmediateProcState (PSTATEField_DAIFClr, BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4))) | (true, (true, (false, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (false, (true, (true, (false, (false, (true, (true, (CRm'3, (CRm'2, (CRm'1, (CRm'0, (true, (true,(true,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) => Unallocated | (true, (true, (false, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (false, (true, (true, (false, (false, (true, (true, (CRm'3, (CRm'2, (CRm'1, (CRm'0, (true, (opc'1, (opc'0,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) => MemoryBarrier ((Cast.natToMemBarrierOp o BitsN.toNat) (BitsN.fromBitstring([opc'1,opc'0],2)), BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4)) | (true, (true, (false, (true, (false, (true, (false, (false, (false, (false, (true, (imm16'15, (imm16'14, (imm16'13, (imm16'12, (imm16'11, (imm16'10, (imm16'9, (imm16'8, (imm16'7, (imm16'6, (imm16'5, (imm16'4, (imm16'3, (imm16'2, (imm16'1, (imm16'0, (false,(false,(false,(false,false))))))))))))))))))))))))))))))) => Debug (Breakpoint (BitsN.fromBitstring ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10, imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3, imm16'2,imm16'1,imm16'0],16))) | (true, (true, (false, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (false, (true, (true, (false, (false, (true, (false, (CRm'3, (CRm'2, (CRm'1, (CRm'0, (op2'2, (op2'1, (op2'0,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) => let val op2 = BitsN.fromBitstring([op2'2,op2'1,op2'0],3) val op' = if ((BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4)) = (BitsN.B(0x0,4))) andalso (BitsN.<+(op2,BitsN.B(0x6,3))) then (Cast.natToSystemHintOp o BitsN.toNat) op2 else SystemHintOp_NOP in Hint op' end | (true, (true, (false, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (false, (true, (true, (false, (false, (true, (true, (CRm'3, (CRm'2, (CRm'1, (CRm'0, (false, (true,(false,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) => ClearExclusive(BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4)) | (true, (true, (false, (true, (false, (true, (true, (false, (true, (false, (true, (true, (true, (true, (true, (true, (false, (false, (false, (false, (false, (false, (true, (true, (true, (true, (true,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) => Debug DebugRestore | (true, (true, (false, (true, (false, (true, (false, (false, (true, (false, (true, (imm16'15, (imm16'14, (imm16'13, (imm16'12, (imm16'11, (imm16'10, (imm16'9, (imm16'8, (imm16'7, (imm16'6, (imm16'5, (imm16'4, (imm16'3, (imm16'2, (imm16'1, (imm16'0,(false,(false,(false,(LL'1,LL'0))))))))))))))))))))))))))))))) => Debug(DebugSwitch(BitsN.fromBitstring([LL'1,LL'0],2))) | (true, (true, (false, (true, (false, (true, (false, (false, (false, (true, (false, (imm16'15, (imm16'14, (imm16'13, (imm16'12, (imm16'11, (imm16'10, (imm16'9, (imm16'8, (imm16'7, (imm16'6, (imm16'5, (imm16'4, (imm16'3, (imm16'2, (imm16'1, (imm16'0, (false,(false,(false,(false,false))))))))))))))))))))))))))))))) => Debug (Halt (BitsN.fromBitstring ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10, imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3, imm16'2,imm16'1,imm16'0],16))) | (true, (true, (false, (true, (false, (true, (true, (false, (true, (false, (false, (true, (true, (true, (true, (true, (false, (false, (false, (false, (false, (false, (true, (true, (true, (true, (true,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) => System ExceptionReturn | (true, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (imm16'15, (imm16'14, (imm16'13, (imm16'12, (imm16'11, (imm16'10, (imm16'9, (imm16'8, (imm16'7, (imm16'6, (imm16'5, (imm16'4, (imm16'3, (imm16'2, (imm16'1, (imm16'0,(false,(false,(false,(false,true))))))))))))))))))))))))))))))) => System (SupervisorCall (BitsN.fromBitstring ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10, imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3, imm16'2,imm16'1,imm16'0],16))) | (true, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (imm16'15, (imm16'14, (imm16'13, (imm16'12, (imm16'11, (imm16'10, (imm16'9, (imm16'8, (imm16'7, (imm16'6, (imm16'5, (imm16'4, (imm16'3, (imm16'2, (imm16'1, (imm16'0,(false,(false,(false,(true,false))))))))))))))))))))))))))))))) => System (HypervisorCall (BitsN.fromBitstring ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10, imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3, imm16'2,imm16'1,imm16'0],16))) | (true, (true, (false, (true, (false, (true, (false, (false, (false, (false, (false, (imm16'15, (imm16'14, (imm16'13, (imm16'12, (imm16'11, (imm16'10, (imm16'9, (imm16'8, (imm16'7, (imm16'6, (imm16'5, (imm16'4, (imm16'3, (imm16'2, (imm16'1, (imm16'0,(false,(false,(false,(true,true))))))))))))))))))))))))))))))) => System (SecureMonitorCall (BitsN.fromBitstring ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10, imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3, imm16'2,imm16'1,imm16'0],16))) | (true, (true, (false, (true, (false, (true, (false, (true, (false, (false, (L'0, (false, (true, (op1'2, (op1'1, (op1'0, (CRn'3, (CRn'2, (CRn'1, (CRn'0, (CRm'3, (CRm'2, (CRm'1, (CRm'0, (op2'2, (op2'1, (op2'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) => System (SystemInstruction (BitsN.fromBitstring([op1'2,op1'1,op1'0],3), (BitsN.fromBitstring([op2'2,op2'1,op2'0],3), (BitsN.fromBitstring([CRn'3,CRn'2,CRn'1,CRn'0],4), (BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4), ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([L'0],1)), BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5))))))) | _ => Unallocated; fun Fetch () = Mem 32 ((!PC),(4,AccType_IFETCH)); fun Next () = ( branch_hint := NONE ; Run(Decode(Fetch ())) ; if not(Option.isSome (!branch_hint)) then PC := (BitsN.+((!PC),BitsN.B(0x4,64))) else () ); fun CountTrailing N (b,w) = if ((BitsN.bit(w,0)) = b) orelse (if b then w = (BitsN.BV(0x0,N)) else w = (BitsN.neg(BitsN.BV(0x1,N)))) then 0 else Nat.+(1,CountTrailing N (b,BitsN.>>+(w,1))); fun EncodeBitMaskAux N imm = let val pref0 = CountTrailing N (true,imm) in if pref0 = 0 then let val pref1 = CountTrailing N (false,imm) val run0 = CountTrailing N (true,BitsN.#>>(imm,pref1)) val run1 = CountTrailing N (false,BitsN.#>>(imm,Nat.+(pref1,run0))) in (Nat.+(run0,run1),(run1,Nat.-(run1,pref1))) end else let val run1 = CountTrailing N (false,BitsN.#>>(imm,pref0)) val run0 = CountTrailing N (true,BitsN.#>>(imm,Nat.+(pref0,run1))) in (Nat.+(run0,run1),(run1,Nat.-(Nat.+(run0,run1),pref0))) end end; fun EncodeBitMask N imm = let val (e,(S,R)) = EncodeBitMaskAux N imm val (immN,(imms,immr)) = if e = 64 then (BitsN.B(0x1,1), (BitsN.fromNat(Nat.-(S,1),6),BitsN.fromNat(R,6))) else (BitsN.B(0x0,1), (BitsN.|| (BitsN.~(BitsN.fromNat(Nat.-(Nat.*(e,2),1),6)), BitsN.fromNat(Nat.-(S,1),6)),BitsN.fromNat(R,6))) in case DecodeBitMasks N (immN,(imms,(immr,true))) of Option.SOME(imm2,_) => (if imm = imm2 then Option.SOME(immN,(imms,immr)) else NONE) | NONE => NONE end; fun e_sf N sf = BitsN.fromBit((BitsN.size(BitsN.BV(0x0,N))) = 64); fun EncodeLogicalOp (opc,setflags) = case (opc,setflags) of (LogicalOp_AND,false) => Option.SOME(BitsN.B(0x0,2)) | (LogicalOp_ORR,false) => Option.SOME(BitsN.B(0x1,2)) | (LogicalOp_EOR,false) => Option.SOME(BitsN.B(0x2,2)) | (LogicalOp_AND,true) => Option.SOME(BitsN.B(0x3,2)) | _ => NONE; fun e_data i = case i of AddSubShiftedRegister''32(_,(opc,(s,(sh,(rm,(imm6,(rn,rd))))))) => (if BitsN.bit(imm6,5) then BadCode "AddSubShiftedRegister32" else ARM8 (BitsN.concat [BitsN.B(0x0,1),BitsN.fromBit opc,BitsN.fromBit s, BitsN.B(0xB,5),BitsN.fromNat(Cast.ShiftTypeToNat sh,2), BitsN.B(0x0,1),rm,imm6,rn,rd])) | AddSubShiftedRegister''64(_,(opc,(s,(sh,(rm,(imm6,(rn,rd))))))) => ARM8 (BitsN.concat [BitsN.B(0x1,1),BitsN.fromBit opc,BitsN.fromBit s, BitsN.B(0xB,5),BitsN.fromNat(Cast.ShiftTypeToNat sh,2), BitsN.B(0x0,1),rm,imm6,rn,rd]) | AddSubExtendRegister''32(sf,(opc,(s,(rm,(sty,(imm3,(rn,rd))))))) => ARM8 (BitsN.concat [e_sf 32 sf,BitsN.fromBit opc,BitsN.fromBit s,BitsN.B(0x59,8), rm,BitsN.fromNat(Cast.ExtendTypeToNat sty,3),imm3,rn,rd]) | AddSubExtendRegister''64(sf,(opc,(s,(rm,(sty,(imm3,(rn,rd))))))) => ARM8 (BitsN.concat [e_sf 64 sf,BitsN.fromBit opc,BitsN.fromBit s,BitsN.B(0x59,8), rm,BitsN.fromNat(Cast.ExtendTypeToNat sty,3),imm3,rn,rd]) | AddSubImmediate''32(sf,(opc,(s,(imm,(rn,rd))))) => (if (BitsN.&&(imm,BitsN.~(BitsN.B(0xFFF,32)))) = (BitsN.B(0x0,32)) then ARM8 (BitsN.concat [e_sf 32 sf,BitsN.fromBit opc,BitsN.fromBit s, BitsN.B(0x44,7),BitsN.bits(11,0) imm,rn,rd]) else if (BitsN.&&(imm,BitsN.~(BitsN.B(0xFFF000,32)))) = (BitsN.B(0x0,32)) then ARM8 (BitsN.concat [e_sf 32 sf,BitsN.fromBit opc,BitsN.fromBit s, BitsN.B(0x45,7),BitsN.bits(23,12) imm,rn,rd]) else BadCode "AddSubImmediate") | AddSubImmediate''64(sf,(opc,(s,(imm,(rn,rd))))) => (if (BitsN.&&(imm,BitsN.~(BitsN.B(0xFFF,64)))) = (BitsN.B(0x0,64)) then ARM8 (BitsN.concat [e_sf 64 sf,BitsN.fromBit opc,BitsN.fromBit s, BitsN.B(0x44,7),BitsN.bits(11,0) imm,rn,rd]) else if (BitsN.&&(imm,BitsN.~(BitsN.B(0xFFF000,64)))) = (BitsN.B(0x0,64)) then ARM8 (BitsN.concat [e_sf 64 sf,BitsN.fromBit opc,BitsN.fromBit s, BitsN.B(0x45,7),BitsN.bits(23,12) imm,rn,rd]) else BadCode "AddSubImmediate") | AddSubCarry''32(_,(opc,(s,(rm,(rn,rd))))) => ARM8 (BitsN.concat [BitsN.B(0x0,1),BitsN.fromBit opc,BitsN.fromBit s, BitsN.B(0xD0,8),rm,BitsN.B(0x0,6),rn,rd]) | AddSubCarry''64(_,(opc,(s,(rm,(rn,rd))))) => ARM8 (BitsN.concat [BitsN.B(0x1,1),BitsN.fromBit opc,BitsN.fromBit s, BitsN.B(0xD0,8),rm,BitsN.B(0x0,6),rn,rd]) | LogicalShiftedRegister''32 (sf,(opc,(invert,(s,(sh,(imm,(rm,(rn,rd)))))))) => (case EncodeLogicalOp(opc,s) of Option.SOME opc => let val imm6 = BitsN.fromNat(imm,6) in if imm = (BitsN.toNat imm6) then ARM8 (BitsN.concat [e_sf 32 sf,opc,BitsN.B(0xA,5), BitsN.fromNat(Cast.ShiftTypeToNat sh,2), BitsN.fromBit invert,rm,imm6,rn,rd]) else BadCode "LogicalShiftedRegister" end | NONE => BadCode "LogicalShiftedRegister") | LogicalShiftedRegister''64 (sf,(opc,(invert,(s,(sh,(imm,(rm,(rn,rd)))))))) => (case EncodeLogicalOp(opc,s) of Option.SOME opc => let val imm6 = BitsN.fromNat(imm,6) in if imm = (BitsN.toNat imm6) then ARM8 (BitsN.concat [e_sf 64 sf,opc,BitsN.B(0xA,5), BitsN.fromNat(Cast.ShiftTypeToNat sh,2), BitsN.fromBit invert,rm,imm6,rn,rd]) else BadCode "LogicalShiftedRegister" end | NONE => BadCode "LogicalShiftedRegister") | LogicalImmediate''32(_,(opc,(s,(imm,(rn,rd))))) => (case (EncodeBitMask 32 imm,EncodeLogicalOp(opc,s)) of (Option.SOME(_,(imms,immr)),Option.SOME opc) => ARM8 (BitsN.concat [BitsN.B(0x0,1),opc,BitsN.B(0x48,7),immr,imms,rn,rd]) | _ => BadCode "LogicalImmediate32") | LogicalImmediate''64(_,(opc,(s,(imm,(rn,rd))))) => (case (EncodeBitMask 64 imm,EncodeLogicalOp(opc,s)) of (Option.SOME(N,(imms,immr)),Option.SOME opc) => ARM8 (BitsN.concat [BitsN.B(0x1,1),opc,BitsN.B(0x24,6),N,immr,imms,rn,rd]) | _ => BadCode "LogicalImmediate64") | Shift''32(_,(sh,(rm,(rn,rd)))) => ARM8 (BitsN.concat [BitsN.B(0xD6,11),rm,BitsN.B(0x2,4), BitsN.fromNat(Cast.ShiftTypeToNat sh,2),rn,rd]) | Shift''64(_,(sh,(rm,(rn,rd)))) => ARM8 (BitsN.concat [BitsN.B(0x4D6,11),rm,BitsN.B(0x2,4), BitsN.fromNat(Cast.ShiftTypeToNat sh,2),rn,rd]) | MoveWide''32(_,(opc,(hw,(imm16,rd)))) => let val opc = case opc of MoveWideOp_N => BitsN.B(0x0,2) | MoveWideOp_Z => BitsN.B(0x2,2) | MoveWideOp_K => BitsN.B(0x3,2) in ARM8(BitsN.concat[BitsN.B(0x0,1),opc,BitsN.B(0x25,6),hw,imm16,rd]) end | MoveWide''64(_,(opc,(hw,(imm16,rd)))) => let val opc = case opc of MoveWideOp_N => BitsN.B(0x0,2) | MoveWideOp_Z => BitsN.B(0x2,2) | MoveWideOp_K => BitsN.B(0x3,2) in ARM8(BitsN.concat[BitsN.B(0x1,1),opc,BitsN.B(0x25,6),hw,imm16,rd]) end | BitfieldMove''32 (sf,(inzero,(extend,(wmask,(tmask,(immr,(imms,(rn,rd)))))))) => let val sz = e_sf 32 sf val opc = case (inzero,extend) of (true,true) => Option.SOME(BitsN.B(0x0,2)) | (false,false) => Option.SOME(BitsN.B(0x1,2)) | (true,false) => Option.SOME(BitsN.B(0x2,2)) | _ => NONE in case opc of Option.SOME opc => let val r = BitsN.fromNat(immr,6) val s = BitsN.fromNat(imms,6) in if (immr = (BitsN.toNat r)) andalso ((imms = (BitsN.toNat s)) andalso ((DecodeBitMasks 32 (sz,(s,(r,false)))) = (Option.SOME(wmask,tmask)))) then ARM8 (BitsN.concat[sz,opc,BitsN.B(0x26,6),sz,r,s,rn,rd]) else BadCode "BitfieldMove" end | NONE => BadCode "BitfieldMove" end | BitfieldMove''64 (sf,(inzero,(extend,(wmask,(tmask,(immr,(imms,(rn,rd)))))))) => let val sz = e_sf 64 sf val opc = case (inzero,extend) of (true,true) => Option.SOME(BitsN.B(0x0,2)) | (false,false) => Option.SOME(BitsN.B(0x1,2)) | (true,false) => Option.SOME(BitsN.B(0x2,2)) | _ => NONE in case opc of Option.SOME opc => let val r = BitsN.fromNat(immr,6) val s = BitsN.fromNat(imms,6) in if (immr = (BitsN.toNat r)) andalso ((imms = (BitsN.toNat s)) andalso ((DecodeBitMasks 64 (sz,(s,(r,false)))) = (Option.SOME(wmask,tmask)))) then ARM8 (BitsN.concat[sz,opc,BitsN.B(0x26,6),sz,r,s,rn,rd]) else BadCode "BitfieldMove" end | NONE => BadCode "BitfieldMove" end | ConditionalCompareImmediate''32 (sf,(opc,(imm,(cd,((n,(z,(c,v))),rn))))) => let val imm5 = BitsN.fromNat(BitsN.toNat imm,5) in if imm = (BitsN.fromNat(BitsN.toNat imm5,32)) then ARM8 (BitsN.concat [e_sf 32 sf,BitsN.fromBit opc,BitsN.B(0x1D2,9),imm5,cd, BitsN.B(0x2,2),rn,BitsN.B(0x0,1),BitsN.fromBit n, BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v]) else BadCode "ConditionalCompareImmediate" end | ConditionalCompareImmediate''64 (sf,(opc,(imm,(cd,((n,(z,(c,v))),rn))))) => let val imm5 = BitsN.fromNat(BitsN.toNat imm,5) in if imm = (BitsN.fromNat(BitsN.toNat imm5,64)) then ARM8 (BitsN.concat [e_sf 64 sf,BitsN.fromBit opc,BitsN.B(0x1D2,9),imm5,cd, BitsN.B(0x2,2),rn,BitsN.B(0x0,1),BitsN.fromBit n, BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v]) else BadCode "ConditionalCompareImmediate" end | ConditionalCompareRegister''32(sf,(opc,(cd,((n,(z,(c,v))),(rm,rn))))) => ARM8 (BitsN.concat [e_sf 32 sf,BitsN.fromBit opc,BitsN.B(0x1D2,9),rm,cd, BitsN.B(0x0,2),rn,BitsN.B(0x0,1),BitsN.fromBit n, BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v]) | ConditionalCompareRegister''64(sf,(opc,(cd,((n,(z,(c,v))),(rm,rn))))) => ARM8 (BitsN.concat [e_sf 64 sf,BitsN.fromBit opc,BitsN.B(0x1D2,9),rm,cd, BitsN.B(0x0,2),rn,BitsN.B(0x0,1),BitsN.fromBit n, BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v]) | ConditionalSelect''32(_,(op',(o2,(cd,(rm,(rn,rd)))))) => ARM8 (BitsN.concat [BitsN.B(0x0,1),BitsN.fromBit op',BitsN.B(0xD4,9),rm,cd, BitsN.B(0x0,1),BitsN.fromBit o2,rn,rd]) | ConditionalSelect''64(_,(op',(o2,(cd,(rm,(rn,rd)))))) => ARM8 (BitsN.concat [BitsN.B(0x1,1),BitsN.fromBit op',BitsN.B(0xD4,9),rm,cd, BitsN.B(0x0,1),BitsN.fromBit o2,rn,rd]) | CountLeading''32(_,(op',(rn,rd))) => ARM8(BitsN.concat[BitsN.B(0xB5802,21),BitsN.fromBit op',rn,rd]) | CountLeading''64(_,(op',(rn,rd))) => ARM8(BitsN.concat[BitsN.B(0x1B5802,21),BitsN.fromBit op',rn,rd]) | ExtractRegister''32(_,(imms,(rm,(rn,rd)))) => (if BitsN.bit(imms,5) then BadCode "ExtractRegister32" else ARM8(BitsN.concat[BitsN.B(0x9C,11),rm,imms,rn,rd])) | ExtractRegister''64(_,(imms,(rm,(rn,rd)))) => ARM8(BitsN.concat[BitsN.B(0x49E,11),rm,imms,rn,rd]) | Division''32(_,(o1,(rm,(rn,rd)))) => ARM8 (BitsN.concat [BitsN.B(0xD6,11),rm,BitsN.B(0x1,5),BitsN.fromBit(not o1),rn,rd]) | Division''64(_,(o1,(rm,(rn,rd)))) => ARM8 (BitsN.concat [BitsN.B(0x4D6,11),rm,BitsN.B(0x1,5),BitsN.fromBit(not o1),rn,rd]) | MultiplyAddSub''32(_,(o0,(rm,(ra,(rn,rd))))) => ARM8(BitsN.concat[BitsN.B(0xD8,11),rm,BitsN.fromBit o0,ra,rn,rd]) | MultiplyAddSub''64(_,(o0,(rm,(ra,(rn,rd))))) => ARM8(BitsN.concat[BitsN.B(0x4D8,11),rm,BitsN.fromBit o0,ra,rn,rd]) | MultiplyAddSubLong(o0,(u,(rm,(ra,(rn,rd))))) => ARM8 (BitsN.concat [BitsN.B(0x9B,8),BitsN.fromBit(not u),BitsN.B(0x1,2),rm, BitsN.fromBit o0,ra,rn,rd]) | MultiplyHigh(u,(rm,(rn,rd))) => ARM8 (BitsN.concat [BitsN.B(0x9B,8),BitsN.fromBit(not u),BitsN.B(0x2,2),rm, BitsN.B(0x1F,6),rn,rd]) | Reverse''32(_,(opc,(rn,rd))) => (if opc = RevOp_REV64 then BadCode "Reverse32" else ARM8 (BitsN.concat [BitsN.B(0x5AC00,20),BitsN.fromNat(Cast.RevOpToNat opc,2), rn,rd])) | Reverse''64(_,(opc,(rn,rd))) => ARM8 (BitsN.concat [BitsN.B(0xDAC00,20),BitsN.fromNat(Cast.RevOpToNat opc,2),rn,rd]); fun e_debug i = case i of Breakpoint imm16 => BitsN.concat[BitsN.B(0x6A1,11),imm16,BitsN.B(0x0,5)] | DebugRestore => BitsN.B(0xD6BF03E0,32) | DebugSwitch LL => BitsN.concat[BitsN.B(0x6A5,11),BitsN.B(0x0,16),BitsN.B(0x0,3),LL] | Halt imm16 => BitsN.concat[BitsN.B(0x6A2,11),imm16,BitsN.B(0x0,5)]; fun e_crc i = case i of CRC''8(_,(c,(rm,(rn,rd)))) => BitsN.concat [BitsN.B(0xD6,11),rm,BitsN.B(0x2,3),BitsN.fromBit c, BitsN.B(0x0,2),rn,rd] | CRC''16(_,(c,(rm,(rn,rd)))) => BitsN.concat [BitsN.B(0xD6,11),rm,BitsN.B(0x2,3),BitsN.fromBit c,BitsN.B(0x1,2), rn,rd] | CRC''32(_,(c,(rm,(rn,rd)))) => BitsN.concat [BitsN.B(0xD6,11),rm,BitsN.B(0x2,3),BitsN.fromBit c,BitsN.B(0x2,2), rn,rd] | CRC''64(_,(c,(rm,(rn,rd)))) => BitsN.concat [BitsN.B(0x4D6,11),rm,BitsN.B(0x2,3),BitsN.fromBit c, BitsN.B(0x3,2),rn,rd]; fun e_branch i = case i of BranchConditional(imm,cd) => let val imm19 = BitsN.bits(20,2) imm in if imm = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2)))) then ARM8 (BitsN.concat[BitsN.B(0x54,8),imm19,BitsN.B(0x0,1),cd]) else BadCode "BranchConditional" end | BranchImmediate(imm,btype) => let val imm26 = BitsN.bits(27,2) imm in if (imm = (BitsN.signExtend 64 (BitsN.@@(imm26,BitsN.B(0x0,2))))) andalso (Set.mem(btype,[BranchType_CALL,BranchType_JMP])) then ARM8 (BitsN.concat [BitsN.fromBit(btype = BranchType_CALL),BitsN.B(0x5,5), imm26]) else BadCode "BranchImmediate" end | BranchRegister(rn,btype) => let val opc = case btype of BranchType_JMP => BitsN.B(0x0,2) | BranchType_CALL => BitsN.B(0x1,2) | BranchType_RET => BitsN.B(0x2,2) | _ => BitsN.B(0x3,2) in if opc = (BitsN.B(0x3,2)) then BadCode "BranchRegister" else ARM8 (BitsN.concat [BitsN.B(0x1AC,9),opc,BitsN.B(0x7C0,11),rn,BitsN.B(0x0,5)]) end | CompareAndBranch''32(_,(iszero,(offset,rt))) => let val imm19 = BitsN.bits(20,2) offset in if offset = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2)))) then ARM8 (BitsN.concat [BitsN.B(0x1A,7),BitsN.fromBit(not iszero),imm19,rt]) else BadCode "CompareAndBranch32" end | CompareAndBranch''64(_,(iszero,(offset,rt))) => let val imm19 = BitsN.bits(20,2) offset in if offset = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2)))) then ARM8 (BitsN.concat [BitsN.B(0x5A,7),BitsN.fromBit(not iszero),imm19,rt]) else BadCode "CompareAndBranch64" end | TestBitAndBranch''32(_,(bit_pos,(bit_val,(offset,rt)))) => let val imm14 = BitsN.bits(15,2) offset in if (offset = (BitsN.signExtend 64 (BitsN.@@(imm14,BitsN.B(0x0,2))))) andalso (not(BitsN.bit(bit_pos,5))) then ARM8 (BitsN.concat [BitsN.B(0x1B,7),BitsN.fromBit bit_val, BitsN.bits(4,0) bit_pos,imm14,rt]) else BadCode "TestBitAndBranch32" end | TestBitAndBranch''64(_,(bit_pos,(bit_val,(offset,rt)))) => let val imm14 = BitsN.bits(15,2) offset in if (offset = (BitsN.signExtend 64 (BitsN.@@(imm14,BitsN.B(0x0,2))))) andalso (BitsN.bit(bit_pos,5)) then ARM8 (BitsN.concat [BitsN.B(0x5B,7),BitsN.fromBit bit_val, BitsN.bits(4,0) bit_pos,imm14,rt]) else BadCode "TestBitAndBranch64" end; fun e_system i = case i of MoveSystemRegister(l,(op0,(op1,(op2,(crn,(crm,rt)))))) => BitsN.concat [BitsN.B(0x354,10),BitsN.fromBit l,BitsN.B(0x1,1), BitsN.fromNat(BitsN.toNat(BitsN.-(op0,BitsN.B(0x2,3))),1),op1, crn,crm,op2,rt] | MoveImmediateProcState(PSTATEField_SP,crm) => BitsN.concat[BitsN.B(0xD5004,20),crm,BitsN.B(0xBF,8)] | MoveImmediateProcState(PSTATEField_DAIFSet,crm) => BitsN.concat[BitsN.B(0xD5034,20),crm,BitsN.B(0xDF,8)] | MoveImmediateProcState(PSTATEField_DAIFClr,crm) => BitsN.concat[BitsN.B(0xD5034,20),crm,BitsN.B(0xFF,8)] | ExceptionReturn => BitsN.B(0xD69F03E0,32) | SupervisorCall imm16 => BitsN.concat[BitsN.B(0x6A0,11),imm16,BitsN.B(0x1,5)] | HypervisorCall imm16 => BitsN.concat[BitsN.B(0x6A0,11),imm16,BitsN.B(0x2,5)] | SecureMonitorCall imm16 => BitsN.concat[BitsN.B(0x6A0,11),imm16,BitsN.B(0x3,5)] | SystemInstruction(op1,(op2,(crn,(crm,(l,rt))))) => BitsN.concat [BitsN.B(0x354,10),BitsN.fromBit l,BitsN.B(0x1,2),op1,crn,crm,op2, rt]; fun e_LoadStoreImmediate (size, (regsize_word, (memop, (acctype, (signed,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))) = let val sz = if memop = MemOp_PREFETCH then BitsN.B(0x3,2) else size val imm9 = BitsN.bits(8,0) offset val imm12 = BitsN.bits(11,0) (BitsN.>>+(offset,BitsN.toNat sz)) val opc = if memop = MemOp_STORE then BitsN.B(0x0,2) else if (memop = MemOp_LOAD) andalso (not signed) then BitsN.B(0x1,2) else BitsN.@@(BitsN.B(0x1,1),BitsN.fromBit regsize_word) in if wback then if (offset = (BitsN.signExtend 64 imm9)) andalso (acctype = AccType_NORMAL) then ARM8 (BitsN.concat [sz,BitsN.B(0x38,6),opc,BitsN.B(0x0,1),imm9, BitsN.fromBit(not postindex),BitsN.B(0x1,1),rn,rt]) else BadCode "LoadStoreImmediate" else if postindex then BadCode "LoadStoreImmediate" else if unsigned_offset andalso ((offset = (BitsN.<<(BitsN.zeroExtend 64 imm12,BitsN.toNat sz))) andalso (acctype = AccType_NORMAL)) then ARM8(BitsN.concat[sz,BitsN.B(0x39,6),opc,imm12,rn,rt]) else if offset = (BitsN.signExtend 64 imm9) then ARM8 (BitsN.concat [sz,BitsN.B(0x38,6),opc,BitsN.B(0x0,1),imm9, BitsN.fromBit(acctype = AccType_UNPRIV),BitsN.B(0x0,1), rn,rt]) else BadCode "LoadStoreImmediate" end; fun e_LoadStoreRegister (size,(regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) = let val opc = if memop = MemOp_STORE then BitsN.B(0x0,2) else if (memop = MemOp_LOAD) andalso (not signed) then BitsN.B(0x1,2) else BitsN.@@(BitsN.B(0x1,1),BitsN.fromBit regsize_word) val sz = if memop = MemOp_PREFETCH then BitsN.B(0x3,2) else size in ARM8 (BitsN.concat [sz,BitsN.B(0x38,6),opc,BitsN.B(0x1,1),rm, BitsN.fromNat(Cast.ExtendTypeToNat extend_type,3), BitsN.fromBit(not(shift = 0)),BitsN.B(0x2,2),rn,rt]) end; fun e_load_store i = case i of LoadStoreImmediate''8 (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) => e_LoadStoreImmediate (BitsN.fromNat(BitsN.toNat size,2), (regsize_word, (memop, (acctype, (signed, (wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))) | LoadStoreImmediate''16 (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) => e_LoadStoreImmediate (BitsN.fromNat(BitsN.toNat size,2), (regsize_word, (memop, (acctype, (signed,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))) | LoadStoreImmediate''32 (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) => e_LoadStoreImmediate (BitsN.fromNat(BitsN.toNat size,2), (regsize_word, (memop, (acctype, (signed,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))) | LoadStoreImmediate''64 (size, (regsize_word, (memop, (acctype, (signed, (wb_unknown, (rt_unknown, (wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) => e_LoadStoreImmediate (BitsN.fromNat(BitsN.toNat size,2), (regsize_word, (memop, (acctype, (signed,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))) | LoadStoreRegister''8 (size, (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) => e_LoadStoreRegister (BitsN.fromNat(BitsN.toNat size,2), (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) | LoadStoreRegister''16 (size, (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) => e_LoadStoreRegister (BitsN.fromNat(BitsN.toNat size,2), (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) | LoadStoreRegister''32 (size, (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) => e_LoadStoreRegister (BitsN.fromNat(BitsN.toNat size,2), (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) | LoadStoreRegister''64 (size, (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) => e_LoadStoreRegister (BitsN.fromNat(BitsN.toNat size,2), (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) | LoadLiteral''32(_,(memop,(signed,(offset,rt)))) => let val imm19 = BitsN.bits(20,2) offset val opc = case (memop,signed) of (MemOp_LOAD,false) => Option.SOME(BitsN.B(0x0,2)) | (MemOp_LOAD,true) => Option.SOME(BitsN.B(0x2,2)) | (MemOp_PREFETCH,false) => Option.SOME(BitsN.B(0x3,2)) | _ => NONE in if (Option.isSome opc) andalso (offset = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2))))) then ARM8 (BitsN.concat[Option.valOf opc,BitsN.B(0x18,6),imm19,rt]) else BadCode "LoadLiteral32" end | LoadLiteral''64(_,(MemOp_LOAD,(false,(offset,rt)))) => let val imm19 = BitsN.bits(20,2) offset in if offset = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2)))) then ARM8(BitsN.concat[BitsN.B(0x58,8),imm19,rt]) else BadCode "LoadLiteral64" end | LoadLiteral''64 _ => BadCode "LoadLiteral64" | LoadStorePair''32 (size, (memop, (acctype, (signed, (wb_unknown, (rt_unknown,(wback,(postindex,(offset,(rn,(rt,rt2))))))))))) => let val sf = BitsN.fromNat(BitsN.toNat size,1) val scale = Nat.+(2,BitsN.toNat sf) val imm7 = BitsN.bits(6,0) (BitsN.>>+(offset,scale)) in if ((sf = (BitsN.B(0x1,1))) = ((BitsN.size size) = 64)) andalso ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso ((Set.mem(acctype,[AccType_STREAM,AccType_NORMAL])) andalso (offset = (BitsN.<<(BitsN.signExtend 64 imm7,scale))))) then ARM8 (BitsN.concat [sf,BitsN.fromBit signed,BitsN.B(0x14,5), BitsN.fromBit(not postindex),BitsN.fromBit wback, BitsN.fromBit(memop = MemOp_LOAD),imm7,rt2,rn,rt]) else BadCode "LoadStorePair" end | LoadStorePair''64 (size, (memop, (acctype, (signed, (wb_unknown, (rt_unknown,(wback,(postindex,(offset,(rn,(rt,rt2))))))))))) => let val sf = BitsN.fromNat(BitsN.toNat size,1) val scale = Nat.+(2,BitsN.toNat sf) val imm7 = BitsN.bits(6,0) (BitsN.>>+(offset,scale)) in if ((sf = (BitsN.B(0x1,1))) = ((BitsN.size size) = 64)) andalso ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso ((Set.mem(acctype,[AccType_STREAM,AccType_NORMAL])) andalso (offset = (BitsN.<<(BitsN.signExtend 64 imm7,scale))))) then ARM8 (BitsN.concat [sf,BitsN.fromBit signed,BitsN.B(0x14,5), BitsN.fromBit(not postindex),BitsN.fromBit wback, BitsN.fromBit(memop = MemOp_LOAD),imm7,rt2,rn,rt]) else BadCode "LoadStorePair" end | LoadStoreAcquire''8 (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(rs,(rn,rt)))))))) => let val sizeok = case BitsN.size size of 8 => size = (BitsN.B(0x0,8)) | 16 => size = (BitsN.B(0x1,8)) | 32 => size = (BitsN.B(0x2,8)) | _ => size = (BitsN.B(0x3,8)) in if sizeok andalso ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC]))) then ARM8 (BitsN.concat [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x8,6), BitsN.fromBit(not excl), BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x0,1),rs, BitsN.fromBit(acctype = AccType_ORDERED), BitsN.B(0x1F,5),rn,rt]) else BadCode "LoadStoreAcquire" end | LoadStoreAcquire''16 (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(rs,(rn,rt)))))))) => let val sizeok = case BitsN.size size of 8 => size = (BitsN.B(0x0,16)) | 16 => size = (BitsN.B(0x1,16)) | 32 => size = (BitsN.B(0x2,16)) | _ => size = (BitsN.B(0x3,16)) in if sizeok andalso ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC]))) then ARM8 (BitsN.concat [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x8,6), BitsN.fromBit(not excl), BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x0,1),rs, BitsN.fromBit(acctype = AccType_ORDERED), BitsN.B(0x1F,5),rn,rt]) else BadCode "LoadStoreAcquire" end | LoadStoreAcquire''32 (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(rs,(rn,rt)))))))) => let val sizeok = case BitsN.size size of 8 => size = (BitsN.B(0x0,32)) | 16 => size = (BitsN.B(0x1,32)) | 32 => size = (BitsN.B(0x2,32)) | _ => size = (BitsN.B(0x3,32)) in if sizeok andalso ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC]))) then ARM8 (BitsN.concat [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x8,6), BitsN.fromBit(not excl), BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x0,1),rs, BitsN.fromBit(acctype = AccType_ORDERED), BitsN.B(0x1F,5),rn,rt]) else BadCode "LoadStoreAcquire" end | LoadStoreAcquire''64 (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(rs,(rn,rt)))))))) => let val sizeok = case BitsN.size size of 8 => size = (BitsN.B(0x0,64)) | 16 => size = (BitsN.B(0x1,64)) | 32 => size = (BitsN.B(0x2,64)) | _ => size = (BitsN.B(0x3,64)) in if sizeok andalso ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC]))) then ARM8 (BitsN.concat [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x8,6), BitsN.fromBit(not excl), BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x0,1),rs, BitsN.fromBit(acctype = AccType_ORDERED), BitsN.B(0x1F,5),rn,rt]) else BadCode "LoadStoreAcquire" end | LoadStoreAcquirePair''64 (size,(memop,(acctype,(rn_unknown,(rt_unknown,(rs,(rn,(rt,rt2)))))))) => let val sizeok = size = (if (BitsN.size size) = 64 then BitsN.B(0x2,64) else BitsN.B(0x3,64)) in if sizeok andalso ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC]))) then ARM8 (BitsN.concat [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x10,7), BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x1,1),rs, BitsN.fromBit(acctype = AccType_ORDERED),rt2,rn,rt]) else BadCode "LoadStoreAcquirePair" end | LoadStoreAcquirePair''128 (size,(memop,(acctype,(rn_unknown,(rt_unknown,(rs,(rn,(rt,rt2)))))))) => let val sizeok = size = (if (BitsN.size size) = 64 then BitsN.B(0x2,128) else BitsN.B(0x3,128)) in if sizeok andalso ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC]))) then ARM8 (BitsN.concat [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x10,7), BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x1,1),rs, BitsN.fromBit(acctype = AccType_ORDERED),rt2,rn,rt]) else BadCode "LoadStoreAcquirePair" end; fun Encode i = case i of Address(page,(imm,rd)) => (if page then let val immlo = BitsN.bits(13,12) imm val immhi = BitsN.bits(32,14) imm in if (BitsN.signExtend 64 (BitsN.concat[immhi,immlo,BitsN.B(0x0,12)])) = imm then ARM8 (BitsN.concat [BitsN.B(0x1,1),immlo,BitsN.B(0x10,5),immhi, rd]) else BadCode "Address" end else let val immlo = BitsN.bits(1,0) imm val immhi = BitsN.bits(20,2) imm in if (BitsN.signExtend 64 (BitsN.@@(immhi,immlo))) = imm then ARM8 (BitsN.concat [BitsN.B(0x0,1),immlo,BitsN.B(0x10,5),immhi,rd]) else BadCode "Address" end) | Data x => e_data x | Branch x => e_branch x | LoadStore x => e_load_store x | CRCExt x => ARM8(e_crc x) | Debug x => ARM8(e_debug x) | System x => ARM8(e_system x) | MemoryBarrier(opc,crm) => ARM8 (BitsN.concat [BitsN.B(0xD5033,20),crm,BitsN.B(0x1,1), BitsN.fromNat(Cast.MemBarrierOpToNat opc,2),BitsN.B(0x1F,5)]) | ClearExclusive crm => ARM8(BitsN.concat[BitsN.B(0xD5033,20),crm,BitsN.B(0x5F,8)]) | Hint opc => ARM8 (BitsN.concat [BitsN.B(0xD50320,24), BitsN.fromNat(Cast.SystemHintOpToNat opc,3),BitsN.B(0x1F,5)]) | Unallocated => BadCode "Unallocated" | Reserved => BadCode "Reserved"; fun skipSpaces s = L3.snd(L3.splitl(fn c => Char.isSpace c,s)); fun stripSpaces s = L3.fst(L3.splitr(fn c => Char.isSpace c,skipSpaces s)); fun p_number s = case String.explode(stripSpaces s) of #"0" :: (#"b" :: t) => Nat.fromBinString(String.implode t) | #"0" :: (#"x" :: t) => Nat.fromHexString(String.implode t) | _ => Nat.fromString s; fun p_encode_immediate N s = case p_number s of Option.SOME n => let val r = BitsN.fromNat(n,N) in Option.SOME(n = (BitsN.toNat r),r) end | NONE => NONE; fun p_unbounded_immediate s = case String.explode(skipSpaces s) of #"#" :: t => p_number(String.implode t) | _ => NONE; fun p_immediate N s = case String.explode(skipSpaces s) of #"#" :: t => p_encode_immediate N (String.implode t) | _ => NONE; fun p_neg_immediate N s = case p_encode_immediate N s of Option.SOME(true,v) => Option.SOME (if (BitsN.neg v) = v then (true,v) else (BitsN.<(BitsN.BV(0x0,N),v),BitsN.neg v)) | x => x; fun p_pos_immediate N s = case p_encode_immediate N s of Option.SOME(true,v) => Option.SOME(BitsN.<=(BitsN.BV(0x0,N),v),v) | x => x; fun p_signed_immediate N s = case String.explode(skipSpaces s) of #"#" :: t => (case String.explode(skipSpaces(String.implode t)) of #"-" :: r => p_neg_immediate N (String.implode r) | #"+" :: r => p_pos_immediate N (String.implode r) | r => p_pos_immediate N (String.implode r)) | _ => NONE; fun p_offset N s = case String.explode(skipSpaces s) of #"+" :: (#"#" :: t) => p_pos_immediate N (String.implode t) | #"-" :: (#"#" :: t) => p_neg_immediate N (String.implode t) | _ => NONE; fun p_label s = case L3.uncurry String.tokens (fn c => Char.isSpace c,s) of [t] => let val (l,r) = L3.splitl (fn c => (Char.isAlphaNum c) orelse (Set.mem(c,[#"_",#"."])), t) in if (r = "") andalso ((not(l = "")) andalso (not(Char.isDigit(L3.strHd l)))) then Option.SOME l else NONE end | _ => NONE; fun p_cond s = case stripSpaces s of "eq" => Option.SOME(BitsN.B(0x0,4)) | "ne" => Option.SOME(BitsN.B(0x1,4)) | "cs" => Option.SOME(BitsN.B(0x2,4)) | "hs" => Option.SOME(BitsN.B(0x2,4)) | "cc" => Option.SOME(BitsN.B(0x3,4)) | "lo" => Option.SOME(BitsN.B(0x3,4)) | "mi" => Option.SOME(BitsN.B(0x4,4)) | "pl" => Option.SOME(BitsN.B(0x5,4)) | "vs" => Option.SOME(BitsN.B(0x6,4)) | "vc" => Option.SOME(BitsN.B(0x7,4)) | "hi" => Option.SOME(BitsN.B(0x8,4)) | "ls" => Option.SOME(BitsN.B(0x9,4)) | "ge" => Option.SOME(BitsN.B(0xA,4)) | "lt" => Option.SOME(BitsN.B(0xB,4)) | "gt" => Option.SOME(BitsN.B(0xC,4)) | "le" => Option.SOME(BitsN.B(0xD,4)) | "al" => Option.SOME(BitsN.B(0xE,4)) | "15" => Option.SOME(BitsN.B(0xF,4)) | _ => NONE; fun invert_cond s = case stripSpaces s of "eq" => "ne" | "ne" => "eq" | "cs" => "cc" | "hs" => "cc" | "cc" => "cs" | "lo" => "cs" | "mi" => "pl" | "pl" => "mi" | "vs" => "vc" | "vc" => "vs" | "hi" => "ls" | "ls" => "hi" | "ge" => "lt" | "lt" => "ge" | "gt" => "le" | "le" => "gt" | _ => "??"; fun p_w_x s = case String.explode s of #"w" :: l => Option.SOME(false,String.implode l) | #"x" :: l => Option.SOME(true,String.implode l) | _ => NONE; fun is_wide_reg s = case String.explode(skipSpaces s) of #"x" :: _ => true | #"s" :: (#"p" :: _) => true | _ => false; fun p_register (zr,s) = let val s = stripSpaces s in case p_w_x s of Option.SOME(isx,l) => (case String.explode l of [b] => (if Char.isDigit b then Option.SOME (isx, (Option.valOf o BitsN.fromHexString) (String.implode[b],5)) else NONE) | [#"1",b] => (if Char.isDigit b then Option.SOME (isx, BitsN.+ (BitsN.B(0xA,5), (Option.valOf o BitsN.fromHexString) (String.implode[b],5))) else NONE) | [#"2",b] => (if Char.isDigit b then Option.SOME (isx, BitsN.+ (BitsN.B(0x14,5), (Option.valOf o BitsN.fromHexString) (String.implode[b],5))) else NONE) | [#"3",#"0"] => Option.SOME(isx,BitsN.B(0x1E,5)) | [#"z",#"r"] => if zr then Option.SOME(isx,BitsN.B(0x1F,5)) else NONE | [#"s",#"p"] => if zr then NONE else Option.SOME(isx,BitsN.B(0x1F,5)) | _ => NONE) | NONE => if (not zr) andalso (s = "sp") then Option.SOME(true,BitsN.B(0x1F,5)) else NONE end; fun p_register1 (zr,l) = case l of [r1] => p_register(zr,r1) | _ => NONE; fun p_register2 (zr1,(zr2,l)) = case l of [r1,r2] => (case (p_register(zr1,r1),p_register(zr2,r2)) of (Option.SOME(b1,v1),Option.SOME(b2,v2)) => (if b1 = b2 then Option.SOME(b1,(v1,v2)) else NONE) | _ => NONE) | _ => NONE; fun p_register3 (zr1,(zr2,(zr3,l))) = case l of [r1,r2,r3] => (case (p_register(zr1,r1),(p_register(zr2,r2),p_register(zr3,r3))) of (Option.SOME(b1,v1),(Option.SOME(b2,v2),Option.SOME(b3,v3))) => (if (b1 = b2) andalso (b2 = b3) then Option.SOME(b1,(v1,(v2,v3))) else NONE) | _ => NONE) | _ => NONE; fun p_register4 (zr1,(zr2,(zr3,(zr4,l)))) = case l of [r1,r2,r3,r4] => (case (p_register(zr1,r1), (p_register(zr2,r2),(p_register(zr3,r3),p_register(zr4,r4)))) of (Option.SOME(b1,v1), (Option.SOME(b2,v2),(Option.SOME(b3,v3),Option.SOME(b4,v4)))) => (if (b1 = b2) andalso ((b2 = b3) andalso (b3 = b4)) then Option.SOME(b1,(v1,(v2,(v3,v4)))) else NONE) | _ => NONE) | _ => NONE; fun p_register2z l = p_register2(true,(true,l)); fun p_register3z l = p_register3(true,(true,(true,l))); fun p_extend_amount (ext,(optional,s)) = case p_unbounded_immediate s of Option.SOME v => Option.SOME(ext,v) | NONE => if optional andalso ((stripSpaces s) = "") then Option.SOME(ext,0) else NONE; fun p_extend s = case String.explode(skipSpaces s) of #"u" :: (#"x" :: (#"t" :: (#"b" :: t))) => p_extend_amount(ExtendType_UXTB,(true,String.implode t)) | #"u" :: (#"x" :: (#"t" :: (#"h" :: t))) => p_extend_amount(ExtendType_UXTH,(true,String.implode t)) | #"u" :: (#"x" :: (#"t" :: (#"w" :: t))) => p_extend_amount(ExtendType_UXTW,(true,String.implode t)) | #"u" :: (#"x" :: (#"t" :: (#"x" :: t))) => p_extend_amount(ExtendType_UXTX,(true,String.implode t)) | #"s" :: (#"x" :: (#"t" :: (#"b" :: t))) => p_extend_amount(ExtendType_SXTB,(true,String.implode t)) | #"s" :: (#"x" :: (#"t" :: (#"h" :: t))) => p_extend_amount(ExtendType_SXTH,(true,String.implode t)) | #"s" :: (#"x" :: (#"t" :: (#"w" :: t))) => p_extend_amount(ExtendType_SXTW,(true,String.implode t)) | #"s" :: (#"x" :: (#"t" :: (#"x" :: t))) => p_extend_amount(ExtendType_SXTX,(true,String.implode t)) | _ => NONE; fun p_extend2 (size,(wide,s)) = let val r = case String.explode(stripSpaces s) of #"u" :: (#"x" :: (#"t" :: (#"w" :: t))) => (if wide then NONE else p_extend_amount(ExtendType_UXTW,(true,String.implode t))) | #"l" :: (#"s" :: (#"l" :: t)) => (if wide then p_extend_amount(ExtendType_UXTX,(false,String.implode t)) else NONE) | #"s" :: (#"x" :: (#"t" :: (#"w" :: t))) => (if wide then NONE else p_extend_amount(ExtendType_SXTW,(true,String.implode t))) | #"s" :: (#"x" :: (#"t" :: (#"x" :: t))) => (if wide then p_extend_amount(ExtendType_SXTX,(true,String.implode t)) else NONE) | _ => NONE in case r of Option.SOME(_,v) => (if Set.mem(v,[0,size]) then r else NONE) | NONE => NONE end; fun p_shift_amount (sh,s) = case p_unbounded_immediate s of Option.SOME v => Option.SOME(sh,v) | NONE => NONE; fun p_shift_imm s = case String.explode(skipSpaces s) of #"l" :: (#"s" :: (#"l" :: t)) => p_shift_amount(ShiftType_LSL,String.implode t) | #"l" :: (#"s" :: (#"r" :: t)) => p_shift_amount(ShiftType_LSR,String.implode t) | #"a" :: (#"s" :: (#"r" :: t)) => p_shift_amount(ShiftType_ASR,String.implode t) | #"r" :: (#"o" :: (#"r" :: t)) => p_shift_amount(ShiftType_ROR,String.implode t) | _ => NONE; fun closingAddress s = let val (l,wb) = L3.splitr(fn c => c = #"!",stripSpaces s) val (l,r) = L3.splitr(fn c => c = #"]",stripSpaces l) in if (r = "]") andalso (Nat.<(L3.size wb,2)) then Option.SOME(wb = "!",l) else NONE end; fun p_address l = case l of h :: t => (case String.explode(skipSpaces h) of #"[" :: r => let val r = String.implode r in case closingAddress r of Option.SOME(wb,r2) => (case p_register(false,r2) of Option.SOME(true,xn) => (case (t,wb) of ([],_) => ("", Option.SOME (xn,(BitsN.B(0x0,64),(wb,false)))) | ([a],false) => (case p_signed_immediate 64 a of Option.SOME(true,imm) => ("",Option.SOME(xn,(imm,(true,true)))) | Option.SOME _ => ("immediate too large",NONE) | NONE => ("syntax error",NONE)) | _ => ("syntax error",NONE)) | _ => ("syntax error",NONE)) | NONE => (case t of [a] => (case (p_register(false,r),closingAddress a) of (Option.SOME(true,xn),Option.SOME(wb,i)) => (case p_signed_immediate 64 i of Option.SOME(true,imm) => ("",Option.SOME(xn,(imm,(wb,false)))) | Option.SOME _ => ("immediate too large",NONE) | NONE => ("syntax error",NONE)) | _ => ("syntax error",NONE)) | _ => ("syntax error",NONE)) end | _ => ("syntax error",NONE)) | _ => ("syntax error",NONE); fun p_exclusive_address l = case p_address l of ("",Option.SOME(xn,(BitsN.B(0x0,_),(false,false)))) => Option.SOME xn | _ => NONE; fun p_opening_reg s = case String.explode(skipSpaces s) of #"[" :: r => p_register(false,String.implode r) | _ => NONE; fun p_reg_address (size,l) = case l of [n,m,e] => (case (p_opening_reg n,(p_register(true,m),closingAddress e)) of (Option.SOME(true,xn), (Option.SOME(wide,rm),Option.SOME(false,e2))) => (case p_extend2(size,(wide,e2)) of Option.SOME(extend_type,shift) => Option.SOME(xn,(rm,(extend_type,shift))) | _ => NONE) | _ => NONE) | [n,m] => (case closingAddress m of Option.SOME(false,m2) => (case p_register(true,m2) of Option.SOME(wide,_) => let val e = if wide then "lsl #0]" else "uxtw]" in p_reg_address(size,[n,m2,e]) end | NONE => NONE) | _ => NONE) | _ => NONE; fun p_ldr_literal (size,(memop,(signed,(allow_unsigned_offset,(wide,(rt,l)))))) = if (size = 2) andalso (allow_unsigned_offset andalso ((memop = MemOp_LOAD) andalso (((not signed) orelse wide) andalso ((L3.length l) = 1)))) then let val a = List.hd l in case p_label a of Option.SOME v => let val a = (memop,(signed,(BitsN.B(0x0,64),rt))) val i = if signed then LoadLiteral''32(BitsN.B(0x2,32),a) else if wide then LoadLiteral''64(BitsN.B(0x1,64),a) else LoadLiteral''32(BitsN.B(0x0,32),a) in PENDING(v,LoadStore i) end | NONE => (case p_offset 21 a of Option.SOME(true,imm21) => let val imm64 = BitsN.signExtend 64 imm21 val a = (memop,(signed,(imm64,rt))) val i = if signed then LoadLiteral''32(BitsN.B(0x2,32),a) else if wide then LoadLiteral''64(BitsN.B(0x1,64),a) else LoadLiteral''32(BitsN.B(0x0,32),a) in OK(LoadStore i) end | Option.SOME _ => FAIL "offset too large: ldr (literal)" | _ => FAIL "syntax error: ldr, ldrsw") end else FAIL "syntax error: ldr, str, ..."; fun p_ldr_str (size,(memop,(acctype,(signed,(allow_unsigned_offset,l))))) = case l of t :: r => (case p_register(true,t) of Option.SOME(wide,rt) => (if ((size = 2) andalso ((not wide) andalso signed)) orelse ((Nat.<(size,2)) andalso (wide andalso (not signed))) then FAIL "syntax error: ldr, str, ..." else let val regsize_word = not wide in case p_address r of ("",Option.SOME(xn,(offset,(wb,postindex)))) => let val unsigned_offset = allow_unsigned_offset andalso (not wb) in if unsigned_offset andalso (BitsN.<(offset,BitsN.B(0x0,64))) then FAIL "unsigned offset required: ldr, str" else if (not(allow_unsigned_offset orelse postindex)) andalso wb then FAIL "write-back not permitted: ldr, str, ..." else let val a = (regsize_word, (memop, (acctype, (signed, (false, (false, (wb, (postindex, (unsigned_offset, (offset,(xn,rt))))))))))) in OK(LoadStore (case size of 0 => LoadStoreImmediate''8 (BitsN.B(0x0,8),a) | 1 => LoadStoreImmediate''16 (BitsN.B(0x1,16),a) | _ => (if wide andalso (not signed) then LoadStoreImmediate''64 (BitsN.B(0x3,64),a) else LoadStoreImmediate''32 (BitsN.B(0x2,32),a)))) end end | (err,_) => (if acctype = AccType_NORMAL then let val sz = if (size = 2) andalso (wide andalso (not signed)) then 3 else size in case p_reg_address(sz,r) of Option.SOME (xn,(rm,(extend_type,shift))) => let val a = (regsize_word, (memop, (signed, (rm, (extend_type, (shift,(xn,rt))))))) in OK(LoadStore (case size of 0 => LoadStoreRegister''8 (BitsN.B(0x0,8),a) | 1 => LoadStoreRegister''16 (BitsN.B(0x1,16),a) | _ => (if wide andalso (not signed) then LoadStoreRegister''64 (BitsN.B (0x3,64),a) else LoadStoreRegister''32 (BitsN.B(0x2,32), a)))) end | NONE => p_ldr_literal (size, (memop, (signed, (allow_unsigned_offset, (wide,(rt,r)))))) end else FAIL(err ^ ": ldr, str, ...")) end) | NONE => FAIL "syntax error: ldr, str, ...") | _ => FAIL "syntax error: ldr, str, ..."; fun p_ldar_stlr (size,(memop,(acctype,(excl,l)))) = case l of t :: r => (case p_register(true,t) of Option.SOME(wide,rt) => (if (Nat.<(size,2)) andalso wide then FAIL "syntax error: ldar, stlr, ..." else case p_exclusive_address r of Option.SOME xn => let val a = (memop, (acctype, (excl, (false,(false,(BitsN.B(0x1F,5),(xn,rt))))))) in OK(LoadStore (case size of 0 => LoadStoreAcquire''8(BitsN.B(0x0,8),a) | 1 => LoadStoreAcquire''16(BitsN.B(0x1,16),a) | _ => (if wide then LoadStoreAcquire''64 (BitsN.B(0x3,64),a) else LoadStoreAcquire''32 (BitsN.B(0x2,32),a)))) end | _ => FAIL "syntax error: ldar, stlr, ...") | NONE => FAIL "syntax error: ldar, stlr, ...") | _ => FAIL "syntax error: ldar, stlr, ..."; fun p_ldp_stp (memop,(acctype,(signed,l))) = case l of t1 :: (t2 :: r) => (case p_register2z[t1,t2] of Option.SOME(wide,(rt1,rt2)) => (case p_address r of ("",Option.SOME(xn,(offset,(wb,postindex)))) => (if ((acctype = AccType_STREAM) andalso (wb orelse signed)) orelse (signed andalso (not wide)) then FAIL "syntax error: ldp, stp, ..." else let val postindex = if acctype = AccType_STREAM then true else postindex val a = (memop, (acctype, (signed, (false, (false, (wb,(postindex,(offset,(xn,(rt1,rt2)))))))))) in OK(LoadStore (if wide andalso (not signed) then LoadStorePair''64 (BitsN.B(0x1,64),a) else LoadStorePair''32(BitsN.B(0x0,32),a))) end) | _ => FAIL "syntax error: ldp, stp, ...") | NONE => FAIL "syntax error: ldp, stp, ...") | _ => FAIL "syntax error: ldp, stp, ..."; fun p_ldxp (acctype,l) = case l of t1 :: (t2 :: r) => (case p_register2z[t1,t2] of Option.SOME(wide,(rt1,rt2)) => (case p_exclusive_address r of Option.SOME xn => let val a = (MemOp_LOAD, (acctype, (false,(false,(BitsN.B(0x1F,5),(xn,(rt1,rt2))))))) in OK(LoadStore (if wide then LoadStoreAcquirePair''128 (BitsN.B(0x3,128),a) else LoadStoreAcquirePair''64 (BitsN.B(0x2,64),a))) end | _ => FAIL "syntax error: ldxp") | NONE => FAIL "syntax error: ldxp") | _ => FAIL "syntax error: ldxp"; fun p_stxp (acctype,l) = case l of s :: (t1 :: (t2 :: r)) => (case (p_register(true,s),p_register2z[t1,t2]) of (Option.SOME(false,rs),Option.SOME(wide,(rt1,rt2))) => (case p_exclusive_address r of Option.SOME xn => let val a = (MemOp_STORE, (acctype,(false,(false,(rs,(xn,(rt1,rt2))))))) in OK(LoadStore (if wide then LoadStoreAcquirePair''128 (BitsN.B(0x3,128),a) else LoadStoreAcquirePair''64 (BitsN.B(0x2,64),a))) end | _ => FAIL "syntax error: stxp") | _ => FAIL "syntax error: stxp") | _ => FAIL "syntax error: stxp"; fun p_adr (page,l) = case l of [d,a] => (case p_register(true,d) of Option.SOME(true,xd) => (case p_label a of Option.SOME v => PENDING(v,Address(page,(BitsN.B(0x0,64),xd))) | NONE => (case p_offset 21 a of Option.SOME(true,imm21) => let val imm64 = BitsN.signExtend 64 imm21 val imm64 = if page then BitsN.<<(imm64,12) else imm64 in OK(Address(page,(imm64,xd))) end | Option.SOME _ => FAIL "offset too large: adr" | _ => FAIL "syntax error: adr")) | _ => FAIL "syntax error: adr") | _ => FAIL "syntax error: adr"; fun p_conditional_b (cd,l) = case l of [a] => (case p_label a of Option.SOME v => PENDING(v,Branch(BranchConditional(BitsN.B(0x0,64),cd))) | NONE => (case p_offset 21 a of Option.SOME(true,imm21) => OK(Branch (BranchConditional(BitsN.signExtend 64 imm21,cd))) | Option.SOME _ => FAIL "offset too large: conditional b" | _ => FAIL "syntax error: conditional b")) | _ => FAIL "syntax error: conditional b"; fun p_b_bl (branch_type,l) = case l of [a] => (case p_label a of Option.SOME v => PENDING (v,Branch(BranchImmediate(BitsN.B(0x0,64),branch_type))) | NONE => (case p_offset 28 a of Option.SOME(true,imm28) => OK(Branch (BranchImmediate (BitsN.signExtend 64 imm28,branch_type))) | Option.SOME _ => FAIL "offset too large: b, bl" | _ => FAIL "syntax error: b, bl")) | _ => FAIL "syntax error: b, bl"; fun p_br_etc (branch_type,l) = case l of [n] => (case p_register(true,n) of Option.SOME(true,xn) => OK(Branch(BranchRegister(xn,branch_type))) | _ => FAIL "syntax error: br, blr, ret") | [] => if branch_type = BranchType_RET then OK(Branch(BranchRegister(BitsN.B(0x1E,5),branch_type))) else FAIL "syntax error: br, blr" | _ => FAIL "syntax error: br, blr, ret"; fun p_cbz_cbnz (iszero,l) = case l of [t,a] => (case p_register(true,t) of Option.SOME(wide,rt) => (case p_label a of Option.SOME v => PENDING (v, Branch (if wide then CompareAndBranch''64 (BitsN.B(0x1,64), (iszero,(BitsN.B(0x0,64),rt))) else CompareAndBranch''32 (BitsN.B(0x0,32), (iszero,(BitsN.B(0x0,64),rt))))) | NONE => (case p_offset 21 a of Option.SOME(true,imm21) => let val imm64 = BitsN.signExtend 64 imm21 in OK(Branch (if wide then CompareAndBranch''64 (BitsN.B(0x1,64), (iszero,(imm64,rt))) else CompareAndBranch''32 (BitsN.B(0x0,32),(iszero,(imm64,rt))))) end | Option.SOME _ => FAIL "offset too large: cbz, cbnz" | _ => FAIL "syntax error: cbz, cbnz")) | _ => FAIL "syntax error: cbz, cbnz") | _ => FAIL "syntax error: cbz, cbnz"; fun p_tbz_tbnz (bit_val,l) = case l of [t,i,a] => (case (p_register(true,t),p_immediate 6 i) of (Option.SOME(wide,rt),Option.SOME(true,bit_pos)) => let val wide = wide andalso (BitsN.<+(BitsN.B(0x1F,6),bit_pos)) in case p_label a of Option.SOME v => PENDING (v, Branch (if wide then TestBitAndBranch''64 (BitsN.B(0x1,64), (bit_pos, (bit_val,(BitsN.B(0x0,64),rt)))) else TestBitAndBranch''32 (BitsN.B(0x0,32), (bit_pos,(bit_val,(BitsN.B(0x0,64),rt)))))) | NONE => (case p_offset 16 a of Option.SOME(true,imm16) => let val imm64 = BitsN.signExtend 64 imm16 in OK(Branch (if wide then TestBitAndBranch''64 (BitsN.B(0x1,64), (bit_pos,(bit_val,(imm64,rt)))) else TestBitAndBranch''32 (BitsN.B(0x0,32), (bit_pos,(bit_val,(imm64,rt)))))) end | Option.SOME _ => FAIL "offset too large: tbz, tbnz" | _ => FAIL "syntax error: tbz, tbnz") end | (Option.SOME _,Option.SOME _) => FAIL "immediate too large: tbz, tbnz" | _ => FAIL "syntax error: tbz, tbnz") | _ => FAIL "syntax error: tbz, tbnz"; fun p_extend_register (sub_op,(setflags,(ext,(amount,(is_lsl,(d,(n,m))))))) = case (p_register2(setflags,(false,[d,n])),p_register(true,m)) of (Option.SOME(true,(xd,xn)),Option.SOME(_,rm)) => (if Nat.<(amount,5) then let val ext = if is_lsl then ExtendType_UXTX else ext in OK(Data (AddSubExtendRegister''64 (BitsN.B(0x1,64), (sub_op, (setflags, (rm,(ext,(BitsN.fromNat(amount,3),(xn,xd))))))))) end else FAIL "syntax error: add, sub") | (Option.SOME(false,(wd,wn)),Option.SOME(false,wm)) => (if Nat.<(amount,5) then OK(Data (AddSubExtendRegister''32 (BitsN.B(0x0,32), (sub_op, (setflags, (wm,(ext,(BitsN.fromNat(amount,3),(wn,wd))))))))) else FAIL "syntax error: add, sub") | (Option.SOME(wide,(rd,rn)),NONE) => (if is_lsl andalso (Set.mem(amount,[0,12])) then case p_immediate 12 m of Option.SOME(true,imm12) => (if wide then let val imm = if amount = 12 then BitsN.<< (BitsN.fromNat (BitsN.toNat imm12,64),12) else BitsN.fromNat(BitsN.toNat imm12,64) in OK(Data (AddSubImmediate''64 (BitsN.B(0x1,64), (sub_op,(setflags,(imm,(rn,rd))))))) end else let val imm = if amount = 12 then BitsN.<< (BitsN.fromNat(BitsN.toNat imm12,32), 12) else BitsN.fromNat(BitsN.toNat imm12,32) in OK(Data (AddSubImmediate''32 (BitsN.B(0x0,32), (sub_op,(setflags,(imm,(rn,rd))))))) end) | Option.SOME _ => FAIL "immediate too large: add, sub" | NONE => FAIL "syntax error: add, sub" else FAIL "syntax error: add, sub") | _ => FAIL "syntax error: add, sub"; fun p_add_sub (sub_op,(setflags,l)) = case l of [d,n,m,e] => (case p_shift_imm e of Option.SOME(sh,amount) => let val imm6 = BitsN.fromNat(amount,6) in if amount = (BitsN.toNat imm6) then case p_register3z[d,n,m] of Option.SOME(true,(xd,(xn,xm))) => OK(Data (AddSubShiftedRegister''64 (BitsN.B(0x1,64), (sub_op, (setflags,(sh,(xm,(imm6,(xn,xd))))))))) | Option.SOME(false,(wd,(wn,wm))) => OK(Data (AddSubShiftedRegister''32 (BitsN.B(0x0,32), (sub_op, (setflags,(sh,(wm,(imm6,(wn,wd))))))))) | NONE => if sh = ShiftType_LSL then p_extend_register (sub_op, (setflags, (ExtendType_UXTW, (amount,(true,(d,(n,m))))))) else FAIL "syntax error: add, sub" else FAIL "syntax error: add, sub" end | NONE => (case p_extend e of Option.SOME(ext,amount) => p_extend_register (sub_op,(setflags,(ext,(amount,(false,(d,(n,m))))))) | NONE => FAIL "syntax error: add, sub")) | [d,n,m] => p_add_sub(sub_op,(setflags,[d,n,m,"lsl #0"])) | _ => FAIL "syntax error: add, sub"; val p_and_etc_fail = FAIL "syntax error: and, bic, eon, eor, orn, orr" val p_and_etc_imm_fail = FAIL "immediate too large: and, bic, eon, eor, orn, orr" fun p_and_etc (opc,(invert,(setflags,l))) = case l of [d,n,m,e] => (case (p_register3z[d,n,m],p_shift_imm e) of (Option.SOME(true,(xd,(xn,xm))),Option.SOME(sh,amount)) => OK(Data (LogicalShiftedRegister''64 (BitsN.B(0x1,64), (opc,(invert,(setflags,(sh,(amount,(xm,(xn,xd)))))))))) | (Option.SOME(false,(wd,(wn,wm))),Option.SOME(sh,amount)) => OK(Data (LogicalShiftedRegister''32 (BitsN.B(0x0,32), (opc,(invert,(setflags,(sh,(amount,(wm,(wn,wd)))))))))) | _ => p_and_etc_fail) | [d,n,m] => (if Option.isSome(p_register(true,m)) then p_and_etc(opc,(invert,(setflags,[d,n,m,"lsl #0"]))) else if invert then p_and_etc_fail else case p_unbounded_immediate m of Option.SOME imm => (case p_register2(setflags,(true,[d,n])) of Option.SOME(true,(xd,xn)) => let val imm64 = BitsN.fromNat(imm,64) in if imm = (BitsN.toNat imm64) then OK(Data (LogicalImmediate''64 (BitsN.B(0x1,64), (opc,(setflags,(imm64,(xn,xd))))))) else p_and_etc_imm_fail end | Option.SOME(false,(wd,wn)) => let val imm32 = BitsN.fromNat(imm,32) in if imm = (BitsN.toNat imm32) then OK(Data (LogicalImmediate''32 (BitsN.B(0x0,32), (opc,(setflags,(imm32,(wn,wd))))))) else p_and_etc_imm_fail end | NONE => p_and_etc_fail) | NONE => p_and_etc_fail) | _ => p_and_etc_fail; fun p_movk_etc (opcode,l) = case l of [d,i,s] => (case (p_register(true,d),(p_immediate 16 i,p_shift_imm s)) of (Option.SOME(wide,rd), (Option.SOME(true,imm16),Option.SOME(sh,amount))) => let val hw = case amount of 0 => 0 | 16 => 1 | 32 => 2 | 48 => 3 | _ => 4 in if wide andalso (not(hw = 4)) then OK(Data (MoveWide''64 (BitsN.B(0x1,64), (opcode,(BitsN.fromNat(hw,2),(imm16,rd)))))) else if (not wide) andalso (Nat.<(hw,2)) then OK(Data (MoveWide''32 (BitsN.B(0x0,32), (opcode,(BitsN.fromNat(hw,2),(imm16,rd)))))) else FAIL "syntax error: movk, movn, movz" end | (Option.SOME _,(Option.SOME _,Option.SOME _)) => FAIL "immediate too large: movk, movn, movz" | _ => FAIL "syntax error: movk, movn, movz") | [d,i] => p_movk_etc(opcode,[d,i,"lsl #0"]) | _ => FAIL "syntax error: movk, movn, movz"; fun p_adc_sbc (sub_op,(setflags,l)) = case p_register3z l of Option.SOME(true,(xd,(xn,xm))) => OK(Data (AddSubCarry''64 (BitsN.B(0x1,64),(sub_op,(setflags,(xm,(xn,xd))))))) | Option.SOME(false,(wd,(wn,wm))) => OK(Data (AddSubCarry''32 (BitsN.B(0x0,32),(sub_op,(setflags,(wm,(wn,wd))))))) | NONE => FAIL "syntax error: adc, sbc"; fun p_asrv_etc (shift_type,l) = case p_register3z l of Option.SOME(true,(xd,(xn,xm))) => OK(Data(Shift''64(BitsN.B(0x1,64),(shift_type,(xm,(xn,xd)))))) | Option.SOME(false,(wd,(wn,wm))) => OK(Data(Shift''32(BitsN.B(0x0,32),(shift_type,(wm,(wn,wd)))))) | NONE => FAIL "syntax error: asrv, lslv, lsrv, rorv"; fun p_cls_clz (count_clz,l) = case p_register2z l of Option.SOME(true,(xd,xn)) => OK(Data(CountLeading''64(BitsN.B(0x1,64),(count_clz,(xn,xd))))) | Option.SOME(false,(wd,wn)) => OK(Data(CountLeading''32(BitsN.B(0x0,32),(count_clz,(wn,wd))))) | NONE => FAIL "syntax error: cls, clz"; fun p_sdiv_udiv (unsigned,l) = case p_register3z l of Option.SOME(true,(xd,(xn,xm))) => OK(Data(Division''64(BitsN.B(0x1,64),(unsigned,(xm,(xn,xd)))))) | Option.SOME(false,(wd,(wn,wm))) => OK(Data(Division''32(BitsN.B(0x0,32),(unsigned,(wm,(wn,wd)))))) | NONE => FAIL "syntax error: sdiv, udiv"; fun p_madd_msub (sub_op,l) = case p_register4(true,(true,(true,(true,l)))) of Option.SOME(true,(xd,(xn,(xm,xa)))) => OK(Data (MultiplyAddSub''64 (BitsN.B(0x1,64),(sub_op,(xm,(xa,(xn,xd))))))) | Option.SOME(false,(wd,(wn,(wm,wa)))) => OK(Data (MultiplyAddSub''32(BitsN.B(0x0,32),(sub_op,(wm,(wa,(wn,wd))))))) | NONE => FAIL "syntax error: madd, msub"; fun p_smaddl_etc (sub_op,(signed,l)) = case l of [d,n,m,a] => (case (p_register2z[d,a],p_register2z[n,m]) of (Option.SOME(true,(xd,xa)),Option.SOME(false,(wn,wm))) => OK(Data (MultiplyAddSubLong(sub_op,(signed,(wm,(xa,(wn,xd))))))) | _ => FAIL "syntax error: smaddl, umaddl, ssubl, usubl") | _ => FAIL "syntax error: smaddl, umaddl, ssubl, usubl"; fun p_smulh_umulh (signed,l) = case p_register3z l of Option.SOME(true,(xd,(xn,xm))) => OK(Data(MultiplyHigh(signed,(xm,(xn,xd))))) | _ => FAIL "syntax error: smulh, umulh"; fun p_rbit_etc (op',l) = case p_register2z l of Option.SOME(true,(xd,xn)) => OK(Data(Reverse''64(BitsN.B(0x1,64),(op',(xn,xd))))) | Option.SOME(false,(wd,wn)) => (if op' = RevOp_REV32 then FAIL "syntax error: rbit, rev16, rev32, rev" else let val op' = if op' = RevOp_REV64 then RevOp_REV32 else op' in OK(Data(Reverse''32(BitsN.B(0x0,32),(op',(wn,wd))))) end) | NONE => FAIL "syntax error: rbit, rev16, rev32, rev"; fun p_crc32b_etc (size,(crc32c,l)) = case p_register3z l of Option.SOME(false,(wd,(wn,wm))) => let val i = case size of 0 => CRC''8(BitsN.B(0x0,8),(crc32c,(wm,(wn,wd)))) | 1 => CRC''16(BitsN.B(0x1,16),(crc32c,(wm,(wn,wd)))) | _ => CRC''32(BitsN.B(0x2,32),(crc32c,(wm,(wn,wd)))) in OK(CRCExt i) end | _ => FAIL "syntax error: crc32b, crc32h, crc32w"; fun p_crc32x (crc32c,l) = case l of [d,n,m] => (case (p_register2z[d,n],p_register(true,m)) of (Option.SOME(false,(wd,wn)),Option.SOME(true,xm)) => OK(CRCExt(CRC''64(BitsN.B(0x3,64),(crc32c,(xm,(wn,wd)))))) | _ => FAIL "syntax error: crc32x") | _ => FAIL "syntax error: crc32x"; fun p_bfm_etc (inzero,(extend,l)) = case l of [d,n,r,s] => (case (p_register2z[d,n],(p_immediate 6 r,p_immediate 6 s)) of (Option.SOME(wide,(rd,rn)), (Option.SOME(true,immr),Option.SOME(true,imms))) => (if wide then case DecodeBitMasks 64 (BitsN.B(0x1,1),(imms,(immr,false))) of Option.SOME(wmask,tmask) => OK(Data (BitfieldMove''64 (BitsN.B(0x1,64), (inzero, (extend, (wmask, (tmask, (BitsN.toNat immr, (BitsN.toNat imms,(rn,rd)))))))))) | NONE => FAIL "bad mask: bfm, sbfm, ubfm" else case DecodeBitMasks 32 (BitsN.B(0x0,1),(imms,(immr,false))) of Option.SOME(wmask,tmask) => OK(Data (BitfieldMove''32 (BitsN.B(0x0,32), (inzero, (extend, (wmask, (tmask, (BitsN.toNat immr, (BitsN.toNat imms,(rn,rd)))))))))) | NONE => FAIL "bad mask: bfm, sbfm, ubfm") | (Option.SOME _,(Option.SOME _,Option.SOME _)) => FAIL "immediate too large: bfm, sbfm, ubfm" | _ => FAIL "syntax error: bfm, sbfm, ubfm") | _ => FAIL "syntax error: bfm, sbfm, ubfm"; fun p_ccmn_ccmp (sub_op,l) = case l of [n,m,f,c] => (case (p_register(true,n),(p_immediate 4 f,p_cond c)) of (Option.SOME(wide,rn),(Option.SOME(true,nzcv),Option.SOME cd)) => let val nzcv = (BitsN.bit(nzcv,3), (BitsN.bit(nzcv,2),(BitsN.bit(nzcv,1),BitsN.bit(nzcv,0)))) in case p_unbounded_immediate m of Option.SOME imm => (if wide then let val imm64 = BitsN.fromNat(imm,64) in if imm = (BitsN.toNat imm64) then OK(Data (ConditionalCompareImmediate''64 (BitsN.B(0x1,64), (sub_op, (imm64,(cd,(nzcv,rn))))))) else FAIL "immediate too large: ccmn, ccmp" end else let val imm32 = BitsN.fromNat(imm,32) in if imm = (BitsN.toNat imm32) then OK(Data (ConditionalCompareImmediate''32 (BitsN.B(0x0,32), (sub_op,(imm32,(cd,(nzcv,rn))))))) else FAIL "immediate too large: ccmn, ccmp" end) | NONE => (case p_register(true,m) of Option.SOME(wide2,rm) => (if wide = wide2 then if wide then OK(Data (ConditionalCompareRegister''64 (BitsN.B(0x1,64), (sub_op, (cd,(nzcv,(rm,rn))))))) else OK(Data (ConditionalCompareRegister''32 (BitsN.B(0x0,32), (sub_op,(cd,(nzcv,(rm,rn))))))) else FAIL "syntax error: ccmn, ccmp") | NONE => FAIL "syntax error: ccmn, ccmp") end | (Option.SOME _,(Option.SOME _,Option.SOME _)) => FAIL "immediate too large: ccmn, ccmp" | _ => FAIL "syntax error: ccmn, ccmp") | _ => FAIL "syntax error: ccmn, ccmp"; fun p_csel_etc (else_inv,(else_inc,l)) = case l of [d,n,m,c] => (case (p_register3z[d,n,m],p_cond c) of (Option.SOME(true,(xd,(xn,xm))),Option.SOME cd) => OK(Data (ConditionalSelect''64 (BitsN.B(0x1,64), (else_inv,(else_inc,(cd,(xm,(xn,xd)))))))) | (Option.SOME(false,(wd,(wn,wm))),Option.SOME cd) => OK(Data (ConditionalSelect''32 (BitsN.B(0x0,32), (else_inv,(else_inc,(cd,(wm,(wn,wd)))))))) | _ => FAIL "syntax error: csel, csinc, csinv, csneg") | _ => FAIL "syntax error: csel, csinc, csinv, csneg"; fun p_extr l = case l of [d,n,m,b] => (case (p_register3z[d,n,m],p_immediate 6 b) of (Option.SOME(wide,(rd,(rn,rm))),Option.SOME(true,lsb)) => (if wide then OK(Data (ExtractRegister''64 (BitsN.B(0x1,64),(lsb,(rm,(rn,rd)))))) else if BitsN.bit(lsb,5) then FAIL "immediate too large: extr" else OK(Data (ExtractRegister''32 (BitsN.B(0x0,32),(lsb,(rm,(rn,rd))))))) | (Option.SOME _,Option.SOME _) => FAIL "immediate too large: extr" | _ => FAIL "syntax error: extr") | _ => FAIL "syntax error: extr"; fun p_hint l = case l of [i] => (case p_immediate 7 i of Option.SOME(true,imm7) => OK(Hint (case imm7 of BitsN.B(0x0,_) => SystemHintOp_NOP | BitsN.B(0x1,_) => SystemHintOp_YIELD | BitsN.B(0x2,_) => SystemHintOp_WFE | BitsN.B(0x3,_) => SystemHintOp_WFI | BitsN.B(0x4,_) => SystemHintOp_SEV | BitsN.B(0x5,_) => SystemHintOp_SEVL | _ => SystemHintOp_NOP)) | Option.SOME _ => FAIL "immediate too large: hint" | _ => FAIL "syntax error: hint") | _ => FAIL "syntax error: hint"; fun p_call (typ,l) = case l of [i] => (case p_immediate 16 i of Option.SOME(true,imm) => (case typ of 0 => OK(Debug(Halt imm)) | 1 => OK(Debug(DebugSwitch(BitsN.fromNat(typ,2)))) | 2 => OK(Debug(DebugSwitch(BitsN.fromNat(typ,2)))) | 3 => OK(Debug(DebugSwitch(BitsN.fromNat(typ,2)))) | 4 => OK(Debug(Breakpoint imm)) | 5 => OK(System(SupervisorCall imm)) | 6 => OK(System(HypervisorCall imm)) | _ => OK(System(SecureMonitorCall imm))) | Option.SOME _ => FAIL "immediate too large: hint" | _ => FAIL "syntax error: svc, hvc, smc, hlt, brk, dcpsN") | [] => if Set.mem(typ,[1,2,3]) then OK(Debug(DebugSwitch(BitsN.fromNat(typ,2)))) else FAIL "syntax error: svc, hvc, smc, hlt, brk" | _ => FAIL "syntax error: svc, hvc, smc, hlt, brk, dcpsN"; fun p_clrex l = case l of [] => OK(ClearExclusive(BitsN.B(0xF,4))) | [i] => (case p_immediate 4 i of Option.SOME(true,crm) => OK(ClearExclusive crm) | Option.SOME _ => FAIL "immediate too large: clrex" | NONE => FAIL "syntax error: clrex") | _ => FAIL "syntax error: clrex"; fun p_dmb_etc (opc,l) = case l of [i] => (case p_immediate 4 i of Option.SOME(true,crm) => OK(MemoryBarrier(opc,crm)) | Option.SOME _ => FAIL "immediate too large: dmb, dsb, isb" | NONE => (case stripSpaces i of "oshld" => OK(MemoryBarrier(opc,BitsN.B(0x1,4))) | "oshst" => OK(MemoryBarrier(opc,BitsN.B(0x2,4))) | "osh" => OK(MemoryBarrier(opc,BitsN.B(0x3,4))) | "nshld" => OK(MemoryBarrier(opc,BitsN.B(0x5,4))) | "nshst" => OK(MemoryBarrier(opc,BitsN.B(0x6,4))) | "nsh" => OK(MemoryBarrier(opc,BitsN.B(0x7,4))) | "ishld" => OK(MemoryBarrier(opc,BitsN.B(0x9,4))) | "ishst" => OK(MemoryBarrier(opc,BitsN.B(0xA,4))) | "ish" => OK(MemoryBarrier(opc,BitsN.B(0xB,4))) | "ld" => OK(MemoryBarrier(opc,BitsN.B(0xD,4))) | "st" => OK(MemoryBarrier(opc,BitsN.B(0xE,4))) | "sy" => OK(MemoryBarrier(opc,BitsN.B(0xF,4))) | _ => FAIL "syntax error: dmb, dsb, isb")) | _ => FAIL "syntax error: dmb, dsb, isb"; fun wzr_xzr s = if is_wide_reg s then "xzr" else "wzr"; fun convert_immediate (wide,imm) = if wide then if (BitsN.bits(63,16) imm) = (BitsN.B(0x0,48)) then ["#0x" ^ (BitsN.toHexString(BitsN.bits(15,0) imm)), "lsl #0"] else if (BitsN.&&(imm,BitsN.B(0xFFFFFFFF0000FFFF,64))) = (BitsN.B(0x0,64)) then ["#0x" ^ (BitsN.toHexString(BitsN.bits(31,16) imm)), "lsl #16"] else if (BitsN.&&(imm,BitsN.B(0xFFFF0000FFFFFFFF,64))) = (BitsN.B(0x0,64)) then ["#0x" ^ (BitsN.toHexString(BitsN.bits(47,32) imm)), "lsl #32"] else if (BitsN.bits(47,0) imm) = (BitsN.B(0x0,48)) then ["#0x" ^ (BitsN.toHexString(BitsN.bits(63,48) imm)), "lsl #48"] else [] else if (BitsN.bits(63,32) imm) = (BitsN.B(0x0,32)) then if (BitsN.bits(31,16) imm) = (BitsN.B(0x0,16)) then ["#0x" ^ (BitsN.toHexString(BitsN.bits(15,0) imm)), "lsl #0"] else if (BitsN.bits(15,0) imm) = (BitsN.B(0x0,16)) then ["#0x" ^ (BitsN.toHexString(BitsN.bits(31,16) imm)), "lsl #16"] else [] else []; fun p_mov l = case l of [d,n] => let val n = stripSpaces n in if n = "" then FAIL "syntax error: mov" else let val d = stripSpaces d val s = ["sp","wsp"] val i = (L3.strHd n) = #"#" val orr = (LogicalOp_ORR,(false,(false,[d,wzr_xzr d,n]))) in if (Set.mem(d,s)) orelse (Set.mem(n,s)) then if i then p_and_etc orr else p_add_sub(false,(false,l @ ["#0"])) else if i then case p_immediate 64 n of Option.SOME(true,imm) => let val wide = is_wide_reg d in case convert_immediate(wide,imm) of [] => let val imm = if wide then BitsN.~ imm else BitsN.?? (imm,BitsN.B(0xFFFFFFFF,64)) in case convert_immediate(wide,imm) of [] => p_and_etc orr | imm16 => p_movk_etc (MoveWideOp_N,d :: imm16) end | imm16 => p_movk_etc(MoveWideOp_Z,d :: imm16) end | Option.SOME _ => FAIL "immediate too large: mov" | NONE => FAIL "syntax error: mov" else p_and_etc orr end end | _ => FAIL "syntax error: mov"; fun p_shift (shift_type,l) = case l of [d,n,x] => (case (p_register(true,n),p_immediate 6 x) of (Option.SOME(wide,_),Option.SOME(true,imms)) => (if (not wide) andalso (BitsN.bit(imms,5)) then FAIL "immediate too large: asr, lsl, lsr, ror" else case shift_type of ShiftType_ASR => p_bfm_etc (true, (true,[d,n,x,if wide then "#63" else "#31"])) | ShiftType_LSR => p_bfm_etc (true, (false,[d,n,x,if wide then "#63" else "#31"])) | ShiftType_LSL => let val (v1,v2) = if wide then (BitsN.neg imms, BitsN.-(BitsN.B(0x3F,6),imms)) else (BitsN.mod(BitsN.neg imms,BitsN.B(0x20,6)), BitsN.-(BitsN.B(0x1F,6),imms)) in p_bfm_etc (true, (false, [d,n,"#0x" ^ (BitsN.toHexString v1), "#0x" ^ (BitsN.toHexString v2)])) end | ShiftType_ROR => p_extr[d,n,n,x]) | (Option.SOME _,Option.SOME _) => FAIL "immediate too large: asr, lsl, lsr, ror" | _ => p_asrv_etc(shift_type,l)) | _ => FAIL "syntax error: asr, lsl, lsr, ror"; fun p_neg (setflags,l) = case l of [d,m] => (if Option.isSome(p_register2z l) then p_add_sub(true,(setflags,[d,wzr_xzr d,m])) else FAIL "syntax error: neg") | [d,m,e] => (if (Option.isSome(p_register2z[d,m])) andalso (Option.isSome(p_shift_imm e)) then p_add_sub(true,(setflags,[d,wzr_xzr d,m,e])) else FAIL "syntax error: neg") | _ => FAIL "syntax error: neg"; fun convert_bfxil_etc l = case l of [d,n,a,b] => (case (p_unbounded_immediate a,p_unbounded_immediate b) of (Option.SOME _,Option.SOME 0) => [] | (Option.SOME lsb,Option.SOME width) => [d,n,a,"#" ^ (Nat.toString(Nat.-(Nat.+(lsb,width),1)))] | _ => l) | _ => l; fun convert_bfi_etc l = case l of [d,n,a,b] => (case (p_unbounded_immediate a,p_unbounded_immediate b) of (Option.SOME _,Option.SOME 0) => [] | (Option.SOME lsb,Option.SOME width) => let val m = if is_wide_reg d then 64 else 32 in [d,n, "#" ^ (IntInf.toString(IntInf.mod(IntInf.~(Nat.toInt lsb),m))), "#" ^ (Nat.toString(Nat.-(width,1)))] end | _ => l) | _ => l; fun convert_cinc_etc l = case l of [d,n,c] => [d,n,n,invert_cond c] | _ => l; fun convert_cset_csetm l = case l of [d,c] => let val z = wzr_xzr d in [d,z,z,invert_cond c] end | _ => l; fun convert_zr1 l = case l of n :: _ => (wzr_xzr n) :: l | [] => []; fun convert_zr2 l = case l of n :: r => [n,wzr_xzr n] @ r | [] => []; fun convert_zr_end l = case l of n :: _ => l @ [wzr_xzr n] | [] => []; fun p_tokens s = let val (l,r) = L3.splitl (fn c => not(Char.isSpace c), L3.lowercase(L3.snd(L3.splitl(fn c => Char.isSpace c,s)))) val r = L3.uncurry String.fields (fn c => c = #",",r) val r = if ((L3.length r) = 1) andalso ((stripSpaces(List.hd r)) = "") then [] else r in l :: r end; fun instructionFromString s = case p_tokens s of v'0 :: v'1 => (case (String.explode v'0,v'1) of ([#"a",#"d",#"r",#"p"],l) => p_adr(true,l) | ([#"a",#"d",#"r"],l) => p_adr(false,l) | ([#"a",#"d",#"d",#"s"],l) => p_add_sub(false,(true,l)) | ([#"c",#"m",#"n"],l) => p_add_sub(false,(true,convert_zr1 l)) | ([#"a",#"d",#"d"],l) => p_add_sub(false,(false,l)) | ([#"s",#"u",#"b",#"s"],l) => p_add_sub(true,(true,l)) | ([#"c",#"m",#"p"],l) => p_add_sub(true,(true,convert_zr1 l)) | ([#"s",#"u",#"b"],l) => p_add_sub(true,(false,l)) | ([#"a",#"n",#"d",#"s"],l) => p_and_etc(LogicalOp_AND,(false,(true,l))) | ([#"t",#"s",#"t"],l) => p_and_etc(LogicalOp_AND,(false,(true,convert_zr1 l))) | ([#"a",#"n",#"d"],l) => p_and_etc(LogicalOp_AND,(false,(false,l))) | ([#"b",#"i",#"c",#"s"],l) => p_and_etc(LogicalOp_AND,(true,(true,l))) | ([#"b",#"i",#"c"],l) => p_and_etc(LogicalOp_AND,(true,(false,l))) | ([#"e",#"o",#"r"],l) => p_and_etc(LogicalOp_EOR,(false,(false,l))) | ([#"e",#"o",#"n"],l) => p_and_etc(LogicalOp_EOR,(true,(false,l))) | ([#"o",#"r",#"r"],l) => p_and_etc(LogicalOp_ORR,(false,(false,l))) | ([#"o",#"r",#"n"],l) => p_and_etc(LogicalOp_ORR,(true,(false,l))) | ([#"m",#"v",#"n"],l) => p_and_etc(LogicalOp_ORR,(true,(false,convert_zr2 l))) | ([#"a",#"d",#"c",#"s"],l) => p_adc_sbc(false,(true,l)) | ([#"a",#"d",#"c"],l) => p_adc_sbc(false,(false,l)) | ([#"s",#"b",#"c",#"s"],l) => p_adc_sbc(true,(true,l)) | ([#"s",#"b",#"c"],l) => p_adc_sbc(true,(false,l)) | ([#"n",#"g",#"c",#"s"],l) => p_adc_sbc(true,(true,convert_zr2 l)) | ([#"n",#"g",#"c"],l) => p_adc_sbc(true,(false,convert_zr2 l)) | ([#"a",#"s",#"r",#"v"],l) => p_asrv_etc(ShiftType_ASR,l) | ([#"l",#"s",#"l",#"v"],l) => p_asrv_etc(ShiftType_LSL,l) | ([#"l",#"s",#"r",#"v"],l) => p_asrv_etc(ShiftType_LSR,l) | ([#"r",#"o",#"r",#"v"],l) => p_asrv_etc(ShiftType_ROR,l) | ([#"a",#"s",#"r"],l) => p_shift(ShiftType_ASR,l) | ([#"l",#"s",#"l"],l) => p_shift(ShiftType_LSL,l) | ([#"l",#"s",#"r"],l) => p_shift(ShiftType_LSR,l) | ([#"r",#"o",#"r"],l) => p_shift(ShiftType_ROR,l) | ([#"n",#"e",#"g",#"s"],l) => p_neg(true,l) | ([#"n",#"e",#"g"],l) => p_neg(false,l) | ([#"m",#"o",#"v",#"k"],l) => p_movk_etc(MoveWideOp_K,l) | ([#"m",#"o",#"v",#"n"],l) => p_movk_etc(MoveWideOp_N,l) | ([#"m",#"o",#"v",#"z"],l) => p_movk_etc(MoveWideOp_Z,l) | ([#"m",#"o",#"v"],l) => p_mov l | ([#"c",#"l",#"s"],l) => p_cls_clz(false,l) | ([#"c",#"l",#"z"],l) => p_cls_clz(true,l) | ([#"s",#"d",#"i",#"v"],l) => p_sdiv_udiv(false,l) | ([#"u",#"d",#"i",#"v"],l) => p_sdiv_udiv(true,l) | ([#"m",#"a",#"d",#"d"],l) => p_madd_msub(false,l) | ([#"m",#"s",#"u",#"b"],l) => p_madd_msub(true,l) | ([#"m",#"u",#"l"],l) => p_madd_msub(false,convert_zr_end l) | ([#"m",#"n",#"e",#"g"],l) => p_madd_msub(true,convert_zr_end l) | ([#"s",#"m",#"a",#"d",#"d",#"l"],l) => p_smaddl_etc(false,(true,l)) | ([#"s",#"m",#"u",#"l",#"l"],l) => p_smaddl_etc(false,(true,convert_zr_end l)) | ([#"u",#"m",#"a",#"d",#"d",#"l"],l) => p_smaddl_etc(false,(false,l)) | ([#"u",#"m",#"u",#"l",#"l"],l) => p_smaddl_etc(false,(false,convert_zr_end l)) | ([#"s",#"m",#"s",#"u",#"b",#"l"],l) => p_smaddl_etc(true,(true,l)) | ([#"s",#"m",#"n",#"e",#"g",#"l"],l) => p_smaddl_etc(true,(true,convert_zr_end l)) | ([#"u",#"m",#"s",#"u",#"b",#"l"],l) => p_smaddl_etc(true,(false,l)) | ([#"u",#"m",#"n",#"e",#"g",#"l"],l) => p_smaddl_etc(true,(false,convert_zr_end l)) | ([#"s",#"m",#"u",#"l",#"h"],l) => p_smulh_umulh(true,l) | ([#"u",#"m",#"u",#"l",#"h"],l) => p_smulh_umulh(false,l) | ([#"r",#"b",#"i",#"t"],l) => p_rbit_etc(RevOp_RBIT,l) | ([#"r",#"e",#"v",#"1",#"6"],l) => p_rbit_etc(RevOp_REV16,l) | ([#"r",#"e",#"v",#"3",#"2"],l) => p_rbit_etc(RevOp_REV32,l) | ([#"r",#"e",#"v"],l) => p_rbit_etc(RevOp_REV64,l) | ([#"c",#"s",#"e",#"l"],l) => p_csel_etc(false,(false,l)) | ([#"c",#"s",#"i",#"n",#"c"],l) => p_csel_etc(false,(true,l)) | ([#"c",#"i",#"n",#"c"],l) => p_csel_etc(false,(true,convert_cinc_etc l)) | ([#"c",#"s",#"e",#"t"],l) => p_csel_etc(false,(true,convert_cset_csetm l)) | ([#"c",#"s",#"i",#"n",#"v"],l) => p_csel_etc(true,(false,l)) | ([#"c",#"i",#"n",#"v"],l) => p_csel_etc(true,(false,convert_cinc_etc l)) | ([#"c",#"s",#"e",#"t",#"m"],l) => p_csel_etc(true,(false,convert_cset_csetm l)) | ([#"c",#"s",#"n",#"e",#"g"],l) => p_csel_etc(true,(true,l)) | ([#"c",#"n",#"e",#"g"],l) => p_csel_etc(true,(true,convert_cinc_etc l)) | ([#"c",#"c",#"m",#"n"],l) => p_ccmn_ccmp(false,l) | ([#"c",#"c",#"m",#"p"],l) => p_ccmn_ccmp(true,l) | ([#"b",#"f",#"m"],l) => p_bfm_etc(false,(false,l)) | ([#"b",#"f",#"i"],l) => p_bfm_etc(false,(false,convert_bfi_etc l)) | ([#"b",#"f",#"x",#"i",#"l"],l) => p_bfm_etc(false,(false,convert_bfxil_etc l)) | ([#"s",#"b",#"f",#"m"],l) => p_bfm_etc(true,(true,l)) | ([#"s",#"b",#"f",#"i",#"z"],l) => p_bfm_etc(true,(true,convert_bfi_etc l)) | ([#"s",#"b",#"f",#"x"],l) => p_bfm_etc(true,(true,convert_bfxil_etc l)) | ([#"s",#"x",#"t",#"b"],l) => p_bfm_etc(true,(true,l @ ["#0","#7"])) | ([#"s",#"x",#"t",#"h"],l) => p_bfm_etc(true,(true,l @ ["#0","#15"])) | ([#"s",#"x",#"t",#"w"],l) => p_bfm_etc(true,(true,l @ ["#0","#31"])) | ([#"u",#"b",#"f",#"m"],l) => p_bfm_etc(true,(false,l)) | ([#"u",#"b",#"f",#"i",#"z"],l) => p_bfm_etc(true,(false,convert_bfi_etc l)) | ([#"u",#"b",#"f",#"x"],l) => p_bfm_etc(true,(false,convert_bfxil_etc l)) | ([#"u",#"x",#"t",#"b"],l) => p_bfm_etc(true,(false,l @ ["#0","#7"])) | ([#"u",#"x",#"t",#"h"],l) => p_bfm_etc(true,(false,l @ ["#0","#15"])) | ([#"e",#"x",#"t",#"r"],l) => p_extr l | ([#"c",#"r",#"c",#"3",#"2",#"c",#"b"],l) => p_crc32b_etc(0,(true,l)) | ([#"c",#"r",#"c",#"3",#"2",#"c",#"h"],l) => p_crc32b_etc(1,(true,l)) | ([#"c",#"r",#"c",#"3",#"2",#"c",#"w"],l) => p_crc32b_etc(2,(true,l)) | ([#"c",#"r",#"c",#"3",#"2",#"c",#"x"],l) => p_crc32x(true,l) | ([#"c",#"r",#"c",#"3",#"2",#"b"],l) => p_crc32b_etc(0,(false,l)) | ([#"c",#"r",#"c",#"3",#"2",#"h"],l) => p_crc32b_etc(1,(false,l)) | ([#"c",#"r",#"c",#"3",#"2",#"w"],l) => p_crc32b_etc(2,(false,l)) | ([#"c",#"r",#"c",#"3",#"2",#"x"],l) => p_crc32x(false,l) | ([#"l",#"d",#"r",#"b"],l) => p_ldr_str(0,(MemOp_LOAD,(AccType_NORMAL,(false,(true,l))))) | ([#"l",#"d",#"r",#"h"],l) => p_ldr_str(1,(MemOp_LOAD,(AccType_NORMAL,(false,(true,l))))) | ([#"l",#"d",#"r"],l) => p_ldr_str(2,(MemOp_LOAD,(AccType_NORMAL,(false,(true,l))))) | ([#"l",#"d",#"r",#"s",#"b"],l) => p_ldr_str(0,(MemOp_LOAD,(AccType_NORMAL,(true,(true,l))))) | ([#"l",#"d",#"r",#"s",#"h"],l) => p_ldr_str(1,(MemOp_LOAD,(AccType_NORMAL,(true,(true,l))))) | ([#"l",#"d",#"r",#"s",#"w"],l) => p_ldr_str(2,(MemOp_LOAD,(AccType_NORMAL,(true,(true,l))))) | ([#"l",#"d",#"u",#"r",#"b"],l) => p_ldr_str(0,(MemOp_LOAD,(AccType_NORMAL,(false,(false,l))))) | ([#"l",#"d",#"u",#"r",#"h"],l) => p_ldr_str(1,(MemOp_LOAD,(AccType_NORMAL,(false,(false,l))))) | ([#"l",#"d",#"u",#"r"],l) => p_ldr_str(2,(MemOp_LOAD,(AccType_NORMAL,(false,(false,l))))) | ([#"l",#"d",#"u",#"r",#"s",#"b"],l) => p_ldr_str(0,(MemOp_LOAD,(AccType_NORMAL,(true,(false,l))))) | ([#"l",#"d",#"u",#"r",#"s",#"h"],l) => p_ldr_str(1,(MemOp_LOAD,(AccType_NORMAL,(true,(false,l))))) | ([#"l",#"d",#"u",#"r",#"s",#"w"],l) => p_ldr_str(2,(MemOp_LOAD,(AccType_NORMAL,(true,(false,l))))) | ([#"l",#"d",#"t",#"r",#"b"],l) => p_ldr_str(0,(MemOp_LOAD,(AccType_UNPRIV,(false,(false,l))))) | ([#"l",#"d",#"t",#"r",#"h"],l) => p_ldr_str(1,(MemOp_LOAD,(AccType_UNPRIV,(false,(false,l))))) | ([#"l",#"d",#"t",#"r"],l) => p_ldr_str(2,(MemOp_LOAD,(AccType_UNPRIV,(false,(false,l))))) | ([#"l",#"d",#"t",#"r",#"s",#"b"],l) => p_ldr_str(0,(MemOp_LOAD,(AccType_UNPRIV,(true,(false,l))))) | ([#"l",#"d",#"t",#"r",#"s",#"h"],l) => p_ldr_str(1,(MemOp_LOAD,(AccType_UNPRIV,(true,(false,l))))) | ([#"l",#"d",#"t",#"r",#"s",#"w"],l) => p_ldr_str(2,(MemOp_LOAD,(AccType_UNPRIV,(true,(false,l))))) | ([#"s",#"t",#"r",#"b"],l) => p_ldr_str(0,(MemOp_STORE,(AccType_NORMAL,(false,(true,l))))) | ([#"s",#"t",#"r",#"h"],l) => p_ldr_str(1,(MemOp_STORE,(AccType_NORMAL,(false,(true,l))))) | ([#"s",#"t",#"r"],l) => p_ldr_str(2,(MemOp_STORE,(AccType_NORMAL,(false,(true,l))))) | ([#"s",#"t",#"u",#"r",#"b"],l) => p_ldr_str(0,(MemOp_STORE,(AccType_NORMAL,(false,(false,l))))) | ([#"s",#"t",#"u",#"r",#"h"],l) => p_ldr_str(1,(MemOp_STORE,(AccType_NORMAL,(false,(false,l))))) | ([#"s",#"t",#"u",#"r"],l) => p_ldr_str(2,(MemOp_STORE,(AccType_NORMAL,(false,(false,l))))) | ([#"s",#"t",#"t",#"r",#"b"],l) => p_ldr_str(0,(MemOp_STORE,(AccType_UNPRIV,(false,(false,l))))) | ([#"s",#"t",#"t",#"r",#"h"],l) => p_ldr_str(1,(MemOp_STORE,(AccType_UNPRIV,(false,(false,l))))) | ([#"s",#"t",#"t",#"r"],l) => p_ldr_str(2,(MemOp_STORE,(AccType_UNPRIV,(false,(false,l))))) | ([#"l",#"d",#"a",#"r",#"b"],l) => p_ldar_stlr(0,(MemOp_LOAD,(AccType_ORDERED,(false,l)))) | ([#"l",#"d",#"a",#"r",#"h"],l) => p_ldar_stlr(1,(MemOp_LOAD,(AccType_ORDERED,(false,l)))) | ([#"l",#"d",#"a",#"r"],l) => p_ldar_stlr(2,(MemOp_LOAD,(AccType_ORDERED,(false,l)))) | ([#"l",#"d",#"a",#"x",#"r",#"b"],l) => p_ldar_stlr(0,(MemOp_LOAD,(AccType_ORDERED,(true,l)))) | ([#"l",#"d",#"a",#"x",#"r",#"h"],l) => p_ldar_stlr(1,(MemOp_LOAD,(AccType_ORDERED,(true,l)))) | ([#"l",#"d",#"a",#"x",#"r"],l) => p_ldar_stlr(2,(MemOp_LOAD,(AccType_ORDERED,(true,l)))) | ([#"l",#"d",#"x",#"r",#"b"],l) => p_ldar_stlr(0,(MemOp_LOAD,(AccType_ATOMIC,(true,l)))) | ([#"l",#"d",#"x",#"r",#"h"],l) => p_ldar_stlr(1,(MemOp_LOAD,(AccType_ATOMIC,(true,l)))) | ([#"l",#"d",#"x",#"r"],l) => p_ldar_stlr(2,(MemOp_LOAD,(AccType_ATOMIC,(true,l)))) | ([#"s",#"t",#"l",#"r",#"b"],l) => p_ldar_stlr(0,(MemOp_STORE,(AccType_ORDERED,(false,l)))) | ([#"s",#"t",#"l",#"r",#"h"],l) => p_ldar_stlr(1,(MemOp_STORE,(AccType_ORDERED,(false,l)))) | ([#"s",#"t",#"l",#"r"],l) => p_ldar_stlr(2,(MemOp_STORE,(AccType_ORDERED,(false,l)))) | ([#"s",#"t",#"l",#"x",#"r",#"b"],l) => p_ldar_stlr(0,(MemOp_STORE,(AccType_ORDERED,(true,l)))) | ([#"s",#"t",#"l",#"x",#"r",#"h"],l) => p_ldar_stlr(1,(MemOp_STORE,(AccType_ORDERED,(true,l)))) | ([#"s",#"t",#"l",#"x",#"r"],l) => p_ldar_stlr(2,(MemOp_STORE,(AccType_ORDERED,(true,l)))) | ([#"s",#"t",#"x",#"r",#"b"],l) => p_ldar_stlr(0,(MemOp_STORE,(AccType_ATOMIC,(true,l)))) | ([#"s",#"t",#"x",#"r",#"h"],l) => p_ldar_stlr(1,(MemOp_STORE,(AccType_ATOMIC,(true,l)))) | ([#"s",#"t",#"x",#"r"],l) => p_ldar_stlr(2,(MemOp_STORE,(AccType_ATOMIC,(true,l)))) | ([#"l",#"d",#"n",#"p"],l) => p_ldp_stp(MemOp_LOAD,(AccType_STREAM,(false,l))) | ([#"l",#"d",#"p"],l) => p_ldp_stp(MemOp_LOAD,(AccType_NORMAL,(false,l))) | ([#"l",#"d",#"p",#"s",#"w"],l) => p_ldp_stp(MemOp_LOAD,(AccType_NORMAL,(true,l))) | ([#"s",#"t",#"n",#"p"],l) => p_ldp_stp(MemOp_STORE,(AccType_STREAM,(false,l))) | ([#"s",#"t",#"p"],l) => p_ldp_stp(MemOp_STORE,(AccType_NORMAL,(false,l))) | ([#"l",#"d",#"a",#"x",#"p"],l) => p_ldxp(AccType_ORDERED,l) | ([#"l",#"d",#"x",#"p"],l) => p_ldxp(AccType_ATOMIC,l) | ([#"s",#"t",#"l",#"x",#"p"],l) => p_stxp(AccType_ORDERED,l) | ([#"s",#"t",#"x",#"p"],l) => p_stxp(AccType_ATOMIC,l) | ([#"c",#"b",#"n",#"z"],l) => p_cbz_cbnz(false,l) | ([#"c",#"b",#"z"],l) => p_cbz_cbnz(true,l) | ([#"t",#"b",#"n",#"z"],l) => p_tbz_tbnz(true,l) | ([#"t",#"b",#"z"],l) => p_tbz_tbnz(false,l) | ([#"b",#"r"],l) => p_br_etc(BranchType_JMP,l) | ([#"b",#"l",#"r"],l) => p_br_etc(BranchType_CALL,l) | ([#"r",#"e",#"t"],l) => p_br_etc(BranchType_RET,l) | ([#"h",#"l",#"t"],l) => p_call(0,l) | ([#"d",#"c",#"p",#"s",#"1"],l) => p_call(1,l) | ([#"d",#"c",#"p",#"s",#"2"],l) => p_call(2,l) | ([#"d",#"c",#"p",#"s",#"3"],l) => p_call(3,l) | ([#"b",#"r",#"k"],l) => p_call(4,l) | ([#"s",#"v",#"c"],l) => p_call(5,l) | ([#"h",#"v",#"c"],l) => p_call(6,l) | ([#"s",#"m",#"c"],l) => p_call(7,l) | ([#"b",#".",c1,c2],l) => (case p_cond(String.implode[c1,c2]) of Option.SOME cd => p_conditional_b(cd,l) | NONE => FAIL "Unrecognised mnemonic") | ([#"b",#"l"],l) => p_b_bl(BranchType_CALL,l) | ([#"b"],l) => p_b_bl(BranchType_JMP,l) | ([#"d",#"m",#"b"],l) => p_dmb_etc(MemBarrierOp_DMB,l) | ([#"d",#"s",#"b"],l) => p_dmb_etc(MemBarrierOp_DSB,l) | ([#"i",#"s",#"b"],l) => p_dmb_etc(MemBarrierOp_ISB,l) | ([#"h",#"i",#"n",#"t"],l) => p_hint l | ([#"c",#"l",#"r",#"e",#"x"],l) => p_clrex l | ([#"y",#"i",#"e",#"l",#"d"],[]) => OK(Hint SystemHintOp_YIELD) | ([#"n",#"o",#"p"],[]) => OK(Hint SystemHintOp_NOP) | ([#"w",#"f",#"e"],[]) => OK(Hint SystemHintOp_WFE) | ([#"w",#"f",#"i"],[]) => OK(Hint SystemHintOp_WFI) | ([#"s",#"e",#"v"],[]) => OK(Hint SystemHintOp_SEV) | ([#"s",#"e",#"v",#"l"],[]) => OK(Hint SystemHintOp_SEVL) | ([#"e",#"r",#"e",#"t"],[]) => OK(System ExceptionReturn) | ([#"d",#"r",#"p",#"s"],[]) => OK(Debug DebugRestore) | ([#"w",#"o",#"r",#"d"],[w]) => (case p_encode_immediate 32 w of Option.SOME(true,w) => WORD w | Option.SOME _ => FAIL "immediate too large" | NONE => FAIL "syntax error: word") | _ => FAIL "Unrecognised mnemonic") | _ => FAIL "Unrecognised mnemonic"; fun EncodeARM s = case instructionFromString s of OK ast => (case Encode ast of ARM8 w => ("", Option.SOME(L3.padLeftString(#"0",(8,BitsN.toHexString w)))) | BadCode err => ("Encode error: " ^ err,NONE)) | PENDING _ => ("Contains label",NONE) | WORD w => ("",Option.SOME(L3.padLeftString(#"0",(8,BitsN.toHexString w)))) | FAIL err => ("Parse error: " ^ err,NONE); fun s_cond c = case c of BitsN.B(0x0,_) => "eq" | BitsN.B(0x1,_) => "ne" | BitsN.B(0x2,_) => "cs" | BitsN.B(0x3,_) => "cc" | BitsN.B(0x4,_) => "mi" | BitsN.B(0x5,_) => "pl" | BitsN.B(0x6,_) => "vs" | BitsN.B(0x7,_) => "vc" | BitsN.B(0x8,_) => "hi" | BitsN.B(0x9,_) => "ls" | BitsN.B(0xA,_) => "ge" | BitsN.B(0xB,_) => "lt" | BitsN.B(0xC,_) => "gt" | BitsN.B(0xD,_) => "le" | BitsN.B(0xE,_) => "al" | BitsN.B(0xF,_) => "15" | _ => raise General.Bind; fun s_regz (wide,r) = (if wide then "x" else "w") ^ (if r = (BitsN.B(0x1F,5)) then "zr" else Nat.toString(BitsN.toNat r)); fun s_regp (wide,r) = if r = (BitsN.B(0x1F,5)) then if wide then "sp" else "wsp" else s_regz(wide,r); fun s_reg2z (wide,(r1,r2)) = String.concat[s_regz(wide,r1),", ",s_regz(wide,r2)]; fun s_reg3z (wide,(r1,(r2,r3))) = String.concat[s_reg2z(wide,(r1,r2)),", ",s_regz(wide,r3)]; fun s_reg4z (wide,(r1,(r2,(r3,r4)))) = String.concat[s_reg3z(wide,(r1,(r2,r3))),", ",s_regz(wide,r4)]; fun s_nat v = "#" ^ (Nat.toString v); fun s_dec N v = s_nat(BitsN.toNat v); fun s_hex N v = if BitsN.<+(v,BitsN.BV(0x64,N)) then s_dec N v else "#0x" ^ (BitsN.toHexString v); fun s_immn v = ", " ^ (s_nat v); fun s_imm N v = ", " ^ (s_hex N v); fun s_offset imm = if BitsN.<(imm,BitsN.B(0x0,64)) then "-" ^ (s_hex 64 (BitsN.neg imm)) else "+" ^ (s_hex 64 imm); fun s_signed_imm imm = case String.explode(s_offset imm) of #"+" :: (#"#" :: a) => ", #" ^ (String.implode a) | #"-" :: (#"#" :: a) => ", #-" ^ (String.implode a) | s => String.implode s; fun s_shifted_imm N imm = let val top = BitsN.>>+(imm,12) in if (not(top = (BitsN.BV(0x0,N)))) andalso ((BitsN.bits(11,0) imm) = (BitsN.B(0x0,12))) then (s_imm N top) ^ ", lsl #12" else s_imm N imm end; fun s_extend_type extend_type = case extend_type of ExtendType_UXTB => "uxtb" | ExtendType_UXTH => "uxth" | ExtendType_UXTW => "uxtw" | ExtendType_UXTX => "uxtx" | ExtendType_SXTB => "sxtb" | ExtendType_SXTH => "sxth" | ExtendType_SXTW => "sxtw" | ExtendType_SXTX => "sxtx"; fun s_shift_type shift_type = case shift_type of ShiftType_LSL => "lsl" | ShiftType_LSR => "lsr" | ShiftType_ASR => "asr" | ShiftType_ROR => "ror"; fun s_move_wide_op opc = case opc of MoveWideOp_N => "movn" | MoveWideOp_Z => "movz" | MoveWideOp_K => "movk"; fun s_logical_op opc = case opc of LogicalOp_AND => "and" | LogicalOp_ORR => "orr" | LogicalOp_EOR => "eor"; fun s_invert_logical_op opc = case opc of LogicalOp_AND => "bic" | LogicalOp_ORR => "orn" | LogicalOp_EOR => "eon"; fun s_rev_op opc = case opc of RevOp_RBIT => "rbit" | RevOp_REV16 => "rev16" | RevOp_REV32 => "rev32" | RevOp_REV64 => "rev"; fun s_hint_op opc = case opc of SystemHintOp_NOP => "nop" | SystemHintOp_YIELD => "yield" | SystemHintOp_WFE => "wfe" | SystemHintOp_WFI => "wfi" | SystemHintOp_SEV => "sev" | SystemHintOp_SEVL => "sevl"; fun s_barrier_op opc = case opc of MemBarrierOp_DSB => "dsb" | MemBarrierOp_DMB => "dmb" | MemBarrierOp_ISB => "isb"; fun s_shift_amount (shift_type,sh) = if (sh = 0) andalso (shift_type = ShiftType_LSL) then "" else String.concat[", ",s_shift_type shift_type," ",s_nat sh]; fun s_nzcv (n,(z,(c,v))) = ", " ^ (s_dec 4 (BitsN.concat [BitsN.fromBit n,BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v])); fun s_data ast = case ast of AddSubCarry''32(sf,(sub_op,(setflags,(m,(n,d))))) => let val wide = (BitsN.size sf) = 64 val sfx = if setflags then "s" else "" in if sub_op andalso (n = (BitsN.B(0x1F,5))) then ("ngc" ^ sfx,s_reg2z(wide,(d,m))) else ((if sub_op then "sbc" else "adc") ^ sfx, s_reg3z(wide,(d,(n,m)))) end | AddSubCarry''64(sf,(sub_op,(setflags,(m,(n,d))))) => let val wide = (BitsN.size sf) = 64 val sfx = if setflags then "s" else "" in if sub_op andalso (n = (BitsN.B(0x1F,5))) then ("ngc" ^ sfx,s_reg2z(wide,(d,m))) else ((if sub_op then "sbc" else "adc") ^ sfx, s_reg3z(wide,(d,(n,m)))) end | AddSubExtendRegister''32 (sf,(sub_op,(setflags,(m,(extend_type,(imm3,(n,d))))))) => let val wide = (BitsN.size sf) = 64 in ((if sub_op then "sub" else "add") ^ (if setflags then "s" else ""), String.concat [if setflags then s_regz(wide,d) else s_regp(wide,d),", ", s_regp(wide,n),", ", s_regz (wide andalso (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX])),m), if ((n = (BitsN.B(0x1F,5))) orelse ((not setflags) andalso (d = (BitsN.B(0x1F,5))))) andalso ((wide andalso (extend_type = ExtendType_UXTX)) orelse ((not wide) andalso (extend_type = ExtendType_UXTW))) then if imm3 = (BitsN.B(0x0,3)) then "" else ", lsl " ^ (s_dec 3 imm3) else String.concat [", ",s_extend_type extend_type," ",s_dec 3 imm3]]) end | AddSubExtendRegister''64 (sf,(sub_op,(setflags,(m,(extend_type,(imm3,(n,d))))))) => let val wide = (BitsN.size sf) = 64 in ((if sub_op then "sub" else "add") ^ (if setflags then "s" else ""), String.concat [if setflags then s_regz(wide,d) else s_regp(wide,d),", ", s_regp(wide,n),", ", s_regz (wide andalso (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX])),m), if ((n = (BitsN.B(0x1F,5))) orelse ((not setflags) andalso (d = (BitsN.B(0x1F,5))))) andalso ((wide andalso (extend_type = ExtendType_UXTX)) orelse ((not wide) andalso (extend_type = ExtendType_UXTW))) then if imm3 = (BitsN.B(0x0,3)) then "" else ", lsl " ^ (s_dec 3 imm3) else String.concat [", ",s_extend_type extend_type," ",s_dec 3 imm3]]) end | AddSubImmediate''32(sf,(sub_op,(setflags,(imm,(n,d))))) => let val wide = (BitsN.size sf) = 64 in if (not(sub_op orelse setflags)) andalso (((n = (BitsN.B(0x1F,5))) orelse (d = (BitsN.B(0x1F,5)))) andalso (imm = (BitsN.B(0x0,32)))) then ("mov",String.concat[s_regp(wide,d),", ",s_regp(wide,n)]) else if setflags andalso (d = (BitsN.B(0x1F,5))) then (if sub_op then "cmp" else "cmn", (s_regp(wide,n)) ^ (s_shifted_imm 32 imm)) else ((if sub_op then "sub" else "add") ^ (if setflags then "s" else ""), String.concat [if setflags then s_regz(wide,d) else s_regp(wide,d),", ", s_regp(wide,n),s_shifted_imm 32 imm]) end | AddSubImmediate''64(sf,(sub_op,(setflags,(imm,(n,d))))) => let val wide = (BitsN.size sf) = 64 in if (not(sub_op orelse setflags)) andalso (((n = (BitsN.B(0x1F,5))) orelse (d = (BitsN.B(0x1F,5)))) andalso (imm = (BitsN.B(0x0,64)))) then ("mov",String.concat[s_regp(wide,d),", ",s_regp(wide,n)]) else if setflags andalso (d = (BitsN.B(0x1F,5))) then (if sub_op then "cmp" else "cmn", (s_regp(wide,n)) ^ (s_shifted_imm 64 imm)) else ((if sub_op then "sub" else "add") ^ (if setflags then "s" else ""), String.concat [if setflags then s_regz(wide,d) else s_regp(wide,d),", ", s_regp(wide,n),s_shifted_imm 64 imm]) end | AddSubShiftedRegister''32 (sf,(sub_op,(setflags,(shift_type,(m,(imm,(n,d))))))) => let val wide = (BitsN.size sf) = 64 in if setflags andalso (d = (BitsN.B(0x1F,5))) then (if sub_op then "cmp" else "cmn", (s_reg2z(wide,(n,m))) ^ (s_shift_amount(shift_type,BitsN.toNat imm))) else ((if sub_op then "sub" else "add") ^ (if setflags then "s" else ""), (s_reg3z(wide,(d,(n,m)))) ^ (s_shift_amount(shift_type,BitsN.toNat imm))) end | AddSubShiftedRegister''64 (sf,(sub_op,(setflags,(shift_type,(m,(imm,(n,d))))))) => let val wide = (BitsN.size sf) = 64 in if setflags andalso (d = (BitsN.B(0x1F,5))) then (if sub_op then "cmp" else "cmn", (s_reg2z(wide,(n,m))) ^ (s_shift_amount(shift_type,BitsN.toNat imm))) else ((if sub_op then "sub" else "add") ^ (if setflags then "s" else ""), (s_reg3z(wide,(d,(n,m)))) ^ (s_shift_amount(shift_type,BitsN.toNat imm))) end | LogicalImmediate''32(sf,(opc,(setflags,(imm,(n,d))))) => let val wide = (BitsN.size sf) = 64 in if (opc = LogicalOp_ORR) andalso (n = (BitsN.B(0x1F,5))) then ("mov",(s_regp(wide,d)) ^ (s_imm 32 imm)) else ((s_logical_op opc) ^ (if setflags then "s" else ""), String.concat [if setflags then s_regz(wide,d) else s_regp(wide,d),", ", s_regz(wide,n),s_imm 32 imm]) end | LogicalImmediate''64(sf,(opc,(setflags,(imm,(n,d))))) => let val wide = (BitsN.size sf) = 64 in if (opc = LogicalOp_ORR) andalso (n = (BitsN.B(0x1F,5))) then ("mov",(s_regp(wide,d)) ^ (s_imm 64 imm)) else ((s_logical_op opc) ^ (if setflags then "s" else ""), String.concat [if setflags then s_regz(wide,d) else s_regp(wide,d),", ", s_regz(wide,n),s_imm 64 imm]) end | LogicalShiftedRegister''32 (sf,(opc,(invert,(setflags,(shift_type,(imm,(m,(n,d)))))))) => let val wide = (BitsN.size sf) = 64 in if (opc = LogicalOp_ORR) andalso ((n = (BitsN.B(0x1F,5))) andalso ((shift_type = ShiftType_LSL) andalso (imm = 0))) then (if invert then "mvn" else "mov", (s_reg2z(wide,(d,m))) ^ (s_shift_amount(shift_type,imm))) else if (opc = LogicalOp_AND) andalso ((not invert) andalso (setflags andalso (d = (BitsN.B(0x1F,5))))) then ("tst", (s_reg2z(wide,(n,m))) ^ (s_shift_amount(shift_type,imm))) else ((if invert then s_invert_logical_op opc else s_logical_op opc) ^ (if setflags then "s" else ""), (s_reg3z(wide,(d,(n,m)))) ^ (s_shift_amount(shift_type,imm))) end | LogicalShiftedRegister''64 (sf,(opc,(invert,(setflags,(shift_type,(imm,(m,(n,d)))))))) => let val wide = (BitsN.size sf) = 64 in if (opc = LogicalOp_ORR) andalso ((n = (BitsN.B(0x1F,5))) andalso ((shift_type = ShiftType_LSL) andalso (imm = 0))) then (if invert then "mvn" else "mov", (s_reg2z(wide,(d,m))) ^ (s_shift_amount(shift_type,imm))) else if (opc = LogicalOp_AND) andalso ((not invert) andalso (setflags andalso (d = (BitsN.B(0x1F,5))))) then ("tst", (s_reg2z(wide,(n,m))) ^ (s_shift_amount(shift_type,imm))) else ((if invert then s_invert_logical_op opc else s_logical_op opc) ^ (if setflags then "s" else ""), (s_reg3z(wide,(d,(n,m)))) ^ (s_shift_amount(shift_type,imm))) end | Shift''32(sf,(shift_type,(m,(n,d)))) => (s_shift_type shift_type,s_reg3z((BitsN.size sf) = 64,(d,(n,m)))) | Shift''64(sf,(shift_type,(m,(n,d)))) => (s_shift_type shift_type,s_reg3z((BitsN.size sf) = 64,(d,(n,m)))) | MoveWide''32(sf,(opc,(hw,(imm,d)))) => let val wide = (BitsN.size sf) = 64 val sh = Nat.*(BitsN.toNat hw,16) in if (opc = MoveWideOp_Z) andalso ((not(imm = (BitsN.B(0x0,16)))) orelse (hw = (BitsN.B(0x0,2)))) then ("mov", (s_regz(wide,d)) ^ (s_imm 64 (BitsN.<<(BitsN.fromNat(BitsN.toNat imm,64),sh)))) else if (opc = MoveWideOp_N) andalso (((not(imm = (BitsN.B(0x0,16)))) orelse (hw = (BitsN.B(0x0,2)))) andalso ((not wide) orelse (not(imm = (BitsN.neg(BitsN.B(0x1,16))))))) then ("mov", (s_regz(wide,d)) ^ (if wide then s_imm 64 (BitsN.~ (BitsN.<< (BitsN.fromNat(BitsN.toNat imm,64),sh))) else s_imm 32 (BitsN.~ (BitsN.<< (BitsN.fromNat(BitsN.toNat imm,32),sh))))) else (s_move_wide_op opc, String.concat [s_regz(wide,d),s_imm 16 imm, if hw = (BitsN.B(0x0,2)) then "" else ", lsl " ^ (s_nat sh)]) end | MoveWide''64(sf,(opc,(hw,(imm,d)))) => let val wide = (BitsN.size sf) = 64 val sh = Nat.*(BitsN.toNat hw,16) in if (opc = MoveWideOp_Z) andalso ((not(imm = (BitsN.B(0x0,16)))) orelse (hw = (BitsN.B(0x0,2)))) then ("mov", (s_regz(wide,d)) ^ (s_imm 64 (BitsN.<<(BitsN.fromNat(BitsN.toNat imm,64),sh)))) else if (opc = MoveWideOp_N) andalso (((not(imm = (BitsN.B(0x0,16)))) orelse (hw = (BitsN.B(0x0,2)))) andalso ((not wide) orelse (not(imm = (BitsN.neg(BitsN.B(0x1,16))))))) then ("mov", (s_regz(wide,d)) ^ (if wide then s_imm 64 (BitsN.~ (BitsN.<< (BitsN.fromNat(BitsN.toNat imm,64),sh))) else s_imm 32 (BitsN.~ (BitsN.<< (BitsN.fromNat(BitsN.toNat imm,32),sh))))) else (s_move_wide_op opc, String.concat [s_regz(wide,d),s_imm 16 imm, if hw = (BitsN.B(0x0,2)) then "" else ", lsl " ^ (s_nat sh)]) end | BitfieldMove''32(sf,(inzero,(extend,(wmask,(tmask,(r,(s,(n,d)))))))) => let val wide = (BitsN.size sf) = 64 val dn = s_reg2z(wide,(d,n)) in case (inzero,extend) of (false,false) => if Nat.<(s,r) then ("bfi", String.concat [dn,", ", if wide then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6))) else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))), s_immn(Nat.+(s,1))]) else ("bfxil", String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))]) | (true,false) => if (wide andalso (s = 63)) orelse ((not wide) andalso (s = 31)) then ("lsr",dn ^ (s_immn r)) else if (Nat.+(s,1)) = r then ("lsl",dn ^ (s_immn(Nat.-(if wide then 63 else 31,s)))) else if (r = 0) andalso (s = 7) then ("uxtb",s_reg2z(false,(d,n))) else if (r = 0) andalso (s = 15) then ("uxth",s_reg2z(false,(d,n))) else if Nat.<(s,r) then ("ubfiz", String.concat [dn,", ", if wide then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6))) else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))), s_immn(Nat.+(s,1))]) else ("ubfx", String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))]) | (true,true) => if (wide andalso (s = 63)) orelse ((not wide) andalso (s = 31)) then ("asr",dn ^ (s_immn r)) else if (r = 0) andalso (s = 7) then ("sxtb",dn) else if (r = 0) andalso (s = 15) then ("sxth",dn) else if (r = 0) andalso (s = 31) then ("sxtw",dn) else if Nat.<(s,r) then ("sbfiz", String.concat [dn,", ", if wide then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6))) else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))), s_immn(Nat.+(s,1))]) else ("sbfx", String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))]) | _ => ("??","") end | BitfieldMove''64(sf,(inzero,(extend,(wmask,(tmask,(r,(s,(n,d)))))))) => let val wide = (BitsN.size sf) = 64 val dn = s_reg2z(wide,(d,n)) in case (inzero,extend) of (false,false) => if Nat.<(s,r) then ("bfi", String.concat [dn,", ", if wide then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6))) else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))), s_immn(Nat.+(s,1))]) else ("bfxil", String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))]) | (true,false) => if (wide andalso (s = 63)) orelse ((not wide) andalso (s = 31)) then ("lsr",dn ^ (s_immn r)) else if (Nat.+(s,1)) = r then ("lsl",dn ^ (s_immn(Nat.-(if wide then 63 else 31,s)))) else if (r = 0) andalso (s = 7) then ("uxtb",s_reg2z(false,(d,n))) else if (r = 0) andalso (s = 15) then ("uxth",s_reg2z(false,(d,n))) else if Nat.<(s,r) then ("ubfiz", String.concat [dn,", ", if wide then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6))) else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))), s_immn(Nat.+(s,1))]) else ("ubfx", String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))]) | (true,true) => if (wide andalso (s = 63)) orelse ((not wide) andalso (s = 31)) then ("asr",dn ^ (s_immn r)) else if (r = 0) andalso (s = 7) then ("sxtb",dn) else if (r = 0) andalso (s = 15) then ("sxth",dn) else if (r = 0) andalso (s = 31) then ("sxtw",dn) else if Nat.<(s,r) then ("sbfiz", String.concat [dn,", ", if wide then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6))) else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))), s_immn(Nat.+(s,1))]) else ("sbfx", String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))]) | _ => ("??","") end | ConditionalCompareImmediate''32(sf,(sub_op,(imm,(cd,(nzcv,n))))) => let val wide = (BitsN.size sf) = 64 in (if sub_op then "ccmp" else "ccmn", String.concat [s_regz(wide,n),s_imm 32 imm,s_nzcv nzcv,", ",s_cond cd]) end | ConditionalCompareImmediate''64(sf,(sub_op,(imm,(cd,(nzcv,n))))) => let val wide = (BitsN.size sf) = 64 in (if sub_op then "ccmp" else "ccmn", String.concat [s_regz(wide,n),s_imm 64 imm,s_nzcv nzcv,", ",s_cond cd]) end | ConditionalCompareRegister''32(sf,(sub_op,(cd,(nzcv,(m,n))))) => let val wide = (BitsN.size sf) = 64 in (if sub_op then "ccmp" else "ccmn", String.concat[s_reg2z(wide,(n,m)),s_nzcv nzcv,", ",s_cond cd]) end | ConditionalCompareRegister''64(sf,(sub_op,(cd,(nzcv,(m,n))))) => let val wide = (BitsN.size sf) = 64 in (if sub_op then "ccmp" else "ccmn", String.concat[s_reg2z(wide,(n,m)),s_nzcv nzcv,", ",s_cond cd]) end | ConditionalSelect''32(sf,(else_inv,(else_inc,(cd,(m,(n,d)))))) => let val wide = (BitsN.size sf) = 64 in case (else_inv,else_inc) of (false,false) => ("csel",String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd]) | (false,true) => if (n = m) andalso ((not(n = (BitsN.B(0x1F,5)))) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))) then ("cinc", String.concat [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)]) else if (n = m) andalso ((n = (BitsN.B(0x1F,5))) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))) then ("cset", String.concat [s_regz(wide,d),", ",invert_cond(s_cond cd)]) else ("csinc", String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd]) | (true,false) => if (n = m) andalso ((not(n = (BitsN.B(0x1F,5)))) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))) then ("cinv", String.concat [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)]) else if (n = m) andalso ((n = (BitsN.B(0x1F,5))) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))) then ("csetm", String.concat [s_regz(wide,d),", ",invert_cond(s_cond cd)]) else ("csinv", String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd]) | (true,true) => if (n = m) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))) then ("cneg", String.concat [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)]) else ("csneg", String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd]) end | ConditionalSelect''64(sf,(else_inv,(else_inc,(cd,(m,(n,d)))))) => let val wide = (BitsN.size sf) = 64 in case (else_inv,else_inc) of (false,false) => ("csel",String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd]) | (false,true) => if (n = m) andalso ((not(n = (BitsN.B(0x1F,5)))) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))) then ("cinc", String.concat [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)]) else if (n = m) andalso ((n = (BitsN.B(0x1F,5))) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))) then ("cset", String.concat [s_regz(wide,d),", ",invert_cond(s_cond cd)]) else ("csinc", String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd]) | (true,false) => if (n = m) andalso ((not(n = (BitsN.B(0x1F,5)))) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))) then ("cinv", String.concat [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)]) else if (n = m) andalso ((n = (BitsN.B(0x1F,5))) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))) then ("csetm", String.concat [s_regz(wide,d),", ",invert_cond(s_cond cd)]) else ("csinv", String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd]) | (true,true) => if (n = m) andalso (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))) then ("cneg", String.concat [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)]) else ("csneg", String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd]) end | CountLeading''32(sf,(count_clz,(n,d))) => (if count_clz then "clz" else "cls", s_reg2z((BitsN.size sf) = 64,(d,n))) | CountLeading''64(sf,(count_clz,(n,d))) => (if count_clz then "clz" else "cls", s_reg2z((BitsN.size sf) = 64,(d,n))) | ExtractRegister''32(sf,(imms,(m,(n,d)))) => let val wide = (BitsN.size sf) = 64 in if n = m then ("ror",String.concat[s_reg2z(wide,(d,n)),", ",s_dec 6 imms]) else ("extr", String.concat[s_reg3z(wide,(d,(n,m))),", ",s_dec 6 imms]) end | ExtractRegister''64(sf,(imms,(m,(n,d)))) => let val wide = (BitsN.size sf) = 64 in if n = m then ("ror",String.concat[s_reg2z(wide,(d,n)),", ",s_dec 6 imms]) else ("extr", String.concat[s_reg3z(wide,(d,(n,m))),", ",s_dec 6 imms]) end | Division''32(sf,(unsigned,(m,(n,d)))) => (if unsigned then "udiv" else "sdiv", s_reg3z((BitsN.size sf) = 64,(d,(n,m)))) | Division''64(sf,(unsigned,(m,(n,d)))) => (if unsigned then "udiv" else "sdiv", s_reg3z((BitsN.size sf) = 64,(d,(n,m)))) | MultiplyAddSub''32(sf,(sub_op,(m,(a,(n,d))))) => let val wide = (BitsN.size sf) = 64 in if a = (BitsN.B(0x1F,5)) then (if sub_op then "mneg" else "mul",s_reg3z(wide,(d,(n,m)))) else (if sub_op then "msub" else "madd",s_reg4z(wide,(d,(n,(m,a))))) end | MultiplyAddSub''64(sf,(sub_op,(m,(a,(n,d))))) => let val wide = (BitsN.size sf) = 64 in if a = (BitsN.B(0x1F,5)) then (if sub_op then "mneg" else "mul",s_reg3z(wide,(d,(n,m)))) else (if sub_op then "msub" else "madd",s_reg4z(wide,(d,(n,(m,a))))) end | MultiplyAddSubLong(sub_op,(signed,(m,(a,(n,d))))) => let val pfx = if signed then "s" else "u" in if a = (BitsN.B(0x1F,5)) then (pfx ^ (if sub_op then "mnegl" else "mull"), String.concat[s_regz(true,d),", ",s_reg2z(false,(n,m))]) else (pfx ^ (if sub_op then "msubl" else "maddl"), String.concat [s_regz(true,d),", ",s_reg2z(false,(n,m)),", ", s_regz(true,a)]) end | MultiplyHigh(signed,(m,(n,d))) => (if signed then "smulh" else "umulh",s_reg3z(true,(d,(n,m)))) | Reverse''32(sf,(opc,(n,d))) => let val wide = (BitsN.size sf) = 64 in (if (not wide) andalso (opc = RevOp_REV32) then "rev" else s_rev_op opc,s_reg2z(wide,(d,n))) end | Reverse''64(sf,(opc,(n,d))) => let val wide = (BitsN.size sf) = 64 in (if (not wide) andalso (opc = RevOp_REV32) then "rev" else s_rev_op opc,s_reg2z(wide,(d,n))) end; fun s_crc ast = case ast of CRC''8(_,(false,(m,(n,d)))) => ("crc32b",s_reg3z(false,(d,(n,m)))) | CRC''16(_,(false,(m,(n,d)))) => ("crc32h",s_reg3z(false,(d,(n,m)))) | CRC''32(_,(false,(m,(n,d)))) => ("crc32w",s_reg3z(false,(d,(n,m)))) | CRC''64(_,(false,(m,(n,d)))) => ("crc32x",String.concat[s_reg2z(false,(d,n)),", ",s_regz(true,m)]) | CRC''8(_,(true,(m,(n,d)))) => ("crc32cb",s_reg3z(false,(d,(n,m)))) | CRC''16(_,(true,(m,(n,d)))) => ("crc32ch",s_reg3z(false,(d,(n,m)))) | CRC''32(_,(true,(m,(n,d)))) => ("crc32cw",s_reg3z(false,(d,(n,m)))) | CRC''64(_,(true,(m,(n,d)))) => ("crc32cx",String.concat[s_reg2z(false,(d,n)),", ",s_regz(true,m)]); fun s_branch ast = case ast of BranchConditional(offset,cd) => ("b." ^ (s_cond cd),s_offset offset) | BranchImmediate(offset,branch_type) => (if branch_type = BranchType_CALL then "bl" else "b",s_offset offset) | BranchRegister(n,branch_type) => (case branch_type of BranchType_JMP => "br" | BranchType_CALL => "blr" | BranchType_RET => "ret" | _ => "??", if (branch_type = BranchType_RET) andalso (n = (BitsN.B(0x1E,5))) then "" else s_regz(true,n)) | CompareAndBranch''32(sf,(iszero,(offset,t))) => let val wide = (BitsN.size sf) = 64 in (if iszero then "cbz" else "cbnz", String.concat[s_regz(wide,t),", ",s_offset offset]) end | CompareAndBranch''64(sf,(iszero,(offset,t))) => let val wide = (BitsN.size sf) = 64 in (if iszero then "cbz" else "cbnz", String.concat[s_regz(wide,t),", ",s_offset offset]) end | TestBitAndBranch''32(sf,(bit_pos,(bit_val,(offset,t)))) => let val wide = (BitsN.size sf) = 64 in (if bit_val then "tbnz" else "tbz", String.concat [s_regz(wide,t),", ",s_dec 6 bit_pos,", ",s_offset offset]) end | TestBitAndBranch''64(sf,(bit_pos,(bit_val,(offset,t)))) => let val wide = (BitsN.size sf) = 64 in (if bit_val then "tbnz" else "tbz", String.concat [s_regz(wide,t),", ",s_dec 6 bit_pos,", ",s_offset offset]) end; fun s_debug ast = case ast of Halt imm => ("hlt",s_hex 16 imm) | DebugSwitch(BitsN.B(0x0,2)) => ("??","") | DebugSwitch LL => ("dcps" ^ (BitsN.toHexString LL),"") | DebugRestore => ("drps","") | Breakpoint imm => ("brk",s_hex 16 imm); fun s_system ast = case ast of ExceptionReturn => ("eret","") | SupervisorCall imm => ("svc",s_hex 16 imm) | HypervisorCall imm => ("hvc",s_hex 16 imm) | SecureMonitorCall imm => ("smc",s_hex 16 imm) | _ => ("?? system ??",""); fun s_load_store ast = case ast of LoadStoreImmediate''8 (size, (regsize_word, (memop, (acctype, (signed, (_,(_,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else let val N = BitsN.size size val wide = (N = 64) orelse (signed andalso ((N = 32) orelse (not regsize_word))) val sfx = case N of 8 => "b" | 16 => "h" | 32 => if signed then "w" else "" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ld" else "st", if acctype = AccType_UNPRIV then "t" else if unsigned_offset orelse wback then "" else "u", if signed then "rs" else "r",sfx], String.concat [s_regz(wide,rt),", [",s_regp(true,rn), if postindex then "]" ^ (s_signed_imm offset) else String.concat [if offset = (BitsN.B(0x0,64)) then "" else if unsigned_offset then s_imm 64 offset else s_signed_imm offset,"]", if wback then "!" else ""]]) end) | LoadStoreImmediate''16 (size, (regsize_word, (memop, (acctype, (signed, (_,(_,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else let val N = BitsN.size size val wide = (N = 64) orelse (signed andalso ((N = 32) orelse (not regsize_word))) val sfx = case N of 8 => "b" | 16 => "h" | 32 => if signed then "w" else "" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ld" else "st", if acctype = AccType_UNPRIV then "t" else if unsigned_offset orelse wback then "" else "u", if signed then "rs" else "r",sfx], String.concat [s_regz(wide,rt),", [",s_regp(true,rn), if postindex then "]" ^ (s_signed_imm offset) else String.concat [if offset = (BitsN.B(0x0,64)) then "" else if unsigned_offset then s_imm 64 offset else s_signed_imm offset,"]", if wback then "!" else ""]]) end) | LoadStoreImmediate''32 (size, (regsize_word, (memop, (acctype, (signed, (_,(_,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else let val N = BitsN.size size val wide = (N = 64) orelse (signed andalso ((N = 32) orelse (not regsize_word))) val sfx = case N of 8 => "b" | 16 => "h" | 32 => if signed then "w" else "" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ld" else "st", if acctype = AccType_UNPRIV then "t" else if unsigned_offset orelse wback then "" else "u", if signed then "rs" else "r",sfx], String.concat [s_regz(wide,rt),", [",s_regp(true,rn), if postindex then "]" ^ (s_signed_imm offset) else String.concat [if offset = (BitsN.B(0x0,64)) then "" else if unsigned_offset then s_imm 64 offset else s_signed_imm offset,"]", if wback then "!" else ""]]) end) | LoadStoreImmediate''64 (size, (regsize_word, (memop, (acctype, (signed, (_,(_,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else let val N = BitsN.size size val wide = (N = 64) orelse (signed andalso ((N = 32) orelse (not regsize_word))) val sfx = case N of 8 => "b" | 16 => "h" | 32 => if signed then "w" else "" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ld" else "st", if acctype = AccType_UNPRIV then "t" else if unsigned_offset orelse wback then "" else "u", if signed then "rs" else "r",sfx], String.concat [s_regz(wide,rt),", [",s_regp(true,rn), if postindex then "]" ^ (s_signed_imm offset) else String.concat [if offset = (BitsN.B(0x0,64)) then "" else if unsigned_offset then s_imm 64 offset else s_signed_imm offset,"]", if wback then "!" else ""]]) end) | LoadStoreRegister''8 (size, (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else let val N = BitsN.size size val wide = (N = 64) orelse (signed andalso ((N = 32) orelse (not regsize_word))) val sfx = case N of 8 => "b" | 16 => "h" | 32 => if signed then "w" else "" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ldr" else "str", if signed then "s" else "",sfx], String.concat [s_regz(wide,rt),", [",s_regp(true,rn),", ", s_regz (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX]), rm), if extend_type = ExtendType_UXTX then if shift = 0 then "" else ", lsl " ^ (s_nat shift) else String.concat [", ",s_extend_type extend_type," ",s_nat shift], "]"]) end) | LoadStoreRegister''16 (size, (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else let val N = BitsN.size size val wide = (N = 64) orelse (signed andalso ((N = 32) orelse (not regsize_word))) val sfx = case N of 8 => "b" | 16 => "h" | 32 => if signed then "w" else "" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ldr" else "str", if signed then "s" else "",sfx], String.concat [s_regz(wide,rt),", [",s_regp(true,rn),", ", s_regz (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX]), rm), if extend_type = ExtendType_UXTX then if shift = 0 then "" else ", lsl " ^ (s_nat shift) else String.concat [", ",s_extend_type extend_type," ",s_nat shift], "]"]) end) | LoadStoreRegister''32 (size, (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else let val N = BitsN.size size val wide = (N = 64) orelse (signed andalso ((N = 32) orelse (not regsize_word))) val sfx = case N of 8 => "b" | 16 => "h" | 32 => if signed then "w" else "" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ldr" else "str", if signed then "s" else "",sfx], String.concat [s_regz(wide,rt),", [",s_regp(true,rn),", ", s_regz (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX]), rm), if extend_type = ExtendType_UXTX then if shift = 0 then "" else ", lsl " ^ (s_nat shift) else String.concat [", ",s_extend_type extend_type," ",s_nat shift], "]"]) end) | LoadStoreRegister''64 (size, (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else let val N = BitsN.size size val wide = (N = 64) orelse (signed andalso ((N = 32) orelse (not regsize_word))) val sfx = case N of 8 => "b" | 16 => "h" | 32 => if signed then "w" else "" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ldr" else "str", if signed then "s" else "",sfx], String.concat [s_regz(wide,rt),", [",s_regp(true,rn),", ", s_regz (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX]), rm), if extend_type = ExtendType_UXTX then if shift = 0 then "" else ", lsl " ^ (s_nat shift) else String.concat [", ",s_extend_type extend_type," ",s_nat shift], "]"]) end) | LoadLiteral''32(size,(memop,(signed,(offset,rt)))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else ("ldr" ^ (if signed then "sw" else ""), String.concat [s_regz(not(size = (BitsN.B(0x0,32))),rt),", ", s_offset offset])) | LoadLiteral''64(size,(memop,(signed,(offset,rt)))) => (if memop = MemOp_PREFETCH then ("?? prefetch ??","") else ("ldr" ^ (if signed then "sw" else ""), String.concat [s_regz(not(size = (BitsN.B(0x0,64))),rt),", ", s_offset offset])) | LoadStorePair''32 (size, (memop, (acctype, (signed,(_,(_,(wback,(postindex,(offset,(rn,(rt,rt2))))))))))) => (String.concat [if memop = MemOp_LOAD then "ld" else "st", if acctype = AccType_STREAM then "np" else "p", if signed andalso (memop = MemOp_LOAD) then "sw" else ""], String.concat [s_reg2z(((BitsN.size size) = 64) orelse signed,(rt,rt2)),", [", s_regp(true,rn), if postindex then "]" ^ (s_signed_imm offset) else String.concat [if offset = (BitsN.B(0x0,64)) then "" else s_signed_imm offset,"]",if wback then "!" else ""]]) | LoadStorePair''64 (size, (memop, (acctype, (signed,(_,(_,(wback,(postindex,(offset,(rn,(rt,rt2))))))))))) => (String.concat [if memop = MemOp_LOAD then "ld" else "st", if acctype = AccType_STREAM then "np" else "p", if signed andalso (memop = MemOp_LOAD) then "sw" else ""], String.concat [s_reg2z(((BitsN.size size) = 64) orelse signed,(rt,rt2)),", [", s_regp(true,rn), if postindex then "]" ^ (s_signed_imm offset) else String.concat [if offset = (BitsN.B(0x0,64)) then "" else s_signed_imm offset,"]",if wback then "!" else ""]]) | LoadStoreAcquire''8 (size,(memop,(acctype,(excl,(_,(_,(rs,(rn,rt)))))))) => let val N = BitsN.size size val sfx = case N of 8 => "b" | 16 => "h" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ld" ^ (if acctype = AccType_ORDERED then "a" else "") else "st" ^ (if acctype = AccType_ORDERED then "l" else ""), if excl then "xr" else "r",sfx], String.concat[s_regz(N = 64,rt),", [",s_regp(true,rn),"]"]) end | LoadStoreAcquire''16 (size,(memop,(acctype,(excl,(_,(_,(rs,(rn,rt)))))))) => let val N = BitsN.size size val sfx = case N of 8 => "b" | 16 => "h" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ld" ^ (if acctype = AccType_ORDERED then "a" else "") else "st" ^ (if acctype = AccType_ORDERED then "l" else ""), if excl then "xr" else "r",sfx], String.concat[s_regz(N = 64,rt),", [",s_regp(true,rn),"]"]) end | LoadStoreAcquire''32 (size,(memop,(acctype,(excl,(_,(_,(rs,(rn,rt)))))))) => let val N = BitsN.size size val sfx = case N of 8 => "b" | 16 => "h" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ld" ^ (if acctype = AccType_ORDERED then "a" else "") else "st" ^ (if acctype = AccType_ORDERED then "l" else ""), if excl then "xr" else "r",sfx], String.concat[s_regz(N = 64,rt),", [",s_regp(true,rn),"]"]) end | LoadStoreAcquire''64 (size,(memop,(acctype,(excl,(_,(_,(rs,(rn,rt)))))))) => let val N = BitsN.size size val sfx = case N of 8 => "b" | 16 => "h" | _ => "" in (String.concat [if memop = MemOp_LOAD then "ld" ^ (if acctype = AccType_ORDERED then "a" else "") else "st" ^ (if acctype = AccType_ORDERED then "l" else ""), if excl then "xr" else "r",sfx], String.concat[s_regz(N = 64,rt),", [",s_regp(true,rn),"]"]) end | LoadStoreAcquirePair''64 (size,(memop,(acctype,(_,(_,(rs,(rn,(rt,rt2)))))))) => ((if memop = MemOp_LOAD then "ld" ^ (if acctype = AccType_ORDERED then "a" else "") else "st" ^ (if acctype = AccType_ORDERED then "l" else "")) ^ "xp", String.concat [if memop = MemOp_STORE then (s_regz(false,rs)) ^ ", " else "", s_reg2z((BitsN.size size) = 128,(rt,rt2)),", [",s_regp(true,rn), "]"]) | LoadStoreAcquirePair''128 (size,(memop,(acctype,(_,(_,(rs,(rn,(rt,rt2)))))))) => ((if memop = MemOp_LOAD then "ld" ^ (if acctype = AccType_ORDERED then "a" else "") else "st" ^ (if acctype = AccType_ORDERED then "l" else "")) ^ "xp", String.concat [if memop = MemOp_STORE then (s_regz(false,rs)) ^ ", " else "", s_reg2z((BitsN.size size) = 128,(rt,rt2)),", [",s_regp(true,rn), "]"]); fun instructionToString ast = case ast of Address(page,(imm,d)) => (if page then "adrp" else "adr", String.concat [s_regz(true,d),", ", s_offset(if page then BitsN.>>(imm,12) else imm)]) | Data d => s_data d | CRCExt c => s_crc c | Branch b => s_branch b | Debug b => s_debug b | Hint h => (s_hint_op h,"") | LoadStore s => s_load_store s | MemoryBarrier(opc,crm) => (s_barrier_op opc,s_dec 4 crm) | System s => s_system s | ClearExclusive crm => ("clrex",s_dec 4 crm) | Unallocated => ("?? unallocated ??","") | Reserved => ("?? reserved ??",""); fun diss s = let val (m,a) = instructionToString (Decode((Option.valOf o BitsN.fromHexString) (s,32))) in if a = "" then m else String.concat[m," ",a] end; end