1(* arm8 - generated by L3 - Wed Oct 11 10:50:34 2017 *)
2
3structure arm8 :> arm8 =
4struct
5
6structure Map = MutableMap
7
8(* -------------------------------------------------------------------------
9   Type declarations
10   ------------------------------------------------------------------------- *)
11
12type ProcState =
13  { C: bool, EL: BitsN.nbit, N: bool, SPS: bool, V: bool, Z: bool }
14
15type TCR_EL1 = { TBI0: bool, TBI1: bool, tcr_el1'rst: BitsN.nbit }
16
17type TCR_EL2_EL3 = { TBI: bool, tcr_el2_el3'rst: BitsN.nbit }
18
19type SCTLRType =
20  { A: bool, E0E: bool, EE: bool, SA: bool, SA0: bool,
21    sctlrtype'rst: BitsN.nbit }
22
23datatype BranchType
24  = BranchType_CALL | BranchType_ERET | BranchType_DBGEXIT
25  | BranchType_RET | BranchType_JMP | BranchType_EXCEPTION
26  | BranchType_UNKNOWN
27
28datatype AccType
29  = AccType_NORMAL | AccType_VEC | AccType_STREAM | AccType_VECSTREAM
30  | AccType_ATOMIC | AccType_ORDERED | AccType_UNPRIV | AccType_IFETCH
31  | AccType_PTW | AccType_DC | AccType_IC | AccType_AT
32
33datatype ShiftType
34  = ShiftType_LSL | ShiftType_LSR | ShiftType_ASR | ShiftType_ROR
35
36datatype ExtendType
37  = ExtendType_UXTB | ExtendType_UXTH | ExtendType_UXTW | ExtendType_UXTX
38  | ExtendType_SXTB | ExtendType_SXTH | ExtendType_SXTW | ExtendType_SXTX
39
40datatype LogicalOp = LogicalOp_AND | LogicalOp_ORR | LogicalOp_EOR
41
42datatype MemOp = MemOp_LOAD | MemOp_STORE | MemOp_PREFETCH
43
44datatype MemBarrierOp
45  = MemBarrierOp_DSB | MemBarrierOp_DMB | MemBarrierOp_ISB
46
47datatype MoveWideOp = MoveWideOp_N | MoveWideOp_Z | MoveWideOp_K
48
49datatype RevOp = RevOp_RBIT | RevOp_REV16 | RevOp_REV32 | RevOp_REV64
50
51datatype SystemHintOp
52  = SystemHintOp_NOP | SystemHintOp_YIELD | SystemHintOp_WFE
53  | SystemHintOp_WFI | SystemHintOp_SEV | SystemHintOp_SEVL
54
55datatype PSTATEField
56  = PSTATEField_DAIFSet | PSTATEField_DAIFClr | PSTATEField_SP
57
58datatype System
59  = ExceptionReturn
60  | HypervisorCall of BitsN.nbit
61  | MoveImmediateProcState of PSTATEField * BitsN.nbit
62  | MoveSystemRegister of
63      bool *
64      (BitsN.nbit *
65       (BitsN.nbit *
66        (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))
67  | SecureMonitorCall of BitsN.nbit
68  | SupervisorCall of BitsN.nbit
69  | SystemInstruction of
70      BitsN.nbit *
71      (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (bool * BitsN.nbit))))
72
73datatype Debug
74  = Breakpoint of BitsN.nbit
75  | DebugRestore
76  | DebugSwitch of BitsN.nbit
77  | Halt of BitsN.nbit
78
79datatype LoadStore
80  = LoadLiteral''32 of
81      BitsN.nbit * (MemOp * (bool * (BitsN.nbit * BitsN.nbit)))
82  | LoadLiteral''64 of
83      BitsN.nbit * (MemOp * (bool * (BitsN.nbit * BitsN.nbit)))
84  | LoadStoreAcquire''16 of
85      BitsN.nbit *
86      (MemOp *
87       (AccType *
88        (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))
89  | LoadStoreAcquire''32 of
90      BitsN.nbit *
91      (MemOp *
92       (AccType *
93        (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))
94  | LoadStoreAcquire''64 of
95      BitsN.nbit *
96      (MemOp *
97       (AccType *
98        (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))
99  | LoadStoreAcquire''8 of
100      BitsN.nbit *
101      (MemOp *
102       (AccType *
103        (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))
104  | LoadStoreAcquirePair''128 of
105      BitsN.nbit *
106      (MemOp *
107       (AccType *
108        (bool *
109         (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))
110  | LoadStoreAcquirePair''64 of
111      BitsN.nbit *
112      (MemOp *
113       (AccType *
114        (bool *
115         (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))
116  | LoadStoreImmediate''16 of
117      BitsN.nbit *
118      (bool *
119       (MemOp *
120        (AccType *
121         (bool *
122          (bool *
123           (bool *
124            (bool *
125             (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))))))
126  | LoadStoreImmediate''32 of
127      BitsN.nbit *
128      (bool *
129       (MemOp *
130        (AccType *
131         (bool *
132          (bool *
133           (bool *
134            (bool *
135             (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))))))
136  | LoadStoreImmediate''64 of
137      BitsN.nbit *
138      (bool *
139       (MemOp *
140        (AccType *
141         (bool *
142          (bool *
143           (bool *
144            (bool *
145             (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))))))
146  | LoadStoreImmediate''8 of
147      BitsN.nbit *
148      (bool *
149       (MemOp *
150        (AccType *
151         (bool *
152          (bool *
153           (bool *
154            (bool *
155             (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))))))
156  | LoadStorePair''32 of
157      BitsN.nbit *
158      (MemOp *
159       (AccType *
160        (bool *
161         (bool *
162          (bool *
163           (bool *
164            (bool *
165             (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))))))
166  | LoadStorePair''64 of
167      BitsN.nbit *
168      (MemOp *
169       (AccType *
170        (bool *
171         (bool *
172          (bool *
173           (bool *
174            (bool *
175             (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))))))
176  | LoadStoreRegister''16 of
177      BitsN.nbit *
178      (bool *
179       (MemOp *
180        (bool *
181         (BitsN.nbit *
182          (ExtendType * (Nat.nat * (BitsN.nbit * BitsN.nbit)))))))
183  | LoadStoreRegister''32 of
184      BitsN.nbit *
185      (bool *
186       (MemOp *
187        (bool *
188         (BitsN.nbit *
189          (ExtendType * (Nat.nat * (BitsN.nbit * BitsN.nbit)))))))
190  | LoadStoreRegister''64 of
191      BitsN.nbit *
192      (bool *
193       (MemOp *
194        (bool *
195         (BitsN.nbit *
196          (ExtendType * (Nat.nat * (BitsN.nbit * BitsN.nbit)))))))
197  | LoadStoreRegister''8 of
198      BitsN.nbit *
199      (bool *
200       (MemOp *
201        (bool *
202         (BitsN.nbit *
203          (ExtendType * (Nat.nat * (BitsN.nbit * BitsN.nbit)))))))
204
205datatype Branch
206  = BranchConditional of BitsN.nbit * BitsN.nbit
207  | BranchImmediate of BitsN.nbit * BranchType
208  | BranchRegister of BitsN.nbit * BranchType
209  | CompareAndBranch''32 of
210      BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit))
211  | CompareAndBranch''64 of
212      BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit))
213  | TestBitAndBranch''32 of
214      BitsN.nbit * (BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit)))
215  | TestBitAndBranch''64 of
216      BitsN.nbit * (BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit)))
217
218datatype CRCExt
219  = CRC''16 of
220      BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
221  | CRC''32 of
222      BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
223  | CRC''64 of
224      BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
225  | CRC''8 of
226      BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
227
228datatype Data
229  = AddSubCarry''32 of
230      BitsN.nbit *
231      (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
232  | AddSubCarry''64 of
233      BitsN.nbit *
234      (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
235  | AddSubExtendRegister''32 of
236      BitsN.nbit *
237      (bool *
238       (bool *
239        (BitsN.nbit *
240         (ExtendType * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))
241  | AddSubExtendRegister''64 of
242      BitsN.nbit *
243      (bool *
244       (bool *
245        (BitsN.nbit *
246         (ExtendType * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))
247  | AddSubImmediate''32 of
248      BitsN.nbit *
249      (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
250  | AddSubImmediate''64 of
251      BitsN.nbit *
252      (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
253  | AddSubShiftedRegister''32 of
254      BitsN.nbit *
255      (bool *
256       (bool *
257        (ShiftType *
258         (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))
259  | AddSubShiftedRegister''64 of
260      BitsN.nbit *
261      (bool *
262       (bool *
263        (ShiftType *
264         (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))))
265  | BitfieldMove''32 of
266      BitsN.nbit *
267      (bool *
268       (bool *
269        (BitsN.nbit *
270         (BitsN.nbit * (Nat.nat * (Nat.nat * (BitsN.nbit * BitsN.nbit)))))))
271  | BitfieldMove''64 of
272      BitsN.nbit *
273      (bool *
274       (bool *
275        (BitsN.nbit *
276         (BitsN.nbit * (Nat.nat * (Nat.nat * (BitsN.nbit * BitsN.nbit)))))))
277  | ConditionalCompareImmediate''32 of
278      BitsN.nbit *
279      (bool *
280       (BitsN.nbit *
281        (BitsN.nbit * ((bool * (bool * (bool * bool))) * BitsN.nbit))))
282  | ConditionalCompareImmediate''64 of
283      BitsN.nbit *
284      (bool *
285       (BitsN.nbit *
286        (BitsN.nbit * ((bool * (bool * (bool * bool))) * BitsN.nbit))))
287  | ConditionalCompareRegister''32 of
288      BitsN.nbit *
289      (bool *
290       (BitsN.nbit *
291        ((bool * (bool * (bool * bool))) * (BitsN.nbit * BitsN.nbit))))
292  | ConditionalCompareRegister''64 of
293      BitsN.nbit *
294      (bool *
295       (BitsN.nbit *
296        ((bool * (bool * (bool * bool))) * (BitsN.nbit * BitsN.nbit))))
297  | ConditionalSelect''32 of
298      BitsN.nbit *
299      (bool *
300       (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))
301  | ConditionalSelect''64 of
302      BitsN.nbit *
303      (bool *
304       (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))
305  | CountLeading''32 of BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit))
306  | CountLeading''64 of BitsN.nbit * (bool * (BitsN.nbit * BitsN.nbit))
307  | Division''32 of
308      BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
309  | Division''64 of
310      BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
311  | ExtractRegister''32 of
312      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
313  | ExtractRegister''64 of
314      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
315  | LogicalImmediate''32 of
316      BitsN.nbit *
317      (LogicalOp * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
318  | LogicalImmediate''64 of
319      BitsN.nbit *
320      (LogicalOp * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
321  | LogicalShiftedRegister''32 of
322      BitsN.nbit *
323      (LogicalOp *
324       (bool *
325        (bool *
326         (ShiftType * (Nat.nat * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))
327  | LogicalShiftedRegister''64 of
328      BitsN.nbit *
329      (LogicalOp *
330       (bool *
331        (bool *
332         (ShiftType * (Nat.nat * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))))
333  | MoveWide''32 of
334      BitsN.nbit * (MoveWideOp * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
335  | MoveWide''64 of
336      BitsN.nbit * (MoveWideOp * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
337  | MultiplyAddSub''32 of
338      BitsN.nbit *
339      (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
340  | MultiplyAddSub''64 of
341      BitsN.nbit *
342      (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
343  | MultiplyAddSubLong of
344      bool *
345      (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
346  | MultiplyHigh of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
347  | Reverse''32 of BitsN.nbit * (RevOp * (BitsN.nbit * BitsN.nbit))
348  | Reverse''64 of BitsN.nbit * (RevOp * (BitsN.nbit * BitsN.nbit))
349  | Shift''32 of
350      BitsN.nbit * (ShiftType * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
351  | Shift''64 of
352      BitsN.nbit * (ShiftType * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
353
354datatype instruction
355  = Address of bool * (BitsN.nbit * BitsN.nbit)
356  | Branch of Branch
357  | CRCExt of CRCExt
358  | ClearExclusive of BitsN.nbit
359  | Data of Data
360  | Debug of Debug
361  | Hint of SystemHintOp
362  | LoadStore of LoadStore
363  | MemoryBarrier of MemBarrierOp * BitsN.nbit
364  | Reserved
365  | System of System
366  | Unallocated
367
368datatype MachineCode = ARM8 of BitsN.nbit | BadCode of string
369
370datatype maybe_instruction
371  = FAIL of string
372  | OK of instruction
373  | PENDING of string * instruction
374  | WORD of BitsN.nbit
375
376(* -------------------------------------------------------------------------
377   Casting maps (for enumerated types)
378   ------------------------------------------------------------------------- *)
379
380structure Cast =
381struct
382fun natToBranchType x =
383  case Nat.toInt x of
384     0 => BranchType_CALL
385   | 1 => BranchType_ERET
386   | 2 => BranchType_DBGEXIT
387   | 3 => BranchType_RET
388   | 4 => BranchType_JMP
389   | 5 => BranchType_EXCEPTION
390   | 6 => BranchType_UNKNOWN
391   | _ => raise Fail "natToBranchType"
392
393fun natToAccType x =
394  case Nat.toInt x of
395     0 => AccType_NORMAL
396   | 1 => AccType_VEC
397   | 2 => AccType_STREAM
398   | 3 => AccType_VECSTREAM
399   | 4 => AccType_ATOMIC
400   | 5 => AccType_ORDERED
401   | 6 => AccType_UNPRIV
402   | 7 => AccType_IFETCH
403   | 8 => AccType_PTW
404   | 9 => AccType_DC
405   | 10 => AccType_IC
406   | 11 => AccType_AT
407   | _ => raise Fail "natToAccType"
408
409fun natToShiftType x =
410  case Nat.toInt x of
411     0 => ShiftType_LSL
412   | 1 => ShiftType_LSR
413   | 2 => ShiftType_ASR
414   | 3 => ShiftType_ROR
415   | _ => raise Fail "natToShiftType"
416
417fun natToExtendType x =
418  case Nat.toInt x of
419     0 => ExtendType_UXTB
420   | 1 => ExtendType_UXTH
421   | 2 => ExtendType_UXTW
422   | 3 => ExtendType_UXTX
423   | 4 => ExtendType_SXTB
424   | 5 => ExtendType_SXTH
425   | 6 => ExtendType_SXTW
426   | 7 => ExtendType_SXTX
427   | _ => raise Fail "natToExtendType"
428
429fun natToLogicalOp x =
430  case Nat.toInt x of
431     0 => LogicalOp_AND
432   | 1 => LogicalOp_ORR
433   | 2 => LogicalOp_EOR
434   | _ => raise Fail "natToLogicalOp"
435
436fun natToMemOp x =
437  case Nat.toInt x of
438     0 => MemOp_LOAD
439   | 1 => MemOp_STORE
440   | 2 => MemOp_PREFETCH
441   | _ => raise Fail "natToMemOp"
442
443fun natToMemBarrierOp x =
444  case Nat.toInt x of
445     0 => MemBarrierOp_DSB
446   | 1 => MemBarrierOp_DMB
447   | 2 => MemBarrierOp_ISB
448   | _ => raise Fail "natToMemBarrierOp"
449
450fun natToMoveWideOp x =
451  case Nat.toInt x of
452     0 => MoveWideOp_N
453   | 1 => MoveWideOp_Z
454   | 2 => MoveWideOp_K
455   | _ => raise Fail "natToMoveWideOp"
456
457fun natToRevOp x =
458  case Nat.toInt x of
459     0 => RevOp_RBIT
460   | 1 => RevOp_REV16
461   | 2 => RevOp_REV32
462   | 3 => RevOp_REV64
463   | _ => raise Fail "natToRevOp"
464
465fun natToSystemHintOp x =
466  case Nat.toInt x of
467     0 => SystemHintOp_NOP
468   | 1 => SystemHintOp_YIELD
469   | 2 => SystemHintOp_WFE
470   | 3 => SystemHintOp_WFI
471   | 4 => SystemHintOp_SEV
472   | 5 => SystemHintOp_SEVL
473   | _ => raise Fail "natToSystemHintOp"
474
475fun natToPSTATEField x =
476  case Nat.toInt x of
477     0 => PSTATEField_DAIFSet
478   | 1 => PSTATEField_DAIFClr
479   | 2 => PSTATEField_SP
480   | _ => raise Fail "natToPSTATEField"
481
482fun BranchTypeToNat x =
483  case x of
484     BranchType_CALL => 0
485   | BranchType_ERET => 1
486   | BranchType_DBGEXIT => 2
487   | BranchType_RET => 3
488   | BranchType_JMP => 4
489   | BranchType_EXCEPTION => 5
490   | BranchType_UNKNOWN => 6
491
492fun AccTypeToNat x =
493  case x of
494     AccType_NORMAL => 0
495   | AccType_VEC => 1
496   | AccType_STREAM => 2
497   | AccType_VECSTREAM => 3
498   | AccType_ATOMIC => 4
499   | AccType_ORDERED => 5
500   | AccType_UNPRIV => 6
501   | AccType_IFETCH => 7
502   | AccType_PTW => 8
503   | AccType_DC => 9
504   | AccType_IC => 10
505   | AccType_AT => 11
506
507fun ShiftTypeToNat x =
508  case x of
509     ShiftType_LSL => 0
510   | ShiftType_LSR => 1
511   | ShiftType_ASR => 2
512   | ShiftType_ROR => 3
513
514fun ExtendTypeToNat x =
515  case x of
516     ExtendType_UXTB => 0
517   | ExtendType_UXTH => 1
518   | ExtendType_UXTW => 2
519   | ExtendType_UXTX => 3
520   | ExtendType_SXTB => 4
521   | ExtendType_SXTH => 5
522   | ExtendType_SXTW => 6
523   | ExtendType_SXTX => 7
524
525fun LogicalOpToNat x =
526  case x of
527     LogicalOp_AND => 0 | LogicalOp_ORR => 1 | LogicalOp_EOR => 2
528
529fun MemOpToNat x =
530  case x of
531     MemOp_LOAD => 0 | MemOp_STORE => 1 | MemOp_PREFETCH => 2
532
533fun MemBarrierOpToNat x =
534  case x of
535     MemBarrierOp_DSB => 0 | MemBarrierOp_DMB => 1 | MemBarrierOp_ISB => 2
536
537fun MoveWideOpToNat x =
538  case x of
539     MoveWideOp_N => 0 | MoveWideOp_Z => 1 | MoveWideOp_K => 2
540
541fun RevOpToNat x =
542  case x of
543     RevOp_RBIT => 0
544   | RevOp_REV16 => 1
545   | RevOp_REV32 => 2
546   | RevOp_REV64 => 3
547
548fun SystemHintOpToNat x =
549  case x of
550     SystemHintOp_NOP => 0
551   | SystemHintOp_YIELD => 1
552   | SystemHintOp_WFE => 2
553   | SystemHintOp_WFI => 3
554   | SystemHintOp_SEV => 4
555   | SystemHintOp_SEVL => 5
556
557fun PSTATEFieldToNat x =
558  case x of
559     PSTATEField_DAIFSet => 0
560   | PSTATEField_DAIFClr => 1
561   | PSTATEField_SP => 2
562
563fun BranchTypeToString x =
564  case x of
565     BranchType_CALL => "BranchType_CALL"
566   | BranchType_ERET => "BranchType_ERET"
567   | BranchType_DBGEXIT => "BranchType_DBGEXIT"
568   | BranchType_RET => "BranchType_RET"
569   | BranchType_JMP => "BranchType_JMP"
570   | BranchType_EXCEPTION => "BranchType_EXCEPTION"
571   | BranchType_UNKNOWN => "BranchType_UNKNOWN"
572
573fun AccTypeToString x =
574  case x of
575     AccType_NORMAL => "AccType_NORMAL"
576   | AccType_VEC => "AccType_VEC"
577   | AccType_STREAM => "AccType_STREAM"
578   | AccType_VECSTREAM => "AccType_VECSTREAM"
579   | AccType_ATOMIC => "AccType_ATOMIC"
580   | AccType_ORDERED => "AccType_ORDERED"
581   | AccType_UNPRIV => "AccType_UNPRIV"
582   | AccType_IFETCH => "AccType_IFETCH"
583   | AccType_PTW => "AccType_PTW"
584   | AccType_DC => "AccType_DC"
585   | AccType_IC => "AccType_IC"
586   | AccType_AT => "AccType_AT"
587
588fun ShiftTypeToString x =
589  case x of
590     ShiftType_LSL => "ShiftType_LSL"
591   | ShiftType_LSR => "ShiftType_LSR"
592   | ShiftType_ASR => "ShiftType_ASR"
593   | ShiftType_ROR => "ShiftType_ROR"
594
595fun ExtendTypeToString x =
596  case x of
597     ExtendType_UXTB => "ExtendType_UXTB"
598   | ExtendType_UXTH => "ExtendType_UXTH"
599   | ExtendType_UXTW => "ExtendType_UXTW"
600   | ExtendType_UXTX => "ExtendType_UXTX"
601   | ExtendType_SXTB => "ExtendType_SXTB"
602   | ExtendType_SXTH => "ExtendType_SXTH"
603   | ExtendType_SXTW => "ExtendType_SXTW"
604   | ExtendType_SXTX => "ExtendType_SXTX"
605
606fun LogicalOpToString x =
607  case x of
608     LogicalOp_AND => "LogicalOp_AND"
609   | LogicalOp_ORR => "LogicalOp_ORR"
610   | LogicalOp_EOR => "LogicalOp_EOR"
611
612fun MemOpToString x =
613  case x of
614     MemOp_LOAD => "MemOp_LOAD"
615   | MemOp_STORE => "MemOp_STORE"
616   | MemOp_PREFETCH => "MemOp_PREFETCH"
617
618fun MemBarrierOpToString x =
619  case x of
620     MemBarrierOp_DSB => "MemBarrierOp_DSB"
621   | MemBarrierOp_DMB => "MemBarrierOp_DMB"
622   | MemBarrierOp_ISB => "MemBarrierOp_ISB"
623
624fun MoveWideOpToString x =
625  case x of
626     MoveWideOp_N => "MoveWideOp_N"
627   | MoveWideOp_Z => "MoveWideOp_Z"
628   | MoveWideOp_K => "MoveWideOp_K"
629
630fun RevOpToString x =
631  case x of
632     RevOp_RBIT => "RevOp_RBIT"
633   | RevOp_REV16 => "RevOp_REV16"
634   | RevOp_REV32 => "RevOp_REV32"
635   | RevOp_REV64 => "RevOp_REV64"
636
637fun SystemHintOpToString x =
638  case x of
639     SystemHintOp_NOP => "SystemHintOp_NOP"
640   | SystemHintOp_YIELD => "SystemHintOp_YIELD"
641   | SystemHintOp_WFE => "SystemHintOp_WFE"
642   | SystemHintOp_WFI => "SystemHintOp_WFI"
643   | SystemHintOp_SEV => "SystemHintOp_SEV"
644   | SystemHintOp_SEVL => "SystemHintOp_SEVL"
645
646fun PSTATEFieldToString x =
647  case x of
648     PSTATEField_DAIFSet => "PSTATEField_DAIFSet"
649   | PSTATEField_DAIFClr => "PSTATEField_DAIFClr"
650   | PSTATEField_SP => "PSTATEField_SP"
651
652fun stringToBranchType x =
653  case x of
654     "BranchType_CALL" => BranchType_CALL
655   | "BranchType_ERET" => BranchType_ERET
656   | "BranchType_DBGEXIT" => BranchType_DBGEXIT
657   | "BranchType_RET" => BranchType_RET
658   | "BranchType_JMP" => BranchType_JMP
659   | "BranchType_EXCEPTION" => BranchType_EXCEPTION
660   | "BranchType_UNKNOWN" => BranchType_UNKNOWN
661   | _ => raise Fail "stringToBranchType"
662
663fun stringToAccType x =
664  case x of
665     "AccType_NORMAL" => AccType_NORMAL
666   | "AccType_VEC" => AccType_VEC
667   | "AccType_STREAM" => AccType_STREAM
668   | "AccType_VECSTREAM" => AccType_VECSTREAM
669   | "AccType_ATOMIC" => AccType_ATOMIC
670   | "AccType_ORDERED" => AccType_ORDERED
671   | "AccType_UNPRIV" => AccType_UNPRIV
672   | "AccType_IFETCH" => AccType_IFETCH
673   | "AccType_PTW" => AccType_PTW
674   | "AccType_DC" => AccType_DC
675   | "AccType_IC" => AccType_IC
676   | "AccType_AT" => AccType_AT
677   | _ => raise Fail "stringToAccType"
678
679fun stringToShiftType x =
680  case x of
681     "ShiftType_LSL" => ShiftType_LSL
682   | "ShiftType_LSR" => ShiftType_LSR
683   | "ShiftType_ASR" => ShiftType_ASR
684   | "ShiftType_ROR" => ShiftType_ROR
685   | _ => raise Fail "stringToShiftType"
686
687fun stringToExtendType x =
688  case x of
689     "ExtendType_UXTB" => ExtendType_UXTB
690   | "ExtendType_UXTH" => ExtendType_UXTH
691   | "ExtendType_UXTW" => ExtendType_UXTW
692   | "ExtendType_UXTX" => ExtendType_UXTX
693   | "ExtendType_SXTB" => ExtendType_SXTB
694   | "ExtendType_SXTH" => ExtendType_SXTH
695   | "ExtendType_SXTW" => ExtendType_SXTW
696   | "ExtendType_SXTX" => ExtendType_SXTX
697   | _ => raise Fail "stringToExtendType"
698
699fun stringToLogicalOp x =
700  case x of
701     "LogicalOp_AND" => LogicalOp_AND
702   | "LogicalOp_ORR" => LogicalOp_ORR
703   | "LogicalOp_EOR" => LogicalOp_EOR
704   | _ => raise Fail "stringToLogicalOp"
705
706fun stringToMemOp x =
707  case x of
708     "MemOp_LOAD" => MemOp_LOAD
709   | "MemOp_STORE" => MemOp_STORE
710   | "MemOp_PREFETCH" => MemOp_PREFETCH
711   | _ => raise Fail "stringToMemOp"
712
713fun stringToMemBarrierOp x =
714  case x of
715     "MemBarrierOp_DSB" => MemBarrierOp_DSB
716   | "MemBarrierOp_DMB" => MemBarrierOp_DMB
717   | "MemBarrierOp_ISB" => MemBarrierOp_ISB
718   | _ => raise Fail "stringToMemBarrierOp"
719
720fun stringToMoveWideOp x =
721  case x of
722     "MoveWideOp_N" => MoveWideOp_N
723   | "MoveWideOp_Z" => MoveWideOp_Z
724   | "MoveWideOp_K" => MoveWideOp_K
725   | _ => raise Fail "stringToMoveWideOp"
726
727fun stringToRevOp x =
728  case x of
729     "RevOp_RBIT" => RevOp_RBIT
730   | "RevOp_REV16" => RevOp_REV16
731   | "RevOp_REV32" => RevOp_REV32
732   | "RevOp_REV64" => RevOp_REV64
733   | _ => raise Fail "stringToRevOp"
734
735fun stringToSystemHintOp x =
736  case x of
737     "SystemHintOp_NOP" => SystemHintOp_NOP
738   | "SystemHintOp_YIELD" => SystemHintOp_YIELD
739   | "SystemHintOp_WFE" => SystemHintOp_WFE
740   | "SystemHintOp_WFI" => SystemHintOp_WFI
741   | "SystemHintOp_SEV" => SystemHintOp_SEV
742   | "SystemHintOp_SEVL" => SystemHintOp_SEVL
743   | _ => raise Fail "stringToSystemHintOp"
744
745fun stringToPSTATEField x =
746  case x of
747     "PSTATEField_DAIFSet" => PSTATEField_DAIFSet
748   | "PSTATEField_DAIFClr" => PSTATEField_DAIFClr
749   | "PSTATEField_SP" => PSTATEField_SP
750   | _ => raise Fail "stringToPSTATEField"
751end
752
753(* -------------------------------------------------------------------------
754   Record update functions
755   ------------------------------------------------------------------------- *)
756
757fun ProcState_C_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') =
758  {C = x', EL = EL, N = N, SPS = SPS, V = V, Z = Z}: ProcState
759
760fun ProcState_EL_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') =
761  {C = C, EL = x', N = N, SPS = SPS, V = V, Z = Z}: ProcState
762
763fun ProcState_N_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') =
764  {C = C, EL = EL, N = x', SPS = SPS, V = V, Z = Z}: ProcState
765
766fun ProcState_SPS_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') =
767  {C = C, EL = EL, N = N, SPS = x', V = V, Z = Z}: ProcState
768
769fun ProcState_V_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') =
770  {C = C, EL = EL, N = N, SPS = SPS, V = x', Z = Z}: ProcState
771
772fun ProcState_Z_rupd ({C, EL, N, SPS, V, Z}: ProcState, x') =
773  {C = C, EL = EL, N = N, SPS = SPS, V = V, Z = x'}: ProcState
774
775fun TCR_EL1_TBI0_rupd ({TBI0, TBI1, tcr_el1'rst}: TCR_EL1, x') =
776  {TBI0 = x', TBI1 = TBI1, tcr_el1'rst = tcr_el1'rst}: TCR_EL1
777
778fun TCR_EL1_TBI1_rupd ({TBI0, TBI1, tcr_el1'rst}: TCR_EL1, x') =
779  {TBI0 = TBI0, TBI1 = x', tcr_el1'rst = tcr_el1'rst}: TCR_EL1
780
781fun TCR_EL1_tcr_el1'rst_rupd ({TBI0, TBI1, tcr_el1'rst}: TCR_EL1, x') =
782  {TBI0 = TBI0, TBI1 = TBI1, tcr_el1'rst = x'}: TCR_EL1
783
784fun TCR_EL2_EL3_TBI_rupd ({TBI, tcr_el2_el3'rst}: TCR_EL2_EL3, x') =
785  {TBI = x', tcr_el2_el3'rst = tcr_el2_el3'rst}: TCR_EL2_EL3
786
787fun TCR_EL2_EL3_tcr_el2_el3'rst_rupd ({TBI, tcr_el2_el3'rst}
788  : TCR_EL2_EL3, x') = {TBI = TBI, tcr_el2_el3'rst = x'}: TCR_EL2_EL3
789
790fun SCTLRType_A_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst}
791  : SCTLRType, x') =
792  {A = x', E0E = E0E, EE = EE, SA = SA, SA0 = SA0,
793   sctlrtype'rst = sctlrtype'rst}: SCTLRType
794
795fun SCTLRType_E0E_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst}
796  : SCTLRType, x') =
797  {A = A, E0E = x', EE = EE, SA = SA, SA0 = SA0,
798   sctlrtype'rst = sctlrtype'rst}: SCTLRType
799
800fun SCTLRType_EE_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst}
801  : SCTLRType, x') =
802  {A = A, E0E = E0E, EE = x', SA = SA, SA0 = SA0,
803   sctlrtype'rst = sctlrtype'rst}: SCTLRType
804
805fun SCTLRType_SA_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst}
806  : SCTLRType, x') =
807  {A = A, E0E = E0E, EE = EE, SA = x', SA0 = SA0,
808   sctlrtype'rst = sctlrtype'rst}: SCTLRType
809
810fun SCTLRType_SA0_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst}
811  : SCTLRType, x') =
812  {A = A, E0E = E0E, EE = EE, SA = SA, SA0 = x',
813   sctlrtype'rst = sctlrtype'rst}: SCTLRType
814
815fun SCTLRType_sctlrtype'rst_rupd ({A, E0E, EE, SA, SA0, sctlrtype'rst}
816  : SCTLRType, x') =
817  {A = A, E0E = E0E, EE = EE, SA = SA, SA0 = SA0, sctlrtype'rst = x'}
818  : SCTLRType
819
820(* -------------------------------------------------------------------------
821   Exceptions
822   ------------------------------------------------------------------------- *)
823
824exception ALIGNMENT_FAULT
825
826exception ASSERT of string
827
828exception UNDEFINED_FAULT of string
829
830(* -------------------------------------------------------------------------
831   Global variables (state)
832   ------------------------------------------------------------------------- *)
833
834val MEM = ref (Map.mkMap(SOME 18446744073709551616,BitsN.B(0x0,8)))
835  : (BitsN.nbit Map.map) ref
836
837val PC = ref (BitsN.B(0x0,64)): BitsN.nbit ref
838
839val PSTATE = ref
840  ({C = false, EL = BitsN.B(0x0,2), N = false, SPS = false, V = false,
841    Z = false}): ProcState ref
842
843val REG = ref (Map.mkMap(SOME 32,BitsN.B(0x0,64)))
844  : (BitsN.nbit Map.map) ref
845
846val SCTLR_EL1 = ref
847  ({A = false, E0E = false, EE = false, SA = false, SA0 = false,
848    sctlrtype'rst = BitsN.B(0x0,27)}): SCTLRType ref
849
850val SCTLR_EL2 = ref
851  ({A = false, E0E = false, EE = false, SA = false, SA0 = false,
852    sctlrtype'rst = BitsN.B(0x0,27)}): SCTLRType ref
853
854val SCTLR_EL3 = ref
855  ({A = false, E0E = false, EE = false, SA = false, SA0 = false,
856    sctlrtype'rst = BitsN.B(0x0,27)}): SCTLRType ref
857
858val SP_EL0 = ref (BitsN.B(0x0,64)): BitsN.nbit ref
859
860val SP_EL1 = ref (BitsN.B(0x0,64)): BitsN.nbit ref
861
862val SP_EL2 = ref (BitsN.B(0x0,64)): BitsN.nbit ref
863
864val SP_EL3 = ref (BitsN.B(0x0,64)): BitsN.nbit ref
865
866val TCR_EL1 = ref
867  ({TBI0 = false, TBI1 = false, tcr_el1'rst = BitsN.B(0x0,62)})
868  : TCR_EL1 ref
869
870val TCR_EL2 = ref ({TBI = false, tcr_el2_el3'rst = BitsN.B(0x0,31)})
871  : TCR_EL2_EL3 ref
872
873val TCR_EL3 = ref ({TBI = false, tcr_el2_el3'rst = BitsN.B(0x0,31)})
874  : TCR_EL2_EL3 ref
875
876val branch_hint = ref (NONE): (BranchType option) ref
877
878(* -------------------------------------------------------------------------
879   Main specification
880   ------------------------------------------------------------------------- *)
881
882local
883  fun tuple'32 [t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,
884                t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,
885                t31] =
886    (t0,
887     (t1,
888      (t2,
889       (t3,
890        (t4,
891         (t5,
892          (t6,
893           (t7,
894            (t8,
895             (t9,
896              (t10,
897               (t11,
898                (t12,
899                 (t13,
900                  (t14,
901                   (t15,
902                    (t16,
903                     (t17,
904                      (t18,
905                       (t19,
906                        (t20,
907                         (t21,
908                          (t22,
909                           (t23,
910                            (t24,(t25,(t26,(t27,(t28,(t29,(t30,t31)))))))))))))))))))))))))))))))
911    | tuple'32 (_: bool list) = raise Fail "tuple'32"
912in
913  val boolify'32 = tuple'32 o BitsN.toList
914end
915
916fun rec'TCR_EL1 x =
917  {TBI0 = BitsN.bit(x,37), TBI1 = BitsN.bit(x,38),
918   tcr_el1'rst = BitsN.@@(BitsN.bits(36,0) x,BitsN.bits(63,39) x)};
919
920fun reg'TCR_EL1 x =
921  case x of
922     {TBI0 = TBI0, TBI1 = TBI1, tcr_el1'rst = tcr_el1'rst} =>
923       BitsN.concat
924         [BitsN.bits(24,0) tcr_el1'rst,BitsN.fromBit TBI1,
925          BitsN.fromBit TBI0,BitsN.bits(61,25) tcr_el1'rst];
926
927fun write'rec'TCR_EL1 (_,x) = reg'TCR_EL1 x;
928
929fun write'reg'TCR_EL1 (_,x) = rec'TCR_EL1 x;
930
931fun rec'TCR_EL2_EL3 x =
932  {TBI = BitsN.bit(x,20),
933   tcr_el2_el3'rst = BitsN.@@(BitsN.bits(19,0) x,BitsN.bits(31,21) x)};
934
935fun reg'TCR_EL2_EL3 x =
936  case x of
937     {TBI = TBI, tcr_el2_el3'rst = tcr_el2_el3'rst} =>
938       BitsN.concat
939         [BitsN.bits(10,0) tcr_el2_el3'rst,BitsN.fromBit TBI,
940          BitsN.bits(30,11) tcr_el2_el3'rst];
941
942fun write'rec'TCR_EL2_EL3 (_,x) = reg'TCR_EL2_EL3 x;
943
944fun write'reg'TCR_EL2_EL3 (_,x) = rec'TCR_EL2_EL3 x;
945
946fun rec'SCTLRType x =
947  {A = BitsN.bit(x,1), E0E = BitsN.bit(x,24), EE = BitsN.bit(x,25),
948   SA = BitsN.bit(x,3), SA0 = BitsN.bit(x,4),
949   sctlrtype'rst =
950     BitsN.concat
951       [BitsN.bits(0,0) x,BitsN.bits(2,2) x,BitsN.bits(23,5) x,
952        BitsN.bits(31,26) x]};
953
954fun reg'SCTLRType x =
955  case x of
956     {A = A, E0E = E0E, EE = EE, SA = SA, SA0 = SA0,
957      sctlrtype'rst = sctlrtype'rst} =>
958       BitsN.concat
959         [BitsN.bits(5,0) sctlrtype'rst,BitsN.fromBit EE,
960          BitsN.fromBit E0E,BitsN.bits(24,6) sctlrtype'rst,
961          BitsN.fromBit SA0,BitsN.fromBit SA,
962          BitsN.bits(25,25) sctlrtype'rst,BitsN.fromBit A,
963          BitsN.bits(26,26) sctlrtype'rst];
964
965fun write'rec'SCTLRType (_,x) = reg'SCTLRType x;
966
967fun write'reg'SCTLRType (_,x) = rec'SCTLRType x;
968
969fun X N n =
970  if n = (BitsN.B(0x1F,5))
971    then BitsN.BV(0x0,N)
972  else BitsN.fromNat(BitsN.toNat(Map.lookup((!REG),BitsN.toNat n)),N);
973
974fun write'X N (value,n) =
975  if not(n = (BitsN.B(0x1F,5)))
976    then REG :=
977         (Map.update
978            ((!REG),BitsN.toNat n,BitsN.fromNat(BitsN.toNat value,64)))
979  else ();
980
981fun SP N =
982  let
983    val sp =
984      if not(#SPS((!PSTATE) : ProcState))
985        then (!SP_EL0)
986      else case #EL((!PSTATE) : ProcState) of
987              BitsN.B(0x0,_) => (!SP_EL0)
988            | BitsN.B(0x1,_) => (!SP_EL1)
989            | BitsN.B(0x2,_) => (!SP_EL2)
990            | BitsN.B(0x3,_) => (!SP_EL3)
991            | _ => raise General.Bind
992  in
993    BitsN.fromNat(BitsN.toNat sp,N)
994  end;
995
996fun write'SP N value =
997  let
998    val v = BitsN.fromNat(BitsN.toNat value,64)
999  in
1000    if not(#SPS((!PSTATE) : ProcState))
1001      then SP_EL0 := v
1002    else case #EL((!PSTATE) : ProcState) of
1003            BitsN.B(0x0,_) => SP_EL0 := v
1004          | BitsN.B(0x1,_) => SP_EL1 := v
1005          | BitsN.B(0x2,_) => SP_EL2 := v
1006          | BitsN.B(0x3,_) => SP_EL3 := v
1007          | _ => raise General.Bind
1008  end;
1009
1010fun TranslationRegime () =
1011  if not((#EL((!PSTATE) : ProcState)) = (BitsN.B(0x0,2)))
1012    then #EL((!PSTATE) : ProcState)
1013  else BitsN.B(0x1,2);
1014
1015fun SCTLR () =
1016  let
1017    val regime = TranslationRegime ()
1018  in
1019    case regime of
1020       BitsN.B(0x1,_) => (!SCTLR_EL1)
1021     | BitsN.B(0x2,_) => (!SCTLR_EL2)
1022     | BitsN.B(0x3,_) => (!SCTLR_EL3)
1023     | BitsN.B(0x0,_) =>
1024       {A = false, E0E = false, EE = false, SA = false, SA0 = false,
1025        sctlrtype'rst = BitsN.B(0x0,27)}
1026     | _ => raise General.Bind
1027  end;
1028
1029fun Hint_Branch branch_type = branch_hint := (Option.SOME branch_type);
1030
1031fun BranchTo (target0,branch_type) =
1032  let
1033    val target = ref target0
1034  in
1035    ( Hint_Branch branch_type
1036    ; case #EL((!PSTATE) : ProcState) of
1037         BitsN.B(0x0,_) =>
1038           ( if (BitsN.bit((!target),55)) andalso
1039                (#TBI1((!TCR_EL1) : TCR_EL1))
1040               then target :=
1041                    (BitsN.bitFieldInsert(63,56)
1042                       ((!target),BitsN.B(0xFF,8)))
1043             else ()
1044           ; if (not(BitsN.bit((!target),55))) andalso
1045                (#TBI0((!TCR_EL1) : TCR_EL1))
1046               then target :=
1047                    (BitsN.bitFieldInsert(63,56)
1048                       ((!target),BitsN.B(0x0,8)))
1049             else ()
1050           )
1051       | BitsN.B(0x1,_) =>
1052         ( if (BitsN.bit((!target),55)) andalso
1053              (#TBI1((!TCR_EL1) : TCR_EL1))
1054             then target :=
1055                  (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0xFF,8)))
1056           else ()
1057         ; if (not(BitsN.bit((!target),55))) andalso
1058              (#TBI0((!TCR_EL1) : TCR_EL1))
1059             then target :=
1060                  (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0x0,8)))
1061           else ()
1062         )
1063       | BitsN.B(0x2,_) =>
1064         if #TBI((!TCR_EL2) : TCR_EL2_EL3)
1065           then target :=
1066                (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0x0,8)))
1067         else ()
1068       | BitsN.B(0x3,_) =>
1069         if #TBI((!TCR_EL3) : TCR_EL2_EL3)
1070           then target :=
1071                (BitsN.bitFieldInsert(63,56) ((!target),BitsN.B(0x0,8)))
1072         else ()
1073       | _ => raise General.Bind
1074    ; PC := (!target)
1075    )
1076  end;
1077
1078fun Align N (w,n) = BitsN.fromNat(Nat.*(n,Nat.div(BitsN.toNat w,n)),N);
1079
1080fun Aligned N (w,n) = w = (Align N (w,n));
1081
1082fun CheckSPAlignment () =
1083  let
1084    val sp = SP 64
1085    val stack_align_check =
1086      if (#EL((!PSTATE) : ProcState)) = (BitsN.B(0x0,2))
1087        then #SA0((!SCTLR_EL1) : SCTLRType)
1088      else #SA((SCTLR ()) : SCTLRType)
1089  in
1090    if stack_align_check andalso (not(Aligned 64 (sp,16)))
1091      then raise ALIGNMENT_FAULT
1092    else ()
1093  end;
1094
1095fun CheckAlignment (address,(size,(acctype,iswrite))) =
1096  if (not(Aligned 64 (address,size))) andalso
1097     ((acctype = AccType_ATOMIC) orelse
1098      ((acctype = AccType_ORDERED) orelse (#A((SCTLR ()) : SCTLRType))))
1099    then raise ALIGNMENT_FAULT
1100  else ();
1101
1102fun BigEndian () =
1103  if (#EL((!PSTATE) : ProcState)) = (BitsN.B(0x0,2))
1104    then #E0E((!SCTLR_EL1) : SCTLRType)
1105  else #EE((SCTLR ()) : SCTLRType);
1106
1107fun ByteList l =
1108  case l of
1109     [] => []
1110   | b0 :: (b1 :: (b2 :: (b3 :: (b4 :: (b5 :: (b6 :: (v7 :: rest))))))) =>
1111     [b0,b1,b2,b3,b4,b5,b6,v7] :: (ByteList rest)
1112   | rest => [rest];
1113
1114fun BigEndianReverse l = List.concat(List.rev(ByteList l));
1115
1116fun Mem N (address,(size,acctype)) =
1117  ( CheckAlignment(address,(size,(acctype,false)))
1118  ; let
1119      val value = ref []
1120    in
1121      ( L3.for
1122          (0,Nat.-(size,1),
1123           fn i =>
1124             value :=
1125             ((BitsN.toBitstring
1126                 (Map.lookup
1127                    ((!MEM),
1128                     BitsN.toNat(BitsN.+(address,BitsN.fromNat(i,64))))))
1129                @
1130                (!value)))
1131      ; BitsN.fromBitstring
1132          (if BigEndian () then BigEndianReverse (!value) else (!value),N)
1133      )
1134    end
1135  );
1136
1137fun write'Mem N (value,(address,(size,acctype))) =
1138  ( CheckAlignment(address,(size,(acctype,true)))
1139  ; let
1140      val value =
1141        if BigEndian ()
1142          then BigEndianReverse(BitsN.toBitstring value)
1143        else BitsN.toBitstring value
1144    in
1145      L3.for
1146        (0,Nat.-(size,1),
1147         fn i =>
1148           let
1149             val x = BitsN.+(address,BitsN.fromNat(i,64))
1150           in
1151             MEM :=
1152             (Map.update
1153                ((!MEM),BitsN.toNat x,
1154                 BitsN.fromBitstring
1155                   (Bitstring.bits(Nat.+(Nat.*(8,i),7),Nat.*(8,i)) value,8)))
1156           end)
1157    end
1158  );
1159
1160fun ConditionTest (cond,(N,(Z,(C,V)))) =
1161  let
1162    val result =
1163      case BitsN.bits(3,1) cond of
1164         BitsN.B(0x0,_) => Z
1165       | BitsN.B(0x1,_) => C
1166       | BitsN.B(0x2,_) => N
1167       | BitsN.B(0x3,_) => V
1168       | BitsN.B(0x4,_) => C andalso (not Z)
1169       | BitsN.B(0x5,_) => N = V
1170       | BitsN.B(0x6,_) => (N = V) andalso (not Z)
1171       | BitsN.B(0x7,_) => true
1172       | _ => raise General.Bind
1173  in
1174    if (BitsN.bit(cond,0)) andalso (not(cond = (BitsN.B(0xF,4))))
1175      then not result
1176    else result
1177  end;
1178
1179fun ConditionHolds cond =
1180  ConditionTest
1181    (cond,
1182     (#N((!PSTATE) : ProcState),
1183      (#Z((!PSTATE) : ProcState),
1184       (#C((!PSTATE) : ProcState),#V((!PSTATE) : ProcState)))));
1185
1186fun Ones n = L3.padLeft(true,(n,[]));
1187
1188fun Zeros n = L3.padLeft(false,(n,[]));
1189
1190fun Replicate N l =
1191  BitsN.fromBitstring
1192    (Bitstring.replicate
1193       (l,Nat.div(BitsN.size(BitsN.BV(0x0,N)),L3.length l)),N);
1194
1195fun HighestSetBit N w =
1196  if w = (BitsN.BV(0x0,N)) then IntInf.~ 1 else BitsN.toInt(BitsN.log2 w);
1197
1198fun CountLeadingZeroBits N w =
1199  Nat.fromInt
1200    (IntInf.-
1201       (IntInf.-(Nat.toInt(BitsN.size(BitsN.BV(0x0,N))),1),
1202        HighestSetBit N w));
1203
1204fun CountLeadingSignBits N w =
1205  Nat.-
1206    (CountLeadingZeroBits N
1207       (BitsN.??
1208          (BitsN.>>+(w,1),
1209           BitsN.&&(w,BitsN.~(BitsN.#>>(BitsN.BV(0x1,N),1))))),1);
1210
1211fun Poly32Mod2_loop (i,(data,poly)) =
1212  if Nat.<(i,32)
1213    then data
1214  else let
1215         val data =
1216           if Bitstring.bit(data,i)
1217             then (Bitstring.bits(Nat.-(L3.length data,1),i) data)
1218                    @
1219                    (Bitstring.??
1220                       (Bitstring.bits(Nat.-(i,1),0) data,
1221                        L3.padRight(false,(i,poly))))
1222           else data
1223       in
1224         Poly32Mod2_loop(Nat.-(i,1),(data,poly))
1225       end;
1226
1227fun Poly32Mod2 (data,poly) =
1228  BitsN.fromBitstring
1229    (Bitstring.bits(31,0)
1230       (Poly32Mod2_loop
1231          (Nat.-(L3.length data,1),(data,BitsN.toBitstring poly))),32);
1232
1233fun AddWithCarry N (x,(y,carry_in)) =
1234  let
1235    val unsigned_sum =
1236      Nat.+(Nat.+(BitsN.toNat x,BitsN.toNat y),Nat.fromBool carry_in)
1237    val signed_sum =
1238      IntInf.+
1239        (IntInf.+(BitsN.toInt x,BitsN.toInt y),IntExtra.fromBool carry_in)
1240    val result = BitsN.fromNat(unsigned_sum,N)
1241    val n = BitsN.msb result
1242    val z = result = (BitsN.BV(0x0,N))
1243    val c = not((BitsN.toNat result) = unsigned_sum)
1244    val v = not((BitsN.toInt result) = signed_sum)
1245  in
1246    (result,(n,(z,(c,v))))
1247  end;
1248
1249fun SetTheFlags (setflags,(n,(z,(c,v)))) =
1250  if setflags
1251    then ( PSTATE := (ProcState_N_rupd((!PSTATE),n))
1252         ; PSTATE := (ProcState_Z_rupd((!PSTATE),z))
1253         ; PSTATE := (ProcState_C_rupd((!PSTATE),c))
1254         ; PSTATE := (ProcState_V_rupd((!PSTATE),v))
1255         )
1256  else ();
1257
1258fun DecodeShift sh = (Cast.natToShiftType o BitsN.toNat) sh;
1259
1260fun ShiftValue N (value,(ty,amount)) =
1261  case ty of
1262     ShiftType_LSL => BitsN.<<(value,amount)
1263   | ShiftType_LSR => BitsN.>>+(value,amount)
1264   | ShiftType_ASR => BitsN.>>(value,amount)
1265   | ShiftType_ROR => BitsN.#>>(value,amount);
1266
1267fun ShiftReg N (reg,(ty,amount)) = ShiftValue N (X N reg,(ty,amount));
1268
1269fun ExtendWord (M,N) (w,signed) =
1270  if signed then BitsN.signExtend N w else BitsN.zeroExtend N w;
1271
1272fun Extend N (l,unsigned) =
1273  if unsigned orelse (not(List.hd l))
1274    then BitsN.fromBitstring(l,N)
1275  else BitsN.fromBitstring
1276         (L3.padLeft(true,(BitsN.size(BitsN.BV(0x0,N)),l)),N);
1277
1278fun DecodeRegExtend ext = (Cast.natToExtendType o BitsN.toNat) ext;
1279
1280fun ExtendValue N (value,(ty,sh)) =
1281  let
1282    val value = BitsN.toBitstring value
1283    val (unsigned,len) =
1284      case ty of
1285         ExtendType_SXTB => (false,8)
1286       | ExtendType_SXTH => (false,16)
1287       | ExtendType_SXTW => (false,32)
1288       | ExtendType_SXTX => (false,64)
1289       | ExtendType_UXTB => (true,8)
1290       | ExtendType_UXTH => (true,16)
1291       | ExtendType_UXTW => (true,32)
1292       | ExtendType_UXTX => (true,64)
1293    val len = Nat.min(len,Nat.-(BitsN.size(BitsN.BV(0x0,N)),sh))
1294  in
1295    Extend N
1296      (Bitstring.<<(Bitstring.bits(Nat.-(len,1),0) value,sh),unsigned)
1297  end;
1298
1299fun ExtendReg N (reg,(ty,sh)) = ExtendValue N (X N reg,(ty,sh));
1300
1301fun DecodeBitMasks M (immN,(imms,(immr,immediate))) =
1302  let
1303    val len = HighestSetBit 7 (BitsN.@@(immN,BitsN.~ imms))
1304  in
1305    if IntInf.<(len,1)
1306      then NONE
1307    else let
1308           val len = Nat.fromInt len
1309           val levels = BitsN.fromBitstring(Ones len,6)
1310           val S = BitsN.&&(imms,levels)
1311           val R = BitsN.&&(immr,levels)
1312         in
1313           if immediate andalso (S = levels)
1314             then NONE
1315           else let
1316                  val diff = BitsN.toBitstring(BitsN.-(S,R))
1317                  val esize = Nat.pow(2,len)
1318                  val d = Bitstring.bits(Nat.-(len,1),0) diff
1319                  val welem =
1320                    L3.padLeft(false,(esize,Ones(Nat.+(BitsN.toNat S,1))))
1321                  val telem =
1322                    L3.padLeft
1323                      (false,(esize,Ones(Nat.+(Bitstring.toNat d,1))))
1324                  val wmask =
1325                    Replicate M (Bitstring.#>>(welem,BitsN.toNat R))
1326                  val tmask = Replicate M telem
1327                in
1328                  Option.SOME(wmask,tmask)
1329                end
1330         end
1331  end;
1332
1333fun dfn'Address (page,(imm,d)) =
1334  let
1335    val base = ref (!PC)
1336  in
1337    ( if page
1338        then base :=
1339             (BitsN.bitFieldInsert(11,0) ((!base),BitsN.B(0x0,12)))
1340      else ()
1341    ; write'X 64 (BitsN.+((!base),imm),d)
1342    )
1343  end;
1344
1345fun dfn'AddSubCarry N (sf,(sub_op,(setflags,(m,(n,d))))) =
1346  let
1347    val operand1 = X N n
1348    val operand2 = X N m
1349    val operand2 = if sub_op then BitsN.~ operand2 else operand2
1350    val (result,nzcv) =
1351      AddWithCarry N (operand1,(operand2,#C((!PSTATE) : ProcState)))
1352  in
1353    ( SetTheFlags(setflags,nzcv); write'X N (result,d) )
1354  end;
1355
1356fun dfn'AddSubExtendRegister N
1357  (sf,(sub_op,(setflags,(m,(extend_type,(imm3,(n,d))))))) =
1358  let
1359    val operand1 = if n = (BitsN.B(0x1F,5)) then SP N else X N n
1360    val operand2 = ExtendReg N (m,(extend_type,BitsN.toNat imm3))
1361    val (operand2,carry_in) =
1362      if sub_op then (BitsN.~ operand2,true) else (operand2,false)
1363    val (result,nzcv) = AddWithCarry N (operand1,(operand2,carry_in))
1364  in
1365    ( SetTheFlags(setflags,nzcv)
1366    ; if (d = (BitsN.B(0x1F,5))) andalso (not setflags)
1367        then write'SP N result
1368      else write'X N (result,d)
1369    )
1370  end;
1371
1372fun dfn'AddSubImmediate N (sf,(sub_op,(setflags,(imm,(n,d))))) =
1373  let
1374    val operand1 = if n = (BitsN.B(0x1F,5)) then SP N else X N n
1375    val operand2 = imm
1376    val (operand2,carry_in) =
1377      if sub_op then (BitsN.~ operand2,true) else (operand2,false)
1378    val (result,nzcv) = AddWithCarry N (operand1,(operand2,carry_in))
1379  in
1380    ( SetTheFlags(setflags,nzcv)
1381    ; if (d = (BitsN.B(0x1F,5))) andalso (not setflags)
1382        then write'SP N result
1383      else write'X N (result,d)
1384    )
1385  end;
1386
1387fun dfn'AddSubShiftedRegister N
1388  (sf,(sub_op,(setflags,(shift_type,(m,(imm,(n,d))))))) =
1389  let
1390    val operand1 = X N n
1391    val operand2 = ShiftReg N (m,(shift_type,BitsN.toNat imm))
1392    val (operand2,carry_in) =
1393      if sub_op then (BitsN.~ operand2,true) else (operand2,false)
1394    val (result,nzcv) = AddWithCarry N (operand1,(operand2,carry_in))
1395  in
1396    ( SetTheFlags(setflags,nzcv); write'X N (result,d) )
1397  end;
1398
1399fun dfn'LogicalImmediate N (sf,(opc,(setflags,(imm,(n,d))))) =
1400  let
1401    val operand1 = X N n
1402    val operand2 = imm
1403    val result =
1404      case opc of
1405         LogicalOp_AND => BitsN.&&(operand1,operand2)
1406       | LogicalOp_ORR => BitsN.||(operand1,operand2)
1407       | LogicalOp_EOR => BitsN.??(operand1,operand2)
1408  in
1409    ( SetTheFlags
1410        (setflags,
1411         (BitsN.msb result,(result = (BitsN.BV(0x0,N)),(false,false))))
1412    ; if (d = (BitsN.B(0x1F,5))) andalso (not setflags)
1413        then write'SP N result
1414      else write'X N (result,d)
1415    )
1416  end;
1417
1418fun dfn'LogicalShiftedRegister N
1419  (sf,(opc,(invert,(setflags,(shift_type,(shift_amount,(m,(n,d)))))))) =
1420  let
1421    val operand1 = X N n
1422    val operand2 = ShiftReg N (m,(shift_type,shift_amount))
1423    val operand2 = if invert then BitsN.~ operand2 else operand2
1424    val result =
1425      case opc of
1426         LogicalOp_AND => BitsN.&&(operand1,operand2)
1427       | LogicalOp_ORR => BitsN.||(operand1,operand2)
1428       | LogicalOp_EOR => BitsN.??(operand1,operand2)
1429  in
1430    ( SetTheFlags
1431        (setflags,
1432         (BitsN.msb result,(result = (BitsN.BV(0x0,N)),(false,false))))
1433    ; write'X N (result,d)
1434    )
1435  end;
1436
1437fun dfn'Shift N (sf,(shift_type,(m,(n,d)))) =
1438  let
1439    val operand2 = X N m
1440    val result =
1441      ShiftReg N
1442        (n,
1443         (shift_type,
1444          Nat.mod(BitsN.toNat operand2,BitsN.size(BitsN.BV(0x0,N)))))
1445  in
1446    write'X N (result,d)
1447  end;
1448
1449fun dfn'MoveWide N (sf,(opcode,(hw,(imm,d)))) =
1450  let
1451    val pos = BitsN.toNat(BitsN.@@(hw,BitsN.B(0x0,4)))
1452  in
1453    let
1454      val result = ref (if opcode = MoveWideOp_K
1455         then X N d
1456       else BitsN.BV(0x0,N))
1457    in
1458      ( let
1459          val h = Nat.+(pos,15)
1460        in
1461          result := (BitsN.bitFieldInsert(h,pos) ((!result),imm))
1462        end
1463      ; let
1464          val result =
1465            if opcode = MoveWideOp_N then BitsN.~ (!result) else (!result)
1466        in
1467          write'X N (result,d)
1468        end
1469      )
1470    end
1471  end;
1472
1473fun dfn'BitfieldMove N
1474  (sf,(inzero,(extend,(wmask,(tmask,(R,(S,(n,d)))))))) =
1475  let
1476    val dst = if inzero then BitsN.BV(0x0,N) else X N d
1477    val src = X N n
1478    val bot =
1479      BitsN.||
1480        (BitsN.&&(dst,BitsN.~ wmask),BitsN.&&(BitsN.#>>(src,R),wmask))
1481    val top =
1482      if extend
1483        then Replicate N (Bitstring.fromBool(BitsN.bit(src,S)))
1484      else dst
1485  in
1486    write'X N
1487      (BitsN.||(BitsN.&&(top,BitsN.~ tmask),BitsN.&&(bot,tmask)),d)
1488  end;
1489
1490fun dfn'ConditionalCompareImmediate N
1491  (sf,(sub_op,(imm,(cond,(nzcv,n))))) =
1492  let
1493    val operand1 = X N n
1494    val operand2 = imm
1495  in
1496    if ConditionHolds cond
1497      then let
1498             val (operand2,carry_in) =
1499               if sub_op
1500                 then (BitsN.~ operand2,true)
1501               else (operand2,false)
1502             val (_,flags) = AddWithCarry N (operand1,(operand2,carry_in))
1503           in
1504             SetTheFlags(true,flags)
1505           end
1506    else SetTheFlags(true,nzcv)
1507  end;
1508
1509fun dfn'ConditionalCompareRegister N (sf,(sub_op,(cond,(nzcv,(m,n))))) =
1510  let
1511    val operand1 = X N n
1512    val operand2 = X N m
1513  in
1514    if ConditionHolds cond
1515      then let
1516             val (operand2,carry_in) =
1517               if sub_op
1518                 then (BitsN.~ operand2,true)
1519               else (operand2,false)
1520             val (_,flags) = AddWithCarry N (operand1,(operand2,carry_in))
1521           in
1522             SetTheFlags(true,flags)
1523           end
1524    else SetTheFlags(true,nzcv)
1525  end;
1526
1527fun dfn'ConditionalSelect N (sf,(else_inv,(else_inc,(cond,(m,(n,d)))))) =
1528  let
1529    val operand1 = X N n
1530    val operand2 = X N m
1531  in
1532    let
1533      val result = ref (BitsN.fromNat(0,N))
1534    in
1535      ( if ConditionHolds cond
1536          then result := operand1
1537        else ( result := operand2
1538             ; if else_inv then result := (BitsN.~ (!result)) else ()
1539             ; if else_inc
1540                 then result := (BitsN.+((!result),BitsN.BV(0x1,N)))
1541               else ()
1542             )
1543      ; write'X N ((!result),d)
1544      )
1545    end
1546  end;
1547
1548fun dfn'CountLeading N (sf,(count_clz,(n,d))) =
1549  let
1550    val operand1 = X N n
1551    val result =
1552      if count_clz
1553        then CountLeadingZeroBits N operand1
1554      else CountLeadingSignBits N operand1
1555  in
1556    write'X N (BitsN.fromNat(result,N),d)
1557  end;
1558
1559fun dfn'ExtractRegister N (sf,(imms,(m,(n,d)))) =
1560  let
1561    val lsb = BitsN.toNat imms
1562    val operand1 = X N n
1563    val operand2 = X N m
1564    val concat =
1565      (BitsN.toBitstring operand1) @ (BitsN.toBitstring operand2)
1566    val result = BitsN.fromBitstring(Bitstring.>>+(concat,lsb),N)
1567  in
1568    write'X N (result,d)
1569  end;
1570
1571fun dfn'Division N (sf,(unsigned,(m,(n,d)))) =
1572  let
1573    val operand1 = X N n
1574    val operand2 = X N m
1575    val result =
1576      if operand2 = (BitsN.BV(0x0,N))
1577        then BitsN.BV(0x0,N)
1578      else if unsigned
1579        then BitsN.div(operand1,operand2)
1580      else BitsN.quot(operand1,operand2)
1581  in
1582    write'X N (result,d)
1583  end;
1584
1585fun dfn'MultiplyAddSub N (sf,(sub_op,(m,(a,(n,d))))) =
1586  let
1587    val operand1 = X N n
1588    val operand2 = X N m
1589    val operand3 = X N a
1590    val result =
1591      if sub_op
1592        then BitsN.-(operand3,BitsN.*(operand1,operand2))
1593      else BitsN.+(operand3,BitsN.*(operand1,operand2))
1594  in
1595    write'X N (result,d)
1596  end;
1597
1598fun dfn'MultiplyAddSubLong (sub_op,(signed,(m,(a,(n,d))))) =
1599  let
1600    val operand1 = X 32 n
1601    val operand2 = X 32 m
1602    val operand3 = X 64 a
1603    val product =
1604      BitsN.*
1605        (ExtendWord (32,64) (operand1,signed),
1606         ExtendWord (32,64) (operand2,signed))
1607    val result =
1608      if sub_op
1609        then BitsN.-(operand3,product)
1610      else BitsN.+(operand3,product)
1611  in
1612    write'X 64 (result,d)
1613  end;
1614
1615fun dfn'MultiplyHigh (signed,(m,(n,d))) =
1616  let
1617    val operand1 = X 64 n
1618    val operand2 = X 64 m
1619    val result =
1620      BitsN.*
1621        (ExtendWord (64,128) (operand1,signed),
1622         ExtendWord (64,128) (operand2,signed))
1623  in
1624    write'X 64 (BitsN.bits(127,64) result,d)
1625  end;
1626
1627fun dfn'Reverse N (sf,(op',(n,d))) =
1628  if (BitsN.size(BitsN.BV(0x0,N))) = 32
1629    then let
1630           val v = X 32 n
1631           val result =
1632             case op' of
1633                RevOp_RBIT => BitsN.reverse v
1634              | RevOp_REV16 =>
1635                BitsN.concat
1636                  [BitsN.bits(23,16) v,BitsN.bits(31,24) v,
1637                   BitsN.bits(7,0) v,BitsN.bits(15,8) v]
1638              | RevOp_REV32 =>
1639                BitsN.concat
1640                  [BitsN.bits(7,0) v,BitsN.bits(15,8) v,
1641                   BitsN.bits(23,16) v,BitsN.bits(31,24) v]
1642              | RevOp_REV64 => BitsN.B(0x0,32)
1643         in
1644           write'X 32 (result,d)
1645         end
1646  else let
1647         val v = X 64 n
1648         val result =
1649           case op' of
1650              RevOp_RBIT => BitsN.reverse v
1651            | RevOp_REV16 =>
1652              BitsN.concat
1653                [BitsN.bits(55,48) v,BitsN.bits(63,56) v,
1654                 BitsN.bits(39,32) v,BitsN.bits(47,40) v,
1655                 BitsN.bits(23,16) v,BitsN.bits(31,24) v,
1656                 BitsN.bits(7,0) v,BitsN.bits(15,8) v]
1657            | RevOp_REV32 =>
1658              BitsN.concat
1659                [BitsN.bits(39,32) v,BitsN.bits(47,40) v,
1660                 BitsN.bits(55,48) v,BitsN.bits(63,56) v,
1661                 BitsN.bits(7,0) v,BitsN.bits(15,8) v,BitsN.bits(23,16) v,
1662                 BitsN.bits(31,24) v]
1663            | RevOp_REV64 =>
1664              BitsN.concat
1665                [BitsN.bits(7,0) v,BitsN.bits(15,8) v,BitsN.bits(23,16) v,
1666                 BitsN.bits(31,24) v,BitsN.bits(39,32) v,
1667                 BitsN.bits(47,40) v,BitsN.bits(55,48) v,
1668                 BitsN.bits(63,56) v]
1669       in
1670         write'X 64 (result,d)
1671       end;
1672
1673fun dfn'CRC N (sz,(crc32c,(m,(n,d)))) =
1674  let
1675    val acc = X 32 n
1676    val val' = X N m
1677    val poly =
1678      if crc32c then BitsN.B(0x1EDC6F41,32) else BitsN.B(0x4C11DB7,32)
1679    val tempacc =
1680      (List.rev(BitsN.toBitstring acc))
1681        @
1682        (Zeros(BitsN.size(BitsN.BV(0x0,N))))
1683    val tempval = (List.rev(BitsN.toBitstring val')) @ (Zeros 32)
1684  in
1685    write'X 32
1686      (BitsN.reverse(Poly32Mod2(Bitstring.??(tempacc,tempval),poly)),d)
1687  end;
1688
1689fun dfn'BranchConditional (offset,cond) =
1690  if ConditionHolds cond
1691    then BranchTo(BitsN.+((!PC),offset),BranchType_JMP)
1692  else ();
1693
1694fun dfn'BranchImmediate (offset,branch_type) =
1695  ( if branch_type = BranchType_CALL
1696      then write'X 64 (BitsN.+((!PC),BitsN.B(0x4,64)),BitsN.B(0x1E,5))
1697    else ()
1698  ; BranchTo(BitsN.+((!PC),offset),branch_type)
1699  );
1700
1701fun dfn'BranchRegister (n,branch_type) =
1702  let
1703    val target = X 64 n
1704  in
1705    ( if branch_type = BranchType_CALL
1706        then write'X 64 (BitsN.+((!PC),BitsN.B(0x4,64)),BitsN.B(0x1E,5))
1707      else ()
1708    ; BranchTo(target,branch_type)
1709    )
1710  end;
1711
1712fun dfn'CompareAndBranch N (sf,(iszero,(offset,t))) =
1713  let
1714    val operand1 = X N t
1715  in
1716    if operand1 = (BitsN.BV(0x0,N))
1717      then BranchTo(BitsN.+((!PC),offset),BranchType_JMP)
1718    else ()
1719  end;
1720
1721fun dfn'TestBitAndBranch N (sf,(bit_pos,(bit_val,(offset,t)))) =
1722  let
1723    val operand1 = X N t
1724  in
1725    if (BitsN.bit(operand1,BitsN.toNat bit_pos)) = bit_val
1726      then BranchTo(BitsN.+((!PC),offset),BranchType_JMP)
1727    else ()
1728  end;
1729
1730fun LoadStoreSingle N
1731  (size,
1732     (regsize_word,
1733      (memop,
1734       (acctype,
1735        (signed,
1736         (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,t))))))))))) =
1737  ( if (n = (BitsN.B(0x1F,5))) andalso (not(memop = MemOp_PREFETCH))
1738      then CheckSPAlignment ()
1739    else ()
1740  ; let
1741      val address = if n = (BitsN.B(0x1F,5)) then SP 64 else X 64 n
1742      val address = if postindex then address else BitsN.+(address,offset)
1743    in
1744      ( case memop of
1745           MemOp_STORE =>
1746             let
1747               val data = if rt_unknown then BitsN.fromNat(0,N) else X N t
1748               val x =
1749                 (address,(Nat.div(BitsN.size(BitsN.BV(0x0,N)),8),acctype))
1750             in
1751               write'Mem N (data,x)
1752             end
1753         | MemOp_LOAD =>
1754           let
1755             val data =
1756               Mem N
1757                 (address,(Nat.div(BitsN.size(BitsN.BV(0x0,N)),8),acctype))
1758           in
1759             if regsize_word
1760               then write'X 32 (ExtendWord (32,32) (data,signed),t)
1761             else write'X 64 (ExtendWord (64,64) (data,signed),t)
1762           end
1763         | MemOp_PREFETCH => ()
1764      ; if wback
1765          then let
1766                 val address =
1767                   if wb_unknown
1768                     then BitsN.B(0x0,64)
1769                   else if postindex
1770                     then BitsN.+(address,offset)
1771                   else address
1772               in
1773                 if n = (BitsN.B(0x1F,5))
1774                   then write'SP 64 address
1775                 else write'X 64 (address,n)
1776               end
1777        else ()
1778      )
1779    end
1780  );
1781
1782fun dfn'LoadStoreImmediate N
1783  (size,
1784     (regsize_word,
1785      (memop,
1786       (acctype,
1787        (signed,
1788         (wb_unknown,
1789          (rt_unknown,(wback,(postindex,(unsigned_offset,(offset,(n,t)))))))))))) =
1790  LoadStoreSingle N
1791    (size,
1792     (regsize_word,
1793      (memop,
1794       (acctype,
1795        (signed,
1796         (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,t)))))))))));
1797
1798fun dfn'LoadStoreRegister N
1799  (size,(regsize_word,(memop,(signed,(m,(extend_type,(shift,(n,t)))))))) =
1800  let
1801    val offset = ExtendReg 64 (m,(extend_type,shift))
1802  in
1803    LoadStoreSingle N
1804      (size,
1805       (regsize_word,
1806        (memop,
1807         (AccType_NORMAL,
1808          (signed,(false,(false,(false,(false,(offset,(n,t)))))))))))
1809  end;
1810
1811fun dfn'LoadStorePair N
1812  (size,
1813     (memop,
1814      (acctype,
1815       (signed,
1816        (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,(t,t2))))))))))) =
1817  let
1818    val dbytes = Nat.div(BitsN.size(BitsN.BV(0x0,N)),8)
1819  in
1820    ( if n = (BitsN.B(0x1F,5)) then CheckSPAlignment () else ()
1821    ; let
1822        val address = if n = (BitsN.B(0x1F,5)) then SP 64 else X 64 n
1823        val address =
1824          if postindex then address else BitsN.+(address,offset)
1825      in
1826        ( case memop of
1827             MemOp_STORE =>
1828               let
1829                 val data1 =
1830                   if rt_unknown andalso (t = n)
1831                     then BitsN.fromNat(0,N)
1832                   else X N t
1833                 val data2 =
1834                   if rt_unknown andalso (t2 = n)
1835                     then BitsN.fromNat(0,N)
1836                   else X N t2
1837               in
1838                 ( let
1839                     val x = (address,(dbytes,acctype))
1840                   in
1841                     write'Mem N (data1,x)
1842                   end
1843                 ; let
1844                     val x =
1845                       (BitsN.+(address,BitsN.fromNat(dbytes,64)),
1846                        (dbytes,acctype))
1847                   in
1848                     write'Mem N (data2,x)
1849                   end
1850                 )
1851               end
1852           | MemOp_LOAD =>
1853             let
1854               val (data1,data2) =
1855                 if rt_unknown
1856                   then (BitsN.fromNat(0,N),BitsN.fromNat(0,N))
1857                 else (Mem N (address,(dbytes,acctype)),
1858                       Mem N
1859                         (BitsN.+(address,BitsN.fromNat(dbytes,64)),
1860                          (dbytes,acctype)))
1861             in
1862               if signed
1863                 then ( write'X 64 (ExtendWord (64,64) (data1,signed),t)
1864                      ; write'X 64 (ExtendWord (64,64) (data2,signed),t2)
1865                      )
1866               else ( write'X N (data1,t); write'X N (data2,t2) )
1867             end
1868           | _ => ()
1869        ; if wback
1870            then let
1871                   val address =
1872                     if wb_unknown
1873                       then BitsN.B(0x0,64)
1874                     else if postindex
1875                       then BitsN.+(address,offset)
1876                     else address
1877                 in
1878                   if n = (BitsN.B(0x1F,5))
1879                     then write'SP 64 address
1880                   else write'X 64 (address,n)
1881                 end
1882          else ()
1883        )
1884      end
1885    )
1886  end;
1887
1888fun ExclusiveMonitorPass (address,n) = false;
1889
1890fun SetExclusiveMonitors (address,n) = ();
1891
1892val ExclusiveMonitorStatus = BitsN.B(0x0,1)
1893
1894fun dfn'LoadStoreAcquire N
1895  (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(s,(n,t)))))))) =
1896  let
1897    val dbytes = Nat.div(BitsN.size(BitsN.BV(0x0,N)),8)
1898  in
1899    ( if n = (BitsN.B(0x1F,5)) then CheckSPAlignment () else ()
1900    ; let
1901        val address =
1902          if n = (BitsN.B(0x1F,5))
1903            then SP 64
1904          else if rn_unknown then BitsN.B(0x0,64) else X 64 n
1905      in
1906        case memop of
1907           MemOp_STORE =>
1908             let
1909               val data = if rt_unknown then BitsN.fromNat(0,N) else X N t
1910             in
1911               if excl
1912                 then if ExclusiveMonitorPass(address,dbytes)
1913                        then ( let
1914                                 val x = (address,(dbytes,acctype))
1915                               in
1916                                 write'Mem N (data,x)
1917                               end
1918                             ; let
1919                                 val status = ExclusiveMonitorStatus
1920                               in
1921                                 write'X 32
1922                                   (BitsN.fromNat(BitsN.toNat status,32),s)
1923                               end
1924                             )
1925                      else write'X 32 (BitsN.B(0x1,32),s)
1926               else let
1927                      val x = (address,(dbytes,acctype))
1928                    in
1929                      write'Mem N (data,x)
1930                    end
1931             end
1932         | MemOp_LOAD =>
1933           ( if excl then SetExclusiveMonitors(address,dbytes) else ()
1934           ; let
1935               val data = Mem N (address,(dbytes,acctype))
1936             in
1937               if (BitsN.size(BitsN.BV(0x0,N))) = 64
1938                 then write'X N (data,t)
1939               else write'X 32 (BitsN.fromNat(BitsN.toNat data,32),t)
1940             end
1941           )
1942         | _ => ()
1943      end
1944    )
1945  end;
1946
1947fun dfn'LoadStoreAcquirePair N
1948  (size,(memop,(acctype,(rn_unknown,(rt_unknown,(s,(n,(t,t2)))))))) =
1949  let
1950    val dbytes = Nat.div(BitsN.size(BitsN.BV(0x0,N)),8)
1951  in
1952    ( if n = (BitsN.B(0x1F,5)) then CheckSPAlignment () else ()
1953    ; let
1954        val address =
1955          if n = (BitsN.B(0x1F,5))
1956            then SP 64
1957          else if rn_unknown then BitsN.B(0x0,64) else X 64 n
1958      in
1959        case memop of
1960           MemOp_STORE =>
1961             let
1962               val data =
1963                 if rt_unknown
1964                   then BitsN.fromNat(0,N)
1965                 else if (BitsN.size(BitsN.BV(0x0,N))) = 64
1966                   then if BigEndian ()
1967                          then BitsN.fromNat
1968                                 (BitsN.toNat(BitsN.@@(X 32 t,X 32 t2)),N)
1969                        else BitsN.fromNat
1970                               (BitsN.toNat(BitsN.@@(X 32 t2,X 32 t)),N)
1971                 else if BigEndian ()
1972                   then BitsN.fromNat
1973                          (BitsN.toNat(BitsN.@@(X 64 t,X 64 t2)),N)
1974                 else BitsN.fromNat
1975                        (BitsN.toNat(BitsN.@@(X 64 t2,X 64 t)),N)
1976             in
1977               if ExclusiveMonitorPass(address,dbytes)
1978                 then ( let
1979                          val x = (address,(dbytes,acctype))
1980                        in
1981                          write'Mem N (data,x)
1982                        end
1983                      ; let
1984                          val status = ExclusiveMonitorStatus
1985                        in
1986                          write'X 32
1987                            (BitsN.fromNat(BitsN.toNat status,32),s)
1988                        end
1989                      )
1990               else write'X 32 (BitsN.B(0x1,32),s)
1991             end
1992         | MemOp_LOAD =>
1993           ( SetExclusiveMonitors(address,dbytes)
1994           ; if rt_unknown
1995               then if (BitsN.size(BitsN.BV(0x0,N))) = 64
1996                      then write'X 32 (BitsN.B(0x0,32),t)
1997                    else write'X 64 (BitsN.B(0x0,64),t)
1998             else if (BitsN.size(BitsN.BV(0x0,N))) = 64
1999               then let
2000                      val data = Mem N (address,(dbytes,acctype))
2001                    in
2002                      if BigEndian ()
2003                        then ( write'X 32 (BitsN.bits(63,32) data,t)
2004                             ; write'X 32 (BitsN.bits(31,0) data,t2)
2005                             )
2006                      else ( write'X 32 (BitsN.bits(31,0) data,t)
2007                           ; write'X 32 (BitsN.bits(63,32) data,t2)
2008                           )
2009                    end
2010             else ( if not(Aligned 64 (address,dbytes))
2011                      then raise ALIGNMENT_FAULT
2012                    else ()
2013                  ; write'X 64 (Mem 64 (address,(8,acctype)),t)
2014                  ; write'X 64
2015                      (Mem 64
2016                         (BitsN.+(address,BitsN.B(0x8,64)),(8,acctype)),t2)
2017                  )
2018           )
2019         | _ => ()
2020      end
2021    )
2022  end;
2023
2024fun dfn'LoadLiteral N (size,(memop,(signed,(offset,t)))) =
2025  let
2026    val address = BitsN.+((!PC),offset)
2027  in
2028    case memop of
2029       MemOp_LOAD =>
2030         let
2031           val data =
2032             Mem N
2033               (address,
2034                (Nat.div(BitsN.size(BitsN.BV(0x0,N)),8),AccType_NORMAL))
2035         in
2036           write'X 64 (ExtendWord (64,64) (data,signed),t)
2037         end
2038     | _ => ()
2039  end;
2040
2041fun dfn'MemoryBarrier (op',crm) = raise UNDEFINED_FAULT "MemoryBarrier";
2042
2043fun dfn'ClearExclusive imm = raise UNDEFINED_FAULT "ClearExclusive";
2044
2045fun dfn'Hint op' =
2046  if op' = SystemHintOp_NOP then () else raise UNDEFINED_FAULT "Hint";
2047
2048fun dfn'Breakpoint imm = raise UNDEFINED_FAULT "Breakpoint";
2049
2050fun dfn'DebugSwitch target_level = raise UNDEFINED_FAULT "DebugSwitch";
2051
2052fun dfn'DebugRestore () = raise UNDEFINED_FAULT "DebugRestore";
2053
2054fun dfn'Halt imm16 = raise UNDEFINED_FAULT "Halt";
2055
2056fun dfn'SystemInstruction
2057  (sys_op1,(sys_op2,(sys_crn,(sys_crm,(has_result,t))))) =
2058  raise UNDEFINED_FAULT "System";
2059
2060fun dfn'MoveSystemRegister
2061  (read,(sys_op0,(sys_op1,(sys_op2,(sys_crn,(sys_crm,t)))))) =
2062  raise UNDEFINED_FAULT "MoveSystemRegister";
2063
2064fun dfn'MoveImmediateProcState (field,operand) =
2065  raise UNDEFINED_FAULT "MoveImmediateProcState";
2066
2067fun dfn'SupervisorCall imm16 = raise UNDEFINED_FAULT "SupervisorCall";
2068
2069fun dfn'HypervisorCall imm16 = raise UNDEFINED_FAULT "HypervisorCall";
2070
2071fun dfn'SecureMonitorCall imm16 =
2072  raise UNDEFINED_FAULT "SecureMonitorCall";
2073
2074fun dfn'ExceptionReturn () = raise UNDEFINED_FAULT "ExceptionReturn";
2075
2076fun dfn'Unallocated () = raise UNDEFINED_FAULT "Unallocated";
2077
2078fun dfn'Reserved () = raise UNDEFINED_FAULT "Reserved";
2079
2080fun Run v0 =
2081  case v0 of
2082     Reserved => dfn'Reserved ()
2083   | Unallocated => dfn'Unallocated ()
2084   | Address v81 => dfn'Address v81
2085   | ClearExclusive v82 => dfn'ClearExclusive v82
2086   | Hint v83 => dfn'Hint v83
2087   | MemoryBarrier v84 => dfn'MemoryBarrier v84
2088   | Branch v1 =>
2089     (case v1 of
2090         BranchConditional v2 => dfn'BranchConditional v2
2091       | BranchImmediate v3 => dfn'BranchImmediate v3
2092       | BranchRegister v4 => dfn'BranchRegister v4
2093       | CompareAndBranch''32 v5 => dfn'CompareAndBranch 32 v5
2094       | CompareAndBranch''64 v6 => dfn'CompareAndBranch 64 v6
2095       | TestBitAndBranch''32 v7 => dfn'TestBitAndBranch 32 v7
2096       | TestBitAndBranch''64 v8 => dfn'TestBitAndBranch 64 v8)
2097   | CRCExt v9 =>
2098     (case v9 of
2099         CRC''16 v10 => dfn'CRC 16 v10
2100       | CRC''32 v11 => dfn'CRC 32 v11
2101       | CRC''64 v12 => dfn'CRC 64 v12
2102       | CRC''8 v13 => dfn'CRC 8 v13)
2103   | Data v14 =>
2104     (case v14 of
2105         AddSubCarry''32 v15 => dfn'AddSubCarry 32 v15
2106       | AddSubCarry''64 v16 => dfn'AddSubCarry 64 v16
2107       | AddSubExtendRegister''32 v17 => dfn'AddSubExtendRegister 32 v17
2108       | AddSubExtendRegister''64 v18 => dfn'AddSubExtendRegister 64 v18
2109       | AddSubImmediate''32 v19 => dfn'AddSubImmediate 32 v19
2110       | AddSubImmediate''64 v20 => dfn'AddSubImmediate 64 v20
2111       | AddSubShiftedRegister''32 v21 => dfn'AddSubShiftedRegister 32 v21
2112       | AddSubShiftedRegister''64 v22 => dfn'AddSubShiftedRegister 64 v22
2113       | BitfieldMove''32 v23 => dfn'BitfieldMove 32 v23
2114       | BitfieldMove''64 v24 => dfn'BitfieldMove 64 v24
2115       | ConditionalCompareImmediate''32 v25 =>
2116         dfn'ConditionalCompareImmediate 32 v25
2117       | ConditionalCompareImmediate''64 v26 =>
2118         dfn'ConditionalCompareImmediate 64 v26
2119       | ConditionalCompareRegister''32 v27 =>
2120         dfn'ConditionalCompareRegister 32 v27
2121       | ConditionalCompareRegister''64 v28 =>
2122         dfn'ConditionalCompareRegister 64 v28
2123       | ConditionalSelect''32 v29 => dfn'ConditionalSelect 32 v29
2124       | ConditionalSelect''64 v30 => dfn'ConditionalSelect 64 v30
2125       | CountLeading''32 v31 => dfn'CountLeading 32 v31
2126       | CountLeading''64 v32 => dfn'CountLeading 64 v32
2127       | Division''32 v33 => dfn'Division 32 v33
2128       | Division''64 v34 => dfn'Division 64 v34
2129       | ExtractRegister''32 v35 => dfn'ExtractRegister 32 v35
2130       | ExtractRegister''64 v36 => dfn'ExtractRegister 64 v36
2131       | LogicalImmediate''32 v37 => dfn'LogicalImmediate 32 v37
2132       | LogicalImmediate''64 v38 => dfn'LogicalImmediate 64 v38
2133       | LogicalShiftedRegister''32 v39 =>
2134         dfn'LogicalShiftedRegister 32 v39
2135       | LogicalShiftedRegister''64 v40 =>
2136         dfn'LogicalShiftedRegister 64 v40
2137       | MoveWide''32 v41 => dfn'MoveWide 32 v41
2138       | MoveWide''64 v42 => dfn'MoveWide 64 v42
2139       | MultiplyAddSub''32 v43 => dfn'MultiplyAddSub 32 v43
2140       | MultiplyAddSub''64 v44 => dfn'MultiplyAddSub 64 v44
2141       | MultiplyAddSubLong v45 => dfn'MultiplyAddSubLong v45
2142       | MultiplyHigh v46 => dfn'MultiplyHigh v46
2143       | Reverse''32 v47 => dfn'Reverse 32 v47
2144       | Reverse''64 v48 => dfn'Reverse 64 v48
2145       | Shift''32 v49 => dfn'Shift 32 v49
2146       | Shift''64 v50 => dfn'Shift 64 v50)
2147   | Debug v51 =>
2148     (case v51 of
2149         DebugRestore => dfn'DebugRestore ()
2150       | Breakpoint v52 => dfn'Breakpoint v52
2151       | DebugSwitch v53 => dfn'DebugSwitch v53
2152       | Halt v54 => dfn'Halt v54)
2153   | LoadStore v55 =>
2154     (case v55 of
2155         LoadLiteral''32 v56 => dfn'LoadLiteral 32 v56
2156       | LoadLiteral''64 v57 => dfn'LoadLiteral 64 v57
2157       | LoadStoreAcquire''16 v58 => dfn'LoadStoreAcquire 16 v58
2158       | LoadStoreAcquire''32 v59 => dfn'LoadStoreAcquire 32 v59
2159       | LoadStoreAcquire''64 v60 => dfn'LoadStoreAcquire 64 v60
2160       | LoadStoreAcquire''8 v61 => dfn'LoadStoreAcquire 8 v61
2161       | LoadStoreAcquirePair''128 v62 => dfn'LoadStoreAcquirePair 128 v62
2162       | LoadStoreAcquirePair''64 v63 => dfn'LoadStoreAcquirePair 64 v63
2163       | LoadStoreImmediate''16 v64 => dfn'LoadStoreImmediate 16 v64
2164       | LoadStoreImmediate''32 v65 => dfn'LoadStoreImmediate 32 v65
2165       | LoadStoreImmediate''64 v66 => dfn'LoadStoreImmediate 64 v66
2166       | LoadStoreImmediate''8 v67 => dfn'LoadStoreImmediate 8 v67
2167       | LoadStorePair''32 v68 => dfn'LoadStorePair 32 v68
2168       | LoadStorePair''64 v69 => dfn'LoadStorePair 64 v69
2169       | LoadStoreRegister''16 v70 => dfn'LoadStoreRegister 16 v70
2170       | LoadStoreRegister''32 v71 => dfn'LoadStoreRegister 32 v71
2171       | LoadStoreRegister''64 v72 => dfn'LoadStoreRegister 64 v72
2172       | LoadStoreRegister''8 v73 => dfn'LoadStoreRegister 8 v73)
2173   | System v74 =>
2174     (case v74 of
2175         ExceptionReturn => dfn'ExceptionReturn ()
2176       | HypervisorCall v75 => dfn'HypervisorCall v75
2177       | MoveImmediateProcState v76 => dfn'MoveImmediateProcState v76
2178       | MoveSystemRegister v77 => dfn'MoveSystemRegister v77
2179       | SecureMonitorCall v78 => dfn'SecureMonitorCall v78
2180       | SupervisorCall v79 => dfn'SupervisorCall v79
2181       | SystemInstruction v80 => dfn'SystemInstruction v80);
2182
2183fun DecodeLogicalOp opc =
2184  case opc of
2185     BitsN.B(0x0,_) => (LogicalOp_AND,false)
2186   | BitsN.B(0x1,_) => (LogicalOp_ORR,false)
2187   | BitsN.B(0x2,_) => (LogicalOp_EOR,false)
2188   | BitsN.B(0x3,_) => (LogicalOp_AND,true)
2189   | _ => raise General.Bind;
2190
2191val NoOperation = Hint SystemHintOp_NOP
2192
2193fun LoadStoreRegister
2194  (size,(regsize_word,(memop,(signed,(m,(extend_type,(shift,(n,t)))))))) =
2195  let
2196    val a =
2197      (regsize_word,(memop,(signed,(m,(extend_type,(shift,(n,t)))))))
2198  in
2199    case size of
2200       BitsN.B(0x0,_) => LoadStore(LoadStoreRegister''8(BitsN.B(0x0,8),a))
2201     | BitsN.B(0x1,_) =>
2202       LoadStore(LoadStoreRegister''16(BitsN.B(0x1,16),a))
2203     | BitsN.B(0x2,_) =>
2204       LoadStore(LoadStoreRegister''32(BitsN.B(0x2,32),a))
2205     | BitsN.B(0x3,_) =>
2206       LoadStore(LoadStoreRegister''64(BitsN.B(0x3,64),a))
2207     | _ => raise General.Bind
2208  end;
2209
2210fun LoadStoreImmediateN
2211  (size,
2212     (regsize_word,
2213      (memop,
2214       (acctype,
2215        (signed,
2216         (wb_unknown,
2217          (rt_unknown,(wback,(postindex,(unsigned_offset,(offset,(n,t)))))))))))) =
2218  let
2219    val a =
2220      (regsize_word,
2221       (memop,
2222        (acctype,
2223         (signed,
2224          (wb_unknown,
2225           (rt_unknown,
2226            (wback,(postindex,(unsigned_offset,(offset,(n,t)))))))))))
2227  in
2228    case size of
2229       BitsN.B(0x0,_) =>
2230         LoadStore(LoadStoreImmediate''8(BitsN.B(0x0,8),a))
2231     | BitsN.B(0x1,_) =>
2232       LoadStore(LoadStoreImmediate''16(BitsN.B(0x1,16),a))
2233     | BitsN.B(0x2,_) =>
2234       LoadStore(LoadStoreImmediate''32(BitsN.B(0x2,32),a))
2235     | BitsN.B(0x3,_) =>
2236       LoadStore(LoadStoreImmediate''64(BitsN.B(0x3,64),a))
2237     | _ => raise General.Bind
2238  end;
2239
2240fun LoadStoreImmediate
2241  (size,
2242     (opc,(acctype,(wback,(postindex,(unsigned_offset,(offset,(Rn,Rt)))))))) =
2243  let
2244    val (memop,(regsize_word,signed)) =
2245      if not(BitsN.bit(opc,1))
2246        then (if BitsN.bit(opc,0) then MemOp_LOAD else MemOp_STORE,
2247              (not(size = (BitsN.B(0x3,2))),false))
2248      else if size = (BitsN.B(0x3,2))
2249        then (MemOp_PREFETCH,(false,false))
2250      else (MemOp_LOAD,(BitsN.bit(opc,0),true))
2251    val wb_unknown = false
2252    val rt_unknown = false
2253  in
2254    if (memop = MemOp_LOAD) andalso
2255       (wback andalso ((Rn = Rt) andalso (not(Rn = (BitsN.B(0x1F,5))))))
2256      then case (L3.K(BitsN.B(0x0,2))) "LoadImmediate unpredictable" of
2257              BitsN.B(0x0,_) =>
2258                let
2259                  val wback = false
2260                in
2261                  LoadStoreImmediateN
2262                    (size,
2263                     (regsize_word,
2264                      (memop,
2265                       (acctype,
2266                        (signed,
2267                         (wb_unknown,
2268                          (rt_unknown,
2269                           (wback,
2270                            (postindex,(unsigned_offset,(offset,(Rn,Rt))))))))))))
2271                end
2272            | BitsN.B(0x1,_) =>
2273              let
2274                val wb_unknown = true
2275              in
2276                LoadStoreImmediateN
2277                  (size,
2278                   (regsize_word,
2279                    (memop,
2280                     (acctype,
2281                      (signed,
2282                       (wb_unknown,
2283                        (rt_unknown,
2284                         (wback,
2285                          (postindex,(unsigned_offset,(offset,(Rn,Rt))))))))))))
2286              end
2287            | BitsN.B(0x2,_) => Unallocated
2288            | BitsN.B(0x3,_) => NoOperation
2289            | _ => raise General.Bind
2290    else if (memop = MemOp_STORE) andalso
2291       (wback andalso ((Rn = Rt) andalso (not(Rn = (BitsN.B(0x1F,5))))))
2292      then case (L3.K(BitsN.B(0x0,2))) "StoreImmediate unpredictable" of
2293              BitsN.B(0x0,_) =>
2294                LoadStoreImmediateN
2295                  (size,
2296                   (regsize_word,
2297                    (memop,
2298                     (acctype,
2299                      (signed,
2300                       (wb_unknown,
2301                        (rt_unknown,
2302                         (wback,
2303                          (postindex,(unsigned_offset,(offset,(Rn,Rt))))))))))))
2304            | BitsN.B(0x1,_) =>
2305              let
2306                val rt_unknown = true
2307              in
2308                LoadStoreImmediateN
2309                  (size,
2310                   (regsize_word,
2311                    (memop,
2312                     (acctype,
2313                      (signed,
2314                       (wb_unknown,
2315                        (rt_unknown,
2316                         (wback,
2317                          (postindex,(unsigned_offset,(offset,(Rn,Rt))))))))))))
2318              end
2319            | BitsN.B(0x2,_) => Unallocated
2320            | BitsN.B(0x3,_) => NoOperation
2321            | _ => raise General.Bind
2322    else LoadStoreImmediateN
2323           (size,
2324            (regsize_word,
2325             (memop,
2326              (acctype,
2327               (signed,
2328                (wb_unknown,
2329                 (rt_unknown,
2330                  (wback,(postindex,(unsigned_offset,(offset,(Rn,Rt))))))))))))
2331  end;
2332
2333fun LoadStorePairN
2334  (sf,
2335     (memop,
2336      (acctype,
2337       (signed,
2338        (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,(t,t2))))))))))) =
2339  let
2340    val a =
2341      (memop,
2342       (acctype,
2343        (signed,
2344         (wb_unknown,(rt_unknown,(wback,(postindex,(offset,(n,(t,t2))))))))))
2345  in
2346    if sf = (BitsN.B(0x1,1))
2347      then LoadStore(LoadStorePair''64(BitsN.B(0x1,64),a))
2348    else LoadStore(LoadStorePair''32(BitsN.B(0x0,32),a))
2349  end;
2350
2351fun LoadStorePair
2352  (sf,
2353     (memop,(acctype,(signed,(wback,(postindex,(offset,(Rn,(Rt,Rt2))))))))) =
2354  let
2355    val wb_unknown = false
2356    val rt_unknown = false
2357  in
2358    if (memop = MemOp_LOAD) andalso
2359       (wback andalso
2360        (((Rn = Rt) orelse (Rn = Rt2)) andalso
2361         (not(Rn = (BitsN.B(0x1F,5))))))
2362      then case (L3.K(BitsN.B(0x0,2))) "LoadPair unpredictable" of
2363              BitsN.B(0x0,_) =>
2364                let
2365                  val wback = false
2366                in
2367                  LoadStorePairN
2368                    (sf,
2369                     (memop,
2370                      (acctype,
2371                       (signed,
2372                        (wb_unknown,
2373                         (rt_unknown,
2374                          (wback,(postindex,(offset,(Rn,(Rt,Rt2)))))))))))
2375                end
2376            | BitsN.B(0x1,_) =>
2377              let
2378                val wb_unknown = true
2379              in
2380                LoadStorePairN
2381                  (sf,
2382                   (memop,
2383                    (acctype,
2384                     (signed,
2385                      (wb_unknown,
2386                       (rt_unknown,
2387                        (wback,(postindex,(offset,(Rn,(Rt,Rt2)))))))))))
2388              end
2389            | BitsN.B(0x2,_) => Unallocated
2390            | BitsN.B(0x3,_) => NoOperation
2391            | _ => raise General.Bind
2392    else if (memop = MemOp_STORE) andalso
2393       (wback andalso
2394        (((Rn = Rt) orelse (Rn = Rt2)) andalso
2395         (not(Rn = (BitsN.B(0x1F,5))))))
2396      then case (L3.K(BitsN.B(0x0,2))) "StorePair unpredictable" of
2397              BitsN.B(0x0,_) =>
2398                LoadStorePairN
2399                  (sf,
2400                   (memop,
2401                    (acctype,
2402                     (signed,
2403                      (wb_unknown,
2404                       (rt_unknown,
2405                        (wback,(postindex,(offset,(Rn,(Rt,Rt2)))))))))))
2406            | BitsN.B(0x1,_) =>
2407              let
2408                val rt_unknown = true
2409              in
2410                LoadStorePairN
2411                  (sf,
2412                   (memop,
2413                    (acctype,
2414                     (signed,
2415                      (wb_unknown,
2416                       (rt_unknown,
2417                        (wback,(postindex,(offset,(Rn,(Rt,Rt2)))))))))))
2418              end
2419            | BitsN.B(0x2,_) => Unallocated
2420            | BitsN.B(0x3,_) => NoOperation
2421            | _ => raise General.Bind
2422    else if (memop = MemOp_LOAD) andalso (Rt = Rt2)
2423      then case (L3.K(BitsN.B(0x0,2))) "LoadPair Rt = Rt2 unpredictable" of
2424              BitsN.B(0x0,_) =>
2425                let
2426                  val rt_unknown = true
2427                in
2428                  LoadStorePairN
2429                    (sf,
2430                     (memop,
2431                      (acctype,
2432                       (signed,
2433                        (wb_unknown,
2434                         (rt_unknown,
2435                          (wback,(postindex,(offset,(Rn,(Rt,Rt2)))))))))))
2436                end
2437            | BitsN.B(0x1,_) => Unallocated
2438            | _ => NoOperation
2439    else LoadStorePairN
2440           (sf,
2441            (memop,
2442             (acctype,
2443              (signed,
2444               (wb_unknown,
2445                (rt_unknown,(wback,(postindex,(offset,(Rn,(Rt,Rt2)))))))))))
2446  end;
2447
2448fun LoadStoreAcquireN
2449  (size,
2450     (memop,
2451      (acctype,(excl,(pair,(rn_unknown,(rt_unknown,(s,(n,(t,t2)))))))))) =
2452  if pair
2453    then let
2454           val a =
2455             (memop,(acctype,(rn_unknown,(rt_unknown,(s,(n,(t,t2)))))))
2456         in
2457           if size = (BitsN.B(0x2,2))
2458             then LoadStore(LoadStoreAcquirePair''64(BitsN.B(0x2,64),a))
2459           else LoadStore(LoadStoreAcquirePair''128(BitsN.B(0x3,128),a))
2460         end
2461  else let
2462         val a =
2463           (memop,(acctype,(excl,(rn_unknown,(rt_unknown,(s,(n,t)))))))
2464       in
2465         case size of
2466            BitsN.B(0x0,_) =>
2467              LoadStore(LoadStoreAcquire''8(BitsN.B(0x0,8),a))
2468          | BitsN.B(0x1,_) =>
2469            LoadStore(LoadStoreAcquire''16(BitsN.B(0x1,16),a))
2470          | BitsN.B(0x2,_) =>
2471            LoadStore(LoadStoreAcquire''32(BitsN.B(0x2,32),a))
2472          | BitsN.B(0x3,_) =>
2473            LoadStore(LoadStoreAcquire''64(BitsN.B(0x3,64),a))
2474          | _ => raise General.Bind
2475       end;
2476
2477fun LoadStoreAcquire
2478  (size,(memop,(acctype,(excl,(pair,(Rs,(Rn,(Rt,Rt2)))))))) =
2479  let
2480    val (rt_unknown,(rn_unknown,ast)) =
2481      if (memop = MemOp_LOAD) andalso (pair andalso (Rt = Rt2))
2482        then case (L3.K(BitsN.B(0x0,2))) "LoadAcquire unpredictable" of
2483                BitsN.B(0x0,_) => (true,(false,NONE))
2484              | BitsN.B(0x1,_) => (false,(false,Option.SOME Unallocated))
2485              | _ => (false,(false,Option.SOME NoOperation))
2486      else (false,(false,NONE))
2487    val (rt_unknown,(rn_unknown,ast)) =
2488      if ((memop = MemOp_STORE) andalso (excl andalso (Rs = Rt))) orelse
2489         (pair andalso (Rs = Rt2))
2490        then case (L3.K(BitsN.B(0x0,2)))
2491               "StoreAcquire Rs = Rt unpredictable" of
2492                BitsN.B(0x0,_) => (true,(rn_unknown,ast))
2493              | BitsN.B(0x1,_) => (rt_unknown,(rn_unknown,ast))
2494              | BitsN.B(0x2,_) =>
2495                (rt_unknown,(rn_unknown,Option.SOME Unallocated))
2496              | BitsN.B(0x3,_) =>
2497                (rt_unknown,(rn_unknown,Option.SOME NoOperation))
2498              | _ => raise General.Bind
2499      else (rt_unknown,(rn_unknown,ast))
2500    val (rt_unknown,(rn_unknown,ast)) =
2501      if (memop = MemOp_STORE) andalso
2502         (excl andalso ((Rs = Rn) andalso (not(Rn = (BitsN.B(0x1F,5))))))
2503        then case (L3.K(BitsN.B(0x0,2)))
2504               "StoreAcquire Rs = Rn unpredictable" of
2505                BitsN.B(0x0,_) => (rt_unknown,(true,ast))
2506              | BitsN.B(0x1,_) => (rt_unknown,(rn_unknown,ast))
2507              | BitsN.B(0x2,_) =>
2508                (rt_unknown,(rn_unknown,Option.SOME Unallocated))
2509              | BitsN.B(0x3,_) =>
2510                (rt_unknown,(rn_unknown,Option.SOME NoOperation))
2511              | _ => raise General.Bind
2512      else (rt_unknown,(rn_unknown,ast))
2513  in
2514    case ast of
2515       Option.SOME i => i
2516     | NONE =>
2517       LoadStoreAcquireN
2518         (size,
2519          (memop,
2520           (acctype,
2521            (excl,(pair,(rn_unknown,(rt_unknown,(Rs,(Rn,(Rt,Rt2))))))))))
2522  end;
2523
2524fun Decode w =
2525  case boolify'32 w of
2526     (op'0,
2527      (immlo'1,
2528       (immlo'0,
2529        (true,
2530         (false,
2531          (false,
2532           (false,
2533            (false,
2534             (immhi'18,
2535              (immhi'17,
2536               (immhi'16,
2537                (immhi'15,
2538                 (immhi'14,
2539                  (immhi'13,
2540                   (immhi'12,
2541                    (immhi'11,
2542                     (immhi'10,
2543                      (immhi'9,
2544                       (immhi'8,
2545                        (immhi'7,
2546                         (immhi'6,
2547                          (immhi'5,
2548                           (immhi'4,
2549                            (immhi'3,
2550                             (immhi'2,
2551                              (immhi'1,
2552                               (immhi'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2553       let
2554         val immhi =
2555           BitsN.fromBitstring
2556             ([immhi'18,immhi'17,immhi'16,immhi'15,immhi'14,immhi'13,
2557               immhi'12,immhi'11,immhi'10,immhi'9,immhi'8,immhi'7,immhi'6,
2558               immhi'5,immhi'4,immhi'3,immhi'2,immhi'1,immhi'0],19)
2559         val immlo = BitsN.fromBitstring([immlo'1,immlo'0],2)
2560         val page =
2561           (not o L3.equal (BitsN.zero (1)))
2562             (BitsN.fromBitstring([op'0],1))
2563         val imm =
2564           if page
2565             then BitsN.signExtend 64
2566                    (BitsN.concat[immhi,immlo,BitsN.B(0x0,12)])
2567           else BitsN.signExtend 64 (BitsN.@@(immhi,immlo))
2568       in
2569         Address
2570           (page,(imm,BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))
2571       end
2572   | (_,
2573    (op'0,
2574     (S'0,
2575      (false,
2576       (true,
2577        (false,
2578         (true,
2579          (true,
2580           (true,
2581            (true,
2582             (false,
2583              (Rm'4,
2584               (Rm'3,
2585                (Rm'2,
2586                 (Rm'1,
2587                  (Rm'0,
2588                   (imm6'5,
2589                    (imm6'4,
2590                     (imm6'3,
2591                      (imm6'2,
2592                       (imm6'1,
2593                        (imm6'0,
2594                         (Rn'4,
2595                          (Rn'3,
2596                           (Rn'2,
2597                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2598     Reserved
2599   | (false,
2600    (op'0,
2601     (S'0,
2602      (false,
2603       (true,
2604        (false,
2605         (true,
2606          (true,
2607           (shift'1,
2608            (shift'0,
2609             (false,
2610              (Rm'4,
2611               (Rm'3,
2612                (Rm'2,
2613                 (Rm'1,
2614                  (Rm'0,
2615                   (imm6'5,
2616                    (imm6'4,
2617                     (imm6'3,
2618                      (imm6'2,
2619                       (imm6'1,
2620                        (imm6'0,
2621                         (Rn'4,
2622                          (Rn'3,
2623                           (Rn'2,
2624                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2625     let
2626       val imm6 =
2627         BitsN.fromBitstring
2628           ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],6)
2629     in
2630       if BitsN.bit(imm6,5)
2631         then Reserved
2632       else Data
2633              (AddSubShiftedRegister''32
2634                 (BitsN.B(0x0,32),
2635                  ((not o L3.equal (BitsN.zero (1)))
2636                     (BitsN.fromBitstring([op'0],1)),
2637                   ((not o L3.equal (BitsN.zero (1)))
2638                      (BitsN.fromBitstring([S'0],1)),
2639                    (DecodeShift(BitsN.fromBitstring([shift'1,shift'0],2)),
2640                     (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
2641                      (imm6,
2642                       (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
2643                        BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))))
2644     end
2645   | (true,
2646    (op'0,
2647     (S'0,
2648      (false,
2649       (true,
2650        (false,
2651         (true,
2652          (true,
2653           (shift'1,
2654            (shift'0,
2655             (false,
2656              (Rm'4,
2657               (Rm'3,
2658                (Rm'2,
2659                 (Rm'1,
2660                  (Rm'0,
2661                   (imm6'5,
2662                    (imm6'4,
2663                     (imm6'3,
2664                      (imm6'2,
2665                       (imm6'1,
2666                        (imm6'0,
2667                         (Rn'4,
2668                          (Rn'3,
2669                           (Rn'2,
2670                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2671     Data
2672       (AddSubShiftedRegister''64
2673          (BitsN.B(0x1,64),
2674           ((not o L3.equal (BitsN.zero (1)))
2675              (BitsN.fromBitstring([op'0],1)),
2676            ((not o L3.equal (BitsN.zero (1)))
2677               (BitsN.fromBitstring([S'0],1)),
2678             (DecodeShift(BitsN.fromBitstring([shift'1,shift'0],2)),
2679              (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
2680               (BitsN.fromBitstring
2681                  ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],6),
2682                (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
2683                 BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))))
2684   | (false,
2685    (op'0,
2686     (S'0,
2687      (false,
2688       (true,
2689        (false,
2690         (true,
2691          (true,
2692           (false,
2693            (false,
2694             (true,
2695              (Rm'4,
2696               (Rm'3,
2697                (Rm'2,
2698                 (Rm'1,
2699                  (Rm'0,
2700                   (option'2,
2701                    (option'1,
2702                     (option'0,
2703                      (imm3'2,
2704                       (imm3'1,
2705                        (imm3'0,
2706                         (Rn'4,
2707                          (Rn'3,
2708                           (Rn'2,
2709                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2710     let
2711       val imm3 = BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3)
2712     in
2713       if BitsN.>+(imm3,BitsN.B(0x4,3))
2714         then Reserved
2715       else Data
2716              (AddSubExtendRegister''32
2717                 (BitsN.B(0x0,32),
2718                  ((not o L3.equal (BitsN.zero (1)))
2719                     (BitsN.fromBitstring([op'0],1)),
2720                   ((not o L3.equal (BitsN.zero (1)))
2721                      (BitsN.fromBitstring([S'0],1)),
2722                    (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
2723                     (DecodeRegExtend
2724                        (BitsN.fromBitstring
2725                           ([option'2,option'1,option'0],3)),
2726                      (imm3,
2727                       (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
2728                        BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))))
2729     end
2730   | (true,
2731    (op'0,
2732     (S'0,
2733      (false,
2734       (true,
2735        (false,
2736         (true,
2737          (true,
2738           (false,
2739            (false,
2740             (true,
2741              (Rm'4,
2742               (Rm'3,
2743                (Rm'2,
2744                 (Rm'1,
2745                  (Rm'0,
2746                   (option'2,
2747                    (option'1,
2748                     (option'0,
2749                      (imm3'2,
2750                       (imm3'1,
2751                        (imm3'0,
2752                         (Rn'4,
2753                          (Rn'3,
2754                           (Rn'2,
2755                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2756     let
2757       val imm3 = BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3)
2758     in
2759       if BitsN.>+(imm3,BitsN.B(0x4,3))
2760         then Reserved
2761       else Data
2762              (AddSubExtendRegister''64
2763                 (BitsN.B(0x1,64),
2764                  ((not o L3.equal (BitsN.zero (1)))
2765                     (BitsN.fromBitstring([op'0],1)),
2766                   ((not o L3.equal (BitsN.zero (1)))
2767                      (BitsN.fromBitstring([S'0],1)),
2768                    (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
2769                     (DecodeRegExtend
2770                        (BitsN.fromBitstring
2771                           ([option'2,option'1,option'0],3)),
2772                      (imm3,
2773                       (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
2774                        BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))))
2775     end
2776   | (_,
2777    (op'0,
2778     (S'0,
2779      (true,
2780       (false,
2781        (false,
2782         (false,
2783          (true,
2784           (true,
2785            (_,
2786             (imm12'11,
2787              (imm12'10,
2788               (imm12'9,
2789                (imm12'8,
2790                 (imm12'7,
2791                  (imm12'6,
2792                   (imm12'5,
2793                    (imm12'4,
2794                     (imm12'3,
2795                      (imm12'2,
2796                       (imm12'1,
2797                        (imm12'0,
2798                         (Rn'4,
2799                          (Rn'3,
2800                           (Rn'2,
2801                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2802     Reserved
2803   | (false,
2804    (op'0,
2805     (S'0,
2806      (true,
2807       (false,
2808        (false,
2809         (false,
2810          (true,
2811           (shift'1,
2812            (shift'0,
2813             (imm12'11,
2814              (imm12'10,
2815               (imm12'9,
2816                (imm12'8,
2817                 (imm12'7,
2818                  (imm12'6,
2819                   (imm12'5,
2820                    (imm12'4,
2821                     (imm12'3,
2822                      (imm12'2,
2823                       (imm12'1,
2824                        (imm12'0,
2825                         (Rn'4,
2826                          (Rn'3,
2827                           (Rn'2,
2828                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2829     let
2830       val imm12 =
2831         BitsN.fromBitstring
2832           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,imm12'6,imm12'5,
2833             imm12'4,imm12'3,imm12'2,imm12'1,imm12'0],12)
2834       val imm =
2835         if (BitsN.fromBitstring([shift'1,shift'0],2)) = (BitsN.B(0x0,2))
2836           then BitsN.fromNat(BitsN.toNat imm12,32)
2837         else BitsN.<<(BitsN.fromNat(BitsN.toNat imm12,32),12)
2838     in
2839       Data
2840         (AddSubImmediate''32
2841            (BitsN.B(0x0,32),
2842             ((not o L3.equal (BitsN.zero (1)))
2843                (BitsN.fromBitstring([op'0],1)),
2844              ((not o L3.equal (BitsN.zero (1)))
2845                 (BitsN.fromBitstring([S'0],1)),
2846               (imm,
2847                (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
2848                 BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
2849     end
2850   | (true,
2851    (op'0,
2852     (S'0,
2853      (true,
2854       (false,
2855        (false,
2856         (false,
2857          (true,
2858           (shift'1,
2859            (shift'0,
2860             (imm12'11,
2861              (imm12'10,
2862               (imm12'9,
2863                (imm12'8,
2864                 (imm12'7,
2865                  (imm12'6,
2866                   (imm12'5,
2867                    (imm12'4,
2868                     (imm12'3,
2869                      (imm12'2,
2870                       (imm12'1,
2871                        (imm12'0,
2872                         (Rn'4,
2873                          (Rn'3,
2874                           (Rn'2,
2875                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2876     let
2877       val imm12 =
2878         BitsN.fromBitstring
2879           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,imm12'6,imm12'5,
2880             imm12'4,imm12'3,imm12'2,imm12'1,imm12'0],12)
2881       val imm =
2882         if (BitsN.fromBitstring([shift'1,shift'0],2)) = (BitsN.B(0x0,2))
2883           then BitsN.fromNat(BitsN.toNat imm12,64)
2884         else BitsN.<<(BitsN.fromNat(BitsN.toNat imm12,64),12)
2885     in
2886       Data
2887         (AddSubImmediate''64
2888            (BitsN.B(0x1,64),
2889             ((not o L3.equal (BitsN.zero (1)))
2890                (BitsN.fromBitstring([op'0],1)),
2891              ((not o L3.equal (BitsN.zero (1)))
2892                 (BitsN.fromBitstring([S'0],1)),
2893               (imm,
2894                (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
2895                 BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
2896     end
2897   | (false,
2898    (op'0,
2899     (S'0,
2900      (true,
2901       (true,
2902        (false,
2903         (true,
2904          (false,
2905           (false,
2906            (false,
2907             (false,
2908              (Rm'4,
2909               (Rm'3,
2910                (Rm'2,
2911                 (Rm'1,
2912                  (Rm'0,
2913                   (false,
2914                    (false,
2915                     (false,
2916                      (false,
2917                       (false,
2918                        (false,
2919                         (Rn'4,
2920                          (Rn'3,
2921                           (Rn'2,
2922                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2923     Data
2924       (AddSubCarry''32
2925          (BitsN.B(0x0,32),
2926           ((not o L3.equal (BitsN.zero (1)))
2927              (BitsN.fromBitstring([op'0],1)),
2928            ((not o L3.equal (BitsN.zero (1)))
2929               (BitsN.fromBitstring([S'0],1)),
2930             (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
2931              (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
2932               BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
2933   | (true,
2934    (op'0,
2935     (S'0,
2936      (true,
2937       (true,
2938        (false,
2939         (true,
2940          (false,
2941           (false,
2942            (false,
2943             (false,
2944              (Rm'4,
2945               (Rm'3,
2946                (Rm'2,
2947                 (Rm'1,
2948                  (Rm'0,
2949                   (false,
2950                    (false,
2951                     (false,
2952                      (false,
2953                       (false,
2954                        (false,
2955                         (Rn'4,
2956                          (Rn'3,
2957                           (Rn'2,
2958                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2959     Data
2960       (AddSubCarry''64
2961          (BitsN.B(0x1,64),
2962           ((not o L3.equal (BitsN.zero (1)))
2963              (BitsN.fromBitstring([op'0],1)),
2964            ((not o L3.equal (BitsN.zero (1)))
2965               (BitsN.fromBitstring([S'0],1)),
2966             (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
2967              (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
2968               BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
2969   | (false,
2970    (opc'1,
2971     (opc'0,
2972      (false,
2973       (true,
2974        (false,
2975         (true,
2976          (false,
2977           (shift'1,
2978            (shift'0,
2979             (N'0,
2980              (Rm'4,
2981               (Rm'3,
2982                (Rm'2,
2983                 (Rm'1,
2984                  (Rm'0,
2985                   (imm6'5,
2986                    (imm6'4,
2987                     (imm6'3,
2988                      (imm6'2,
2989                       (imm6'1,
2990                        (imm6'0,
2991                         (Rn'4,
2992                          (Rn'3,
2993                           (Rn'2,
2994                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
2995     let
2996       val imm6 =
2997         BitsN.fromBitstring
2998           ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],6)
2999     in
3000       if BitsN.bit(imm6,5)
3001         then Reserved
3002       else let
3003              val invert =
3004                (BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x1,1))
3005              val (opc,setflags) =
3006                DecodeLogicalOp(BitsN.fromBitstring([opc'1,opc'0],2))
3007            in
3008              Data
3009                (LogicalShiftedRegister''32
3010                   (BitsN.B(0x0,32),
3011                    (opc,
3012                     (invert,
3013                      (setflags,
3014                       (DecodeShift
3015                          (BitsN.fromBitstring([shift'1,shift'0],2)),
3016                        (BitsN.toNat imm6,
3017                         (BitsN.fromBitstring
3018                            ([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3019                          (BitsN.fromBitstring
3020                             ([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3021                           BitsN.fromBitstring
3022                             ([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))))
3023            end
3024     end
3025   | (true,
3026    (opc'1,
3027     (opc'0,
3028      (false,
3029       (true,
3030        (false,
3031         (true,
3032          (false,
3033           (shift'1,
3034            (shift'0,
3035             (N'0,
3036              (Rm'4,
3037               (Rm'3,
3038                (Rm'2,
3039                 (Rm'1,
3040                  (Rm'0,
3041                   (imm6'5,
3042                    (imm6'4,
3043                     (imm6'3,
3044                      (imm6'2,
3045                       (imm6'1,
3046                        (imm6'0,
3047                         (Rn'4,
3048                          (Rn'3,
3049                           (Rn'2,
3050                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3051     let
3052       val invert = (BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x1,1))
3053       val (opc,setflags) =
3054         DecodeLogicalOp(BitsN.fromBitstring([opc'1,opc'0],2))
3055     in
3056       Data
3057         (LogicalShiftedRegister''64
3058            (BitsN.B(0x1,64),
3059             (opc,
3060              (invert,
3061               (setflags,
3062                (DecodeShift(BitsN.fromBitstring([shift'1,shift'0],2)),
3063                 (BitsN.toNat
3064                    (BitsN.fromBitstring
3065                       ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],6)),
3066                  (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3067                   (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3068                    BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))))
3069     end
3070   | (false,
3071    (opc'1,
3072     (opc'0,
3073      (true,
3074       (false,
3075        (false,
3076         (true,
3077          (false,
3078           (false,
3079            (true,
3080             (immr'5,
3081              (immr'4,
3082               (immr'3,
3083                (immr'2,
3084                 (immr'1,
3085                  (immr'0,
3086                   (imms'5,
3087                    (imms'4,
3088                     (imms'3,
3089                      (imms'2,
3090                       (imms'1,
3091                        (imms'0,
3092                         (Rn'4,
3093                          (Rn'3,
3094                           (Rn'2,
3095                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3096     Reserved
3097   | (false,
3098    (opc'1,
3099     (opc'0,
3100      (true,
3101       (false,
3102        (false,
3103         (true,
3104          (false,
3105           (false,
3106            (N'0,
3107             (immr'5,
3108              (immr'4,
3109               (immr'3,
3110                (immr'2,
3111                 (immr'1,
3112                  (immr'0,
3113                   (imms'5,
3114                    (imms'4,
3115                     (imms'3,
3116                      (imms'2,
3117                       (imms'1,
3118                        (imms'0,
3119                         (Rn'4,
3120                          (Rn'3,
3121                           (Rn'2,
3122                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3123     (case DecodeBitMasks 32
3124        (BitsN.fromBitstring([N'0],1),
3125         (BitsN.fromBitstring
3126            ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6),
3127          (BitsN.fromBitstring
3128             ([immr'5,immr'4,immr'3,immr'2,immr'1,immr'0],6),true))) of
3129         Option.SOME(imm,_) =>
3130           let
3131             val (opc,setflags) =
3132               DecodeLogicalOp(BitsN.fromBitstring([opc'1,opc'0],2))
3133           in
3134             Data
3135               (LogicalImmediate''32
3136                  (BitsN.B(0x0,32),
3137                   (opc,
3138                    (setflags,
3139                     (imm,
3140                      (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3141                       BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
3142           end
3143       | NONE => Reserved)
3144   | (true,
3145    (opc'1,
3146     (opc'0,
3147      (true,
3148       (false,
3149        (false,
3150         (true,
3151          (false,
3152           (false,
3153            (N'0,
3154             (immr'5,
3155              (immr'4,
3156               (immr'3,
3157                (immr'2,
3158                 (immr'1,
3159                  (immr'0,
3160                   (imms'5,
3161                    (imms'4,
3162                     (imms'3,
3163                      (imms'2,
3164                       (imms'1,
3165                        (imms'0,
3166                         (Rn'4,
3167                          (Rn'3,
3168                           (Rn'2,
3169                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3170     (case DecodeBitMasks 64
3171        (BitsN.fromBitstring([N'0],1),
3172         (BitsN.fromBitstring
3173            ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6),
3174          (BitsN.fromBitstring
3175             ([immr'5,immr'4,immr'3,immr'2,immr'1,immr'0],6),true))) of
3176         Option.SOME(imm,_) =>
3177           let
3178             val (opc,setflags) =
3179               DecodeLogicalOp(BitsN.fromBitstring([opc'1,opc'0],2))
3180           in
3181             Data
3182               (LogicalImmediate''64
3183                  (BitsN.B(0x1,64),
3184                   (opc,
3185                    (setflags,
3186                     (imm,
3187                      (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3188                       BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
3189           end
3190       | NONE => Reserved)
3191   | (false,
3192    (false,
3193     (false,
3194      (true,
3195       (true,
3196        (false,
3197         (true,
3198          (false,
3199           (true,
3200            (true,
3201             (false,
3202              (Rm'4,
3203               (Rm'3,
3204                (Rm'2,
3205                 (Rm'1,
3206                  (Rm'0,
3207                   (false,
3208                    (false,
3209                     (true,
3210                      (false,
3211                       (op2'1,
3212                        (op2'0,
3213                         (Rn'4,
3214                          (Rn'3,
3215                           (Rn'2,
3216                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3217     Data
3218       (Shift''32
3219          (BitsN.B(0x0,32),
3220           (DecodeShift(BitsN.fromBitstring([op2'1,op2'0],2)),
3221            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3222             (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3223              BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))
3224   | (true,
3225    (false,
3226     (false,
3227      (true,
3228       (true,
3229        (false,
3230         (true,
3231          (false,
3232           (true,
3233            (true,
3234             (false,
3235              (Rm'4,
3236               (Rm'3,
3237                (Rm'2,
3238                 (Rm'1,
3239                  (Rm'0,
3240                   (false,
3241                    (false,
3242                     (true,
3243                      (false,
3244                       (op2'1,
3245                        (op2'0,
3246                         (Rn'4,
3247                          (Rn'3,
3248                           (Rn'2,
3249                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3250     Data
3251       (Shift''64
3252          (BitsN.B(0x1,64),
3253           (DecodeShift(BitsN.fromBitstring([op2'1,op2'0],2)),
3254            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3255             (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3256              BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))
3257   | (false,
3258    (opc'1,
3259     (opc'0,
3260      (true,
3261       (false,
3262        (false,
3263         (true,
3264          (false,
3265           (true,
3266            (true,
3267             (_,
3268              (imm16'15,
3269               (imm16'14,
3270                (imm16'13,
3271                 (imm16'12,
3272                  (imm16'11,
3273                   (imm16'10,
3274                    (imm16'9,
3275                     (imm16'8,
3276                      (imm16'7,
3277                       (imm16'6,
3278                        (imm16'5,
3279                         (imm16'4,
3280                          (imm16'3,
3281                           (imm16'2,
3282                            (imm16'1,
3283                             (imm16'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3284     Unallocated
3285   | (sf'0,
3286    (false,
3287     (true,
3288      (true,
3289       (false,
3290        (false,
3291         (true,
3292          (false,
3293           (true,
3294            (hw'1,
3295             (hw'0,
3296              (imm16'15,
3297               (imm16'14,
3298                (imm16'13,
3299                 (imm16'12,
3300                  (imm16'11,
3301                   (imm16'10,
3302                    (imm16'9,
3303                     (imm16'8,
3304                      (imm16'7,
3305                       (imm16'6,
3306                        (imm16'5,
3307                         (imm16'4,
3308                          (imm16'3,
3309                           (imm16'2,
3310                            (imm16'1,
3311                             (imm16'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3312     Unallocated
3313   | (sf'0,
3314    (opc'1,
3315     (opc'0,
3316      (true,
3317       (false,
3318        (false,
3319         (true,
3320          (false,
3321           (true,
3322            (hw'1,
3323             (hw'0,
3324              (imm16'15,
3325               (imm16'14,
3326                (imm16'13,
3327                 (imm16'12,
3328                  (imm16'11,
3329                   (imm16'10,
3330                    (imm16'9,
3331                     (imm16'8,
3332                      (imm16'7,
3333                       (imm16'6,
3334                        (imm16'5,
3335                         (imm16'4,
3336                          (imm16'3,
3337                           (imm16'2,
3338                            (imm16'1,
3339                             (imm16'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3340     let
3341       val Rd = BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)
3342       val imm16 =
3343         BitsN.fromBitstring
3344           ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10,
3345             imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3,
3346             imm16'2,imm16'1,imm16'0],16)
3347       val hw = BitsN.fromBitstring([hw'1,hw'0],2)
3348       val opcode =
3349         case BitsN.fromBitstring([opc'1,opc'0],2) of
3350            BitsN.B(0x0,_) => MoveWideOp_N
3351          | BitsN.B(0x2,_) => MoveWideOp_Z
3352          | BitsN.B(0x3,_) => MoveWideOp_K
3353          | BitsN.B(0x1,_) => MoveWideOp_K
3354          | _ => raise General.Bind
3355     in
3356       if (BitsN.fromBitstring([sf'0],1)) = (BitsN.B(0x1,1))
3357         then Data(MoveWide''64(BitsN.B(0x1,64),(opcode,(hw,(imm16,Rd)))))
3358       else Data(MoveWide''32(BitsN.B(0x0,32),(opcode,(hw,(imm16,Rd)))))
3359     end
3360   | (_,
3361    (true,
3362     (true,
3363      (true,
3364       (false,
3365        (false,
3366         (true,
3367          (true,
3368           (false,
3369            (N'0,
3370             (immr'5,
3371              (immr'4,
3372               (immr'3,
3373                (immr'2,
3374                 (immr'1,
3375                  (immr'0,
3376                   (imms'5,
3377                    (imms'4,
3378                     (imms'3,
3379                      (imms'2,
3380                       (imms'1,
3381                        (imms'0,
3382                         (Rn'4,
3383                          (Rn'3,
3384                           (Rn'2,
3385                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3386     Unallocated
3387   | (false,
3388    (opc'1,
3389     (opc'0,
3390      (true,
3391       (false,
3392        (false,
3393         (true,
3394          (true,
3395           (false,
3396            (N'0,
3397             (immr'5,
3398              (immr'4,
3399               (immr'3,
3400                (immr'2,
3401                 (immr'1,
3402                  (immr'0,
3403                   (imms'5,
3404                    (imms'4,
3405                     (imms'3,
3406                      (imms'2,
3407                       (imms'1,
3408                        (imms'0,
3409                         (Rn'4,
3410                          (Rn'3,
3411                           (Rn'2,
3412                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3413     let
3414       val imms =
3415         BitsN.fromBitstring
3416           ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6)
3417       val immr =
3418         BitsN.fromBitstring
3419           ([immr'5,immr'4,immr'3,immr'2,immr'1,immr'0],6)
3420       val N = BitsN.fromBitstring([N'0],1)
3421     in
3422       if (N = (BitsN.B(0x1,1))) orelse
3423          ((BitsN.bit(immr,5)) orelse (BitsN.bit(imms,5)))
3424         then Reserved
3425       else let
3426              val (inzero,extend) =
3427                case BitsN.fromBitstring([opc'1,opc'0],2) of
3428                   BitsN.B(0x0,_) => (true,true)
3429                 | BitsN.B(0x1,_) => (false,false)
3430                 | BitsN.B(0x2,_) => (true,false)
3431                 | _ => (false,false)
3432            in
3433              case DecodeBitMasks 32 (N,(imms,(immr,false))) of
3434                 Option.SOME(wmask,tmask) =>
3435                   Data
3436                     (BitfieldMove''32
3437                        (BitsN.B(0x0,32),
3438                         (inzero,
3439                          (extend,
3440                           (wmask,
3441                            (tmask,
3442                             (BitsN.toNat immr,
3443                              (BitsN.toNat imms,
3444                               (BitsN.fromBitstring
3445                                  ([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3446                                BitsN.fromBitstring
3447                                  ([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))))
3448               | NONE => Reserved
3449            end
3450     end
3451   | (true,
3452    (opc'1,
3453     (opc'0,
3454      (true,
3455       (false,
3456        (false,
3457         (true,
3458          (true,
3459           (false,
3460            (N'0,
3461             (immr'5,
3462              (immr'4,
3463               (immr'3,
3464                (immr'2,
3465                 (immr'1,
3466                  (immr'0,
3467                   (imms'5,
3468                    (imms'4,
3469                     (imms'3,
3470                      (imms'2,
3471                       (imms'1,
3472                        (imms'0,
3473                         (Rn'4,
3474                          (Rn'3,
3475                           (Rn'2,
3476                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3477     let
3478       val imms =
3479         BitsN.fromBitstring
3480           ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6)
3481       val immr =
3482         BitsN.fromBitstring
3483           ([immr'5,immr'4,immr'3,immr'2,immr'1,immr'0],6)
3484       val N = BitsN.fromBitstring([N'0],1)
3485     in
3486       if N = (BitsN.B(0x0,1))
3487         then Reserved
3488       else let
3489              val (inzero,extend) =
3490                case BitsN.fromBitstring([opc'1,opc'0],2) of
3491                   BitsN.B(0x0,_) => (true,true)
3492                 | BitsN.B(0x1,_) => (false,false)
3493                 | BitsN.B(0x2,_) => (true,false)
3494                 | _ => (false,false)
3495            in
3496              case DecodeBitMasks 64 (N,(imms,(immr,false))) of
3497                 Option.SOME(wmask,tmask) =>
3498                   Data
3499                     (BitfieldMove''64
3500                        (BitsN.B(0x1,64),
3501                         (inzero,
3502                          (extend,
3503                           (wmask,
3504                            (tmask,
3505                             (BitsN.toNat immr,
3506                              (BitsN.toNat imms,
3507                               (BitsN.fromBitstring
3508                                  ([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3509                                BitsN.fromBitstring
3510                                  ([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))))
3511               | NONE => Reserved
3512            end
3513     end
3514   | (false,
3515    (op'0,
3516     (true,
3517      (true,
3518       (true,
3519        (false,
3520         (true,
3521          (false,
3522           (false,
3523            (true,
3524             (false,
3525              (imm5'4,
3526               (imm5'3,
3527                (imm5'2,
3528                 (imm5'1,
3529                  (imm5'0,
3530                   (cond'3,
3531                    (cond'2,
3532                     (cond'1,
3533                      (cond'0,
3534                       (true,
3535                        (false,
3536                         (Rn'4,
3537                          (Rn'3,
3538                           (Rn'2,
3539                            (Rn'1,(Rn'0,(false,(n'0,(z'0,(c'0,v'0))))))))))))))))))))))))))))))) =>
3540     let
3541       val nzcv =
3542         ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([n'0],1)),
3543          ((not o L3.equal (BitsN.zero (1)))
3544             (BitsN.fromBitstring([z'0],1)),
3545           ((not o L3.equal (BitsN.zero (1)))
3546              (BitsN.fromBitstring([c'0],1)),
3547            (not o L3.equal (BitsN.zero (1)))
3548              (BitsN.fromBitstring([v'0],1)))))
3549     in
3550       Data
3551         (ConditionalCompareImmediate''32
3552            (BitsN.B(0x0,32),
3553             ((not o L3.equal (BitsN.zero (1)))
3554                (BitsN.fromBitstring([op'0],1)),
3555              (BitsN.fromNat
3556                 (BitsN.toNat
3557                    (BitsN.fromBitstring
3558                       ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5)),32),
3559               (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4),
3560                (nzcv,BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5)))))))
3561     end
3562   | (true,
3563    (op'0,
3564     (true,
3565      (true,
3566       (true,
3567        (false,
3568         (true,
3569          (false,
3570           (false,
3571            (true,
3572             (false,
3573              (imm5'4,
3574               (imm5'3,
3575                (imm5'2,
3576                 (imm5'1,
3577                  (imm5'0,
3578                   (cond'3,
3579                    (cond'2,
3580                     (cond'1,
3581                      (cond'0,
3582                       (true,
3583                        (false,
3584                         (Rn'4,
3585                          (Rn'3,
3586                           (Rn'2,
3587                            (Rn'1,(Rn'0,(false,(n'0,(z'0,(c'0,v'0))))))))))))))))))))))))))))))) =>
3588     let
3589       val nzcv =
3590         ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([n'0],1)),
3591          ((not o L3.equal (BitsN.zero (1)))
3592             (BitsN.fromBitstring([z'0],1)),
3593           ((not o L3.equal (BitsN.zero (1)))
3594              (BitsN.fromBitstring([c'0],1)),
3595            (not o L3.equal (BitsN.zero (1)))
3596              (BitsN.fromBitstring([v'0],1)))))
3597     in
3598       Data
3599         (ConditionalCompareImmediate''64
3600            (BitsN.B(0x1,64),
3601             ((not o L3.equal (BitsN.zero (1)))
3602                (BitsN.fromBitstring([op'0],1)),
3603              (BitsN.fromNat
3604                 (BitsN.toNat
3605                    (BitsN.fromBitstring
3606                       ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5)),64),
3607               (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4),
3608                (nzcv,BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5)))))))
3609     end
3610   | (false,
3611    (op'0,
3612     (true,
3613      (true,
3614       (true,
3615        (false,
3616         (true,
3617          (false,
3618           (false,
3619            (true,
3620             (false,
3621              (Rm'4,
3622               (Rm'3,
3623                (Rm'2,
3624                 (Rm'1,
3625                  (Rm'0,
3626                   (cond'3,
3627                    (cond'2,
3628                     (cond'1,
3629                      (cond'0,
3630                       (false,
3631                        (false,
3632                         (Rn'4,
3633                          (Rn'3,
3634                           (Rn'2,
3635                            (Rn'1,(Rn'0,(false,(n'0,(z'0,(c'0,v'0))))))))))))))))))))))))))))))) =>
3636     let
3637       val nzcv =
3638         ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([n'0],1)),
3639          ((not o L3.equal (BitsN.zero (1)))
3640             (BitsN.fromBitstring([z'0],1)),
3641           ((not o L3.equal (BitsN.zero (1)))
3642              (BitsN.fromBitstring([c'0],1)),
3643            (not o L3.equal (BitsN.zero (1)))
3644              (BitsN.fromBitstring([v'0],1)))))
3645     in
3646       Data
3647         (ConditionalCompareRegister''32
3648            (BitsN.B(0x0,32),
3649             ((not o L3.equal (BitsN.zero (1)))
3650                (BitsN.fromBitstring([op'0],1)),
3651              (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4),
3652               (nzcv,
3653                (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3654                 BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5)))))))
3655     end
3656   | (true,
3657    (op'0,
3658     (true,
3659      (true,
3660       (true,
3661        (false,
3662         (true,
3663          (false,
3664           (false,
3665            (true,
3666             (false,
3667              (Rm'4,
3668               (Rm'3,
3669                (Rm'2,
3670                 (Rm'1,
3671                  (Rm'0,
3672                   (cond'3,
3673                    (cond'2,
3674                     (cond'1,
3675                      (cond'0,
3676                       (false,
3677                        (false,
3678                         (Rn'4,
3679                          (Rn'3,
3680                           (Rn'2,
3681                            (Rn'1,(Rn'0,(false,(n'0,(z'0,(c'0,v'0))))))))))))))))))))))))))))))) =>
3682     let
3683       val nzcv =
3684         ((not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([n'0],1)),
3685          ((not o L3.equal (BitsN.zero (1)))
3686             (BitsN.fromBitstring([z'0],1)),
3687           ((not o L3.equal (BitsN.zero (1)))
3688              (BitsN.fromBitstring([c'0],1)),
3689            (not o L3.equal (BitsN.zero (1)))
3690              (BitsN.fromBitstring([v'0],1)))))
3691     in
3692       Data
3693         (ConditionalCompareRegister''64
3694            (BitsN.B(0x1,64),
3695             ((not o L3.equal (BitsN.zero (1)))
3696                (BitsN.fromBitstring([op'0],1)),
3697              (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4),
3698               (nzcv,
3699                (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3700                 BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5)))))))
3701     end
3702   | (false,
3703    (op'0,
3704     (false,
3705      (true,
3706       (true,
3707        (false,
3708         (true,
3709          (false,
3710           (true,
3711            (false,
3712             (false,
3713              (Rm'4,
3714               (Rm'3,
3715                (Rm'2,
3716                 (Rm'1,
3717                  (Rm'0,
3718                   (cond'3,
3719                    (cond'2,
3720                     (cond'1,
3721                      (cond'0,
3722                       (false,
3723                        (o2'0,
3724                         (Rn'4,
3725                          (Rn'3,
3726                           (Rn'2,
3727                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3728     Data
3729       (ConditionalSelect''32
3730          (BitsN.B(0x0,32),
3731           ((not o L3.equal (BitsN.zero (1)))
3732              (BitsN.fromBitstring([op'0],1)),
3733            ((not o L3.equal (BitsN.zero (1)))
3734               (BitsN.fromBitstring([o2'0],1)),
3735             (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4),
3736              (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3737               (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3738                BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))
3739   | (true,
3740    (op'0,
3741     (false,
3742      (true,
3743       (true,
3744        (false,
3745         (true,
3746          (false,
3747           (true,
3748            (false,
3749             (false,
3750              (Rm'4,
3751               (Rm'3,
3752                (Rm'2,
3753                 (Rm'1,
3754                  (Rm'0,
3755                   (cond'3,
3756                    (cond'2,
3757                     (cond'1,
3758                      (cond'0,
3759                       (false,
3760                        (o2'0,
3761                         (Rn'4,
3762                          (Rn'3,
3763                           (Rn'2,
3764                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3765     Data
3766       (ConditionalSelect''64
3767          (BitsN.B(0x1,64),
3768           ((not o L3.equal (BitsN.zero (1)))
3769              (BitsN.fromBitstring([op'0],1)),
3770            ((not o L3.equal (BitsN.zero (1)))
3771               (BitsN.fromBitstring([o2'0],1)),
3772             (BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4),
3773              (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3774               (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3775                BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))))
3776   | (false,
3777    (true,
3778     (false,
3779      (true,
3780       (true,
3781        (false,
3782         (true,
3783          (false,
3784           (true,
3785            (true,
3786             (false,
3787              (false,
3788               (false,
3789                (false,
3790                 (false,
3791                  (false,
3792                   (false,
3793                    (false,
3794                     (false,
3795                      (true,
3796                       (false,
3797                        (op'0,
3798                         (Rn'4,
3799                          (Rn'3,
3800                           (Rn'2,
3801                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3802     Data
3803       (CountLeading''32
3804          (BitsN.B(0x0,32),
3805           ((not o L3.equal (BitsN.zero (1)))
3806              (BitsN.fromBitstring([op'0],1)),
3807            (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3808             BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))
3809   | (true,
3810    (true,
3811     (false,
3812      (true,
3813       (true,
3814        (false,
3815         (true,
3816          (false,
3817           (true,
3818            (true,
3819             (false,
3820              (false,
3821               (false,
3822                (false,
3823                 (false,
3824                  (false,
3825                   (false,
3826                    (false,
3827                     (false,
3828                      (true,
3829                       (false,
3830                        (op'0,
3831                         (Rn'4,
3832                          (Rn'3,
3833                           (Rn'2,
3834                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3835     Data
3836       (CountLeading''64
3837          (BitsN.B(0x1,64),
3838           ((not o L3.equal (BitsN.zero (1)))
3839              (BitsN.fromBitstring([op'0],1)),
3840            (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3841             BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))
3842   | (false,
3843    (false,
3844     (false,
3845      (true,
3846       (false,
3847        (false,
3848         (true,
3849          (true,
3850           (true,
3851            (N'0,
3852             (false,
3853              (Rm'4,
3854               (Rm'3,
3855                (Rm'2,
3856                 (Rm'1,
3857                  (Rm'0,
3858                   (imms'5,
3859                    (imms'4,
3860                     (imms'3,
3861                      (imms'2,
3862                       (imms'1,
3863                        (imms'0,
3864                         (Rn'4,
3865                          (Rn'3,
3866                           (Rn'2,
3867                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3868     let
3869       val imms =
3870         BitsN.fromBitstring
3871           ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6)
3872     in
3873       if not((BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x0,1)))
3874         then Unallocated
3875       else if BitsN.bit(imms,5)
3876         then Reserved
3877       else Data
3878              (ExtractRegister''32
3879                 (BitsN.B(0x0,32),
3880                  (imms,
3881                   (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3882                    (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3883                     BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))
3884     end
3885   | (true,
3886    (false,
3887     (false,
3888      (true,
3889       (false,
3890        (false,
3891         (true,
3892          (true,
3893           (true,
3894            (N'0,
3895             (false,
3896              (Rm'4,
3897               (Rm'3,
3898                (Rm'2,
3899                 (Rm'1,
3900                  (Rm'0,
3901                   (imms'5,
3902                    (imms'4,
3903                     (imms'3,
3904                      (imms'2,
3905                       (imms'1,
3906                        (imms'0,
3907                         (Rn'4,
3908                          (Rn'3,
3909                           (Rn'2,
3910                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3911     (if not((BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x1,1)))
3912        then Unallocated
3913      else Data
3914             (ExtractRegister''64
3915                (BitsN.B(0x1,64),
3916                 (BitsN.fromBitstring
3917                    ([imms'5,imms'4,imms'3,imms'2,imms'1,imms'0],6),
3918                  (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3919                   (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3920                    BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
3921   | (false,
3922    (false,
3923     (false,
3924      (true,
3925       (true,
3926        (false,
3927         (true,
3928          (false,
3929           (true,
3930            (true,
3931             (false,
3932              (Rm'4,
3933               (Rm'3,
3934                (Rm'2,
3935                 (Rm'1,
3936                  (Rm'0,
3937                   (false,
3938                    (false,
3939                     (false,
3940                      (false,
3941                       (true,
3942                        (o1'0,
3943                         (Rn'4,
3944                          (Rn'3,
3945                           (Rn'2,
3946                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3947     Data
3948       (Division''32
3949          (BitsN.B(0x0,32),
3950           ((BitsN.fromBitstring([o1'0],1)) = (BitsN.B(0x0,1)),
3951            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3952             (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3953              BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))
3954   | (true,
3955    (false,
3956     (false,
3957      (true,
3958       (true,
3959        (false,
3960         (true,
3961          (false,
3962           (true,
3963            (true,
3964             (false,
3965              (Rm'4,
3966               (Rm'3,
3967                (Rm'2,
3968                 (Rm'1,
3969                  (Rm'0,
3970                   (false,
3971                    (false,
3972                     (false,
3973                      (false,
3974                       (true,
3975                        (o1'0,
3976                         (Rn'4,
3977                          (Rn'3,
3978                           (Rn'2,
3979                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
3980     Data
3981       (Division''64
3982          (BitsN.B(0x1,64),
3983           ((BitsN.fromBitstring([o1'0],1)) = (BitsN.B(0x0,1)),
3984            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
3985             (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
3986              BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))
3987   | (false,
3988    (false,
3989     (false,
3990      (true,
3991       (true,
3992        (false,
3993         (true,
3994          (true,
3995           (false,
3996            (false,
3997             (false,
3998              (Rm'4,
3999               (Rm'3,
4000                (Rm'2,
4001                 (Rm'1,
4002                  (Rm'0,
4003                   (o0'0,
4004                    (Ra'4,
4005                     (Ra'3,
4006                      (Ra'2,
4007                       (Ra'1,
4008                        (Ra'0,
4009                         (Rn'4,
4010                          (Rn'3,
4011                           (Rn'2,
4012                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4013     Data
4014       (MultiplyAddSub''32
4015          (BitsN.B(0x0,32),
4016           ((BitsN.fromBitstring([o0'0],1)) = (BitsN.B(0x1,1)),
4017            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
4018             (BitsN.fromBitstring([Ra'4,Ra'3,Ra'2,Ra'1,Ra'0],5),
4019              (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4020               BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
4021   | (true,
4022    (false,
4023     (false,
4024      (true,
4025       (true,
4026        (false,
4027         (true,
4028          (true,
4029           (false,
4030            (false,
4031             (false,
4032              (Rm'4,
4033               (Rm'3,
4034                (Rm'2,
4035                 (Rm'1,
4036                  (Rm'0,
4037                   (o0'0,
4038                    (Ra'4,
4039                     (Ra'3,
4040                      (Ra'2,
4041                       (Ra'1,
4042                        (Ra'0,
4043                         (Rn'4,
4044                          (Rn'3,
4045                           (Rn'2,
4046                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4047     Data
4048       (MultiplyAddSub''64
4049          (BitsN.B(0x1,64),
4050           ((BitsN.fromBitstring([o0'0],1)) = (BitsN.B(0x1,1)),
4051            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
4052             (BitsN.fromBitstring([Ra'4,Ra'3,Ra'2,Ra'1,Ra'0],5),
4053              (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4054               BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
4055   | (true,
4056    (false,
4057     (false,
4058      (true,
4059       (true,
4060        (false,
4061         (true,
4062          (true,
4063           (U'0,
4064            (false,
4065             (true,
4066              (Rm'4,
4067               (Rm'3,
4068                (Rm'2,
4069                 (Rm'1,
4070                  (Rm'0,
4071                   (o0'0,
4072                    (Ra'4,
4073                     (Ra'3,
4074                      (Ra'2,
4075                       (Ra'1,
4076                        (Ra'0,
4077                         (Rn'4,
4078                          (Rn'3,
4079                           (Rn'2,
4080                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4081     Data
4082       (MultiplyAddSubLong
4083          ((not o L3.equal (BitsN.zero (1)))
4084             (BitsN.fromBitstring([o0'0],1)),
4085           ((BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x0,1)),
4086            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
4087             (BitsN.fromBitstring([Ra'4,Ra'3,Ra'2,Ra'1,Ra'0],5),
4088              (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4089               BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))))
4090   | (true,
4091    (false,
4092     (false,
4093      (true,
4094       (true,
4095        (false,
4096         (true,
4097          (true,
4098           (U'0,
4099            (true,
4100             (false,
4101              (Rm'4,
4102               (Rm'3,
4103                (Rm'2,
4104                 (Rm'1,
4105                  (Rm'0,
4106                   (false,
4107                    (_,
4108                     (_,
4109                      (_,
4110                       (_,
4111                        (_,
4112                         (Rn'4,
4113                          (Rn'3,
4114                           (Rn'2,
4115                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4116     Data
4117       (MultiplyHigh
4118          ((BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x0,1)),
4119           (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
4120            (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4121             BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))
4122   | (false,
4123    (true,
4124     (false,
4125      (true,
4126       (true,
4127        (false,
4128         (true,
4129          (false,
4130           (true,
4131            (true,
4132             (false,
4133              (false,
4134               (false,
4135                (false,
4136                 (false,
4137                  (false,
4138                   (false,
4139                    (false,
4140                     (false,
4141                      (false,
4142                       (true,
4143                        (true,
4144                         (Rn'4,
4145                          (Rn'3,
4146                           (Rn'2,
4147                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4148     Unallocated
4149   | (false,
4150    (true,
4151     (false,
4152      (true,
4153       (true,
4154        (false,
4155         (true,
4156          (false,
4157           (true,
4158            (true,
4159             (false,
4160              (false,
4161               (false,
4162                (false,
4163                 (false,
4164                  (false,
4165                   (false,
4166                    (false,
4167                     (false,
4168                      (false,
4169                       (opc'1,
4170                        (opc'0,
4171                         (Rn'4,
4172                          (Rn'3,
4173                           (Rn'2,
4174                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4175     Data
4176       (Reverse''32
4177          (BitsN.B(0x0,32),
4178           ((Cast.natToRevOp o BitsN.toNat)
4179              (BitsN.fromBitstring([opc'1,opc'0],2)),
4180            (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4181             BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))
4182   | (true,
4183    (true,
4184     (false,
4185      (true,
4186       (true,
4187        (false,
4188         (true,
4189          (false,
4190           (true,
4191            (true,
4192             (false,
4193              (false,
4194               (false,
4195                (false,
4196                 (false,
4197                  (false,
4198                   (false,
4199                    (false,
4200                     (false,
4201                      (false,
4202                       (opc'1,
4203                        (opc'0,
4204                         (Rn'4,
4205                          (Rn'3,
4206                           (Rn'2,
4207                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4208     Data
4209       (Reverse''64
4210          (BitsN.B(0x1,64),
4211           ((Cast.natToRevOp o BitsN.toNat)
4212              (BitsN.fromBitstring([opc'1,opc'0],2)),
4213            (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4214             BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5)))))
4215   | (false,
4216    (false,
4217     (false,
4218      (true,
4219       (true,
4220        (false,
4221         (true,
4222          (false,
4223           (true,
4224            (true,
4225             (false,
4226              (Rm'4,
4227               (Rm'3,
4228                (Rm'2,
4229                 (Rm'1,
4230                  (Rm'0,
4231                   (false,
4232                    (true,
4233                     (false,
4234                      (C'0,
4235                       (false,
4236                        (false,
4237                         (Rn'4,
4238                          (Rn'3,
4239                           (Rn'2,
4240                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4241     CRCExt
4242       (CRC''8
4243          (BitsN.B(0x0,8),
4244           ((not o L3.equal (BitsN.zero (1)))
4245              (BitsN.fromBitstring([C'0],1)),
4246            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
4247             (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4248              BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))
4249   | (false,
4250    (false,
4251     (false,
4252      (true,
4253       (true,
4254        (false,
4255         (true,
4256          (false,
4257           (true,
4258            (true,
4259             (false,
4260              (Rm'4,
4261               (Rm'3,
4262                (Rm'2,
4263                 (Rm'1,
4264                  (Rm'0,
4265                   (false,
4266                    (true,
4267                     (false,
4268                      (C'0,
4269                       (false,
4270                        (true,
4271                         (Rn'4,
4272                          (Rn'3,
4273                           (Rn'2,
4274                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4275     CRCExt
4276       (CRC''16
4277          (BitsN.B(0x1,16),
4278           ((not o L3.equal (BitsN.zero (1)))
4279              (BitsN.fromBitstring([C'0],1)),
4280            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
4281             (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4282              BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))
4283   | (false,
4284    (false,
4285     (false,
4286      (true,
4287       (true,
4288        (false,
4289         (true,
4290          (false,
4291           (true,
4292            (true,
4293             (false,
4294              (Rm'4,
4295               (Rm'3,
4296                (Rm'2,
4297                 (Rm'1,
4298                  (Rm'0,
4299                   (false,
4300                    (true,
4301                     (false,
4302                      (C'0,
4303                       (true,
4304                        (false,
4305                         (Rn'4,
4306                          (Rn'3,
4307                           (Rn'2,
4308                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4309     CRCExt
4310       (CRC''32
4311          (BitsN.B(0x2,32),
4312           ((not o L3.equal (BitsN.zero (1)))
4313              (BitsN.fromBitstring([C'0],1)),
4314            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
4315             (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4316              BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))
4317   | (true,
4318    (false,
4319     (false,
4320      (true,
4321       (true,
4322        (false,
4323         (true,
4324          (false,
4325           (true,
4326            (true,
4327             (false,
4328              (Rm'4,
4329               (Rm'3,
4330                (Rm'2,
4331                 (Rm'1,
4332                  (Rm'0,
4333                   (false,
4334                    (true,
4335                     (false,
4336                      (C'0,
4337                       (true,
4338                        (true,
4339                         (Rn'4,
4340                          (Rn'3,
4341                           (Rn'2,
4342                            (Rn'1,(Rn'0,(Rd'4,(Rd'3,(Rd'2,(Rd'1,Rd'0))))))))))))))))))))))))))))))) =>
4343     CRCExt
4344       (CRC''64
4345          (BitsN.B(0x3,64),
4346           ((not o L3.equal (BitsN.zero (1)))
4347              (BitsN.fromBitstring([C'0],1)),
4348            (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
4349             (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4350              BitsN.fromBitstring([Rd'4,Rd'3,Rd'2,Rd'1,Rd'0],5))))))
4351   | (false,
4352    (true,
4353     (false,
4354      (true,
4355       (false,
4356        (true,
4357         (false,
4358          (false,
4359           (imm19'18,
4360            (imm19'17,
4361             (imm19'16,
4362              (imm19'15,
4363               (imm19'14,
4364                (imm19'13,
4365                 (imm19'12,
4366                  (imm19'11,
4367                   (imm19'10,
4368                    (imm19'9,
4369                     (imm19'8,
4370                      (imm19'7,
4371                       (imm19'6,
4372                        (imm19'5,
4373                         (imm19'4,
4374                          (imm19'3,
4375                           (imm19'2,
4376                            (imm19'1,
4377                             (imm19'0,
4378                              (false,(cond'3,(cond'2,(cond'1,cond'0))))))))))))))))))))))))))))))) =>
4379     Branch
4380       (BranchConditional
4381          (BitsN.signExtend 64
4382             (BitsN.@@
4383                (BitsN.fromBitstring
4384                   ([imm19'18,imm19'17,imm19'16,imm19'15,imm19'14,
4385                     imm19'13,imm19'12,imm19'11,imm19'10,imm19'9,imm19'8,
4386                     imm19'7,imm19'6,imm19'5,imm19'4,imm19'3,imm19'2,
4387                     imm19'1,imm19'0],19),BitsN.B(0x0,2))),
4388           BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4)))
4389   | (op'0,
4390    (false,
4391     (false,
4392      (true,
4393       (false,
4394        (true,
4395         (imm26'25,
4396          (imm26'24,
4397           (imm26'23,
4398            (imm26'22,
4399             (imm26'21,
4400              (imm26'20,
4401               (imm26'19,
4402                (imm26'18,
4403                 (imm26'17,
4404                  (imm26'16,
4405                   (imm26'15,
4406                    (imm26'14,
4407                     (imm26'13,
4408                      (imm26'12,
4409                       (imm26'11,
4410                        (imm26'10,
4411                         (imm26'9,
4412                          (imm26'8,
4413                           (imm26'7,
4414                            (imm26'6,
4415                             (imm26'5,
4416                              (imm26'4,
4417                               (imm26'3,(imm26'2,(imm26'1,imm26'0))))))))))))))))))))))))))))))) =>
4418     let
4419       val branch_type =
4420         if (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x1,1))
4421           then BranchType_CALL
4422         else BranchType_JMP
4423     in
4424       Branch
4425         (BranchImmediate
4426            (BitsN.signExtend 64
4427               (BitsN.@@
4428                  (BitsN.fromBitstring
4429                     ([imm26'25,imm26'24,imm26'23,imm26'22,imm26'21,
4430                       imm26'20,imm26'19,imm26'18,imm26'17,imm26'16,
4431                       imm26'15,imm26'14,imm26'13,imm26'12,imm26'11,
4432                       imm26'10,imm26'9,imm26'8,imm26'7,imm26'6,imm26'5,
4433                       imm26'4,imm26'3,imm26'2,imm26'1,imm26'0],26),
4434                   BitsN.B(0x0,2))),branch_type))
4435     end
4436   | (true,
4437    (true,
4438     (false,
4439      (true,
4440       (false,
4441        (true,
4442         (true,
4443          (false,
4444           (false,
4445            (false,
4446             (false,
4447              (true,
4448               (true,
4449                (true,
4450                 (true,
4451                  (true,
4452                   (false,
4453                    (false,
4454                     (false,
4455                      (false,
4456                       (false,
4457                        (false,
4458                         (Rn'4,
4459                          (Rn'3,
4460                           (Rn'2,
4461                            (Rn'1,
4462                             (Rn'0,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) =>
4463     Branch
4464       (BranchRegister
4465          (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4466           BranchType_JMP))
4467   | (true,
4468    (true,
4469     (false,
4470      (true,
4471       (false,
4472        (true,
4473         (true,
4474          (false,
4475           (false,
4476            (false,
4477             (true,
4478              (true,
4479               (true,
4480                (true,
4481                 (true,
4482                  (true,
4483                   (false,
4484                    (false,
4485                     (false,
4486                      (false,
4487                       (false,
4488                        (false,
4489                         (Rn'4,
4490                          (Rn'3,
4491                           (Rn'2,
4492                            (Rn'1,
4493                             (Rn'0,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) =>
4494     Branch
4495       (BranchRegister
4496          (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4497           BranchType_CALL))
4498   | (true,
4499    (true,
4500     (false,
4501      (true,
4502       (false,
4503        (true,
4504         (true,
4505          (false,
4506           (false,
4507            (true,
4508             (false,
4509              (true,
4510               (true,
4511                (true,
4512                 (true,
4513                  (true,
4514                   (false,
4515                    (false,
4516                     (false,
4517                      (false,
4518                       (false,
4519                        (false,
4520                         (Rn'4,
4521                          (Rn'3,
4522                           (Rn'2,
4523                            (Rn'1,
4524                             (Rn'0,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) =>
4525     Branch
4526       (BranchRegister
4527          (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4528           BranchType_RET))
4529   | (true,
4530    (true,
4531     (false,
4532      (true,
4533       (false,
4534        (true,
4535         (true,
4536          (false,
4537           (false,
4538            (_,
4539             (_,
4540              (true,
4541               (true,
4542                (true,
4543                 (true,
4544                  (true,
4545                   (false,
4546                    (false,
4547                     (false,
4548                      (false,
4549                       (false,
4550                        (false,
4551                         (Rn'4,
4552                          (Rn'3,
4553                           (Rn'2,
4554                            (Rn'1,
4555                             (Rn'0,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) =>
4556     Unallocated
4557   | (sf'0,
4558    (false,
4559     (true,
4560      (true,
4561       (false,
4562        (true,
4563         (false,
4564          (op'0,
4565           (imm19'18,
4566            (imm19'17,
4567             (imm19'16,
4568              (imm19'15,
4569               (imm19'14,
4570                (imm19'13,
4571                 (imm19'12,
4572                  (imm19'11,
4573                   (imm19'10,
4574                    (imm19'9,
4575                     (imm19'8,
4576                      (imm19'7,
4577                       (imm19'6,
4578                        (imm19'5,
4579                         (imm19'4,
4580                          (imm19'3,
4581                           (imm19'2,
4582                            (imm19'1,
4583                             (imm19'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4584     let
4585       val Rt = BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5)
4586       val iszero = (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x0,1))
4587       val offset =
4588         BitsN.signExtend 64
4589           (BitsN.@@
4590              (BitsN.fromBitstring
4591                 ([imm19'18,imm19'17,imm19'16,imm19'15,imm19'14,imm19'13,
4592                   imm19'12,imm19'11,imm19'10,imm19'9,imm19'8,imm19'7,
4593                   imm19'6,imm19'5,imm19'4,imm19'3,imm19'2,imm19'1,imm19'0],
4594                  19),BitsN.B(0x0,2)))
4595     in
4596       if (BitsN.fromBitstring([sf'0],1)) = (BitsN.B(0x1,1))
4597         then Branch
4598                (CompareAndBranch''64
4599                   (BitsN.B(0x1,64),(iszero,(offset,Rt))))
4600       else Branch
4601              (CompareAndBranch''32(BitsN.B(0x0,32),(iszero,(offset,Rt))))
4602     end
4603   | (sf'0,
4604    (false,
4605     (true,
4606      (true,
4607       (false,
4608        (true,
4609         (true,
4610          (op'0,
4611           (b40'4,
4612            (b40'3,
4613             (b40'2,
4614              (b40'1,
4615               (b40'0,
4616                (imm14'13,
4617                 (imm14'12,
4618                  (imm14'11,
4619                   (imm14'10,
4620                    (imm14'9,
4621                     (imm14'8,
4622                      (imm14'7,
4623                       (imm14'6,
4624                        (imm14'5,
4625                         (imm14'4,
4626                          (imm14'3,
4627                           (imm14'2,
4628                            (imm14'1,
4629                             (imm14'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4630     let
4631       val Rt = BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5)
4632       val sf = BitsN.fromBitstring([sf'0],1)
4633       val bit_pos =
4634         BitsN.@@
4635           (sf,BitsN.fromBitstring([b40'4,b40'3,b40'2,b40'1,b40'0],5))
4636       val bit_val =
4637         (not o L3.equal (BitsN.zero (1))) (BitsN.fromBitstring([op'0],1))
4638       val offset =
4639         BitsN.signExtend 64
4640           (BitsN.@@
4641              (BitsN.fromBitstring
4642                 ([imm14'13,imm14'12,imm14'11,imm14'10,imm14'9,imm14'8,
4643                   imm14'7,imm14'6,imm14'5,imm14'4,imm14'3,imm14'2,
4644                   imm14'1,imm14'0],14),BitsN.B(0x0,2)))
4645     in
4646       if sf = (BitsN.B(0x1,1))
4647         then Branch
4648                (TestBitAndBranch''64
4649                   (BitsN.B(0x1,64),(bit_pos,(bit_val,(offset,Rt)))))
4650       else Branch
4651              (TestBitAndBranch''32
4652                 (BitsN.B(0x0,32),(bit_pos,(bit_val,(offset,Rt)))))
4653     end
4654   | (true,
4655    (false,
4656     (true,
4657      (true,
4658       (true,
4659        (false,
4660         (false,
4661          (false,
4662           (true,
4663            (true,
4664             (false,
4665              (imm9'8,
4666               (imm9'7,
4667                (imm9'6,
4668                 (imm9'5,
4669                  (imm9'4,
4670                   (imm9'3,
4671                    (imm9'2,
4672                     (imm9'1,
4673                      (imm9'0,
4674                       (_,
4675                        (_,
4676                         (Rn'4,
4677                          (Rn'3,
4678                           (Rn'2,
4679                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4680     Unallocated
4681   | (true,
4682    (false,
4683     (true,
4684      (true,
4685       (true,
4686        (false,
4687         (false,
4688          (true,
4689           (true,
4690            (true,
4691             (imm12'11,
4692              (imm12'10,
4693               (imm12'9,
4694                (imm12'8,
4695                 (imm12'7,
4696                  (imm12'6,
4697                   (imm12'5,
4698                    (imm12'4,
4699                     (imm12'3,
4700                      (imm12'2,
4701                       (imm12'1,
4702                        (imm12'0,
4703                         (Rn'4,
4704                          (Rn'3,
4705                           (Rn'2,
4706                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4707     Unallocated
4708   | (true,
4709    (true,
4710     (true,
4711      (true,
4712       (true,
4713        (false,
4714         (false,
4715          (false,
4716           (true,
4717            (true,
4718             (false,
4719              (imm9'8,
4720               (imm9'7,
4721                (imm9'6,
4722                 (imm9'5,
4723                  (imm9'4,
4724                   (imm9'3,
4725                    (imm9'2,
4726                     (imm9'1,
4727                      (imm9'0,
4728                       (_,
4729                        (_,
4730                         (Rn'4,
4731                          (Rn'3,
4732                           (Rn'2,
4733                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4734     Unallocated
4735   | (true,
4736    (true,
4737     (true,
4738      (true,
4739       (true,
4740        (false,
4741         (false,
4742          (false,
4743           (true,
4744            (_,
4745             (false,
4746              (imm9'8,
4747               (imm9'7,
4748                (imm9'6,
4749                 (imm9'5,
4750                  (imm9'4,
4751                   (imm9'3,
4752                    (imm9'2,
4753                     (imm9'1,
4754                      (imm9'0,
4755                       (true,
4756                        (false,
4757                         (Rn'4,
4758                          (Rn'3,
4759                           (Rn'2,
4760                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4761     Unallocated
4762   | (size'1,
4763    (size'0,
4764     (true,
4765      (true,
4766       (true,
4767        (false,
4768         (false,
4769          (false,
4770           (opc'1,
4771            (opc'0,
4772             (false,
4773              (imm9'8,
4774               (imm9'7,
4775                (imm9'6,
4776                 (imm9'5,
4777                  (imm9'4,
4778                   (imm9'3,
4779                    (imm9'2,
4780                     (imm9'1,
4781                      (imm9'0,
4782                       (P'0,
4783                        (true,
4784                         (Rn'4,
4785                          (Rn'3,
4786                           (Rn'2,
4787                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4788     let
4789       val wback = true
4790       val postindex = (BitsN.fromBitstring([P'0],1)) = (BitsN.B(0x0,1))
4791       val offset =
4792         BitsN.signExtend 64
4793           (BitsN.fromBitstring
4794              ([imm9'8,imm9'7,imm9'6,imm9'5,imm9'4,imm9'3,imm9'2,imm9'1,
4795                imm9'0],9))
4796       val acctype = AccType_NORMAL
4797     in
4798       LoadStoreImmediate
4799         (BitsN.fromBitstring([size'1,size'0],2),
4800          (BitsN.fromBitstring([opc'1,opc'0],2),
4801           (acctype,
4802            (wback,
4803             (postindex,
4804              (false,
4805               (offset,
4806                (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4807                 BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5)))))))))
4808     end
4809   | (size'1,
4810    (size'0,
4811     (true,
4812      (true,
4813       (true,
4814        (false,
4815         (false,
4816          (false,
4817           (opc'1,
4818            (opc'0,
4819             (false,
4820              (imm9'8,
4821               (imm9'7,
4822                (imm9'6,
4823                 (imm9'5,
4824                  (imm9'4,
4825                   (imm9'3,
4826                    (imm9'2,
4827                     (imm9'1,
4828                      (imm9'0,
4829                       (U'0,
4830                        (false,
4831                         (Rn'4,
4832                          (Rn'3,
4833                           (Rn'2,
4834                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4835     let
4836       val wback = false
4837       val postindex = false
4838       val offset =
4839         BitsN.signExtend 64
4840           (BitsN.fromBitstring
4841              ([imm9'8,imm9'7,imm9'6,imm9'5,imm9'4,imm9'3,imm9'2,imm9'1,
4842                imm9'0],9))
4843       val acctype =
4844         if (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
4845           then AccType_UNPRIV
4846         else AccType_NORMAL
4847     in
4848       LoadStoreImmediate
4849         (BitsN.fromBitstring([size'1,size'0],2),
4850          (BitsN.fromBitstring([opc'1,opc'0],2),
4851           (acctype,
4852            (wback,
4853             (postindex,
4854              (false,
4855               (offset,
4856                (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4857                 BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5)))))))))
4858     end
4859   | (size'1,
4860    (size'0,
4861     (true,
4862      (true,
4863       (true,
4864        (false,
4865         (false,
4866          (true,
4867           (opc'1,
4868            (opc'0,
4869             (imm12'11,
4870              (imm12'10,
4871               (imm12'9,
4872                (imm12'8,
4873                 (imm12'7,
4874                  (imm12'6,
4875                   (imm12'5,
4876                    (imm12'4,
4877                     (imm12'3,
4878                      (imm12'2,
4879                       (imm12'1,
4880                        (imm12'0,
4881                         (Rn'4,
4882                          (Rn'3,
4883                           (Rn'2,
4884                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4885     let
4886       val size = BitsN.fromBitstring([size'1,size'0],2)
4887       val wback = false
4888       val postindex = false
4889       val offset =
4890         BitsN.<<
4891           (BitsN.zeroExtend 64
4892              (BitsN.fromBitstring
4893                 ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,imm12'6,
4894                   imm12'5,imm12'4,imm12'3,imm12'2,imm12'1,imm12'0],12)),
4895            BitsN.toNat size)
4896       val acctype = AccType_NORMAL
4897     in
4898       LoadStoreImmediate
4899         (size,
4900          (BitsN.fromBitstring([opc'1,opc'0],2),
4901           (acctype,
4902            (wback,
4903             (postindex,
4904              (true,
4905               (offset,
4906                (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
4907                 BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5)))))))))
4908     end
4909   | (true,
4910    (_,
4911     (true,
4912      (true,
4913       (true,
4914        (false,
4915         (false,
4916          (false,
4917           (true,
4918            (true,
4919             (true,
4920              (Rm'4,
4921               (Rm'3,
4922                (Rm'2,
4923                 (Rm'1,
4924                  (Rm'0,
4925                   (option'2,
4926                    (option'1,
4927                     (option'0,
4928                      (S'0,
4929                       (true,
4930                        (false,
4931                         (Rn'4,
4932                          (Rn'3,
4933                           (Rn'2,
4934                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4935     Unallocated
4936   | (size'1,
4937    (size'0,
4938     (true,
4939      (true,
4940       (true,
4941        (false,
4942         (false,
4943          (false,
4944           (opc'1,
4945            (opc'0,
4946             (true,
4947              (Rm'4,
4948               (Rm'3,
4949                (Rm'2,
4950                 (Rm'1,
4951                  (Rm'0,
4952                   (false,
4953                    (false,
4954                     (_,
4955                      (S'0,
4956                       (true,
4957                        (false,
4958                         (Rn'4,
4959                          (Rn'3,
4960                           (Rn'2,
4961                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4962     Reserved
4963   | (size'1,
4964    (size'0,
4965     (true,
4966      (true,
4967       (true,
4968        (false,
4969         (false,
4970          (false,
4971           (opc'1,
4972            (opc'0,
4973             (true,
4974              (Rm'4,
4975               (Rm'3,
4976                (Rm'2,
4977                 (Rm'1,
4978                  (Rm'0,
4979                   (true,
4980                    (false,
4981                     (_,
4982                      (S'0,
4983                       (true,
4984                        (false,
4985                         (Rn'4,
4986                          (Rn'3,
4987                           (Rn'2,
4988                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
4989     Reserved
4990   | (size'1,
4991    (size'0,
4992     (true,
4993      (true,
4994       (true,
4995        (false,
4996         (false,
4997          (false,
4998           (opc'1,
4999            (opc'0,
5000             (true,
5001              (Rm'4,
5002               (Rm'3,
5003                (Rm'2,
5004                 (Rm'1,
5005                  (Rm'0,
5006                   (option'2,
5007                    (option'1,
5008                     (option'0,
5009                      (S'0,
5010                       (true,
5011                        (false,
5012                         (Rn'4,
5013                          (Rn'3,
5014                           (Rn'2,
5015                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5016     let
5017       val opc = BitsN.fromBitstring([opc'1,opc'0],2)
5018       val size = BitsN.fromBitstring([size'1,size'0],2)
5019       val scale = BitsN.toNat size
5020       val extend_type =
5021         DecodeRegExtend
5022           (BitsN.fromBitstring([option'2,option'1,option'0],3))
5023       val shift =
5024         if (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
5025           then scale
5026         else 0
5027       val (memop,(regsize_word,signed)) =
5028         if not(BitsN.bit(opc,1))
5029           then (if BitsN.bit(opc,0) then MemOp_LOAD else MemOp_STORE,
5030                 (not(size = (BitsN.B(0x3,2))),false))
5031         else if size = (BitsN.B(0x3,2))
5032           then (MemOp_PREFETCH,(false,false))
5033         else (MemOp_LOAD,(BitsN.bit(opc,0),true))
5034     in
5035       LoadStoreRegister
5036         (size,
5037          (regsize_word,
5038           (memop,
5039            (signed,
5040             (BitsN.fromBitstring([Rm'4,Rm'3,Rm'2,Rm'1,Rm'0],5),
5041              (extend_type,
5042               (shift,
5043                (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
5044                 BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5)))))))))
5045     end
5046   | (opc'1,
5047    (opc'0,
5048     (false,
5049      (true,
5050       (true,
5051        (false,
5052         (false,
5053          (false,
5054           (imm19'18,
5055            (imm19'17,
5056             (imm19'16,
5057              (imm19'15,
5058               (imm19'14,
5059                (imm19'13,
5060                 (imm19'12,
5061                  (imm19'11,
5062                   (imm19'10,
5063                    (imm19'9,
5064                     (imm19'8,
5065                      (imm19'7,
5066                       (imm19'6,
5067                        (imm19'5,
5068                         (imm19'4,
5069                          (imm19'3,
5070                           (imm19'2,
5071                            (imm19'1,
5072                             (imm19'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5073     let
5074       val Rt = BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5)
5075       val offset =
5076         BitsN.signExtend 64
5077           (BitsN.@@
5078              (BitsN.fromBitstring
5079                 ([imm19'18,imm19'17,imm19'16,imm19'15,imm19'14,imm19'13,
5080                   imm19'12,imm19'11,imm19'10,imm19'9,imm19'8,imm19'7,
5081                   imm19'6,imm19'5,imm19'4,imm19'3,imm19'2,imm19'1,imm19'0],
5082                  19),BitsN.B(0x0,2)))
5083     in
5084       case BitsN.fromBitstring([opc'1,opc'0],2) of
5085          BitsN.B(0x0,_) =>
5086            LoadStore
5087              (LoadLiteral''32
5088                 (BitsN.B(0x0,32),(MemOp_LOAD,(false,(offset,Rt)))))
5089        | BitsN.B(0x1,_) =>
5090          LoadStore
5091            (LoadLiteral''64
5092               (BitsN.B(0x1,64),(MemOp_LOAD,(false,(offset,Rt)))))
5093        | BitsN.B(0x2,_) =>
5094          LoadStore
5095            (LoadLiteral''32
5096               (BitsN.B(0x2,32),(MemOp_LOAD,(true,(offset,Rt)))))
5097        | BitsN.B(0x3,_) =>
5098          LoadStore
5099            (LoadLiteral''32
5100               (BitsN.B(0x3,32),(MemOp_PREFETCH,(false,(offset,Rt)))))
5101        | _ => raise General.Bind
5102     end
5103   | (_,
5104    (true,
5105     (true,
5106      (false,
5107       (true,
5108        (false,
5109         (false,
5110          (_,
5111           (_,
5112            (false,
5113             (imm7'6,
5114              (imm7'5,
5115               (imm7'4,
5116                (imm7'3,
5117                 (imm7'2,
5118                  (imm7'1,
5119                   (imm7'0,
5120                    (Rt2'4,
5121                     (Rt2'3,
5122                      (Rt2'2,
5123                       (Rt2'1,
5124                        (Rt2'0,
5125                         (Rn'4,
5126                          (Rn'3,
5127                           (Rn'2,
5128                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5129     Unallocated
5130   | (true,
5131    (true,
5132     (true,
5133      (false,
5134       (true,
5135        (false,
5136         (false,
5137          (_,
5138           (_,
5139            (_,
5140             (imm7'6,
5141              (imm7'5,
5142               (imm7'4,
5143                (imm7'3,
5144                 (imm7'2,
5145                  (imm7'1,
5146                   (imm7'0,
5147                    (Rt2'4,
5148                     (Rt2'3,
5149                      (Rt2'2,
5150                       (Rt2'1,
5151                        (Rt2'0,
5152                         (Rn'4,
5153                          (Rn'3,
5154                           (Rn'2,
5155                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5156     Unallocated
5157   | (sf'0,
5158    (S'0,
5159     (true,
5160      (false,
5161       (true,
5162        (false,
5163         (false,
5164          (false,
5165           (false,
5166            (L'0,
5167             (imm7'6,
5168              (imm7'5,
5169               (imm7'4,
5170                (imm7'3,
5171                 (imm7'2,
5172                  (imm7'1,
5173                   (imm7'0,
5174                    (Rt2'4,
5175                     (Rt2'3,
5176                      (Rt2'2,
5177                       (Rt2'1,
5178                        (Rt2'0,
5179                         (Rn'4,
5180                          (Rn'3,
5181                           (Rn'2,
5182                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5183     Unallocated
5184   | (sf'0,
5185    (S'0,
5186     (true,
5187      (false,
5188       (true,
5189        (false,
5190         (false,
5191          (P'0,
5192           (W'0,
5193            (L'0,
5194             (imm7'6,
5195              (imm7'5,
5196               (imm7'4,
5197                (imm7'3,
5198                 (imm7'2,
5199                  (imm7'1,
5200                   (imm7'0,
5201                    (Rt2'4,
5202                     (Rt2'3,
5203                      (Rt2'2,
5204                       (Rt2'1,
5205                        (Rt2'0,
5206                         (Rn'4,
5207                          (Rn'3,
5208                           (Rn'2,
5209                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5210     let
5211       val sf = BitsN.fromBitstring([sf'0],1)
5212       val wback = (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
5213       val signed = (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
5214       val postindex = (BitsN.fromBitstring([P'0],1)) = (BitsN.B(0x0,1))
5215       val nontemporal = (not(wback orelse signed)) andalso postindex
5216       val postindex = (not nontemporal) andalso postindex
5217       val acctype =
5218         if nontemporal then AccType_STREAM else AccType_NORMAL
5219       val scale = Nat.+(2,BitsN.toNat sf)
5220       val offset =
5221         BitsN.<<
5222           (BitsN.signExtend 64
5223              (BitsN.fromBitstring
5224                 ([imm7'6,imm7'5,imm7'4,imm7'3,imm7'2,imm7'1,imm7'0],7)),
5225            scale)
5226       val memop =
5227         if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
5228           then MemOp_LOAD
5229         else MemOp_STORE
5230     in
5231       LoadStorePair
5232         (sf,
5233          (memop,
5234           (acctype,
5235            (signed,
5236             (wback,
5237              (postindex,
5238               (offset,
5239                (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
5240                 (BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5),
5241                  BitsN.fromBitstring([Rt2'4,Rt2'3,Rt2'2,Rt2'1,Rt2'0],5))))))))))
5242     end
5243   | (size'1,
5244    (size'0,
5245     (false,
5246      (false,
5247       (true,
5248        (false,
5249         (false,
5250          (false,
5251           (true,
5252            (L'0,
5253             (false,
5254              (Rs'4,
5255               (Rs'3,
5256                (Rs'2,
5257                 (Rs'1,
5258                  (Rs'0,
5259                   (false,
5260                    (Rt2'4,
5261                     (Rt2'3,
5262                      (Rt2'2,
5263                       (Rt2'1,
5264                        (Rt2'0,
5265                         (Rn'4,
5266                          (Rn'3,
5267                           (Rn'2,
5268                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5269     Unallocated
5270   | (size'1,
5271    (size'0,
5272     (false,
5273      (false,
5274       (true,
5275        (false,
5276         (false,
5277          (false,
5278           (true,
5279            (L'0,
5280             (true,
5281              (Rs'4,
5282               (Rs'3,
5283                (Rs'2,
5284                 (Rs'1,
5285                  (Rs'0,
5286                   (_,
5287                    (Rt2'4,
5288                     (Rt2'3,
5289                      (Rt2'2,
5290                       (Rt2'1,
5291                        (Rt2'0,
5292                         (Rn'4,
5293                          (Rn'3,
5294                           (Rn'2,
5295                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5296     Unallocated
5297   | (false,
5298    (_,
5299     (false,
5300      (false,
5301       (true,
5302        (false,
5303         (false,
5304          (false,
5305           (o2'0,
5306            (L'0,
5307             (true,
5308              (Rs'4,
5309               (Rs'3,
5310                (Rs'2,
5311                 (Rs'1,
5312                  (Rs'0,
5313                   (o0'0,
5314                    (Rt2'4,
5315                     (Rt2'3,
5316                      (Rt2'2,
5317                       (Rt2'1,
5318                        (Rt2'0,
5319                         (Rn'4,
5320                          (Rn'3,
5321                           (Rn'2,
5322                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5323     Unallocated
5324   | (size'1,
5325    (size'0,
5326     (false,
5327      (false,
5328       (true,
5329        (false,
5330         (false,
5331          (false,
5332           (o2'0,
5333            (L'0,
5334             (o1'0,
5335              (Rs'4,
5336               (Rs'3,
5337                (Rs'2,
5338                 (Rs'1,
5339                  (Rs'0,
5340                   (o0'0,
5341                    (Rt2'4,
5342                     (Rt2'3,
5343                      (Rt2'2,
5344                       (Rt2'1,
5345                        (Rt2'0,
5346                         (Rn'4,
5347                          (Rn'3,
5348                           (Rn'2,
5349                            (Rn'1,(Rn'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5350     let
5351       val memop =
5352         if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
5353           then MemOp_LOAD
5354         else MemOp_STORE
5355       val acctype =
5356         if (BitsN.fromBitstring([o0'0],1)) = (BitsN.B(0x1,1))
5357           then AccType_ORDERED
5358         else AccType_ATOMIC
5359       val excl = (BitsN.fromBitstring([o2'0],1)) = (BitsN.B(0x0,1))
5360       val pair = (BitsN.fromBitstring([o1'0],1)) = (BitsN.B(0x1,1))
5361     in
5362       LoadStoreAcquire
5363         (BitsN.fromBitstring([size'1,size'0],2),
5364          (memop,
5365           (acctype,
5366            (excl,
5367             (pair,
5368              (BitsN.fromBitstring([Rs'4,Rs'3,Rs'2,Rs'1,Rs'0],5),
5369               (BitsN.fromBitstring([Rn'4,Rn'3,Rn'2,Rn'1,Rn'0],5),
5370                (BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5),
5371                 BitsN.fromBitstring([Rt2'4,Rt2'3,Rt2'2,Rt2'1,Rt2'0],5)))))))))
5372     end
5373   | (true,
5374    (true,
5375     (false,
5376      (true,
5377       (false,
5378        (true,
5379         (false,
5380          (true,
5381           (false,
5382            (false,
5383             (L'0,
5384              (true,
5385               (o0'0,
5386                (op1'2,
5387                 (op1'1,
5388                  (op1'0,
5389                   (CRn'3,
5390                    (CRn'2,
5391                     (CRn'1,
5392                      (CRn'0,
5393                       (CRm'3,
5394                        (CRm'2,
5395                         (CRm'1,
5396                          (CRm'0,
5397                           (op2'2,
5398                            (op2'1,
5399                             (op2'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5400     System
5401       (MoveSystemRegister
5402          ((not o L3.equal (BitsN.zero (1)))
5403             (BitsN.fromBitstring([L'0],1)),
5404           (BitsN.+
5405              (BitsN.B(0x2,3),
5406               BitsN.fromNat(BitsN.toNat(BitsN.fromBitstring([o0'0],1)),3)),
5407            (BitsN.fromBitstring([op1'2,op1'1,op1'0],3),
5408             (BitsN.fromBitstring([op2'2,op2'1,op2'0],3),
5409              (BitsN.fromBitstring([CRn'3,CRn'2,CRn'1,CRn'0],4),
5410               (BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4),
5411                BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5))))))))
5412   | (true,
5413    (true,
5414     (false,
5415      (true,
5416       (false,
5417        (true,
5418         (false,
5419          (true,
5420           (false,
5421            (false,
5422             (false,
5423              (false,
5424               (false,
5425                (false,
5426                 (false,
5427                  (false,
5428                   (false,
5429                    (true,
5430                     (false,
5431                      (false,
5432                       (CRm'3,
5433                        (CRm'2,
5434                         (CRm'1,
5435                          (CRm'0,
5436                           (true,
5437                            (false,(true,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) =>
5438     System
5439       (MoveImmediateProcState
5440          (PSTATEField_SP,BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4)))
5441   | (true,
5442    (true,
5443     (false,
5444      (true,
5445       (false,
5446        (true,
5447         (false,
5448          (true,
5449           (false,
5450            (false,
5451             (false,
5452              (false,
5453               (false,
5454                (false,
5455                 (true,
5456                  (true,
5457                   (false,
5458                    (true,
5459                     (false,
5460                      (false,
5461                       (CRm'3,
5462                        (CRm'2,
5463                         (CRm'1,
5464                          (CRm'0,
5465                           (true,
5466                            (true,(false,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) =>
5467     System
5468       (MoveImmediateProcState
5469          (PSTATEField_DAIFSet,
5470           BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4)))
5471   | (true,
5472    (true,
5473     (false,
5474      (true,
5475       (false,
5476        (true,
5477         (false,
5478          (true,
5479           (false,
5480            (false,
5481             (false,
5482              (false,
5483               (false,
5484                (false,
5485                 (true,
5486                  (true,
5487                   (false,
5488                    (true,
5489                     (false,
5490                      (false,
5491                       (CRm'3,
5492                        (CRm'2,
5493                         (CRm'1,
5494                          (CRm'0,
5495                           (true,
5496                            (true,(true,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) =>
5497     System
5498       (MoveImmediateProcState
5499          (PSTATEField_DAIFClr,
5500           BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4)))
5501   | (true,
5502    (true,
5503     (false,
5504      (true,
5505       (false,
5506        (true,
5507         (false,
5508          (true,
5509           (false,
5510            (false,
5511             (false,
5512              (false,
5513               (false,
5514                (false,
5515                 (true,
5516                  (true,
5517                   (false,
5518                    (false,
5519                     (true,
5520                      (true,
5521                       (CRm'3,
5522                        (CRm'2,
5523                         (CRm'1,
5524                          (CRm'0,
5525                           (true,
5526                            (true,(true,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) =>
5527     Unallocated
5528   | (true,
5529    (true,
5530     (false,
5531      (true,
5532       (false,
5533        (true,
5534         (false,
5535          (true,
5536           (false,
5537            (false,
5538             (false,
5539              (false,
5540               (false,
5541                (false,
5542                 (true,
5543                  (true,
5544                   (false,
5545                    (false,
5546                     (true,
5547                      (true,
5548                       (CRm'3,
5549                        (CRm'2,
5550                         (CRm'1,
5551                          (CRm'0,
5552                           (true,
5553                            (opc'1,
5554                             (opc'0,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) =>
5555     MemoryBarrier
5556       ((Cast.natToMemBarrierOp o BitsN.toNat)
5557          (BitsN.fromBitstring([opc'1,opc'0],2)),
5558        BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4))
5559   | (true,
5560    (true,
5561     (false,
5562      (true,
5563       (false,
5564        (true,
5565         (false,
5566          (false,
5567           (false,
5568            (false,
5569             (true,
5570              (imm16'15,
5571               (imm16'14,
5572                (imm16'13,
5573                 (imm16'12,
5574                  (imm16'11,
5575                   (imm16'10,
5576                    (imm16'9,
5577                     (imm16'8,
5578                      (imm16'7,
5579                       (imm16'6,
5580                        (imm16'5,
5581                         (imm16'4,
5582                          (imm16'3,
5583                           (imm16'2,
5584                            (imm16'1,
5585                             (imm16'0,
5586                              (false,(false,(false,(false,false))))))))))))))))))))))))))))))) =>
5587     Debug
5588       (Breakpoint
5589          (BitsN.fromBitstring
5590             ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10,
5591               imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3,
5592               imm16'2,imm16'1,imm16'0],16)))
5593   | (true,
5594    (true,
5595     (false,
5596      (true,
5597       (false,
5598        (true,
5599         (false,
5600          (true,
5601           (false,
5602            (false,
5603             (false,
5604              (false,
5605               (false,
5606                (false,
5607                 (true,
5608                  (true,
5609                   (false,
5610                    (false,
5611                     (true,
5612                      (false,
5613                       (CRm'3,
5614                        (CRm'2,
5615                         (CRm'1,
5616                          (CRm'0,
5617                           (op2'2,
5618                            (op2'1,
5619                             (op2'0,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) =>
5620     let
5621       val op2 = BitsN.fromBitstring([op2'2,op2'1,op2'0],3)
5622       val op' =
5623         if ((BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4)) =
5624             (BitsN.B(0x0,4))) andalso (BitsN.<+(op2,BitsN.B(0x6,3)))
5625           then (Cast.natToSystemHintOp o BitsN.toNat) op2
5626         else SystemHintOp_NOP
5627     in
5628       Hint op'
5629     end
5630   | (true,
5631    (true,
5632     (false,
5633      (true,
5634       (false,
5635        (true,
5636         (false,
5637          (true,
5638           (false,
5639            (false,
5640             (false,
5641              (false,
5642               (false,
5643                (false,
5644                 (true,
5645                  (true,
5646                   (false,
5647                    (false,
5648                     (true,
5649                      (true,
5650                       (CRm'3,
5651                        (CRm'2,
5652                         (CRm'1,
5653                          (CRm'0,
5654                           (false,
5655                            (true,(false,(true,(true,(true,(true,true))))))))))))))))))))))))))))))) =>
5656     ClearExclusive(BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4))
5657   | (true,
5658    (true,
5659     (false,
5660      (true,
5661       (false,
5662        (true,
5663         (true,
5664          (false,
5665           (true,
5666            (false,
5667             (true,
5668              (true,
5669               (true,
5670                (true,
5671                 (true,
5672                  (true,
5673                   (false,
5674                    (false,
5675                     (false,
5676                      (false,
5677                       (false,
5678                        (false,
5679                         (true,
5680                          (true,
5681                           (true,
5682                            (true,
5683                             (true,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) =>
5684     Debug DebugRestore
5685   | (true,
5686    (true,
5687     (false,
5688      (true,
5689       (false,
5690        (true,
5691         (false,
5692          (false,
5693           (true,
5694            (false,
5695             (true,
5696              (imm16'15,
5697               (imm16'14,
5698                (imm16'13,
5699                 (imm16'12,
5700                  (imm16'11,
5701                   (imm16'10,
5702                    (imm16'9,
5703                     (imm16'8,
5704                      (imm16'7,
5705                       (imm16'6,
5706                        (imm16'5,
5707                         (imm16'4,
5708                          (imm16'3,
5709                           (imm16'2,
5710                            (imm16'1,
5711                             (imm16'0,(false,(false,(false,(LL'1,LL'0))))))))))))))))))))))))))))))) =>
5712     Debug(DebugSwitch(BitsN.fromBitstring([LL'1,LL'0],2)))
5713   | (true,
5714    (true,
5715     (false,
5716      (true,
5717       (false,
5718        (true,
5719         (false,
5720          (false,
5721           (false,
5722            (true,
5723             (false,
5724              (imm16'15,
5725               (imm16'14,
5726                (imm16'13,
5727                 (imm16'12,
5728                  (imm16'11,
5729                   (imm16'10,
5730                    (imm16'9,
5731                     (imm16'8,
5732                      (imm16'7,
5733                       (imm16'6,
5734                        (imm16'5,
5735                         (imm16'4,
5736                          (imm16'3,
5737                           (imm16'2,
5738                            (imm16'1,
5739                             (imm16'0,
5740                              (false,(false,(false,(false,false))))))))))))))))))))))))))))))) =>
5741     Debug
5742       (Halt
5743          (BitsN.fromBitstring
5744             ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10,
5745               imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3,
5746               imm16'2,imm16'1,imm16'0],16)))
5747   | (true,
5748    (true,
5749     (false,
5750      (true,
5751       (false,
5752        (true,
5753         (true,
5754          (false,
5755           (true,
5756            (false,
5757             (false,
5758              (true,
5759               (true,
5760                (true,
5761                 (true,
5762                  (true,
5763                   (false,
5764                    (false,
5765                     (false,
5766                      (false,
5767                       (false,
5768                        (false,
5769                         (true,
5770                          (true,
5771                           (true,
5772                            (true,
5773                             (true,(false,(false,(false,(false,false))))))))))))))))))))))))))))))) =>
5774     System ExceptionReturn
5775   | (true,
5776    (true,
5777     (false,
5778      (true,
5779       (false,
5780        (true,
5781         (false,
5782          (false,
5783           (false,
5784            (false,
5785             (false,
5786              (imm16'15,
5787               (imm16'14,
5788                (imm16'13,
5789                 (imm16'12,
5790                  (imm16'11,
5791                   (imm16'10,
5792                    (imm16'9,
5793                     (imm16'8,
5794                      (imm16'7,
5795                       (imm16'6,
5796                        (imm16'5,
5797                         (imm16'4,
5798                          (imm16'3,
5799                           (imm16'2,
5800                            (imm16'1,
5801                             (imm16'0,(false,(false,(false,(false,true))))))))))))))))))))))))))))))) =>
5802     System
5803       (SupervisorCall
5804          (BitsN.fromBitstring
5805             ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10,
5806               imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3,
5807               imm16'2,imm16'1,imm16'0],16)))
5808   | (true,
5809    (true,
5810     (false,
5811      (true,
5812       (false,
5813        (true,
5814         (false,
5815          (false,
5816           (false,
5817            (false,
5818             (false,
5819              (imm16'15,
5820               (imm16'14,
5821                (imm16'13,
5822                 (imm16'12,
5823                  (imm16'11,
5824                   (imm16'10,
5825                    (imm16'9,
5826                     (imm16'8,
5827                      (imm16'7,
5828                       (imm16'6,
5829                        (imm16'5,
5830                         (imm16'4,
5831                          (imm16'3,
5832                           (imm16'2,
5833                            (imm16'1,
5834                             (imm16'0,(false,(false,(false,(true,false))))))))))))))))))))))))))))))) =>
5835     System
5836       (HypervisorCall
5837          (BitsN.fromBitstring
5838             ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10,
5839               imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3,
5840               imm16'2,imm16'1,imm16'0],16)))
5841   | (true,
5842    (true,
5843     (false,
5844      (true,
5845       (false,
5846        (true,
5847         (false,
5848          (false,
5849           (false,
5850            (false,
5851             (false,
5852              (imm16'15,
5853               (imm16'14,
5854                (imm16'13,
5855                 (imm16'12,
5856                  (imm16'11,
5857                   (imm16'10,
5858                    (imm16'9,
5859                     (imm16'8,
5860                      (imm16'7,
5861                       (imm16'6,
5862                        (imm16'5,
5863                         (imm16'4,
5864                          (imm16'3,
5865                           (imm16'2,
5866                            (imm16'1,
5867                             (imm16'0,(false,(false,(false,(true,true))))))))))))))))))))))))))))))) =>
5868     System
5869       (SecureMonitorCall
5870          (BitsN.fromBitstring
5871             ([imm16'15,imm16'14,imm16'13,imm16'12,imm16'11,imm16'10,
5872               imm16'9,imm16'8,imm16'7,imm16'6,imm16'5,imm16'4,imm16'3,
5873               imm16'2,imm16'1,imm16'0],16)))
5874   | (true,
5875    (true,
5876     (false,
5877      (true,
5878       (false,
5879        (true,
5880         (false,
5881          (true,
5882           (false,
5883            (false,
5884             (L'0,
5885              (false,
5886               (true,
5887                (op1'2,
5888                 (op1'1,
5889                  (op1'0,
5890                   (CRn'3,
5891                    (CRn'2,
5892                     (CRn'1,
5893                      (CRn'0,
5894                       (CRm'3,
5895                        (CRm'2,
5896                         (CRm'1,
5897                          (CRm'0,
5898                           (op2'2,
5899                            (op2'1,
5900                             (op2'0,(Rt'4,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))))))) =>
5901     System
5902       (SystemInstruction
5903          (BitsN.fromBitstring([op1'2,op1'1,op1'0],3),
5904           (BitsN.fromBitstring([op2'2,op2'1,op2'0],3),
5905            (BitsN.fromBitstring([CRn'3,CRn'2,CRn'1,CRn'0],4),
5906             (BitsN.fromBitstring([CRm'3,CRm'2,CRm'1,CRm'0],4),
5907              ((not o L3.equal (BitsN.zero (1)))
5908                 (BitsN.fromBitstring([L'0],1)),
5909               BitsN.fromBitstring([Rt'4,Rt'3,Rt'2,Rt'1,Rt'0],5)))))))
5910   | _ => Unallocated;
5911
5912fun Fetch () = Mem 32 ((!PC),(4,AccType_IFETCH));
5913
5914fun Next () =
5915  ( branch_hint := NONE
5916  ; Run(Decode(Fetch ()))
5917  ; if not(Option.isSome (!branch_hint))
5918      then PC := (BitsN.+((!PC),BitsN.B(0x4,64)))
5919    else ()
5920  );
5921
5922fun CountTrailing N (b,w) =
5923  if ((BitsN.bit(w,0)) = b) orelse
5924     (if b
5925        then w = (BitsN.BV(0x0,N))
5926      else w = (BitsN.neg(BitsN.BV(0x1,N))))
5927    then 0
5928  else Nat.+(1,CountTrailing N (b,BitsN.>>+(w,1)));
5929
5930fun EncodeBitMaskAux N imm =
5931  let
5932    val pref0 = CountTrailing N (true,imm)
5933  in
5934    if pref0 = 0
5935      then let
5936             val pref1 = CountTrailing N (false,imm)
5937             val run0 = CountTrailing N (true,BitsN.#>>(imm,pref1))
5938             val run1 =
5939               CountTrailing N (false,BitsN.#>>(imm,Nat.+(pref1,run0)))
5940           in
5941             (Nat.+(run0,run1),(run1,Nat.-(run1,pref1)))
5942           end
5943    else let
5944           val run1 = CountTrailing N (false,BitsN.#>>(imm,pref0))
5945           val run0 =
5946             CountTrailing N (true,BitsN.#>>(imm,Nat.+(pref0,run1)))
5947         in
5948           (Nat.+(run0,run1),(run1,Nat.-(Nat.+(run0,run1),pref0)))
5949         end
5950  end;
5951
5952fun EncodeBitMask N imm =
5953  let
5954    val (e,(S,R)) = EncodeBitMaskAux N imm
5955    val (immN,(imms,immr)) =
5956      if e = 64
5957        then (BitsN.B(0x1,1),
5958              (BitsN.fromNat(Nat.-(S,1),6),BitsN.fromNat(R,6)))
5959      else (BitsN.B(0x0,1),
5960            (BitsN.||
5961               (BitsN.~(BitsN.fromNat(Nat.-(Nat.*(e,2),1),6)),
5962                BitsN.fromNat(Nat.-(S,1),6)),BitsN.fromNat(R,6)))
5963  in
5964    case DecodeBitMasks N (immN,(imms,(immr,true))) of
5965       Option.SOME(imm2,_) =>
5966         (if imm = imm2 then Option.SOME(immN,(imms,immr)) else NONE)
5967     | NONE => NONE
5968  end;
5969
5970fun e_sf N sf = BitsN.fromBit((BitsN.size(BitsN.BV(0x0,N))) = 64);
5971
5972fun EncodeLogicalOp (opc,setflags) =
5973  case (opc,setflags) of
5974     (LogicalOp_AND,false) => Option.SOME(BitsN.B(0x0,2))
5975   | (LogicalOp_ORR,false) => Option.SOME(BitsN.B(0x1,2))
5976   | (LogicalOp_EOR,false) => Option.SOME(BitsN.B(0x2,2))
5977   | (LogicalOp_AND,true) => Option.SOME(BitsN.B(0x3,2))
5978   | _ => NONE;
5979
5980fun e_data i =
5981  case i of
5982     AddSubShiftedRegister''32(_,(opc,(s,(sh,(rm,(imm6,(rn,rd))))))) =>
5983       (if BitsN.bit(imm6,5)
5984          then BadCode "AddSubShiftedRegister32"
5985        else ARM8
5986               (BitsN.concat
5987                  [BitsN.B(0x0,1),BitsN.fromBit opc,BitsN.fromBit s,
5988                   BitsN.B(0xB,5),BitsN.fromNat(Cast.ShiftTypeToNat sh,2),
5989                   BitsN.B(0x0,1),rm,imm6,rn,rd]))
5990   | AddSubShiftedRegister''64(_,(opc,(s,(sh,(rm,(imm6,(rn,rd))))))) =>
5991     ARM8
5992       (BitsN.concat
5993          [BitsN.B(0x1,1),BitsN.fromBit opc,BitsN.fromBit s,
5994           BitsN.B(0xB,5),BitsN.fromNat(Cast.ShiftTypeToNat sh,2),
5995           BitsN.B(0x0,1),rm,imm6,rn,rd])
5996   | AddSubExtendRegister''32(sf,(opc,(s,(rm,(sty,(imm3,(rn,rd))))))) =>
5997     ARM8
5998       (BitsN.concat
5999          [e_sf 32 sf,BitsN.fromBit opc,BitsN.fromBit s,BitsN.B(0x59,8),
6000           rm,BitsN.fromNat(Cast.ExtendTypeToNat sty,3),imm3,rn,rd])
6001   | AddSubExtendRegister''64(sf,(opc,(s,(rm,(sty,(imm3,(rn,rd))))))) =>
6002     ARM8
6003       (BitsN.concat
6004          [e_sf 64 sf,BitsN.fromBit opc,BitsN.fromBit s,BitsN.B(0x59,8),
6005           rm,BitsN.fromNat(Cast.ExtendTypeToNat sty,3),imm3,rn,rd])
6006   | AddSubImmediate''32(sf,(opc,(s,(imm,(rn,rd))))) =>
6007     (if (BitsN.&&(imm,BitsN.~(BitsN.B(0xFFF,32)))) = (BitsN.B(0x0,32))
6008        then ARM8
6009               (BitsN.concat
6010                  [e_sf 32 sf,BitsN.fromBit opc,BitsN.fromBit s,
6011                   BitsN.B(0x44,7),BitsN.bits(11,0) imm,rn,rd])
6012      else if (BitsN.&&(imm,BitsN.~(BitsN.B(0xFFF000,32)))) =
6013         (BitsN.B(0x0,32))
6014        then ARM8
6015               (BitsN.concat
6016                  [e_sf 32 sf,BitsN.fromBit opc,BitsN.fromBit s,
6017                   BitsN.B(0x45,7),BitsN.bits(23,12) imm,rn,rd])
6018      else BadCode "AddSubImmediate")
6019   | AddSubImmediate''64(sf,(opc,(s,(imm,(rn,rd))))) =>
6020     (if (BitsN.&&(imm,BitsN.~(BitsN.B(0xFFF,64)))) = (BitsN.B(0x0,64))
6021        then ARM8
6022               (BitsN.concat
6023                  [e_sf 64 sf,BitsN.fromBit opc,BitsN.fromBit s,
6024                   BitsN.B(0x44,7),BitsN.bits(11,0) imm,rn,rd])
6025      else if (BitsN.&&(imm,BitsN.~(BitsN.B(0xFFF000,64)))) =
6026         (BitsN.B(0x0,64))
6027        then ARM8
6028               (BitsN.concat
6029                  [e_sf 64 sf,BitsN.fromBit opc,BitsN.fromBit s,
6030                   BitsN.B(0x45,7),BitsN.bits(23,12) imm,rn,rd])
6031      else BadCode "AddSubImmediate")
6032   | AddSubCarry''32(_,(opc,(s,(rm,(rn,rd))))) =>
6033     ARM8
6034       (BitsN.concat
6035          [BitsN.B(0x0,1),BitsN.fromBit opc,BitsN.fromBit s,
6036           BitsN.B(0xD0,8),rm,BitsN.B(0x0,6),rn,rd])
6037   | AddSubCarry''64(_,(opc,(s,(rm,(rn,rd))))) =>
6038     ARM8
6039       (BitsN.concat
6040          [BitsN.B(0x1,1),BitsN.fromBit opc,BitsN.fromBit s,
6041           BitsN.B(0xD0,8),rm,BitsN.B(0x0,6),rn,rd])
6042   | LogicalShiftedRegister''32
6043     (sf,(opc,(invert,(s,(sh,(imm,(rm,(rn,rd)))))))) =>
6044     (case EncodeLogicalOp(opc,s) of
6045         Option.SOME opc =>
6046           let
6047             val imm6 = BitsN.fromNat(imm,6)
6048           in
6049             if imm = (BitsN.toNat imm6)
6050               then ARM8
6051                      (BitsN.concat
6052                         [e_sf 32 sf,opc,BitsN.B(0xA,5),
6053                          BitsN.fromNat(Cast.ShiftTypeToNat sh,2),
6054                          BitsN.fromBit invert,rm,imm6,rn,rd])
6055             else BadCode "LogicalShiftedRegister"
6056           end
6057       | NONE => BadCode "LogicalShiftedRegister")
6058   | LogicalShiftedRegister''64
6059     (sf,(opc,(invert,(s,(sh,(imm,(rm,(rn,rd)))))))) =>
6060     (case EncodeLogicalOp(opc,s) of
6061         Option.SOME opc =>
6062           let
6063             val imm6 = BitsN.fromNat(imm,6)
6064           in
6065             if imm = (BitsN.toNat imm6)
6066               then ARM8
6067                      (BitsN.concat
6068                         [e_sf 64 sf,opc,BitsN.B(0xA,5),
6069                          BitsN.fromNat(Cast.ShiftTypeToNat sh,2),
6070                          BitsN.fromBit invert,rm,imm6,rn,rd])
6071             else BadCode "LogicalShiftedRegister"
6072           end
6073       | NONE => BadCode "LogicalShiftedRegister")
6074   | LogicalImmediate''32(_,(opc,(s,(imm,(rn,rd))))) =>
6075     (case (EncodeBitMask 32 imm,EncodeLogicalOp(opc,s)) of
6076         (Option.SOME(_,(imms,immr)),Option.SOME opc) =>
6077           ARM8
6078             (BitsN.concat
6079                [BitsN.B(0x0,1),opc,BitsN.B(0x48,7),immr,imms,rn,rd])
6080       | _ => BadCode "LogicalImmediate32")
6081   | LogicalImmediate''64(_,(opc,(s,(imm,(rn,rd))))) =>
6082     (case (EncodeBitMask 64 imm,EncodeLogicalOp(opc,s)) of
6083         (Option.SOME(N,(imms,immr)),Option.SOME opc) =>
6084           ARM8
6085             (BitsN.concat
6086                [BitsN.B(0x1,1),opc,BitsN.B(0x24,6),N,immr,imms,rn,rd])
6087       | _ => BadCode "LogicalImmediate64")
6088   | Shift''32(_,(sh,(rm,(rn,rd)))) =>
6089     ARM8
6090       (BitsN.concat
6091          [BitsN.B(0xD6,11),rm,BitsN.B(0x2,4),
6092           BitsN.fromNat(Cast.ShiftTypeToNat sh,2),rn,rd])
6093   | Shift''64(_,(sh,(rm,(rn,rd)))) =>
6094     ARM8
6095       (BitsN.concat
6096          [BitsN.B(0x4D6,11),rm,BitsN.B(0x2,4),
6097           BitsN.fromNat(Cast.ShiftTypeToNat sh,2),rn,rd])
6098   | MoveWide''32(_,(opc,(hw,(imm16,rd)))) =>
6099     let
6100       val opc =
6101         case opc of
6102            MoveWideOp_N => BitsN.B(0x0,2)
6103          | MoveWideOp_Z => BitsN.B(0x2,2)
6104          | MoveWideOp_K => BitsN.B(0x3,2)
6105     in
6106       ARM8(BitsN.concat[BitsN.B(0x0,1),opc,BitsN.B(0x25,6),hw,imm16,rd])
6107     end
6108   | MoveWide''64(_,(opc,(hw,(imm16,rd)))) =>
6109     let
6110       val opc =
6111         case opc of
6112            MoveWideOp_N => BitsN.B(0x0,2)
6113          | MoveWideOp_Z => BitsN.B(0x2,2)
6114          | MoveWideOp_K => BitsN.B(0x3,2)
6115     in
6116       ARM8(BitsN.concat[BitsN.B(0x1,1),opc,BitsN.B(0x25,6),hw,imm16,rd])
6117     end
6118   | BitfieldMove''32
6119     (sf,(inzero,(extend,(wmask,(tmask,(immr,(imms,(rn,rd)))))))) =>
6120     let
6121       val sz = e_sf 32 sf
6122       val opc =
6123         case (inzero,extend) of
6124            (true,true) => Option.SOME(BitsN.B(0x0,2))
6125          | (false,false) => Option.SOME(BitsN.B(0x1,2))
6126          | (true,false) => Option.SOME(BitsN.B(0x2,2))
6127          | _ => NONE
6128     in
6129       case opc of
6130          Option.SOME opc =>
6131            let
6132              val r = BitsN.fromNat(immr,6)
6133              val s = BitsN.fromNat(imms,6)
6134            in
6135              if (immr = (BitsN.toNat r)) andalso
6136                 ((imms = (BitsN.toNat s)) andalso
6137                  ((DecodeBitMasks 32 (sz,(s,(r,false)))) =
6138                   (Option.SOME(wmask,tmask))))
6139                then ARM8
6140                       (BitsN.concat[sz,opc,BitsN.B(0x26,6),sz,r,s,rn,rd])
6141              else BadCode "BitfieldMove"
6142            end
6143        | NONE => BadCode "BitfieldMove"
6144     end
6145   | BitfieldMove''64
6146     (sf,(inzero,(extend,(wmask,(tmask,(immr,(imms,(rn,rd)))))))) =>
6147     let
6148       val sz = e_sf 64 sf
6149       val opc =
6150         case (inzero,extend) of
6151            (true,true) => Option.SOME(BitsN.B(0x0,2))
6152          | (false,false) => Option.SOME(BitsN.B(0x1,2))
6153          | (true,false) => Option.SOME(BitsN.B(0x2,2))
6154          | _ => NONE
6155     in
6156       case opc of
6157          Option.SOME opc =>
6158            let
6159              val r = BitsN.fromNat(immr,6)
6160              val s = BitsN.fromNat(imms,6)
6161            in
6162              if (immr = (BitsN.toNat r)) andalso
6163                 ((imms = (BitsN.toNat s)) andalso
6164                  ((DecodeBitMasks 64 (sz,(s,(r,false)))) =
6165                   (Option.SOME(wmask,tmask))))
6166                then ARM8
6167                       (BitsN.concat[sz,opc,BitsN.B(0x26,6),sz,r,s,rn,rd])
6168              else BadCode "BitfieldMove"
6169            end
6170        | NONE => BadCode "BitfieldMove"
6171     end
6172   | ConditionalCompareImmediate''32
6173     (sf,(opc,(imm,(cd,((n,(z,(c,v))),rn))))) =>
6174     let
6175       val imm5 = BitsN.fromNat(BitsN.toNat imm,5)
6176     in
6177       if imm = (BitsN.fromNat(BitsN.toNat imm5,32))
6178         then ARM8
6179                (BitsN.concat
6180                   [e_sf 32 sf,BitsN.fromBit opc,BitsN.B(0x1D2,9),imm5,cd,
6181                    BitsN.B(0x2,2),rn,BitsN.B(0x0,1),BitsN.fromBit n,
6182                    BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v])
6183       else BadCode "ConditionalCompareImmediate"
6184     end
6185   | ConditionalCompareImmediate''64
6186     (sf,(opc,(imm,(cd,((n,(z,(c,v))),rn))))) =>
6187     let
6188       val imm5 = BitsN.fromNat(BitsN.toNat imm,5)
6189     in
6190       if imm = (BitsN.fromNat(BitsN.toNat imm5,64))
6191         then ARM8
6192                (BitsN.concat
6193                   [e_sf 64 sf,BitsN.fromBit opc,BitsN.B(0x1D2,9),imm5,cd,
6194                    BitsN.B(0x2,2),rn,BitsN.B(0x0,1),BitsN.fromBit n,
6195                    BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v])
6196       else BadCode "ConditionalCompareImmediate"
6197     end
6198   | ConditionalCompareRegister''32(sf,(opc,(cd,((n,(z,(c,v))),(rm,rn))))) =>
6199     ARM8
6200       (BitsN.concat
6201          [e_sf 32 sf,BitsN.fromBit opc,BitsN.B(0x1D2,9),rm,cd,
6202           BitsN.B(0x0,2),rn,BitsN.B(0x0,1),BitsN.fromBit n,
6203           BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v])
6204   | ConditionalCompareRegister''64(sf,(opc,(cd,((n,(z,(c,v))),(rm,rn))))) =>
6205     ARM8
6206       (BitsN.concat
6207          [e_sf 64 sf,BitsN.fromBit opc,BitsN.B(0x1D2,9),rm,cd,
6208           BitsN.B(0x0,2),rn,BitsN.B(0x0,1),BitsN.fromBit n,
6209           BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v])
6210   | ConditionalSelect''32(_,(op',(o2,(cd,(rm,(rn,rd)))))) =>
6211     ARM8
6212       (BitsN.concat
6213          [BitsN.B(0x0,1),BitsN.fromBit op',BitsN.B(0xD4,9),rm,cd,
6214           BitsN.B(0x0,1),BitsN.fromBit o2,rn,rd])
6215   | ConditionalSelect''64(_,(op',(o2,(cd,(rm,(rn,rd)))))) =>
6216     ARM8
6217       (BitsN.concat
6218          [BitsN.B(0x1,1),BitsN.fromBit op',BitsN.B(0xD4,9),rm,cd,
6219           BitsN.B(0x0,1),BitsN.fromBit o2,rn,rd])
6220   | CountLeading''32(_,(op',(rn,rd))) =>
6221     ARM8(BitsN.concat[BitsN.B(0xB5802,21),BitsN.fromBit op',rn,rd])
6222   | CountLeading''64(_,(op',(rn,rd))) =>
6223     ARM8(BitsN.concat[BitsN.B(0x1B5802,21),BitsN.fromBit op',rn,rd])
6224   | ExtractRegister''32(_,(imms,(rm,(rn,rd)))) =>
6225     (if BitsN.bit(imms,5)
6226        then BadCode "ExtractRegister32"
6227      else ARM8(BitsN.concat[BitsN.B(0x9C,11),rm,imms,rn,rd]))
6228   | ExtractRegister''64(_,(imms,(rm,(rn,rd)))) =>
6229     ARM8(BitsN.concat[BitsN.B(0x49E,11),rm,imms,rn,rd])
6230   | Division''32(_,(o1,(rm,(rn,rd)))) =>
6231     ARM8
6232       (BitsN.concat
6233          [BitsN.B(0xD6,11),rm,BitsN.B(0x1,5),BitsN.fromBit(not o1),rn,rd])
6234   | Division''64(_,(o1,(rm,(rn,rd)))) =>
6235     ARM8
6236       (BitsN.concat
6237          [BitsN.B(0x4D6,11),rm,BitsN.B(0x1,5),BitsN.fromBit(not o1),rn,rd])
6238   | MultiplyAddSub''32(_,(o0,(rm,(ra,(rn,rd))))) =>
6239     ARM8(BitsN.concat[BitsN.B(0xD8,11),rm,BitsN.fromBit o0,ra,rn,rd])
6240   | MultiplyAddSub''64(_,(o0,(rm,(ra,(rn,rd))))) =>
6241     ARM8(BitsN.concat[BitsN.B(0x4D8,11),rm,BitsN.fromBit o0,ra,rn,rd])
6242   | MultiplyAddSubLong(o0,(u,(rm,(ra,(rn,rd))))) =>
6243     ARM8
6244       (BitsN.concat
6245          [BitsN.B(0x9B,8),BitsN.fromBit(not u),BitsN.B(0x1,2),rm,
6246           BitsN.fromBit o0,ra,rn,rd])
6247   | MultiplyHigh(u,(rm,(rn,rd))) =>
6248     ARM8
6249       (BitsN.concat
6250          [BitsN.B(0x9B,8),BitsN.fromBit(not u),BitsN.B(0x2,2),rm,
6251           BitsN.B(0x1F,6),rn,rd])
6252   | Reverse''32(_,(opc,(rn,rd))) =>
6253     (if opc = RevOp_REV64
6254        then BadCode "Reverse32"
6255      else ARM8
6256             (BitsN.concat
6257                [BitsN.B(0x5AC00,20),BitsN.fromNat(Cast.RevOpToNat opc,2),
6258                 rn,rd]))
6259   | Reverse''64(_,(opc,(rn,rd))) =>
6260     ARM8
6261       (BitsN.concat
6262          [BitsN.B(0xDAC00,20),BitsN.fromNat(Cast.RevOpToNat opc,2),rn,rd]);
6263
6264fun e_debug i =
6265  case i of
6266     Breakpoint imm16 =>
6267       BitsN.concat[BitsN.B(0x6A1,11),imm16,BitsN.B(0x0,5)]
6268   | DebugRestore => BitsN.B(0xD6BF03E0,32)
6269   | DebugSwitch LL =>
6270     BitsN.concat[BitsN.B(0x6A5,11),BitsN.B(0x0,16),BitsN.B(0x0,3),LL]
6271   | Halt imm16 => BitsN.concat[BitsN.B(0x6A2,11),imm16,BitsN.B(0x0,5)];
6272
6273fun e_crc i =
6274  case i of
6275     CRC''8(_,(c,(rm,(rn,rd)))) =>
6276       BitsN.concat
6277         [BitsN.B(0xD6,11),rm,BitsN.B(0x2,3),BitsN.fromBit c,
6278          BitsN.B(0x0,2),rn,rd]
6279   | CRC''16(_,(c,(rm,(rn,rd)))) =>
6280     BitsN.concat
6281       [BitsN.B(0xD6,11),rm,BitsN.B(0x2,3),BitsN.fromBit c,BitsN.B(0x1,2),
6282        rn,rd]
6283   | CRC''32(_,(c,(rm,(rn,rd)))) =>
6284     BitsN.concat
6285       [BitsN.B(0xD6,11),rm,BitsN.B(0x2,3),BitsN.fromBit c,BitsN.B(0x2,2),
6286        rn,rd]
6287   | CRC''64(_,(c,(rm,(rn,rd)))) =>
6288     BitsN.concat
6289       [BitsN.B(0x4D6,11),rm,BitsN.B(0x2,3),BitsN.fromBit c,
6290        BitsN.B(0x3,2),rn,rd];
6291
6292fun e_branch i =
6293  case i of
6294     BranchConditional(imm,cd) =>
6295       let
6296         val imm19 = BitsN.bits(20,2) imm
6297       in
6298         if imm = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2))))
6299           then ARM8
6300                  (BitsN.concat[BitsN.B(0x54,8),imm19,BitsN.B(0x0,1),cd])
6301         else BadCode "BranchConditional"
6302       end
6303   | BranchImmediate(imm,btype) =>
6304     let
6305       val imm26 = BitsN.bits(27,2) imm
6306     in
6307       if (imm = (BitsN.signExtend 64 (BitsN.@@(imm26,BitsN.B(0x0,2))))) andalso
6308          (Set.mem(btype,[BranchType_CALL,BranchType_JMP]))
6309         then ARM8
6310                (BitsN.concat
6311                   [BitsN.fromBit(btype = BranchType_CALL),BitsN.B(0x5,5),
6312                    imm26])
6313       else BadCode "BranchImmediate"
6314     end
6315   | BranchRegister(rn,btype) =>
6316     let
6317       val opc =
6318         case btype of
6319            BranchType_JMP => BitsN.B(0x0,2)
6320          | BranchType_CALL => BitsN.B(0x1,2)
6321          | BranchType_RET => BitsN.B(0x2,2)
6322          | _ => BitsN.B(0x3,2)
6323     in
6324       if opc = (BitsN.B(0x3,2))
6325         then BadCode "BranchRegister"
6326       else ARM8
6327              (BitsN.concat
6328                 [BitsN.B(0x1AC,9),opc,BitsN.B(0x7C0,11),rn,BitsN.B(0x0,5)])
6329     end
6330   | CompareAndBranch''32(_,(iszero,(offset,rt))) =>
6331     let
6332       val imm19 = BitsN.bits(20,2) offset
6333     in
6334       if offset = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2))))
6335         then ARM8
6336                (BitsN.concat
6337                   [BitsN.B(0x1A,7),BitsN.fromBit(not iszero),imm19,rt])
6338       else BadCode "CompareAndBranch32"
6339     end
6340   | CompareAndBranch''64(_,(iszero,(offset,rt))) =>
6341     let
6342       val imm19 = BitsN.bits(20,2) offset
6343     in
6344       if offset = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2))))
6345         then ARM8
6346                (BitsN.concat
6347                   [BitsN.B(0x5A,7),BitsN.fromBit(not iszero),imm19,rt])
6348       else BadCode "CompareAndBranch64"
6349     end
6350   | TestBitAndBranch''32(_,(bit_pos,(bit_val,(offset,rt)))) =>
6351     let
6352       val imm14 = BitsN.bits(15,2) offset
6353     in
6354       if (offset = (BitsN.signExtend 64 (BitsN.@@(imm14,BitsN.B(0x0,2))))) andalso
6355          (not(BitsN.bit(bit_pos,5)))
6356         then ARM8
6357                (BitsN.concat
6358                   [BitsN.B(0x1B,7),BitsN.fromBit bit_val,
6359                    BitsN.bits(4,0) bit_pos,imm14,rt])
6360       else BadCode "TestBitAndBranch32"
6361     end
6362   | TestBitAndBranch''64(_,(bit_pos,(bit_val,(offset,rt)))) =>
6363     let
6364       val imm14 = BitsN.bits(15,2) offset
6365     in
6366       if (offset = (BitsN.signExtend 64 (BitsN.@@(imm14,BitsN.B(0x0,2))))) andalso
6367          (BitsN.bit(bit_pos,5))
6368         then ARM8
6369                (BitsN.concat
6370                   [BitsN.B(0x5B,7),BitsN.fromBit bit_val,
6371                    BitsN.bits(4,0) bit_pos,imm14,rt])
6372       else BadCode "TestBitAndBranch64"
6373     end;
6374
6375fun e_system i =
6376  case i of
6377     MoveSystemRegister(l,(op0,(op1,(op2,(crn,(crm,rt)))))) =>
6378       BitsN.concat
6379         [BitsN.B(0x354,10),BitsN.fromBit l,BitsN.B(0x1,1),
6380          BitsN.fromNat(BitsN.toNat(BitsN.-(op0,BitsN.B(0x2,3))),1),op1,
6381          crn,crm,op2,rt]
6382   | MoveImmediateProcState(PSTATEField_SP,crm) =>
6383     BitsN.concat[BitsN.B(0xD5004,20),crm,BitsN.B(0xBF,8)]
6384   | MoveImmediateProcState(PSTATEField_DAIFSet,crm) =>
6385     BitsN.concat[BitsN.B(0xD5034,20),crm,BitsN.B(0xDF,8)]
6386   | MoveImmediateProcState(PSTATEField_DAIFClr,crm) =>
6387     BitsN.concat[BitsN.B(0xD5034,20),crm,BitsN.B(0xFF,8)]
6388   | ExceptionReturn => BitsN.B(0xD69F03E0,32)
6389   | SupervisorCall imm16 =>
6390     BitsN.concat[BitsN.B(0x6A0,11),imm16,BitsN.B(0x1,5)]
6391   | HypervisorCall imm16 =>
6392     BitsN.concat[BitsN.B(0x6A0,11),imm16,BitsN.B(0x2,5)]
6393   | SecureMonitorCall imm16 =>
6394     BitsN.concat[BitsN.B(0x6A0,11),imm16,BitsN.B(0x3,5)]
6395   | SystemInstruction(op1,(op2,(crn,(crm,(l,rt))))) =>
6396     BitsN.concat
6397       [BitsN.B(0x354,10),BitsN.fromBit l,BitsN.B(0x1,2),op1,crn,crm,op2,
6398        rt];
6399
6400fun e_LoadStoreImmediate
6401  (size,
6402     (regsize_word,
6403      (memop,
6404       (acctype,
6405        (signed,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))) =
6406  let
6407    val sz = if memop = MemOp_PREFETCH then BitsN.B(0x3,2) else size
6408    val imm9 = BitsN.bits(8,0) offset
6409    val imm12 = BitsN.bits(11,0) (BitsN.>>+(offset,BitsN.toNat sz))
6410    val opc =
6411      if memop = MemOp_STORE
6412        then BitsN.B(0x0,2)
6413      else if (memop = MemOp_LOAD) andalso (not signed)
6414        then BitsN.B(0x1,2)
6415      else BitsN.@@(BitsN.B(0x1,1),BitsN.fromBit regsize_word)
6416  in
6417    if wback
6418      then if (offset = (BitsN.signExtend 64 imm9)) andalso
6419              (acctype = AccType_NORMAL)
6420             then ARM8
6421                    (BitsN.concat
6422                       [sz,BitsN.B(0x38,6),opc,BitsN.B(0x0,1),imm9,
6423                        BitsN.fromBit(not postindex),BitsN.B(0x1,1),rn,rt])
6424           else BadCode "LoadStoreImmediate"
6425    else if postindex
6426      then BadCode "LoadStoreImmediate"
6427    else if unsigned_offset andalso
6428       ((offset = (BitsN.<<(BitsN.zeroExtend 64 imm12,BitsN.toNat sz))) andalso
6429        (acctype = AccType_NORMAL))
6430      then ARM8(BitsN.concat[sz,BitsN.B(0x39,6),opc,imm12,rn,rt])
6431    else if offset = (BitsN.signExtend 64 imm9)
6432      then ARM8
6433             (BitsN.concat
6434                [sz,BitsN.B(0x38,6),opc,BitsN.B(0x0,1),imm9,
6435                 BitsN.fromBit(acctype = AccType_UNPRIV),BitsN.B(0x0,1),
6436                 rn,rt])
6437    else BadCode "LoadStoreImmediate"
6438  end;
6439
6440fun e_LoadStoreRegister
6441  (size,(regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) =
6442  let
6443    val opc =
6444      if memop = MemOp_STORE
6445        then BitsN.B(0x0,2)
6446      else if (memop = MemOp_LOAD) andalso (not signed)
6447        then BitsN.B(0x1,2)
6448      else BitsN.@@(BitsN.B(0x1,1),BitsN.fromBit regsize_word)
6449    val sz = if memop = MemOp_PREFETCH then BitsN.B(0x3,2) else size
6450  in
6451    ARM8
6452      (BitsN.concat
6453         [sz,BitsN.B(0x38,6),opc,BitsN.B(0x1,1),rm,
6454          BitsN.fromNat(Cast.ExtendTypeToNat extend_type,3),
6455          BitsN.fromBit(not(shift = 0)),BitsN.B(0x2,2),rn,rt])
6456  end;
6457
6458fun e_load_store i =
6459  case i of
6460     LoadStoreImmediate''8
6461       (size,
6462        (regsize_word,
6463         (memop,
6464          (acctype,
6465           (signed,
6466            (wb_unknown,
6467             (rt_unknown,
6468              (wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) =>
6469       e_LoadStoreImmediate
6470         (BitsN.fromNat(BitsN.toNat size,2),
6471          (regsize_word,
6472           (memop,
6473            (acctype,
6474             (signed,
6475              (wback,(postindex,(unsigned_offset,(offset,(rn,rt))))))))))
6476   | LoadStoreImmediate''16
6477     (size,
6478      (regsize_word,
6479       (memop,
6480        (acctype,
6481         (signed,
6482          (wb_unknown,
6483           (rt_unknown,
6484            (wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) =>
6485     e_LoadStoreImmediate
6486       (BitsN.fromNat(BitsN.toNat size,2),
6487        (regsize_word,
6488         (memop,
6489          (acctype,
6490           (signed,(wback,(postindex,(unsigned_offset,(offset,(rn,rt))))))))))
6491   | LoadStoreImmediate''32
6492     (size,
6493      (regsize_word,
6494       (memop,
6495        (acctype,
6496         (signed,
6497          (wb_unknown,
6498           (rt_unknown,
6499            (wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) =>
6500     e_LoadStoreImmediate
6501       (BitsN.fromNat(BitsN.toNat size,2),
6502        (regsize_word,
6503         (memop,
6504          (acctype,
6505           (signed,(wback,(postindex,(unsigned_offset,(offset,(rn,rt))))))))))
6506   | LoadStoreImmediate''64
6507     (size,
6508      (regsize_word,
6509       (memop,
6510        (acctype,
6511         (signed,
6512          (wb_unknown,
6513           (rt_unknown,
6514            (wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) =>
6515     e_LoadStoreImmediate
6516       (BitsN.fromNat(BitsN.toNat size,2),
6517        (regsize_word,
6518         (memop,
6519          (acctype,
6520           (signed,(wback,(postindex,(unsigned_offset,(offset,(rn,rt))))))))))
6521   | LoadStoreRegister''8
6522     (size,
6523      (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) =>
6524     e_LoadStoreRegister
6525       (BitsN.fromNat(BitsN.toNat size,2),
6526        (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt))))))))
6527   | LoadStoreRegister''16
6528     (size,
6529      (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) =>
6530     e_LoadStoreRegister
6531       (BitsN.fromNat(BitsN.toNat size,2),
6532        (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt))))))))
6533   | LoadStoreRegister''32
6534     (size,
6535      (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) =>
6536     e_LoadStoreRegister
6537       (BitsN.fromNat(BitsN.toNat size,2),
6538        (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt))))))))
6539   | LoadStoreRegister''64
6540     (size,
6541      (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) =>
6542     e_LoadStoreRegister
6543       (BitsN.fromNat(BitsN.toNat size,2),
6544        (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt))))))))
6545   | LoadLiteral''32(_,(memop,(signed,(offset,rt)))) =>
6546     let
6547       val imm19 = BitsN.bits(20,2) offset
6548       val opc =
6549         case (memop,signed) of
6550            (MemOp_LOAD,false) => Option.SOME(BitsN.B(0x0,2))
6551          | (MemOp_LOAD,true) => Option.SOME(BitsN.B(0x2,2))
6552          | (MemOp_PREFETCH,false) => Option.SOME(BitsN.B(0x3,2))
6553          | _ => NONE
6554     in
6555       if (Option.isSome opc) andalso
6556          (offset = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2)))))
6557         then ARM8
6558                (BitsN.concat[Option.valOf opc,BitsN.B(0x18,6),imm19,rt])
6559       else BadCode "LoadLiteral32"
6560     end
6561   | LoadLiteral''64(_,(MemOp_LOAD,(false,(offset,rt)))) =>
6562     let
6563       val imm19 = BitsN.bits(20,2) offset
6564     in
6565       if offset = (BitsN.signExtend 64 (BitsN.@@(imm19,BitsN.B(0x0,2))))
6566         then ARM8(BitsN.concat[BitsN.B(0x58,8),imm19,rt])
6567       else BadCode "LoadLiteral64"
6568     end
6569   | LoadLiteral''64 _ => BadCode "LoadLiteral64"
6570   | LoadStorePair''32
6571     (size,
6572      (memop,
6573       (acctype,
6574        (signed,
6575         (wb_unknown,
6576          (rt_unknown,(wback,(postindex,(offset,(rn,(rt,rt2))))))))))) =>
6577     let
6578       val sf = BitsN.fromNat(BitsN.toNat size,1)
6579       val scale = Nat.+(2,BitsN.toNat sf)
6580       val imm7 = BitsN.bits(6,0) (BitsN.>>+(offset,scale))
6581     in
6582       if ((sf = (BitsN.B(0x1,1))) = ((BitsN.size size) = 64)) andalso
6583          ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso
6584           ((Set.mem(acctype,[AccType_STREAM,AccType_NORMAL])) andalso
6585            (offset = (BitsN.<<(BitsN.signExtend 64 imm7,scale)))))
6586         then ARM8
6587                (BitsN.concat
6588                   [sf,BitsN.fromBit signed,BitsN.B(0x14,5),
6589                    BitsN.fromBit(not postindex),BitsN.fromBit wback,
6590                    BitsN.fromBit(memop = MemOp_LOAD),imm7,rt2,rn,rt])
6591       else BadCode "LoadStorePair"
6592     end
6593   | LoadStorePair''64
6594     (size,
6595      (memop,
6596       (acctype,
6597        (signed,
6598         (wb_unknown,
6599          (rt_unknown,(wback,(postindex,(offset,(rn,(rt,rt2))))))))))) =>
6600     let
6601       val sf = BitsN.fromNat(BitsN.toNat size,1)
6602       val scale = Nat.+(2,BitsN.toNat sf)
6603       val imm7 = BitsN.bits(6,0) (BitsN.>>+(offset,scale))
6604     in
6605       if ((sf = (BitsN.B(0x1,1))) = ((BitsN.size size) = 64)) andalso
6606          ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso
6607           ((Set.mem(acctype,[AccType_STREAM,AccType_NORMAL])) andalso
6608            (offset = (BitsN.<<(BitsN.signExtend 64 imm7,scale)))))
6609         then ARM8
6610                (BitsN.concat
6611                   [sf,BitsN.fromBit signed,BitsN.B(0x14,5),
6612                    BitsN.fromBit(not postindex),BitsN.fromBit wback,
6613                    BitsN.fromBit(memop = MemOp_LOAD),imm7,rt2,rn,rt])
6614       else BadCode "LoadStorePair"
6615     end
6616   | LoadStoreAcquire''8
6617     (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(rs,(rn,rt)))))))) =>
6618     let
6619       val sizeok =
6620         case BitsN.size size of
6621            8 => size = (BitsN.B(0x0,8))
6622          | 16 => size = (BitsN.B(0x1,8))
6623          | 32 => size = (BitsN.B(0x2,8))
6624          | _ => size = (BitsN.B(0x3,8))
6625     in
6626       if sizeok andalso
6627          ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso
6628           (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC])))
6629         then ARM8
6630                (BitsN.concat
6631                   [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x8,6),
6632                    BitsN.fromBit(not excl),
6633                    BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x0,1),rs,
6634                    BitsN.fromBit(acctype = AccType_ORDERED),
6635                    BitsN.B(0x1F,5),rn,rt])
6636       else BadCode "LoadStoreAcquire"
6637     end
6638   | LoadStoreAcquire''16
6639     (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(rs,(rn,rt)))))))) =>
6640     let
6641       val sizeok =
6642         case BitsN.size size of
6643            8 => size = (BitsN.B(0x0,16))
6644          | 16 => size = (BitsN.B(0x1,16))
6645          | 32 => size = (BitsN.B(0x2,16))
6646          | _ => size = (BitsN.B(0x3,16))
6647     in
6648       if sizeok andalso
6649          ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso
6650           (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC])))
6651         then ARM8
6652                (BitsN.concat
6653                   [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x8,6),
6654                    BitsN.fromBit(not excl),
6655                    BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x0,1),rs,
6656                    BitsN.fromBit(acctype = AccType_ORDERED),
6657                    BitsN.B(0x1F,5),rn,rt])
6658       else BadCode "LoadStoreAcquire"
6659     end
6660   | LoadStoreAcquire''32
6661     (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(rs,(rn,rt)))))))) =>
6662     let
6663       val sizeok =
6664         case BitsN.size size of
6665            8 => size = (BitsN.B(0x0,32))
6666          | 16 => size = (BitsN.B(0x1,32))
6667          | 32 => size = (BitsN.B(0x2,32))
6668          | _ => size = (BitsN.B(0x3,32))
6669     in
6670       if sizeok andalso
6671          ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso
6672           (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC])))
6673         then ARM8
6674                (BitsN.concat
6675                   [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x8,6),
6676                    BitsN.fromBit(not excl),
6677                    BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x0,1),rs,
6678                    BitsN.fromBit(acctype = AccType_ORDERED),
6679                    BitsN.B(0x1F,5),rn,rt])
6680       else BadCode "LoadStoreAcquire"
6681     end
6682   | LoadStoreAcquire''64
6683     (size,(memop,(acctype,(excl,(rn_unknown,(rt_unknown,(rs,(rn,rt)))))))) =>
6684     let
6685       val sizeok =
6686         case BitsN.size size of
6687            8 => size = (BitsN.B(0x0,64))
6688          | 16 => size = (BitsN.B(0x1,64))
6689          | 32 => size = (BitsN.B(0x2,64))
6690          | _ => size = (BitsN.B(0x3,64))
6691     in
6692       if sizeok andalso
6693          ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso
6694           (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC])))
6695         then ARM8
6696                (BitsN.concat
6697                   [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x8,6),
6698                    BitsN.fromBit(not excl),
6699                    BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x0,1),rs,
6700                    BitsN.fromBit(acctype = AccType_ORDERED),
6701                    BitsN.B(0x1F,5),rn,rt])
6702       else BadCode "LoadStoreAcquire"
6703     end
6704   | LoadStoreAcquirePair''64
6705     (size,(memop,(acctype,(rn_unknown,(rt_unknown,(rs,(rn,(rt,rt2)))))))) =>
6706     let
6707       val sizeok =
6708         size =
6709         (if (BitsN.size size) = 64
6710            then BitsN.B(0x2,64)
6711          else BitsN.B(0x3,64))
6712     in
6713       if sizeok andalso
6714          ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso
6715           (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC])))
6716         then ARM8
6717                (BitsN.concat
6718                   [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x10,7),
6719                    BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x1,1),rs,
6720                    BitsN.fromBit(acctype = AccType_ORDERED),rt2,rn,rt])
6721       else BadCode "LoadStoreAcquirePair"
6722     end
6723   | LoadStoreAcquirePair''128
6724     (size,(memop,(acctype,(rn_unknown,(rt_unknown,(rs,(rn,(rt,rt2)))))))) =>
6725     let
6726       val sizeok =
6727         size =
6728         (if (BitsN.size size) = 64
6729            then BitsN.B(0x2,128)
6730          else BitsN.B(0x3,128))
6731     in
6732       if sizeok andalso
6733          ((Set.mem(memop,[MemOp_LOAD,MemOp_STORE])) andalso
6734           (Set.mem(acctype,[AccType_ORDERED,AccType_ATOMIC])))
6735         then ARM8
6736                (BitsN.concat
6737                   [BitsN.fromNat(BitsN.toNat size,2),BitsN.B(0x10,7),
6738                    BitsN.fromBit(memop = MemOp_LOAD),BitsN.B(0x1,1),rs,
6739                    BitsN.fromBit(acctype = AccType_ORDERED),rt2,rn,rt])
6740       else BadCode "LoadStoreAcquirePair"
6741     end;
6742
6743fun Encode i =
6744  case i of
6745     Address(page,(imm,rd)) =>
6746       (if page
6747          then let
6748                 val immlo = BitsN.bits(13,12) imm
6749                 val immhi = BitsN.bits(32,14) imm
6750               in
6751                 if (BitsN.signExtend 64
6752                       (BitsN.concat[immhi,immlo,BitsN.B(0x0,12)])) = imm
6753                   then ARM8
6754                          (BitsN.concat
6755                             [BitsN.B(0x1,1),immlo,BitsN.B(0x10,5),immhi,
6756                              rd])
6757                 else BadCode "Address"
6758               end
6759        else let
6760               val immlo = BitsN.bits(1,0) imm
6761               val immhi = BitsN.bits(20,2) imm
6762             in
6763               if (BitsN.signExtend 64 (BitsN.@@(immhi,immlo))) = imm
6764                 then ARM8
6765                        (BitsN.concat
6766                           [BitsN.B(0x0,1),immlo,BitsN.B(0x10,5),immhi,rd])
6767               else BadCode "Address"
6768             end)
6769   | Data x => e_data x
6770   | Branch x => e_branch x
6771   | LoadStore x => e_load_store x
6772   | CRCExt x => ARM8(e_crc x)
6773   | Debug x => ARM8(e_debug x)
6774   | System x => ARM8(e_system x)
6775   | MemoryBarrier(opc,crm) =>
6776     ARM8
6777       (BitsN.concat
6778          [BitsN.B(0xD5033,20),crm,BitsN.B(0x1,1),
6779           BitsN.fromNat(Cast.MemBarrierOpToNat opc,2),BitsN.B(0x1F,5)])
6780   | ClearExclusive crm =>
6781     ARM8(BitsN.concat[BitsN.B(0xD5033,20),crm,BitsN.B(0x5F,8)])
6782   | Hint opc =>
6783     ARM8
6784       (BitsN.concat
6785          [BitsN.B(0xD50320,24),
6786           BitsN.fromNat(Cast.SystemHintOpToNat opc,3),BitsN.B(0x1F,5)])
6787   | Unallocated => BadCode "Unallocated"
6788   | Reserved => BadCode "Reserved";
6789
6790fun skipSpaces s = L3.snd(L3.splitl(fn c => Char.isSpace c,s));
6791
6792fun stripSpaces s =
6793  L3.fst(L3.splitr(fn c => Char.isSpace c,skipSpaces s));
6794
6795fun p_number s =
6796  case String.explode(stripSpaces s) of
6797     #"0" :: (#"b" :: t) => Nat.fromBinString(String.implode t)
6798   | #"0" :: (#"x" :: t) => Nat.fromHexString(String.implode t)
6799   | _ => Nat.fromString s;
6800
6801fun p_encode_immediate N s =
6802  case p_number s of
6803     Option.SOME n =>
6804       let
6805         val r = BitsN.fromNat(n,N)
6806       in
6807         Option.SOME(n = (BitsN.toNat r),r)
6808       end
6809   | NONE => NONE;
6810
6811fun p_unbounded_immediate s =
6812  case String.explode(skipSpaces s) of
6813     #"#" :: t => p_number(String.implode t)
6814   | _ => NONE;
6815
6816fun p_immediate N s =
6817  case String.explode(skipSpaces s) of
6818     #"#" :: t => p_encode_immediate N (String.implode t)
6819   | _ => NONE;
6820
6821fun p_neg_immediate N s =
6822  case p_encode_immediate N s of
6823     Option.SOME(true,v) =>
6824       Option.SOME
6825         (if (BitsN.neg v) = v
6826            then (true,v)
6827          else (BitsN.<(BitsN.BV(0x0,N),v),BitsN.neg v))
6828   | x => x;
6829
6830fun p_pos_immediate N s =
6831  case p_encode_immediate N s of
6832     Option.SOME(true,v) => Option.SOME(BitsN.<=(BitsN.BV(0x0,N),v),v)
6833   | x => x;
6834
6835fun p_signed_immediate N s =
6836  case String.explode(skipSpaces s) of
6837     #"#" :: t =>
6838       (case String.explode(skipSpaces(String.implode t)) of
6839           #"-" :: r => p_neg_immediate N (String.implode r)
6840         | #"+" :: r => p_pos_immediate N (String.implode r)
6841         | r => p_pos_immediate N (String.implode r))
6842   | _ => NONE;
6843
6844fun p_offset N s =
6845  case String.explode(skipSpaces s) of
6846     #"+" :: (#"#" :: t) => p_pos_immediate N (String.implode t)
6847   | #"-" :: (#"#" :: t) => p_neg_immediate N (String.implode t)
6848   | _ => NONE;
6849
6850fun p_label s =
6851  case L3.uncurry String.tokens (fn c => Char.isSpace c,s) of
6852     [t] =>
6853       let
6854         val (l,r) =
6855           L3.splitl
6856             (fn c => (Char.isAlphaNum c) orelse (Set.mem(c,[#"_",#"."])),
6857              t)
6858       in
6859         if (r = "") andalso
6860            ((not(l = "")) andalso (not(Char.isDigit(L3.strHd l))))
6861           then Option.SOME l
6862         else NONE
6863       end
6864   | _ => NONE;
6865
6866fun p_cond s =
6867  case stripSpaces s of
6868     "eq" => Option.SOME(BitsN.B(0x0,4))
6869   | "ne" => Option.SOME(BitsN.B(0x1,4))
6870   | "cs" => Option.SOME(BitsN.B(0x2,4))
6871   | "hs" => Option.SOME(BitsN.B(0x2,4))
6872   | "cc" => Option.SOME(BitsN.B(0x3,4))
6873   | "lo" => Option.SOME(BitsN.B(0x3,4))
6874   | "mi" => Option.SOME(BitsN.B(0x4,4))
6875   | "pl" => Option.SOME(BitsN.B(0x5,4))
6876   | "vs" => Option.SOME(BitsN.B(0x6,4))
6877   | "vc" => Option.SOME(BitsN.B(0x7,4))
6878   | "hi" => Option.SOME(BitsN.B(0x8,4))
6879   | "ls" => Option.SOME(BitsN.B(0x9,4))
6880   | "ge" => Option.SOME(BitsN.B(0xA,4))
6881   | "lt" => Option.SOME(BitsN.B(0xB,4))
6882   | "gt" => Option.SOME(BitsN.B(0xC,4))
6883   | "le" => Option.SOME(BitsN.B(0xD,4))
6884   | "al" => Option.SOME(BitsN.B(0xE,4))
6885   | "15" => Option.SOME(BitsN.B(0xF,4))
6886   | _ => NONE;
6887
6888fun invert_cond s =
6889  case stripSpaces s of
6890     "eq" => "ne"
6891   | "ne" => "eq"
6892   | "cs" => "cc"
6893   | "hs" => "cc"
6894   | "cc" => "cs"
6895   | "lo" => "cs"
6896   | "mi" => "pl"
6897   | "pl" => "mi"
6898   | "vs" => "vc"
6899   | "vc" => "vs"
6900   | "hi" => "ls"
6901   | "ls" => "hi"
6902   | "ge" => "lt"
6903   | "lt" => "ge"
6904   | "gt" => "le"
6905   | "le" => "gt"
6906   | _ => "??";
6907
6908fun p_w_x s =
6909  case String.explode s of
6910     #"w" :: l => Option.SOME(false,String.implode l)
6911   | #"x" :: l => Option.SOME(true,String.implode l)
6912   | _ => NONE;
6913
6914fun is_wide_reg s =
6915  case String.explode(skipSpaces s) of
6916     #"x" :: _ => true
6917   | #"s" :: (#"p" :: _) => true
6918   | _ => false;
6919
6920fun p_register (zr,s) =
6921  let
6922    val s = stripSpaces s
6923  in
6924    case p_w_x s of
6925       Option.SOME(isx,l) =>
6926         (case String.explode l of
6927             [b] =>
6928               (if Char.isDigit b
6929                  then Option.SOME
6930                         (isx,
6931                          (Option.valOf o BitsN.fromHexString)
6932                            (String.implode[b],5))
6933                else NONE)
6934           | [#"1",b] =>
6935             (if Char.isDigit b
6936                then Option.SOME
6937                       (isx,
6938                        BitsN.+
6939                          (BitsN.B(0xA,5),
6940                           (Option.valOf o BitsN.fromHexString)
6941                             (String.implode[b],5)))
6942              else NONE)
6943           | [#"2",b] =>
6944             (if Char.isDigit b
6945                then Option.SOME
6946                       (isx,
6947                        BitsN.+
6948                          (BitsN.B(0x14,5),
6949                           (Option.valOf o BitsN.fromHexString)
6950                             (String.implode[b],5)))
6951              else NONE)
6952           | [#"3",#"0"] => Option.SOME(isx,BitsN.B(0x1E,5))
6953           | [#"z",#"r"] =>
6954             if zr then Option.SOME(isx,BitsN.B(0x1F,5)) else NONE
6955           | [#"s",#"p"] =>
6956             if zr then NONE else Option.SOME(isx,BitsN.B(0x1F,5))
6957           | _ => NONE)
6958     | NONE =>
6959       if (not zr) andalso (s = "sp")
6960         then Option.SOME(true,BitsN.B(0x1F,5))
6961       else NONE
6962  end;
6963
6964fun p_register1 (zr,l) = case l of [r1] => p_register(zr,r1) | _ => NONE;
6965
6966fun p_register2 (zr1,(zr2,l)) =
6967  case l of
6968     [r1,r2] =>
6969       (case (p_register(zr1,r1),p_register(zr2,r2)) of
6970           (Option.SOME(b1,v1),Option.SOME(b2,v2)) =>
6971             (if b1 = b2 then Option.SOME(b1,(v1,v2)) else NONE)
6972         | _ => NONE)
6973   | _ => NONE;
6974
6975fun p_register3 (zr1,(zr2,(zr3,l))) =
6976  case l of
6977     [r1,r2,r3] =>
6978       (case (p_register(zr1,r1),(p_register(zr2,r2),p_register(zr3,r3))) of
6979           (Option.SOME(b1,v1),(Option.SOME(b2,v2),Option.SOME(b3,v3))) =>
6980             (if (b1 = b2) andalso (b2 = b3)
6981                then Option.SOME(b1,(v1,(v2,v3)))
6982              else NONE)
6983         | _ => NONE)
6984   | _ => NONE;
6985
6986fun p_register4 (zr1,(zr2,(zr3,(zr4,l)))) =
6987  case l of
6988     [r1,r2,r3,r4] =>
6989       (case (p_register(zr1,r1),
6990         (p_register(zr2,r2),(p_register(zr3,r3),p_register(zr4,r4)))) of
6991           (Option.SOME(b1,v1),
6992            (Option.SOME(b2,v2),(Option.SOME(b3,v3),Option.SOME(b4,v4)))) =>
6993             (if (b1 = b2) andalso ((b2 = b3) andalso (b3 = b4))
6994                then Option.SOME(b1,(v1,(v2,(v3,v4))))
6995              else NONE)
6996         | _ => NONE)
6997   | _ => NONE;
6998
6999fun p_register2z l = p_register2(true,(true,l));
7000
7001fun p_register3z l = p_register3(true,(true,(true,l)));
7002
7003fun p_extend_amount (ext,(optional,s)) =
7004  case p_unbounded_immediate s of
7005     Option.SOME v => Option.SOME(ext,v)
7006   | NONE =>
7007     if optional andalso ((stripSpaces s) = "")
7008       then Option.SOME(ext,0)
7009     else NONE;
7010
7011fun p_extend s =
7012  case String.explode(skipSpaces s) of
7013     #"u" :: (#"x" :: (#"t" :: (#"b" :: t))) =>
7014       p_extend_amount(ExtendType_UXTB,(true,String.implode t))
7015   | #"u" :: (#"x" :: (#"t" :: (#"h" :: t))) =>
7016     p_extend_amount(ExtendType_UXTH,(true,String.implode t))
7017   | #"u" :: (#"x" :: (#"t" :: (#"w" :: t))) =>
7018     p_extend_amount(ExtendType_UXTW,(true,String.implode t))
7019   | #"u" :: (#"x" :: (#"t" :: (#"x" :: t))) =>
7020     p_extend_amount(ExtendType_UXTX,(true,String.implode t))
7021   | #"s" :: (#"x" :: (#"t" :: (#"b" :: t))) =>
7022     p_extend_amount(ExtendType_SXTB,(true,String.implode t))
7023   | #"s" :: (#"x" :: (#"t" :: (#"h" :: t))) =>
7024     p_extend_amount(ExtendType_SXTH,(true,String.implode t))
7025   | #"s" :: (#"x" :: (#"t" :: (#"w" :: t))) =>
7026     p_extend_amount(ExtendType_SXTW,(true,String.implode t))
7027   | #"s" :: (#"x" :: (#"t" :: (#"x" :: t))) =>
7028     p_extend_amount(ExtendType_SXTX,(true,String.implode t))
7029   | _ => NONE;
7030
7031fun p_extend2 (size,(wide,s)) =
7032  let
7033    val r =
7034      case String.explode(stripSpaces s) of
7035         #"u" :: (#"x" :: (#"t" :: (#"w" :: t))) =>
7036           (if wide
7037              then NONE
7038            else p_extend_amount(ExtendType_UXTW,(true,String.implode t)))
7039       | #"l" :: (#"s" :: (#"l" :: t)) =>
7040         (if wide
7041            then p_extend_amount(ExtendType_UXTX,(false,String.implode t))
7042          else NONE)
7043       | #"s" :: (#"x" :: (#"t" :: (#"w" :: t))) =>
7044         (if wide
7045            then NONE
7046          else p_extend_amount(ExtendType_SXTW,(true,String.implode t)))
7047       | #"s" :: (#"x" :: (#"t" :: (#"x" :: t))) =>
7048         (if wide
7049            then p_extend_amount(ExtendType_SXTX,(true,String.implode t))
7050          else NONE)
7051       | _ => NONE
7052  in
7053    case r of
7054       Option.SOME(_,v) => (if Set.mem(v,[0,size]) then r else NONE)
7055     | NONE => NONE
7056  end;
7057
7058fun p_shift_amount (sh,s) =
7059  case p_unbounded_immediate s of
7060     Option.SOME v => Option.SOME(sh,v)
7061   | NONE => NONE;
7062
7063fun p_shift_imm s =
7064  case String.explode(skipSpaces s) of
7065     #"l" :: (#"s" :: (#"l" :: t)) =>
7066       p_shift_amount(ShiftType_LSL,String.implode t)
7067   | #"l" :: (#"s" :: (#"r" :: t)) =>
7068     p_shift_amount(ShiftType_LSR,String.implode t)
7069   | #"a" :: (#"s" :: (#"r" :: t)) =>
7070     p_shift_amount(ShiftType_ASR,String.implode t)
7071   | #"r" :: (#"o" :: (#"r" :: t)) =>
7072     p_shift_amount(ShiftType_ROR,String.implode t)
7073   | _ => NONE;
7074
7075fun closingAddress s =
7076  let
7077    val (l,wb) = L3.splitr(fn c => c = #"!",stripSpaces s)
7078    val (l,r) = L3.splitr(fn c => c = #"]",stripSpaces l)
7079  in
7080    if (r = "]") andalso (Nat.<(L3.size wb,2))
7081      then Option.SOME(wb = "!",l)
7082    else NONE
7083  end;
7084
7085fun p_address l =
7086  case l of
7087     h :: t =>
7088       (case String.explode(skipSpaces h) of
7089           #"[" :: r =>
7090             let
7091               val r = String.implode r
7092             in
7093               case closingAddress r of
7094                  Option.SOME(wb,r2) =>
7095                    (case p_register(false,r2) of
7096                        Option.SOME(true,xn) =>
7097                          (case (t,wb) of
7098                              ([],_) =>
7099                                ("",
7100                                 Option.SOME
7101                                   (xn,(BitsN.B(0x0,64),(wb,false))))
7102                            | ([a],false) =>
7103                              (case p_signed_immediate 64 a of
7104                                  Option.SOME(true,imm) =>
7105                                    ("",Option.SOME(xn,(imm,(true,true))))
7106                                | Option.SOME _ =>
7107                                  ("immediate too large",NONE)
7108                                | NONE => ("syntax error",NONE))
7109                            | _ => ("syntax error",NONE))
7110                      | _ => ("syntax error",NONE))
7111                | NONE =>
7112                  (case t of
7113                      [a] =>
7114                        (case (p_register(false,r),closingAddress a) of
7115                            (Option.SOME(true,xn),Option.SOME(wb,i)) =>
7116                              (case p_signed_immediate 64 i of
7117                                  Option.SOME(true,imm) =>
7118                                    ("",Option.SOME(xn,(imm,(wb,false))))
7119                                | Option.SOME _ =>
7120                                  ("immediate too large",NONE)
7121                                | NONE => ("syntax error",NONE))
7122                          | _ => ("syntax error",NONE))
7123                    | _ => ("syntax error",NONE))
7124             end
7125         | _ => ("syntax error",NONE))
7126   | _ => ("syntax error",NONE);
7127
7128fun p_exclusive_address l =
7129  case p_address l of
7130     ("",Option.SOME(xn,(BitsN.B(0x0,_),(false,false)))) => Option.SOME xn
7131   | _ => NONE;
7132
7133fun p_opening_reg s =
7134  case String.explode(skipSpaces s) of
7135     #"[" :: r => p_register(false,String.implode r)
7136   | _ => NONE;
7137
7138fun p_reg_address (size,l) =
7139  case l of
7140     [n,m,e] =>
7141       (case (p_opening_reg n,(p_register(true,m),closingAddress e)) of
7142           (Option.SOME(true,xn),
7143            (Option.SOME(wide,rm),Option.SOME(false,e2))) =>
7144             (case p_extend2(size,(wide,e2)) of
7145                 Option.SOME(extend_type,shift) =>
7146                   Option.SOME(xn,(rm,(extend_type,shift)))
7147               | _ => NONE)
7148         | _ => NONE)
7149   | [n,m] =>
7150     (case closingAddress m of
7151         Option.SOME(false,m2) =>
7152           (case p_register(true,m2) of
7153               Option.SOME(wide,_) =>
7154                 let
7155                   val e = if wide then "lsl #0]" else "uxtw]"
7156                 in
7157                   p_reg_address(size,[n,m2,e])
7158                 end
7159             | NONE => NONE)
7160       | _ => NONE)
7161   | _ => NONE;
7162
7163fun p_ldr_literal
7164  (size,(memop,(signed,(allow_unsigned_offset,(wide,(rt,l)))))) =
7165  if (size = 2) andalso
7166     (allow_unsigned_offset andalso
7167      ((memop = MemOp_LOAD) andalso
7168       (((not signed) orelse wide) andalso ((L3.length l) = 1))))
7169    then let
7170           val a = List.hd l
7171         in
7172           case p_label a of
7173              Option.SOME v =>
7174                let
7175                  val a = (memop,(signed,(BitsN.B(0x0,64),rt)))
7176                  val i =
7177                    if signed
7178                      then LoadLiteral''32(BitsN.B(0x2,32),a)
7179                    else if wide
7180                      then LoadLiteral''64(BitsN.B(0x1,64),a)
7181                    else LoadLiteral''32(BitsN.B(0x0,32),a)
7182                in
7183                  PENDING(v,LoadStore i)
7184                end
7185            | NONE =>
7186              (case p_offset 21 a of
7187                  Option.SOME(true,imm21) =>
7188                    let
7189                      val imm64 = BitsN.signExtend 64 imm21
7190                      val a = (memop,(signed,(imm64,rt)))
7191                      val i =
7192                        if signed
7193                          then LoadLiteral''32(BitsN.B(0x2,32),a)
7194                        else if wide
7195                          then LoadLiteral''64(BitsN.B(0x1,64),a)
7196                        else LoadLiteral''32(BitsN.B(0x0,32),a)
7197                    in
7198                      OK(LoadStore i)
7199                    end
7200                | Option.SOME _ => FAIL "offset too large: ldr (literal)"
7201                | _ => FAIL "syntax error: ldr, ldrsw")
7202         end
7203  else FAIL "syntax error: ldr, str, ...";
7204
7205fun p_ldr_str
7206  (size,(memop,(acctype,(signed,(allow_unsigned_offset,l))))) =
7207  case l of
7208     t :: r =>
7209       (case p_register(true,t) of
7210           Option.SOME(wide,rt) =>
7211             (if ((size = 2) andalso ((not wide) andalso signed)) orelse
7212                 ((Nat.<(size,2)) andalso (wide andalso (not signed)))
7213                then FAIL "syntax error: ldr, str, ..."
7214              else let
7215                     val regsize_word = not wide
7216                   in
7217                     case p_address r of
7218                        ("",Option.SOME(xn,(offset,(wb,postindex)))) =>
7219                          let
7220                            val unsigned_offset =
7221                              allow_unsigned_offset andalso (not wb)
7222                          in
7223                            if unsigned_offset andalso
7224                               (BitsN.<(offset,BitsN.B(0x0,64)))
7225                              then FAIL
7226                                     "unsigned offset required: ldr, str"
7227                            else if (not(allow_unsigned_offset orelse
7228                                    postindex)) andalso wb
7229                              then FAIL
7230                                     "write-back not permitted: ldr, str, ..."
7231                            else let
7232                                   val a =
7233                                     (regsize_word,
7234                                      (memop,
7235                                       (acctype,
7236                                        (signed,
7237                                         (false,
7238                                          (false,
7239                                           (wb,
7240                                            (postindex,
7241                                             (unsigned_offset,
7242                                              (offset,(xn,rt)))))))))))
7243                                 in
7244                                   OK(LoadStore
7245                                        (case size of
7246                                            0 =>
7247                                              LoadStoreImmediate''8
7248                                                (BitsN.B(0x0,8),a)
7249                                          | 1 =>
7250                                            LoadStoreImmediate''16
7251                                              (BitsN.B(0x1,16),a)
7252                                          | _ =>
7253                                            (if wide andalso (not signed)
7254                                               then LoadStoreImmediate''64
7255                                                      (BitsN.B(0x3,64),a)
7256                                             else LoadStoreImmediate''32
7257                                                    (BitsN.B(0x2,32),a))))
7258                                 end
7259                          end
7260                      | (err,_) =>
7261                        (if acctype = AccType_NORMAL
7262                           then let
7263                                  val sz =
7264                                    if (size = 2) andalso
7265                                       (wide andalso (not signed))
7266                                      then 3
7267                                    else size
7268                                in
7269                                  case p_reg_address(sz,r) of
7270                                     Option.SOME
7271                                       (xn,(rm,(extend_type,shift))) =>
7272                                       let
7273                                         val a =
7274                                           (regsize_word,
7275                                            (memop,
7276                                             (signed,
7277                                              (rm,
7278                                               (extend_type,
7279                                                (shift,(xn,rt)))))))
7280                                       in
7281                                         OK(LoadStore
7282                                              (case size of
7283                                                  0 =>
7284                                                    LoadStoreRegister''8
7285                                                      (BitsN.B(0x0,8),a)
7286                                                | 1 =>
7287                                                  LoadStoreRegister''16
7288                                                    (BitsN.B(0x1,16),a)
7289                                                | _ =>
7290                                                  (if wide andalso
7291                                                      (not signed)
7292                                                     then LoadStoreRegister''64
7293                                                            (BitsN.B
7294                                                               (0x3,64),a)
7295                                                   else LoadStoreRegister''32
7296                                                          (BitsN.B(0x2,32),
7297                                                           a))))
7298                                       end
7299                                   | NONE =>
7300                                     p_ldr_literal
7301                                       (size,
7302                                        (memop,
7303                                         (signed,
7304                                          (allow_unsigned_offset,
7305                                           (wide,(rt,r))))))
7306                                end
7307                         else FAIL(err ^ ": ldr, str, ..."))
7308                   end)
7309         | NONE => FAIL "syntax error: ldr, str, ...")
7310   | _ => FAIL "syntax error: ldr, str, ...";
7311
7312fun p_ldar_stlr (size,(memop,(acctype,(excl,l)))) =
7313  case l of
7314     t :: r =>
7315       (case p_register(true,t) of
7316           Option.SOME(wide,rt) =>
7317             (if (Nat.<(size,2)) andalso wide
7318                then FAIL "syntax error: ldar, stlr, ..."
7319              else case p_exclusive_address r of
7320                      Option.SOME xn =>
7321                        let
7322                          val a =
7323                            (memop,
7324                             (acctype,
7325                              (excl,
7326                               (false,(false,(BitsN.B(0x1F,5),(xn,rt)))))))
7327                        in
7328                          OK(LoadStore
7329                               (case size of
7330                                   0 =>
7331                                     LoadStoreAcquire''8(BitsN.B(0x0,8),a)
7332                                 | 1 =>
7333                                   LoadStoreAcquire''16(BitsN.B(0x1,16),a)
7334                                 | _ =>
7335                                   (if wide
7336                                      then LoadStoreAcquire''64
7337                                             (BitsN.B(0x3,64),a)
7338                                    else LoadStoreAcquire''32
7339                                           (BitsN.B(0x2,32),a))))
7340                        end
7341                    | _ => FAIL "syntax error: ldar, stlr, ...")
7342         | NONE => FAIL "syntax error: ldar, stlr, ...")
7343   | _ => FAIL "syntax error: ldar, stlr, ...";
7344
7345fun p_ldp_stp (memop,(acctype,(signed,l))) =
7346  case l of
7347     t1 :: (t2 :: r) =>
7348       (case p_register2z[t1,t2] of
7349           Option.SOME(wide,(rt1,rt2)) =>
7350             (case p_address r of
7351                 ("",Option.SOME(xn,(offset,(wb,postindex)))) =>
7352                   (if ((acctype = AccType_STREAM) andalso
7353                        (wb orelse signed)) orelse
7354                       (signed andalso (not wide))
7355                      then FAIL "syntax error: ldp, stp, ..."
7356                    else let
7357                           val postindex =
7358                             if acctype = AccType_STREAM
7359                               then true
7360                             else postindex
7361                           val a =
7362                             (memop,
7363                              (acctype,
7364                               (signed,
7365                                (false,
7366                                 (false,
7367                                  (wb,(postindex,(offset,(xn,(rt1,rt2))))))))))
7368                         in
7369                           OK(LoadStore
7370                                (if wide andalso (not signed)
7371                                   then LoadStorePair''64
7372                                          (BitsN.B(0x1,64),a)
7373                                 else LoadStorePair''32(BitsN.B(0x0,32),a)))
7374                         end)
7375               | _ => FAIL "syntax error: ldp, stp, ...")
7376         | NONE => FAIL "syntax error: ldp, stp, ...")
7377   | _ => FAIL "syntax error: ldp, stp, ...";
7378
7379fun p_ldxp (acctype,l) =
7380  case l of
7381     t1 :: (t2 :: r) =>
7382       (case p_register2z[t1,t2] of
7383           Option.SOME(wide,(rt1,rt2)) =>
7384             (case p_exclusive_address r of
7385                 Option.SOME xn =>
7386                   let
7387                     val a =
7388                       (MemOp_LOAD,
7389                        (acctype,
7390                         (false,(false,(BitsN.B(0x1F,5),(xn,(rt1,rt2)))))))
7391                   in
7392                     OK(LoadStore
7393                          (if wide
7394                             then LoadStoreAcquirePair''128
7395                                    (BitsN.B(0x3,128),a)
7396                           else LoadStoreAcquirePair''64
7397                                  (BitsN.B(0x2,64),a)))
7398                   end
7399               | _ => FAIL "syntax error: ldxp")
7400         | NONE => FAIL "syntax error: ldxp")
7401   | _ => FAIL "syntax error: ldxp";
7402
7403fun p_stxp (acctype,l) =
7404  case l of
7405     s :: (t1 :: (t2 :: r)) =>
7406       (case (p_register(true,s),p_register2z[t1,t2]) of
7407           (Option.SOME(false,rs),Option.SOME(wide,(rt1,rt2))) =>
7408             (case p_exclusive_address r of
7409                 Option.SOME xn =>
7410                   let
7411                     val a =
7412                       (MemOp_STORE,
7413                        (acctype,(false,(false,(rs,(xn,(rt1,rt2)))))))
7414                   in
7415                     OK(LoadStore
7416                          (if wide
7417                             then LoadStoreAcquirePair''128
7418                                    (BitsN.B(0x3,128),a)
7419                           else LoadStoreAcquirePair''64
7420                                  (BitsN.B(0x2,64),a)))
7421                   end
7422               | _ => FAIL "syntax error: stxp")
7423         | _ => FAIL "syntax error: stxp")
7424   | _ => FAIL "syntax error: stxp";
7425
7426fun p_adr (page,l) =
7427  case l of
7428     [d,a] =>
7429       (case p_register(true,d) of
7430           Option.SOME(true,xd) =>
7431             (case p_label a of
7432                 Option.SOME v =>
7433                   PENDING(v,Address(page,(BitsN.B(0x0,64),xd)))
7434               | NONE =>
7435                 (case p_offset 21 a of
7436                     Option.SOME(true,imm21) =>
7437                       let
7438                         val imm64 = BitsN.signExtend 64 imm21
7439                         val imm64 =
7440                           if page then BitsN.<<(imm64,12) else imm64
7441                       in
7442                         OK(Address(page,(imm64,xd)))
7443                       end
7444                   | Option.SOME _ => FAIL "offset too large: adr"
7445                   | _ => FAIL "syntax error: adr"))
7446         | _ => FAIL "syntax error: adr")
7447   | _ => FAIL "syntax error: adr";
7448
7449fun p_conditional_b (cd,l) =
7450  case l of
7451     [a] =>
7452       (case p_label a of
7453           Option.SOME v =>
7454             PENDING(v,Branch(BranchConditional(BitsN.B(0x0,64),cd)))
7455         | NONE =>
7456           (case p_offset 21 a of
7457               Option.SOME(true,imm21) =>
7458                 OK(Branch
7459                      (BranchConditional(BitsN.signExtend 64 imm21,cd)))
7460             | Option.SOME _ => FAIL "offset too large: conditional b"
7461             | _ => FAIL "syntax error: conditional b"))
7462   | _ => FAIL "syntax error: conditional b";
7463
7464fun p_b_bl (branch_type,l) =
7465  case l of
7466     [a] =>
7467       (case p_label a of
7468           Option.SOME v =>
7469             PENDING
7470               (v,Branch(BranchImmediate(BitsN.B(0x0,64),branch_type)))
7471         | NONE =>
7472           (case p_offset 28 a of
7473               Option.SOME(true,imm28) =>
7474                 OK(Branch
7475                      (BranchImmediate
7476                         (BitsN.signExtend 64 imm28,branch_type)))
7477             | Option.SOME _ => FAIL "offset too large: b, bl"
7478             | _ => FAIL "syntax error: b, bl"))
7479   | _ => FAIL "syntax error: b, bl";
7480
7481fun p_br_etc (branch_type,l) =
7482  case l of
7483     [n] =>
7484       (case p_register(true,n) of
7485           Option.SOME(true,xn) =>
7486             OK(Branch(BranchRegister(xn,branch_type)))
7487         | _ => FAIL "syntax error: br, blr, ret")
7488   | [] =>
7489     if branch_type = BranchType_RET
7490       then OK(Branch(BranchRegister(BitsN.B(0x1E,5),branch_type)))
7491     else FAIL "syntax error: br, blr"
7492   | _ => FAIL "syntax error: br, blr, ret";
7493
7494fun p_cbz_cbnz (iszero,l) =
7495  case l of
7496     [t,a] =>
7497       (case p_register(true,t) of
7498           Option.SOME(wide,rt) =>
7499             (case p_label a of
7500                 Option.SOME v =>
7501                   PENDING
7502                     (v,
7503                      Branch
7504                        (if wide
7505                           then CompareAndBranch''64
7506                                  (BitsN.B(0x1,64),
7507                                   (iszero,(BitsN.B(0x0,64),rt)))
7508                         else CompareAndBranch''32
7509                                (BitsN.B(0x0,32),
7510                                 (iszero,(BitsN.B(0x0,64),rt)))))
7511               | NONE =>
7512                 (case p_offset 21 a of
7513                     Option.SOME(true,imm21) =>
7514                       let
7515                         val imm64 = BitsN.signExtend 64 imm21
7516                       in
7517                         OK(Branch
7518                              (if wide
7519                                 then CompareAndBranch''64
7520                                        (BitsN.B(0x1,64),
7521                                         (iszero,(imm64,rt)))
7522                               else CompareAndBranch''32
7523                                      (BitsN.B(0x0,32),(iszero,(imm64,rt)))))
7524                       end
7525                   | Option.SOME _ => FAIL "offset too large: cbz, cbnz"
7526                   | _ => FAIL "syntax error: cbz, cbnz"))
7527         | _ => FAIL "syntax error: cbz, cbnz")
7528   | _ => FAIL "syntax error: cbz, cbnz";
7529
7530fun p_tbz_tbnz (bit_val,l) =
7531  case l of
7532     [t,i,a] =>
7533       (case (p_register(true,t),p_immediate 6 i) of
7534           (Option.SOME(wide,rt),Option.SOME(true,bit_pos)) =>
7535             let
7536               val wide = wide andalso (BitsN.<+(BitsN.B(0x1F,6),bit_pos))
7537             in
7538               case p_label a of
7539                  Option.SOME v =>
7540                    PENDING
7541                      (v,
7542                       Branch
7543                         (if wide
7544                            then TestBitAndBranch''64
7545                                   (BitsN.B(0x1,64),
7546                                    (bit_pos,
7547                                     (bit_val,(BitsN.B(0x0,64),rt))))
7548                          else TestBitAndBranch''32
7549                                 (BitsN.B(0x0,32),
7550                                  (bit_pos,(bit_val,(BitsN.B(0x0,64),rt))))))
7551                | NONE =>
7552                  (case p_offset 16 a of
7553                      Option.SOME(true,imm16) =>
7554                        let
7555                          val imm64 = BitsN.signExtend 64 imm16
7556                        in
7557                          OK(Branch
7558                               (if wide
7559                                  then TestBitAndBranch''64
7560                                         (BitsN.B(0x1,64),
7561                                          (bit_pos,(bit_val,(imm64,rt))))
7562                                else TestBitAndBranch''32
7563                                       (BitsN.B(0x0,32),
7564                                        (bit_pos,(bit_val,(imm64,rt))))))
7565                        end
7566                    | Option.SOME _ => FAIL "offset too large: tbz, tbnz"
7567                    | _ => FAIL "syntax error: tbz, tbnz")
7568             end
7569         | (Option.SOME _,Option.SOME _) =>
7570           FAIL "immediate too large: tbz, tbnz"
7571         | _ => FAIL "syntax error: tbz, tbnz")
7572   | _ => FAIL "syntax error: tbz, tbnz";
7573
7574fun p_extend_register
7575  (sub_op,(setflags,(ext,(amount,(is_lsl,(d,(n,m))))))) =
7576  case (p_register2(setflags,(false,[d,n])),p_register(true,m)) of
7577     (Option.SOME(true,(xd,xn)),Option.SOME(_,rm)) =>
7578       (if Nat.<(amount,5)
7579          then let
7580                 val ext = if is_lsl then ExtendType_UXTX else ext
7581               in
7582                 OK(Data
7583                      (AddSubExtendRegister''64
7584                         (BitsN.B(0x1,64),
7585                          (sub_op,
7586                           (setflags,
7587                            (rm,(ext,(BitsN.fromNat(amount,3),(xn,xd)))))))))
7588               end
7589        else FAIL "syntax error: add, sub")
7590   | (Option.SOME(false,(wd,wn)),Option.SOME(false,wm)) =>
7591     (if Nat.<(amount,5)
7592        then OK(Data
7593                  (AddSubExtendRegister''32
7594                     (BitsN.B(0x0,32),
7595                      (sub_op,
7596                       (setflags,
7597                        (wm,(ext,(BitsN.fromNat(amount,3),(wn,wd)))))))))
7598      else FAIL "syntax error: add, sub")
7599   | (Option.SOME(wide,(rd,rn)),NONE) =>
7600     (if is_lsl andalso (Set.mem(amount,[0,12]))
7601        then case p_immediate 12 m of
7602                Option.SOME(true,imm12) =>
7603                  (if wide
7604                     then let
7605                            val imm =
7606                              if amount = 12
7607                                then BitsN.<<
7608                                       (BitsN.fromNat
7609                                          (BitsN.toNat imm12,64),12)
7610                              else BitsN.fromNat(BitsN.toNat imm12,64)
7611                          in
7612                            OK(Data
7613                                 (AddSubImmediate''64
7614                                    (BitsN.B(0x1,64),
7615                                     (sub_op,(setflags,(imm,(rn,rd)))))))
7616                          end
7617                   else let
7618                          val imm =
7619                            if amount = 12
7620                              then BitsN.<<
7621                                     (BitsN.fromNat(BitsN.toNat imm12,32),
7622                                      12)
7623                            else BitsN.fromNat(BitsN.toNat imm12,32)
7624                        in
7625                          OK(Data
7626                               (AddSubImmediate''32
7627                                  (BitsN.B(0x0,32),
7628                                   (sub_op,(setflags,(imm,(rn,rd)))))))
7629                        end)
7630              | Option.SOME _ => FAIL "immediate too large: add, sub"
7631              | NONE => FAIL "syntax error: add, sub"
7632      else FAIL "syntax error: add, sub")
7633   | _ => FAIL "syntax error: add, sub";
7634
7635fun p_add_sub (sub_op,(setflags,l)) =
7636  case l of
7637     [d,n,m,e] =>
7638       (case p_shift_imm e of
7639           Option.SOME(sh,amount) =>
7640             let
7641               val imm6 = BitsN.fromNat(amount,6)
7642             in
7643               if amount = (BitsN.toNat imm6)
7644                 then case p_register3z[d,n,m] of
7645                         Option.SOME(true,(xd,(xn,xm))) =>
7646                           OK(Data
7647                                (AddSubShiftedRegister''64
7648                                   (BitsN.B(0x1,64),
7649                                    (sub_op,
7650                                     (setflags,(sh,(xm,(imm6,(xn,xd)))))))))
7651                       | Option.SOME(false,(wd,(wn,wm))) =>
7652                         OK(Data
7653                              (AddSubShiftedRegister''32
7654                                 (BitsN.B(0x0,32),
7655                                  (sub_op,
7656                                   (setflags,(sh,(wm,(imm6,(wn,wd)))))))))
7657                       | NONE =>
7658                         if sh = ShiftType_LSL
7659                           then p_extend_register
7660                                  (sub_op,
7661                                   (setflags,
7662                                    (ExtendType_UXTW,
7663                                     (amount,(true,(d,(n,m)))))))
7664                         else FAIL "syntax error: add, sub"
7665               else FAIL "syntax error: add, sub"
7666             end
7667         | NONE =>
7668           (case p_extend e of
7669               Option.SOME(ext,amount) =>
7670                 p_extend_register
7671                   (sub_op,(setflags,(ext,(amount,(false,(d,(n,m)))))))
7672             | NONE => FAIL "syntax error: add, sub"))
7673   | [d,n,m] => p_add_sub(sub_op,(setflags,[d,n,m,"lsl #0"]))
7674   | _ => FAIL "syntax error: add, sub";
7675
7676val p_and_etc_fail = FAIL "syntax error: and, bic, eon, eor, orn, orr"
7677
7678val p_and_etc_imm_fail =
7679  FAIL "immediate too large: and, bic, eon, eor, orn, orr"
7680
7681fun p_and_etc (opc,(invert,(setflags,l))) =
7682  case l of
7683     [d,n,m,e] =>
7684       (case (p_register3z[d,n,m],p_shift_imm e) of
7685           (Option.SOME(true,(xd,(xn,xm))),Option.SOME(sh,amount)) =>
7686             OK(Data
7687                  (LogicalShiftedRegister''64
7688                     (BitsN.B(0x1,64),
7689                      (opc,(invert,(setflags,(sh,(amount,(xm,(xn,xd))))))))))
7690         | (Option.SOME(false,(wd,(wn,wm))),Option.SOME(sh,amount)) =>
7691           OK(Data
7692                (LogicalShiftedRegister''32
7693                   (BitsN.B(0x0,32),
7694                    (opc,(invert,(setflags,(sh,(amount,(wm,(wn,wd))))))))))
7695         | _ => p_and_etc_fail)
7696   | [d,n,m] =>
7697     (if Option.isSome(p_register(true,m))
7698        then p_and_etc(opc,(invert,(setflags,[d,n,m,"lsl #0"])))
7699      else if invert
7700        then p_and_etc_fail
7701      else case p_unbounded_immediate m of
7702              Option.SOME imm =>
7703                (case p_register2(setflags,(true,[d,n])) of
7704                    Option.SOME(true,(xd,xn)) =>
7705                      let
7706                        val imm64 = BitsN.fromNat(imm,64)
7707                      in
7708                        if imm = (BitsN.toNat imm64)
7709                          then OK(Data
7710                                    (LogicalImmediate''64
7711                                       (BitsN.B(0x1,64),
7712                                        (opc,(setflags,(imm64,(xn,xd)))))))
7713                        else p_and_etc_imm_fail
7714                      end
7715                  | Option.SOME(false,(wd,wn)) =>
7716                    let
7717                      val imm32 = BitsN.fromNat(imm,32)
7718                    in
7719                      if imm = (BitsN.toNat imm32)
7720                        then OK(Data
7721                                  (LogicalImmediate''32
7722                                     (BitsN.B(0x0,32),
7723                                      (opc,(setflags,(imm32,(wn,wd)))))))
7724                      else p_and_etc_imm_fail
7725                    end
7726                  | NONE => p_and_etc_fail)
7727            | NONE => p_and_etc_fail)
7728   | _ => p_and_etc_fail;
7729
7730fun p_movk_etc (opcode,l) =
7731  case l of
7732     [d,i,s] =>
7733       (case (p_register(true,d),(p_immediate 16 i,p_shift_imm s)) of
7734           (Option.SOME(wide,rd),
7735            (Option.SOME(true,imm16),Option.SOME(sh,amount))) =>
7736             let
7737               val hw =
7738                 case amount of
7739                    0 => 0
7740                  | 16 => 1
7741                  | 32 => 2
7742                  | 48 => 3
7743                  | _ => 4
7744             in
7745               if wide andalso (not(hw = 4))
7746                 then OK(Data
7747                           (MoveWide''64
7748                              (BitsN.B(0x1,64),
7749                               (opcode,(BitsN.fromNat(hw,2),(imm16,rd))))))
7750               else if (not wide) andalso (Nat.<(hw,2))
7751                 then OK(Data
7752                           (MoveWide''32
7753                              (BitsN.B(0x0,32),
7754                               (opcode,(BitsN.fromNat(hw,2),(imm16,rd))))))
7755               else FAIL "syntax error: movk, movn, movz"
7756             end
7757         | (Option.SOME _,(Option.SOME _,Option.SOME _)) =>
7758           FAIL "immediate too large: movk, movn, movz"
7759         | _ => FAIL "syntax error: movk, movn, movz")
7760   | [d,i] => p_movk_etc(opcode,[d,i,"lsl #0"])
7761   | _ => FAIL "syntax error: movk, movn, movz";
7762
7763fun p_adc_sbc (sub_op,(setflags,l)) =
7764  case p_register3z l of
7765     Option.SOME(true,(xd,(xn,xm))) =>
7766       OK(Data
7767            (AddSubCarry''64
7768               (BitsN.B(0x1,64),(sub_op,(setflags,(xm,(xn,xd)))))))
7769   | Option.SOME(false,(wd,(wn,wm))) =>
7770     OK(Data
7771          (AddSubCarry''32
7772             (BitsN.B(0x0,32),(sub_op,(setflags,(wm,(wn,wd)))))))
7773   | NONE => FAIL "syntax error: adc, sbc";
7774
7775fun p_asrv_etc (shift_type,l) =
7776  case p_register3z l of
7777     Option.SOME(true,(xd,(xn,xm))) =>
7778       OK(Data(Shift''64(BitsN.B(0x1,64),(shift_type,(xm,(xn,xd))))))
7779   | Option.SOME(false,(wd,(wn,wm))) =>
7780     OK(Data(Shift''32(BitsN.B(0x0,32),(shift_type,(wm,(wn,wd))))))
7781   | NONE => FAIL "syntax error: asrv, lslv, lsrv, rorv";
7782
7783fun p_cls_clz (count_clz,l) =
7784  case p_register2z l of
7785     Option.SOME(true,(xd,xn)) =>
7786       OK(Data(CountLeading''64(BitsN.B(0x1,64),(count_clz,(xn,xd)))))
7787   | Option.SOME(false,(wd,wn)) =>
7788     OK(Data(CountLeading''32(BitsN.B(0x0,32),(count_clz,(wn,wd)))))
7789   | NONE => FAIL "syntax error: cls, clz";
7790
7791fun p_sdiv_udiv (unsigned,l) =
7792  case p_register3z l of
7793     Option.SOME(true,(xd,(xn,xm))) =>
7794       OK(Data(Division''64(BitsN.B(0x1,64),(unsigned,(xm,(xn,xd))))))
7795   | Option.SOME(false,(wd,(wn,wm))) =>
7796     OK(Data(Division''32(BitsN.B(0x0,32),(unsigned,(wm,(wn,wd))))))
7797   | NONE => FAIL "syntax error: sdiv, udiv";
7798
7799fun p_madd_msub (sub_op,l) =
7800  case p_register4(true,(true,(true,(true,l)))) of
7801     Option.SOME(true,(xd,(xn,(xm,xa)))) =>
7802       OK(Data
7803            (MultiplyAddSub''64
7804               (BitsN.B(0x1,64),(sub_op,(xm,(xa,(xn,xd)))))))
7805   | Option.SOME(false,(wd,(wn,(wm,wa)))) =>
7806     OK(Data
7807          (MultiplyAddSub''32(BitsN.B(0x0,32),(sub_op,(wm,(wa,(wn,wd)))))))
7808   | NONE => FAIL "syntax error: madd, msub";
7809
7810fun p_smaddl_etc (sub_op,(signed,l)) =
7811  case l of
7812     [d,n,m,a] =>
7813       (case (p_register2z[d,a],p_register2z[n,m]) of
7814           (Option.SOME(true,(xd,xa)),Option.SOME(false,(wn,wm))) =>
7815             OK(Data
7816                  (MultiplyAddSubLong(sub_op,(signed,(wm,(xa,(wn,xd)))))))
7817         | _ => FAIL "syntax error: smaddl, umaddl, ssubl, usubl")
7818   | _ => FAIL "syntax error: smaddl, umaddl, ssubl, usubl";
7819
7820fun p_smulh_umulh (signed,l) =
7821  case p_register3z l of
7822     Option.SOME(true,(xd,(xn,xm))) =>
7823       OK(Data(MultiplyHigh(signed,(xm,(xn,xd)))))
7824   | _ => FAIL "syntax error: smulh, umulh";
7825
7826fun p_rbit_etc (op',l) =
7827  case p_register2z l of
7828     Option.SOME(true,(xd,xn)) =>
7829       OK(Data(Reverse''64(BitsN.B(0x1,64),(op',(xn,xd)))))
7830   | Option.SOME(false,(wd,wn)) =>
7831     (if op' = RevOp_REV32
7832        then FAIL "syntax error: rbit, rev16, rev32, rev"
7833      else let
7834             val op' = if op' = RevOp_REV64 then RevOp_REV32 else op'
7835           in
7836             OK(Data(Reverse''32(BitsN.B(0x0,32),(op',(wn,wd)))))
7837           end)
7838   | NONE => FAIL "syntax error: rbit, rev16, rev32, rev";
7839
7840fun p_crc32b_etc (size,(crc32c,l)) =
7841  case p_register3z l of
7842     Option.SOME(false,(wd,(wn,wm))) =>
7843       let
7844         val i =
7845           case size of
7846              0 => CRC''8(BitsN.B(0x0,8),(crc32c,(wm,(wn,wd))))
7847            | 1 => CRC''16(BitsN.B(0x1,16),(crc32c,(wm,(wn,wd))))
7848            | _ => CRC''32(BitsN.B(0x2,32),(crc32c,(wm,(wn,wd))))
7849       in
7850         OK(CRCExt i)
7851       end
7852   | _ => FAIL "syntax error: crc32b, crc32h, crc32w";
7853
7854fun p_crc32x (crc32c,l) =
7855  case l of
7856     [d,n,m] =>
7857       (case (p_register2z[d,n],p_register(true,m)) of
7858           (Option.SOME(false,(wd,wn)),Option.SOME(true,xm)) =>
7859             OK(CRCExt(CRC''64(BitsN.B(0x3,64),(crc32c,(xm,(wn,wd))))))
7860         | _ => FAIL "syntax error: crc32x")
7861   | _ => FAIL "syntax error: crc32x";
7862
7863fun p_bfm_etc (inzero,(extend,l)) =
7864  case l of
7865     [d,n,r,s] =>
7866       (case (p_register2z[d,n],(p_immediate 6 r,p_immediate 6 s)) of
7867           (Option.SOME(wide,(rd,rn)),
7868            (Option.SOME(true,immr),Option.SOME(true,imms))) =>
7869             (if wide
7870                then case DecodeBitMasks 64
7871                       (BitsN.B(0x1,1),(imms,(immr,false))) of
7872                        Option.SOME(wmask,tmask) =>
7873                          OK(Data
7874                               (BitfieldMove''64
7875                                  (BitsN.B(0x1,64),
7876                                   (inzero,
7877                                    (extend,
7878                                     (wmask,
7879                                      (tmask,
7880                                       (BitsN.toNat immr,
7881                                        (BitsN.toNat imms,(rn,rd))))))))))
7882                      | NONE => FAIL "bad mask: bfm, sbfm, ubfm"
7883              else case DecodeBitMasks 32
7884                     (BitsN.B(0x0,1),(imms,(immr,false))) of
7885                      Option.SOME(wmask,tmask) =>
7886                        OK(Data
7887                             (BitfieldMove''32
7888                                (BitsN.B(0x0,32),
7889                                 (inzero,
7890                                  (extend,
7891                                   (wmask,
7892                                    (tmask,
7893                                     (BitsN.toNat immr,
7894                                      (BitsN.toNat imms,(rn,rd))))))))))
7895                    | NONE => FAIL "bad mask: bfm, sbfm, ubfm")
7896         | (Option.SOME _,(Option.SOME _,Option.SOME _)) =>
7897           FAIL "immediate too large: bfm, sbfm, ubfm"
7898         | _ => FAIL "syntax error: bfm, sbfm, ubfm")
7899   | _ => FAIL "syntax error: bfm, sbfm, ubfm";
7900
7901fun p_ccmn_ccmp (sub_op,l) =
7902  case l of
7903     [n,m,f,c] =>
7904       (case (p_register(true,n),(p_immediate 4 f,p_cond c)) of
7905           (Option.SOME(wide,rn),(Option.SOME(true,nzcv),Option.SOME cd)) =>
7906             let
7907               val nzcv =
7908                 (BitsN.bit(nzcv,3),
7909                  (BitsN.bit(nzcv,2),(BitsN.bit(nzcv,1),BitsN.bit(nzcv,0))))
7910             in
7911               case p_unbounded_immediate m of
7912                  Option.SOME imm =>
7913                    (if wide
7914                       then let
7915                              val imm64 = BitsN.fromNat(imm,64)
7916                            in
7917                              if imm = (BitsN.toNat imm64)
7918                                then OK(Data
7919                                          (ConditionalCompareImmediate''64
7920                                             (BitsN.B(0x1,64),
7921                                              (sub_op,
7922                                               (imm64,(cd,(nzcv,rn)))))))
7923                              else FAIL "immediate too large: ccmn, ccmp"
7924                            end
7925                     else let
7926                            val imm32 = BitsN.fromNat(imm,32)
7927                          in
7928                            if imm = (BitsN.toNat imm32)
7929                              then OK(Data
7930                                        (ConditionalCompareImmediate''32
7931                                           (BitsN.B(0x0,32),
7932                                            (sub_op,(imm32,(cd,(nzcv,rn)))))))
7933                            else FAIL "immediate too large: ccmn, ccmp"
7934                          end)
7935                | NONE =>
7936                  (case p_register(true,m) of
7937                      Option.SOME(wide2,rm) =>
7938                        (if wide = wide2
7939                           then if wide
7940                                  then OK(Data
7941                                            (ConditionalCompareRegister''64
7942                                               (BitsN.B(0x1,64),
7943                                                (sub_op,
7944                                                 (cd,(nzcv,(rm,rn)))))))
7945                                else OK(Data
7946                                          (ConditionalCompareRegister''32
7947                                             (BitsN.B(0x0,32),
7948                                              (sub_op,(cd,(nzcv,(rm,rn)))))))
7949                         else FAIL "syntax error: ccmn, ccmp")
7950                    | NONE => FAIL "syntax error: ccmn, ccmp")
7951             end
7952         | (Option.SOME _,(Option.SOME _,Option.SOME _)) =>
7953           FAIL "immediate too large: ccmn, ccmp"
7954         | _ => FAIL "syntax error: ccmn, ccmp")
7955   | _ => FAIL "syntax error: ccmn, ccmp";
7956
7957fun p_csel_etc (else_inv,(else_inc,l)) =
7958  case l of
7959     [d,n,m,c] =>
7960       (case (p_register3z[d,n,m],p_cond c) of
7961           (Option.SOME(true,(xd,(xn,xm))),Option.SOME cd) =>
7962             OK(Data
7963                  (ConditionalSelect''64
7964                     (BitsN.B(0x1,64),
7965                      (else_inv,(else_inc,(cd,(xm,(xn,xd))))))))
7966         | (Option.SOME(false,(wd,(wn,wm))),Option.SOME cd) =>
7967           OK(Data
7968                (ConditionalSelect''32
7969                   (BitsN.B(0x0,32),
7970                    (else_inv,(else_inc,(cd,(wm,(wn,wd))))))))
7971         | _ => FAIL "syntax error: csel, csinc, csinv, csneg")
7972   | _ => FAIL "syntax error: csel, csinc, csinv, csneg";
7973
7974fun p_extr l =
7975  case l of
7976     [d,n,m,b] =>
7977       (case (p_register3z[d,n,m],p_immediate 6 b) of
7978           (Option.SOME(wide,(rd,(rn,rm))),Option.SOME(true,lsb)) =>
7979             (if wide
7980                then OK(Data
7981                          (ExtractRegister''64
7982                             (BitsN.B(0x1,64),(lsb,(rm,(rn,rd))))))
7983              else if BitsN.bit(lsb,5)
7984                then FAIL "immediate too large: extr"
7985              else OK(Data
7986                        (ExtractRegister''32
7987                           (BitsN.B(0x0,32),(lsb,(rm,(rn,rd)))))))
7988         | (Option.SOME _,Option.SOME _) =>
7989           FAIL "immediate too large: extr"
7990         | _ => FAIL "syntax error: extr")
7991   | _ => FAIL "syntax error: extr";
7992
7993fun p_hint l =
7994  case l of
7995     [i] =>
7996       (case p_immediate 7 i of
7997           Option.SOME(true,imm7) =>
7998             OK(Hint
7999                  (case imm7 of
8000                      BitsN.B(0x0,_) => SystemHintOp_NOP
8001                    | BitsN.B(0x1,_) => SystemHintOp_YIELD
8002                    | BitsN.B(0x2,_) => SystemHintOp_WFE
8003                    | BitsN.B(0x3,_) => SystemHintOp_WFI
8004                    | BitsN.B(0x4,_) => SystemHintOp_SEV
8005                    | BitsN.B(0x5,_) => SystemHintOp_SEVL
8006                    | _ => SystemHintOp_NOP))
8007         | Option.SOME _ => FAIL "immediate too large: hint"
8008         | _ => FAIL "syntax error: hint")
8009   | _ => FAIL "syntax error: hint";
8010
8011fun p_call (typ,l) =
8012  case l of
8013     [i] =>
8014       (case p_immediate 16 i of
8015           Option.SOME(true,imm) =>
8016             (case typ of
8017                 0 => OK(Debug(Halt imm))
8018               | 1 => OK(Debug(DebugSwitch(BitsN.fromNat(typ,2))))
8019               | 2 => OK(Debug(DebugSwitch(BitsN.fromNat(typ,2))))
8020               | 3 => OK(Debug(DebugSwitch(BitsN.fromNat(typ,2))))
8021               | 4 => OK(Debug(Breakpoint imm))
8022               | 5 => OK(System(SupervisorCall imm))
8023               | 6 => OK(System(HypervisorCall imm))
8024               | _ => OK(System(SecureMonitorCall imm)))
8025         | Option.SOME _ => FAIL "immediate too large: hint"
8026         | _ => FAIL "syntax error: svc, hvc, smc, hlt, brk, dcpsN")
8027   | [] =>
8028     if Set.mem(typ,[1,2,3])
8029       then OK(Debug(DebugSwitch(BitsN.fromNat(typ,2))))
8030     else FAIL "syntax error: svc, hvc, smc, hlt, brk"
8031   | _ => FAIL "syntax error: svc, hvc, smc, hlt, brk, dcpsN";
8032
8033fun p_clrex l =
8034  case l of
8035     [] => OK(ClearExclusive(BitsN.B(0xF,4)))
8036   | [i] =>
8037     (case p_immediate 4 i of
8038         Option.SOME(true,crm) => OK(ClearExclusive crm)
8039       | Option.SOME _ => FAIL "immediate too large: clrex"
8040       | NONE => FAIL "syntax error: clrex")
8041   | _ => FAIL "syntax error: clrex";
8042
8043fun p_dmb_etc (opc,l) =
8044  case l of
8045     [i] =>
8046       (case p_immediate 4 i of
8047           Option.SOME(true,crm) => OK(MemoryBarrier(opc,crm))
8048         | Option.SOME _ => FAIL "immediate too large: dmb, dsb, isb"
8049         | NONE =>
8050           (case stripSpaces i of
8051               "oshld" => OK(MemoryBarrier(opc,BitsN.B(0x1,4)))
8052             | "oshst" => OK(MemoryBarrier(opc,BitsN.B(0x2,4)))
8053             | "osh" => OK(MemoryBarrier(opc,BitsN.B(0x3,4)))
8054             | "nshld" => OK(MemoryBarrier(opc,BitsN.B(0x5,4)))
8055             | "nshst" => OK(MemoryBarrier(opc,BitsN.B(0x6,4)))
8056             | "nsh" => OK(MemoryBarrier(opc,BitsN.B(0x7,4)))
8057             | "ishld" => OK(MemoryBarrier(opc,BitsN.B(0x9,4)))
8058             | "ishst" => OK(MemoryBarrier(opc,BitsN.B(0xA,4)))
8059             | "ish" => OK(MemoryBarrier(opc,BitsN.B(0xB,4)))
8060             | "ld" => OK(MemoryBarrier(opc,BitsN.B(0xD,4)))
8061             | "st" => OK(MemoryBarrier(opc,BitsN.B(0xE,4)))
8062             | "sy" => OK(MemoryBarrier(opc,BitsN.B(0xF,4)))
8063             | _ => FAIL "syntax error: dmb, dsb, isb"))
8064   | _ => FAIL "syntax error: dmb, dsb, isb";
8065
8066fun wzr_xzr s = if is_wide_reg s then "xzr" else "wzr";
8067
8068fun convert_immediate (wide,imm) =
8069  if wide
8070    then if (BitsN.bits(63,16) imm) = (BitsN.B(0x0,48))
8071           then ["#0x" ^ (BitsN.toHexString(BitsN.bits(15,0) imm)),
8072                 "lsl #0"]
8073         else if (BitsN.&&(imm,BitsN.B(0xFFFFFFFF0000FFFF,64))) =
8074            (BitsN.B(0x0,64))
8075           then ["#0x" ^ (BitsN.toHexString(BitsN.bits(31,16) imm)),
8076                 "lsl #16"]
8077         else if (BitsN.&&(imm,BitsN.B(0xFFFF0000FFFFFFFF,64))) =
8078            (BitsN.B(0x0,64))
8079           then ["#0x" ^ (BitsN.toHexString(BitsN.bits(47,32) imm)),
8080                 "lsl #32"]
8081         else if (BitsN.bits(47,0) imm) = (BitsN.B(0x0,48))
8082           then ["#0x" ^ (BitsN.toHexString(BitsN.bits(63,48) imm)),
8083                 "lsl #48"]
8084         else []
8085  else if (BitsN.bits(63,32) imm) = (BitsN.B(0x0,32))
8086    then if (BitsN.bits(31,16) imm) = (BitsN.B(0x0,16))
8087           then ["#0x" ^ (BitsN.toHexString(BitsN.bits(15,0) imm)),
8088                 "lsl #0"]
8089         else if (BitsN.bits(15,0) imm) = (BitsN.B(0x0,16))
8090           then ["#0x" ^ (BitsN.toHexString(BitsN.bits(31,16) imm)),
8091                 "lsl #16"]
8092         else []
8093  else [];
8094
8095fun p_mov l =
8096  case l of
8097     [d,n] =>
8098       let
8099         val n = stripSpaces n
8100       in
8101         if n = ""
8102           then FAIL "syntax error: mov"
8103         else let
8104                val d = stripSpaces d
8105                val s = ["sp","wsp"]
8106                val i = (L3.strHd n) = #"#"
8107                val orr = (LogicalOp_ORR,(false,(false,[d,wzr_xzr d,n])))
8108              in
8109                if (Set.mem(d,s)) orelse (Set.mem(n,s))
8110                  then if i
8111                         then p_and_etc orr
8112                       else p_add_sub(false,(false,l @ ["#0"]))
8113                else if i
8114                  then case p_immediate 64 n of
8115                          Option.SOME(true,imm) =>
8116                            let
8117                              val wide = is_wide_reg d
8118                            in
8119                              case convert_immediate(wide,imm) of
8120                                 [] =>
8121                                   let
8122                                     val imm =
8123                                       if wide
8124                                         then BitsN.~ imm
8125                                       else BitsN.??
8126                                              (imm,BitsN.B(0xFFFFFFFF,64))
8127                                   in
8128                                     case convert_immediate(wide,imm) of
8129                                        [] => p_and_etc orr
8130                                      | imm16 =>
8131                                        p_movk_etc
8132                                          (MoveWideOp_N,d :: imm16)
8133                                   end
8134                               | imm16 =>
8135                                 p_movk_etc(MoveWideOp_Z,d :: imm16)
8136                            end
8137                        | Option.SOME _ => FAIL "immediate too large: mov"
8138                        | NONE => FAIL "syntax error: mov"
8139                else p_and_etc orr
8140              end
8141       end
8142   | _ => FAIL "syntax error: mov";
8143
8144fun p_shift (shift_type,l) =
8145  case l of
8146     [d,n,x] =>
8147       (case (p_register(true,n),p_immediate 6 x) of
8148           (Option.SOME(wide,_),Option.SOME(true,imms)) =>
8149             (if (not wide) andalso (BitsN.bit(imms,5))
8150                then FAIL "immediate too large: asr, lsl, lsr, ror"
8151              else case shift_type of
8152                      ShiftType_ASR =>
8153                        p_bfm_etc
8154                          (true,
8155                           (true,[d,n,x,if wide then "#63" else "#31"]))
8156                    | ShiftType_LSR =>
8157                      p_bfm_etc
8158                        (true,
8159                         (false,[d,n,x,if wide then "#63" else "#31"]))
8160                    | ShiftType_LSL =>
8161                      let
8162                        val (v1,v2) =
8163                          if wide
8164                            then (BitsN.neg imms,
8165                                  BitsN.-(BitsN.B(0x3F,6),imms))
8166                          else (BitsN.mod(BitsN.neg imms,BitsN.B(0x20,6)),
8167                                BitsN.-(BitsN.B(0x1F,6),imms))
8168                      in
8169                        p_bfm_etc
8170                          (true,
8171                           (false,
8172                            [d,n,"#0x" ^ (BitsN.toHexString v1),
8173                             "#0x" ^ (BitsN.toHexString v2)]))
8174                      end
8175                    | ShiftType_ROR => p_extr[d,n,n,x])
8176         | (Option.SOME _,Option.SOME _) =>
8177           FAIL "immediate too large: asr, lsl, lsr, ror"
8178         | _ => p_asrv_etc(shift_type,l))
8179   | _ => FAIL "syntax error: asr, lsl, lsr, ror";
8180
8181fun p_neg (setflags,l) =
8182  case l of
8183     [d,m] =>
8184       (if Option.isSome(p_register2z l)
8185          then p_add_sub(true,(setflags,[d,wzr_xzr d,m]))
8186        else FAIL "syntax error: neg")
8187   | [d,m,e] =>
8188     (if (Option.isSome(p_register2z[d,m])) andalso
8189         (Option.isSome(p_shift_imm e))
8190        then p_add_sub(true,(setflags,[d,wzr_xzr d,m,e]))
8191      else FAIL "syntax error: neg")
8192   | _ => FAIL "syntax error: neg";
8193
8194fun convert_bfxil_etc l =
8195  case l of
8196     [d,n,a,b] =>
8197       (case (p_unbounded_immediate a,p_unbounded_immediate b) of
8198           (Option.SOME _,Option.SOME 0) => []
8199         | (Option.SOME lsb,Option.SOME width) =>
8200           [d,n,a,"#" ^ (Nat.toString(Nat.-(Nat.+(lsb,width),1)))]
8201         | _ => l)
8202   | _ => l;
8203
8204fun convert_bfi_etc l =
8205  case l of
8206     [d,n,a,b] =>
8207       (case (p_unbounded_immediate a,p_unbounded_immediate b) of
8208           (Option.SOME _,Option.SOME 0) => []
8209         | (Option.SOME lsb,Option.SOME width) =>
8210           let
8211             val m = if is_wide_reg d then 64 else 32
8212           in
8213             [d,n,
8214              "#"
8215                ^
8216                (IntInf.toString(IntInf.mod(IntInf.~(Nat.toInt lsb),m))),
8217              "#" ^ (Nat.toString(Nat.-(width,1)))]
8218           end
8219         | _ => l)
8220   | _ => l;
8221
8222fun convert_cinc_etc l =
8223  case l of [d,n,c] => [d,n,n,invert_cond c] | _ => l;
8224
8225fun convert_cset_csetm l =
8226  case l of
8227     [d,c] => let val z = wzr_xzr d in [d,z,z,invert_cond c] end
8228   | _ => l;
8229
8230fun convert_zr1 l = case l of n :: _ => (wzr_xzr n) :: l | [] => [];
8231
8232fun convert_zr2 l = case l of n :: r => [n,wzr_xzr n] @ r | [] => [];
8233
8234fun convert_zr_end l = case l of n :: _ => l @ [wzr_xzr n] | [] => [];
8235
8236fun p_tokens s =
8237  let
8238    val (l,r) =
8239      L3.splitl
8240        (fn c => not(Char.isSpace c),
8241         L3.lowercase(L3.snd(L3.splitl(fn c => Char.isSpace c,s))))
8242    val r = L3.uncurry String.fields (fn c => c = #",",r)
8243    val r =
8244      if ((L3.length r) = 1) andalso ((stripSpaces(List.hd r)) = "")
8245        then []
8246      else r
8247  in
8248    l :: r
8249  end;
8250
8251fun instructionFromString s =
8252  case p_tokens s of
8253     v'0 :: v'1 =>
8254       (case (String.explode v'0,v'1) of
8255           ([#"a",#"d",#"r",#"p"],l) => p_adr(true,l)
8256         | ([#"a",#"d",#"r"],l) => p_adr(false,l)
8257         | ([#"a",#"d",#"d",#"s"],l) => p_add_sub(false,(true,l))
8258         | ([#"c",#"m",#"n"],l) => p_add_sub(false,(true,convert_zr1 l))
8259         | ([#"a",#"d",#"d"],l) => p_add_sub(false,(false,l))
8260         | ([#"s",#"u",#"b",#"s"],l) => p_add_sub(true,(true,l))
8261         | ([#"c",#"m",#"p"],l) => p_add_sub(true,(true,convert_zr1 l))
8262         | ([#"s",#"u",#"b"],l) => p_add_sub(true,(false,l))
8263         | ([#"a",#"n",#"d",#"s"],l) =>
8264           p_and_etc(LogicalOp_AND,(false,(true,l)))
8265         | ([#"t",#"s",#"t"],l) =>
8266           p_and_etc(LogicalOp_AND,(false,(true,convert_zr1 l)))
8267         | ([#"a",#"n",#"d"],l) =>
8268           p_and_etc(LogicalOp_AND,(false,(false,l)))
8269         | ([#"b",#"i",#"c",#"s"],l) =>
8270           p_and_etc(LogicalOp_AND,(true,(true,l)))
8271         | ([#"b",#"i",#"c"],l) =>
8272           p_and_etc(LogicalOp_AND,(true,(false,l)))
8273         | ([#"e",#"o",#"r"],l) =>
8274           p_and_etc(LogicalOp_EOR,(false,(false,l)))
8275         | ([#"e",#"o",#"n"],l) =>
8276           p_and_etc(LogicalOp_EOR,(true,(false,l)))
8277         | ([#"o",#"r",#"r"],l) =>
8278           p_and_etc(LogicalOp_ORR,(false,(false,l)))
8279         | ([#"o",#"r",#"n"],l) =>
8280           p_and_etc(LogicalOp_ORR,(true,(false,l)))
8281         | ([#"m",#"v",#"n"],l) =>
8282           p_and_etc(LogicalOp_ORR,(true,(false,convert_zr2 l)))
8283         | ([#"a",#"d",#"c",#"s"],l) => p_adc_sbc(false,(true,l))
8284         | ([#"a",#"d",#"c"],l) => p_adc_sbc(false,(false,l))
8285         | ([#"s",#"b",#"c",#"s"],l) => p_adc_sbc(true,(true,l))
8286         | ([#"s",#"b",#"c"],l) => p_adc_sbc(true,(false,l))
8287         | ([#"n",#"g",#"c",#"s"],l) =>
8288           p_adc_sbc(true,(true,convert_zr2 l))
8289         | ([#"n",#"g",#"c"],l) => p_adc_sbc(true,(false,convert_zr2 l))
8290         | ([#"a",#"s",#"r",#"v"],l) => p_asrv_etc(ShiftType_ASR,l)
8291         | ([#"l",#"s",#"l",#"v"],l) => p_asrv_etc(ShiftType_LSL,l)
8292         | ([#"l",#"s",#"r",#"v"],l) => p_asrv_etc(ShiftType_LSR,l)
8293         | ([#"r",#"o",#"r",#"v"],l) => p_asrv_etc(ShiftType_ROR,l)
8294         | ([#"a",#"s",#"r"],l) => p_shift(ShiftType_ASR,l)
8295         | ([#"l",#"s",#"l"],l) => p_shift(ShiftType_LSL,l)
8296         | ([#"l",#"s",#"r"],l) => p_shift(ShiftType_LSR,l)
8297         | ([#"r",#"o",#"r"],l) => p_shift(ShiftType_ROR,l)
8298         | ([#"n",#"e",#"g",#"s"],l) => p_neg(true,l)
8299         | ([#"n",#"e",#"g"],l) => p_neg(false,l)
8300         | ([#"m",#"o",#"v",#"k"],l) => p_movk_etc(MoveWideOp_K,l)
8301         | ([#"m",#"o",#"v",#"n"],l) => p_movk_etc(MoveWideOp_N,l)
8302         | ([#"m",#"o",#"v",#"z"],l) => p_movk_etc(MoveWideOp_Z,l)
8303         | ([#"m",#"o",#"v"],l) => p_mov l
8304         | ([#"c",#"l",#"s"],l) => p_cls_clz(false,l)
8305         | ([#"c",#"l",#"z"],l) => p_cls_clz(true,l)
8306         | ([#"s",#"d",#"i",#"v"],l) => p_sdiv_udiv(false,l)
8307         | ([#"u",#"d",#"i",#"v"],l) => p_sdiv_udiv(true,l)
8308         | ([#"m",#"a",#"d",#"d"],l) => p_madd_msub(false,l)
8309         | ([#"m",#"s",#"u",#"b"],l) => p_madd_msub(true,l)
8310         | ([#"m",#"u",#"l"],l) => p_madd_msub(false,convert_zr_end l)
8311         | ([#"m",#"n",#"e",#"g"],l) => p_madd_msub(true,convert_zr_end l)
8312         | ([#"s",#"m",#"a",#"d",#"d",#"l"],l) =>
8313           p_smaddl_etc(false,(true,l))
8314         | ([#"s",#"m",#"u",#"l",#"l"],l) =>
8315           p_smaddl_etc(false,(true,convert_zr_end l))
8316         | ([#"u",#"m",#"a",#"d",#"d",#"l"],l) =>
8317           p_smaddl_etc(false,(false,l))
8318         | ([#"u",#"m",#"u",#"l",#"l"],l) =>
8319           p_smaddl_etc(false,(false,convert_zr_end l))
8320         | ([#"s",#"m",#"s",#"u",#"b",#"l"],l) =>
8321           p_smaddl_etc(true,(true,l))
8322         | ([#"s",#"m",#"n",#"e",#"g",#"l"],l) =>
8323           p_smaddl_etc(true,(true,convert_zr_end l))
8324         | ([#"u",#"m",#"s",#"u",#"b",#"l"],l) =>
8325           p_smaddl_etc(true,(false,l))
8326         | ([#"u",#"m",#"n",#"e",#"g",#"l"],l) =>
8327           p_smaddl_etc(true,(false,convert_zr_end l))
8328         | ([#"s",#"m",#"u",#"l",#"h"],l) => p_smulh_umulh(true,l)
8329         | ([#"u",#"m",#"u",#"l",#"h"],l) => p_smulh_umulh(false,l)
8330         | ([#"r",#"b",#"i",#"t"],l) => p_rbit_etc(RevOp_RBIT,l)
8331         | ([#"r",#"e",#"v",#"1",#"6"],l) => p_rbit_etc(RevOp_REV16,l)
8332         | ([#"r",#"e",#"v",#"3",#"2"],l) => p_rbit_etc(RevOp_REV32,l)
8333         | ([#"r",#"e",#"v"],l) => p_rbit_etc(RevOp_REV64,l)
8334         | ([#"c",#"s",#"e",#"l"],l) => p_csel_etc(false,(false,l))
8335         | ([#"c",#"s",#"i",#"n",#"c"],l) => p_csel_etc(false,(true,l))
8336         | ([#"c",#"i",#"n",#"c"],l) =>
8337           p_csel_etc(false,(true,convert_cinc_etc l))
8338         | ([#"c",#"s",#"e",#"t"],l) =>
8339           p_csel_etc(false,(true,convert_cset_csetm l))
8340         | ([#"c",#"s",#"i",#"n",#"v"],l) => p_csel_etc(true,(false,l))
8341         | ([#"c",#"i",#"n",#"v"],l) =>
8342           p_csel_etc(true,(false,convert_cinc_etc l))
8343         | ([#"c",#"s",#"e",#"t",#"m"],l) =>
8344           p_csel_etc(true,(false,convert_cset_csetm l))
8345         | ([#"c",#"s",#"n",#"e",#"g"],l) => p_csel_etc(true,(true,l))
8346         | ([#"c",#"n",#"e",#"g"],l) =>
8347           p_csel_etc(true,(true,convert_cinc_etc l))
8348         | ([#"c",#"c",#"m",#"n"],l) => p_ccmn_ccmp(false,l)
8349         | ([#"c",#"c",#"m",#"p"],l) => p_ccmn_ccmp(true,l)
8350         | ([#"b",#"f",#"m"],l) => p_bfm_etc(false,(false,l))
8351         | ([#"b",#"f",#"i"],l) =>
8352           p_bfm_etc(false,(false,convert_bfi_etc l))
8353         | ([#"b",#"f",#"x",#"i",#"l"],l) =>
8354           p_bfm_etc(false,(false,convert_bfxil_etc l))
8355         | ([#"s",#"b",#"f",#"m"],l) => p_bfm_etc(true,(true,l))
8356         | ([#"s",#"b",#"f",#"i",#"z"],l) =>
8357           p_bfm_etc(true,(true,convert_bfi_etc l))
8358         | ([#"s",#"b",#"f",#"x"],l) =>
8359           p_bfm_etc(true,(true,convert_bfxil_etc l))
8360         | ([#"s",#"x",#"t",#"b"],l) =>
8361           p_bfm_etc(true,(true,l @ ["#0","#7"]))
8362         | ([#"s",#"x",#"t",#"h"],l) =>
8363           p_bfm_etc(true,(true,l @ ["#0","#15"]))
8364         | ([#"s",#"x",#"t",#"w"],l) =>
8365           p_bfm_etc(true,(true,l @ ["#0","#31"]))
8366         | ([#"u",#"b",#"f",#"m"],l) => p_bfm_etc(true,(false,l))
8367         | ([#"u",#"b",#"f",#"i",#"z"],l) =>
8368           p_bfm_etc(true,(false,convert_bfi_etc l))
8369         | ([#"u",#"b",#"f",#"x"],l) =>
8370           p_bfm_etc(true,(false,convert_bfxil_etc l))
8371         | ([#"u",#"x",#"t",#"b"],l) =>
8372           p_bfm_etc(true,(false,l @ ["#0","#7"]))
8373         | ([#"u",#"x",#"t",#"h"],l) =>
8374           p_bfm_etc(true,(false,l @ ["#0","#15"]))
8375         | ([#"e",#"x",#"t",#"r"],l) => p_extr l
8376         | ([#"c",#"r",#"c",#"3",#"2",#"c",#"b"],l) =>
8377           p_crc32b_etc(0,(true,l))
8378         | ([#"c",#"r",#"c",#"3",#"2",#"c",#"h"],l) =>
8379           p_crc32b_etc(1,(true,l))
8380         | ([#"c",#"r",#"c",#"3",#"2",#"c",#"w"],l) =>
8381           p_crc32b_etc(2,(true,l))
8382         | ([#"c",#"r",#"c",#"3",#"2",#"c",#"x"],l) => p_crc32x(true,l)
8383         | ([#"c",#"r",#"c",#"3",#"2",#"b"],l) =>
8384           p_crc32b_etc(0,(false,l))
8385         | ([#"c",#"r",#"c",#"3",#"2",#"h"],l) =>
8386           p_crc32b_etc(1,(false,l))
8387         | ([#"c",#"r",#"c",#"3",#"2",#"w"],l) =>
8388           p_crc32b_etc(2,(false,l))
8389         | ([#"c",#"r",#"c",#"3",#"2",#"x"],l) => p_crc32x(false,l)
8390         | ([#"l",#"d",#"r",#"b"],l) =>
8391           p_ldr_str(0,(MemOp_LOAD,(AccType_NORMAL,(false,(true,l)))))
8392         | ([#"l",#"d",#"r",#"h"],l) =>
8393           p_ldr_str(1,(MemOp_LOAD,(AccType_NORMAL,(false,(true,l)))))
8394         | ([#"l",#"d",#"r"],l) =>
8395           p_ldr_str(2,(MemOp_LOAD,(AccType_NORMAL,(false,(true,l)))))
8396         | ([#"l",#"d",#"r",#"s",#"b"],l) =>
8397           p_ldr_str(0,(MemOp_LOAD,(AccType_NORMAL,(true,(true,l)))))
8398         | ([#"l",#"d",#"r",#"s",#"h"],l) =>
8399           p_ldr_str(1,(MemOp_LOAD,(AccType_NORMAL,(true,(true,l)))))
8400         | ([#"l",#"d",#"r",#"s",#"w"],l) =>
8401           p_ldr_str(2,(MemOp_LOAD,(AccType_NORMAL,(true,(true,l)))))
8402         | ([#"l",#"d",#"u",#"r",#"b"],l) =>
8403           p_ldr_str(0,(MemOp_LOAD,(AccType_NORMAL,(false,(false,l)))))
8404         | ([#"l",#"d",#"u",#"r",#"h"],l) =>
8405           p_ldr_str(1,(MemOp_LOAD,(AccType_NORMAL,(false,(false,l)))))
8406         | ([#"l",#"d",#"u",#"r"],l) =>
8407           p_ldr_str(2,(MemOp_LOAD,(AccType_NORMAL,(false,(false,l)))))
8408         | ([#"l",#"d",#"u",#"r",#"s",#"b"],l) =>
8409           p_ldr_str(0,(MemOp_LOAD,(AccType_NORMAL,(true,(false,l)))))
8410         | ([#"l",#"d",#"u",#"r",#"s",#"h"],l) =>
8411           p_ldr_str(1,(MemOp_LOAD,(AccType_NORMAL,(true,(false,l)))))
8412         | ([#"l",#"d",#"u",#"r",#"s",#"w"],l) =>
8413           p_ldr_str(2,(MemOp_LOAD,(AccType_NORMAL,(true,(false,l)))))
8414         | ([#"l",#"d",#"t",#"r",#"b"],l) =>
8415           p_ldr_str(0,(MemOp_LOAD,(AccType_UNPRIV,(false,(false,l)))))
8416         | ([#"l",#"d",#"t",#"r",#"h"],l) =>
8417           p_ldr_str(1,(MemOp_LOAD,(AccType_UNPRIV,(false,(false,l)))))
8418         | ([#"l",#"d",#"t",#"r"],l) =>
8419           p_ldr_str(2,(MemOp_LOAD,(AccType_UNPRIV,(false,(false,l)))))
8420         | ([#"l",#"d",#"t",#"r",#"s",#"b"],l) =>
8421           p_ldr_str(0,(MemOp_LOAD,(AccType_UNPRIV,(true,(false,l)))))
8422         | ([#"l",#"d",#"t",#"r",#"s",#"h"],l) =>
8423           p_ldr_str(1,(MemOp_LOAD,(AccType_UNPRIV,(true,(false,l)))))
8424         | ([#"l",#"d",#"t",#"r",#"s",#"w"],l) =>
8425           p_ldr_str(2,(MemOp_LOAD,(AccType_UNPRIV,(true,(false,l)))))
8426         | ([#"s",#"t",#"r",#"b"],l) =>
8427           p_ldr_str(0,(MemOp_STORE,(AccType_NORMAL,(false,(true,l)))))
8428         | ([#"s",#"t",#"r",#"h"],l) =>
8429           p_ldr_str(1,(MemOp_STORE,(AccType_NORMAL,(false,(true,l)))))
8430         | ([#"s",#"t",#"r"],l) =>
8431           p_ldr_str(2,(MemOp_STORE,(AccType_NORMAL,(false,(true,l)))))
8432         | ([#"s",#"t",#"u",#"r",#"b"],l) =>
8433           p_ldr_str(0,(MemOp_STORE,(AccType_NORMAL,(false,(false,l)))))
8434         | ([#"s",#"t",#"u",#"r",#"h"],l) =>
8435           p_ldr_str(1,(MemOp_STORE,(AccType_NORMAL,(false,(false,l)))))
8436         | ([#"s",#"t",#"u",#"r"],l) =>
8437           p_ldr_str(2,(MemOp_STORE,(AccType_NORMAL,(false,(false,l)))))
8438         | ([#"s",#"t",#"t",#"r",#"b"],l) =>
8439           p_ldr_str(0,(MemOp_STORE,(AccType_UNPRIV,(false,(false,l)))))
8440         | ([#"s",#"t",#"t",#"r",#"h"],l) =>
8441           p_ldr_str(1,(MemOp_STORE,(AccType_UNPRIV,(false,(false,l)))))
8442         | ([#"s",#"t",#"t",#"r"],l) =>
8443           p_ldr_str(2,(MemOp_STORE,(AccType_UNPRIV,(false,(false,l)))))
8444         | ([#"l",#"d",#"a",#"r",#"b"],l) =>
8445           p_ldar_stlr(0,(MemOp_LOAD,(AccType_ORDERED,(false,l))))
8446         | ([#"l",#"d",#"a",#"r",#"h"],l) =>
8447           p_ldar_stlr(1,(MemOp_LOAD,(AccType_ORDERED,(false,l))))
8448         | ([#"l",#"d",#"a",#"r"],l) =>
8449           p_ldar_stlr(2,(MemOp_LOAD,(AccType_ORDERED,(false,l))))
8450         | ([#"l",#"d",#"a",#"x",#"r",#"b"],l) =>
8451           p_ldar_stlr(0,(MemOp_LOAD,(AccType_ORDERED,(true,l))))
8452         | ([#"l",#"d",#"a",#"x",#"r",#"h"],l) =>
8453           p_ldar_stlr(1,(MemOp_LOAD,(AccType_ORDERED,(true,l))))
8454         | ([#"l",#"d",#"a",#"x",#"r"],l) =>
8455           p_ldar_stlr(2,(MemOp_LOAD,(AccType_ORDERED,(true,l))))
8456         | ([#"l",#"d",#"x",#"r",#"b"],l) =>
8457           p_ldar_stlr(0,(MemOp_LOAD,(AccType_ATOMIC,(true,l))))
8458         | ([#"l",#"d",#"x",#"r",#"h"],l) =>
8459           p_ldar_stlr(1,(MemOp_LOAD,(AccType_ATOMIC,(true,l))))
8460         | ([#"l",#"d",#"x",#"r"],l) =>
8461           p_ldar_stlr(2,(MemOp_LOAD,(AccType_ATOMIC,(true,l))))
8462         | ([#"s",#"t",#"l",#"r",#"b"],l) =>
8463           p_ldar_stlr(0,(MemOp_STORE,(AccType_ORDERED,(false,l))))
8464         | ([#"s",#"t",#"l",#"r",#"h"],l) =>
8465           p_ldar_stlr(1,(MemOp_STORE,(AccType_ORDERED,(false,l))))
8466         | ([#"s",#"t",#"l",#"r"],l) =>
8467           p_ldar_stlr(2,(MemOp_STORE,(AccType_ORDERED,(false,l))))
8468         | ([#"s",#"t",#"l",#"x",#"r",#"b"],l) =>
8469           p_ldar_stlr(0,(MemOp_STORE,(AccType_ORDERED,(true,l))))
8470         | ([#"s",#"t",#"l",#"x",#"r",#"h"],l) =>
8471           p_ldar_stlr(1,(MemOp_STORE,(AccType_ORDERED,(true,l))))
8472         | ([#"s",#"t",#"l",#"x",#"r"],l) =>
8473           p_ldar_stlr(2,(MemOp_STORE,(AccType_ORDERED,(true,l))))
8474         | ([#"s",#"t",#"x",#"r",#"b"],l) =>
8475           p_ldar_stlr(0,(MemOp_STORE,(AccType_ATOMIC,(true,l))))
8476         | ([#"s",#"t",#"x",#"r",#"h"],l) =>
8477           p_ldar_stlr(1,(MemOp_STORE,(AccType_ATOMIC,(true,l))))
8478         | ([#"s",#"t",#"x",#"r"],l) =>
8479           p_ldar_stlr(2,(MemOp_STORE,(AccType_ATOMIC,(true,l))))
8480         | ([#"l",#"d",#"n",#"p"],l) =>
8481           p_ldp_stp(MemOp_LOAD,(AccType_STREAM,(false,l)))
8482         | ([#"l",#"d",#"p"],l) =>
8483           p_ldp_stp(MemOp_LOAD,(AccType_NORMAL,(false,l)))
8484         | ([#"l",#"d",#"p",#"s",#"w"],l) =>
8485           p_ldp_stp(MemOp_LOAD,(AccType_NORMAL,(true,l)))
8486         | ([#"s",#"t",#"n",#"p"],l) =>
8487           p_ldp_stp(MemOp_STORE,(AccType_STREAM,(false,l)))
8488         | ([#"s",#"t",#"p"],l) =>
8489           p_ldp_stp(MemOp_STORE,(AccType_NORMAL,(false,l)))
8490         | ([#"l",#"d",#"a",#"x",#"p"],l) => p_ldxp(AccType_ORDERED,l)
8491         | ([#"l",#"d",#"x",#"p"],l) => p_ldxp(AccType_ATOMIC,l)
8492         | ([#"s",#"t",#"l",#"x",#"p"],l) => p_stxp(AccType_ORDERED,l)
8493         | ([#"s",#"t",#"x",#"p"],l) => p_stxp(AccType_ATOMIC,l)
8494         | ([#"c",#"b",#"n",#"z"],l) => p_cbz_cbnz(false,l)
8495         | ([#"c",#"b",#"z"],l) => p_cbz_cbnz(true,l)
8496         | ([#"t",#"b",#"n",#"z"],l) => p_tbz_tbnz(true,l)
8497         | ([#"t",#"b",#"z"],l) => p_tbz_tbnz(false,l)
8498         | ([#"b",#"r"],l) => p_br_etc(BranchType_JMP,l)
8499         | ([#"b",#"l",#"r"],l) => p_br_etc(BranchType_CALL,l)
8500         | ([#"r",#"e",#"t"],l) => p_br_etc(BranchType_RET,l)
8501         | ([#"h",#"l",#"t"],l) => p_call(0,l)
8502         | ([#"d",#"c",#"p",#"s",#"1"],l) => p_call(1,l)
8503         | ([#"d",#"c",#"p",#"s",#"2"],l) => p_call(2,l)
8504         | ([#"d",#"c",#"p",#"s",#"3"],l) => p_call(3,l)
8505         | ([#"b",#"r",#"k"],l) => p_call(4,l)
8506         | ([#"s",#"v",#"c"],l) => p_call(5,l)
8507         | ([#"h",#"v",#"c"],l) => p_call(6,l)
8508         | ([#"s",#"m",#"c"],l) => p_call(7,l)
8509         | ([#"b",#".",c1,c2],l) =>
8510           (case p_cond(String.implode[c1,c2]) of
8511               Option.SOME cd => p_conditional_b(cd,l)
8512             | NONE => FAIL "Unrecognised mnemonic")
8513         | ([#"b",#"l"],l) => p_b_bl(BranchType_CALL,l)
8514         | ([#"b"],l) => p_b_bl(BranchType_JMP,l)
8515         | ([#"d",#"m",#"b"],l) => p_dmb_etc(MemBarrierOp_DMB,l)
8516         | ([#"d",#"s",#"b"],l) => p_dmb_etc(MemBarrierOp_DSB,l)
8517         | ([#"i",#"s",#"b"],l) => p_dmb_etc(MemBarrierOp_ISB,l)
8518         | ([#"h",#"i",#"n",#"t"],l) => p_hint l
8519         | ([#"c",#"l",#"r",#"e",#"x"],l) => p_clrex l
8520         | ([#"y",#"i",#"e",#"l",#"d"],[]) => OK(Hint SystemHintOp_YIELD)
8521         | ([#"n",#"o",#"p"],[]) => OK(Hint SystemHintOp_NOP)
8522         | ([#"w",#"f",#"e"],[]) => OK(Hint SystemHintOp_WFE)
8523         | ([#"w",#"f",#"i"],[]) => OK(Hint SystemHintOp_WFI)
8524         | ([#"s",#"e",#"v"],[]) => OK(Hint SystemHintOp_SEV)
8525         | ([#"s",#"e",#"v",#"l"],[]) => OK(Hint SystemHintOp_SEVL)
8526         | ([#"e",#"r",#"e",#"t"],[]) => OK(System ExceptionReturn)
8527         | ([#"d",#"r",#"p",#"s"],[]) => OK(Debug DebugRestore)
8528         | ([#"w",#"o",#"r",#"d"],[w]) =>
8529           (case p_encode_immediate 32 w of
8530               Option.SOME(true,w) => WORD w
8531             | Option.SOME _ => FAIL "immediate too large"
8532             | NONE => FAIL "syntax error: word")
8533         | _ => FAIL "Unrecognised mnemonic")
8534   | _ => FAIL "Unrecognised mnemonic";
8535
8536fun EncodeARM s =
8537  case instructionFromString s of
8538     OK ast =>
8539       (case Encode ast of
8540           ARM8 w =>
8541             ("",
8542              Option.SOME(L3.padLeftString(#"0",(8,BitsN.toHexString w))))
8543         | BadCode err => ("Encode error: " ^ err,NONE))
8544   | PENDING _ => ("Contains label",NONE)
8545   | WORD w =>
8546     ("",Option.SOME(L3.padLeftString(#"0",(8,BitsN.toHexString w))))
8547   | FAIL err => ("Parse error: " ^ err,NONE);
8548
8549fun s_cond c =
8550  case c of
8551     BitsN.B(0x0,_) => "eq"
8552   | BitsN.B(0x1,_) => "ne"
8553   | BitsN.B(0x2,_) => "cs"
8554   | BitsN.B(0x3,_) => "cc"
8555   | BitsN.B(0x4,_) => "mi"
8556   | BitsN.B(0x5,_) => "pl"
8557   | BitsN.B(0x6,_) => "vs"
8558   | BitsN.B(0x7,_) => "vc"
8559   | BitsN.B(0x8,_) => "hi"
8560   | BitsN.B(0x9,_) => "ls"
8561   | BitsN.B(0xA,_) => "ge"
8562   | BitsN.B(0xB,_) => "lt"
8563   | BitsN.B(0xC,_) => "gt"
8564   | BitsN.B(0xD,_) => "le"
8565   | BitsN.B(0xE,_) => "al"
8566   | BitsN.B(0xF,_) => "15"
8567   | _ => raise General.Bind;
8568
8569fun s_regz (wide,r) =
8570  (if wide then "x" else "w")
8571    ^
8572    (if r = (BitsN.B(0x1F,5)) then "zr" else Nat.toString(BitsN.toNat r));
8573
8574fun s_regp (wide,r) =
8575  if r = (BitsN.B(0x1F,5))
8576    then if wide then "sp" else "wsp"
8577  else s_regz(wide,r);
8578
8579fun s_reg2z (wide,(r1,r2)) =
8580  String.concat[s_regz(wide,r1),", ",s_regz(wide,r2)];
8581
8582fun s_reg3z (wide,(r1,(r2,r3))) =
8583  String.concat[s_reg2z(wide,(r1,r2)),", ",s_regz(wide,r3)];
8584
8585fun s_reg4z (wide,(r1,(r2,(r3,r4)))) =
8586  String.concat[s_reg3z(wide,(r1,(r2,r3))),", ",s_regz(wide,r4)];
8587
8588fun s_nat v = "#" ^ (Nat.toString v);
8589
8590fun s_dec N v = s_nat(BitsN.toNat v);
8591
8592fun s_hex N v =
8593  if BitsN.<+(v,BitsN.BV(0x64,N))
8594    then s_dec N v
8595  else "#0x" ^ (BitsN.toHexString v);
8596
8597fun s_immn v = ", " ^ (s_nat v);
8598
8599fun s_imm N v = ", " ^ (s_hex N v);
8600
8601fun s_offset imm =
8602  if BitsN.<(imm,BitsN.B(0x0,64))
8603    then "-" ^ (s_hex 64 (BitsN.neg imm))
8604  else "+" ^ (s_hex 64 imm);
8605
8606fun s_signed_imm imm =
8607  case String.explode(s_offset imm) of
8608     #"+" :: (#"#" :: a) => ", #" ^ (String.implode a)
8609   | #"-" :: (#"#" :: a) => ", #-" ^ (String.implode a)
8610   | s => String.implode s;
8611
8612fun s_shifted_imm N imm =
8613  let
8614    val top = BitsN.>>+(imm,12)
8615  in
8616    if (not(top = (BitsN.BV(0x0,N)))) andalso
8617       ((BitsN.bits(11,0) imm) = (BitsN.B(0x0,12)))
8618      then (s_imm N top) ^ ", lsl #12"
8619    else s_imm N imm
8620  end;
8621
8622fun s_extend_type extend_type =
8623  case extend_type of
8624     ExtendType_UXTB => "uxtb"
8625   | ExtendType_UXTH => "uxth"
8626   | ExtendType_UXTW => "uxtw"
8627   | ExtendType_UXTX => "uxtx"
8628   | ExtendType_SXTB => "sxtb"
8629   | ExtendType_SXTH => "sxth"
8630   | ExtendType_SXTW => "sxtw"
8631   | ExtendType_SXTX => "sxtx";
8632
8633fun s_shift_type shift_type =
8634  case shift_type of
8635     ShiftType_LSL => "lsl"
8636   | ShiftType_LSR => "lsr"
8637   | ShiftType_ASR => "asr"
8638   | ShiftType_ROR => "ror";
8639
8640fun s_move_wide_op opc =
8641  case opc of
8642     MoveWideOp_N => "movn"
8643   | MoveWideOp_Z => "movz"
8644   | MoveWideOp_K => "movk";
8645
8646fun s_logical_op opc =
8647  case opc of
8648     LogicalOp_AND => "and"
8649   | LogicalOp_ORR => "orr"
8650   | LogicalOp_EOR => "eor";
8651
8652fun s_invert_logical_op opc =
8653  case opc of
8654     LogicalOp_AND => "bic"
8655   | LogicalOp_ORR => "orn"
8656   | LogicalOp_EOR => "eon";
8657
8658fun s_rev_op opc =
8659  case opc of
8660     RevOp_RBIT => "rbit"
8661   | RevOp_REV16 => "rev16"
8662   | RevOp_REV32 => "rev32"
8663   | RevOp_REV64 => "rev";
8664
8665fun s_hint_op opc =
8666  case opc of
8667     SystemHintOp_NOP => "nop"
8668   | SystemHintOp_YIELD => "yield"
8669   | SystemHintOp_WFE => "wfe"
8670   | SystemHintOp_WFI => "wfi"
8671   | SystemHintOp_SEV => "sev"
8672   | SystemHintOp_SEVL => "sevl";
8673
8674fun s_barrier_op opc =
8675  case opc of
8676     MemBarrierOp_DSB => "dsb"
8677   | MemBarrierOp_DMB => "dmb"
8678   | MemBarrierOp_ISB => "isb";
8679
8680fun s_shift_amount (shift_type,sh) =
8681  if (sh = 0) andalso (shift_type = ShiftType_LSL)
8682    then ""
8683  else String.concat[", ",s_shift_type shift_type," ",s_nat sh];
8684
8685fun s_nzcv (n,(z,(c,v))) =
8686  ", "
8687    ^
8688    (s_dec 4
8689       (BitsN.concat
8690          [BitsN.fromBit n,BitsN.fromBit z,BitsN.fromBit c,BitsN.fromBit v]));
8691
8692fun s_data ast =
8693  case ast of
8694     AddSubCarry''32(sf,(sub_op,(setflags,(m,(n,d))))) =>
8695       let
8696         val wide = (BitsN.size sf) = 64
8697         val sfx = if setflags then "s" else ""
8698       in
8699         if sub_op andalso (n = (BitsN.B(0x1F,5)))
8700           then ("ngc" ^ sfx,s_reg2z(wide,(d,m)))
8701         else ((if sub_op then "sbc" else "adc") ^ sfx,
8702               s_reg3z(wide,(d,(n,m))))
8703       end
8704   | AddSubCarry''64(sf,(sub_op,(setflags,(m,(n,d))))) =>
8705     let
8706       val wide = (BitsN.size sf) = 64
8707       val sfx = if setflags then "s" else ""
8708     in
8709       if sub_op andalso (n = (BitsN.B(0x1F,5)))
8710         then ("ngc" ^ sfx,s_reg2z(wide,(d,m)))
8711       else ((if sub_op then "sbc" else "adc") ^ sfx,
8712             s_reg3z(wide,(d,(n,m))))
8713     end
8714   | AddSubExtendRegister''32
8715     (sf,(sub_op,(setflags,(m,(extend_type,(imm3,(n,d))))))) =>
8716     let
8717       val wide = (BitsN.size sf) = 64
8718     in
8719       ((if sub_op then "sub" else "add") ^ (if setflags then "s" else ""),
8720        String.concat
8721          [if setflags then s_regz(wide,d) else s_regp(wide,d),", ",
8722           s_regp(wide,n),", ",
8723           s_regz
8724             (wide andalso
8725              (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX])),m),
8726           if ((n = (BitsN.B(0x1F,5))) orelse
8727               ((not setflags) andalso (d = (BitsN.B(0x1F,5))))) andalso
8728              ((wide andalso (extend_type = ExtendType_UXTX)) orelse
8729               ((not wide) andalso (extend_type = ExtendType_UXTW)))
8730             then if imm3 = (BitsN.B(0x0,3))
8731                    then ""
8732                  else ", lsl " ^ (s_dec 3 imm3)
8733           else String.concat
8734                  [", ",s_extend_type extend_type," ",s_dec 3 imm3]])
8735     end
8736   | AddSubExtendRegister''64
8737     (sf,(sub_op,(setflags,(m,(extend_type,(imm3,(n,d))))))) =>
8738     let
8739       val wide = (BitsN.size sf) = 64
8740     in
8741       ((if sub_op then "sub" else "add") ^ (if setflags then "s" else ""),
8742        String.concat
8743          [if setflags then s_regz(wide,d) else s_regp(wide,d),", ",
8744           s_regp(wide,n),", ",
8745           s_regz
8746             (wide andalso
8747              (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX])),m),
8748           if ((n = (BitsN.B(0x1F,5))) orelse
8749               ((not setflags) andalso (d = (BitsN.B(0x1F,5))))) andalso
8750              ((wide andalso (extend_type = ExtendType_UXTX)) orelse
8751               ((not wide) andalso (extend_type = ExtendType_UXTW)))
8752             then if imm3 = (BitsN.B(0x0,3))
8753                    then ""
8754                  else ", lsl " ^ (s_dec 3 imm3)
8755           else String.concat
8756                  [", ",s_extend_type extend_type," ",s_dec 3 imm3]])
8757     end
8758   | AddSubImmediate''32(sf,(sub_op,(setflags,(imm,(n,d))))) =>
8759     let
8760       val wide = (BitsN.size sf) = 64
8761     in
8762       if (not(sub_op orelse setflags)) andalso
8763          (((n = (BitsN.B(0x1F,5))) orelse (d = (BitsN.B(0x1F,5)))) andalso
8764           (imm = (BitsN.B(0x0,32))))
8765         then ("mov",String.concat[s_regp(wide,d),", ",s_regp(wide,n)])
8766       else if setflags andalso (d = (BitsN.B(0x1F,5)))
8767         then (if sub_op then "cmp" else "cmn",
8768               (s_regp(wide,n)) ^ (s_shifted_imm 32 imm))
8769       else ((if sub_op then "sub" else "add")
8770               ^
8771               (if setflags then "s" else ""),
8772             String.concat
8773               [if setflags then s_regz(wide,d) else s_regp(wide,d),", ",
8774                s_regp(wide,n),s_shifted_imm 32 imm])
8775     end
8776   | AddSubImmediate''64(sf,(sub_op,(setflags,(imm,(n,d))))) =>
8777     let
8778       val wide = (BitsN.size sf) = 64
8779     in
8780       if (not(sub_op orelse setflags)) andalso
8781          (((n = (BitsN.B(0x1F,5))) orelse (d = (BitsN.B(0x1F,5)))) andalso
8782           (imm = (BitsN.B(0x0,64))))
8783         then ("mov",String.concat[s_regp(wide,d),", ",s_regp(wide,n)])
8784       else if setflags andalso (d = (BitsN.B(0x1F,5)))
8785         then (if sub_op then "cmp" else "cmn",
8786               (s_regp(wide,n)) ^ (s_shifted_imm 64 imm))
8787       else ((if sub_op then "sub" else "add")
8788               ^
8789               (if setflags then "s" else ""),
8790             String.concat
8791               [if setflags then s_regz(wide,d) else s_regp(wide,d),", ",
8792                s_regp(wide,n),s_shifted_imm 64 imm])
8793     end
8794   | AddSubShiftedRegister''32
8795     (sf,(sub_op,(setflags,(shift_type,(m,(imm,(n,d))))))) =>
8796     let
8797       val wide = (BitsN.size sf) = 64
8798     in
8799       if setflags andalso (d = (BitsN.B(0x1F,5)))
8800         then (if sub_op then "cmp" else "cmn",
8801               (s_reg2z(wide,(n,m)))
8802                 ^
8803                 (s_shift_amount(shift_type,BitsN.toNat imm)))
8804       else ((if sub_op then "sub" else "add")
8805               ^
8806               (if setflags then "s" else ""),
8807             (s_reg3z(wide,(d,(n,m))))
8808               ^
8809               (s_shift_amount(shift_type,BitsN.toNat imm)))
8810     end
8811   | AddSubShiftedRegister''64
8812     (sf,(sub_op,(setflags,(shift_type,(m,(imm,(n,d))))))) =>
8813     let
8814       val wide = (BitsN.size sf) = 64
8815     in
8816       if setflags andalso (d = (BitsN.B(0x1F,5)))
8817         then (if sub_op then "cmp" else "cmn",
8818               (s_reg2z(wide,(n,m)))
8819                 ^
8820                 (s_shift_amount(shift_type,BitsN.toNat imm)))
8821       else ((if sub_op then "sub" else "add")
8822               ^
8823               (if setflags then "s" else ""),
8824             (s_reg3z(wide,(d,(n,m))))
8825               ^
8826               (s_shift_amount(shift_type,BitsN.toNat imm)))
8827     end
8828   | LogicalImmediate''32(sf,(opc,(setflags,(imm,(n,d))))) =>
8829     let
8830       val wide = (BitsN.size sf) = 64
8831     in
8832       if (opc = LogicalOp_ORR) andalso (n = (BitsN.B(0x1F,5)))
8833         then ("mov",(s_regp(wide,d)) ^ (s_imm 32 imm))
8834       else ((s_logical_op opc) ^ (if setflags then "s" else ""),
8835             String.concat
8836               [if setflags then s_regz(wide,d) else s_regp(wide,d),", ",
8837                s_regz(wide,n),s_imm 32 imm])
8838     end
8839   | LogicalImmediate''64(sf,(opc,(setflags,(imm,(n,d))))) =>
8840     let
8841       val wide = (BitsN.size sf) = 64
8842     in
8843       if (opc = LogicalOp_ORR) andalso (n = (BitsN.B(0x1F,5)))
8844         then ("mov",(s_regp(wide,d)) ^ (s_imm 64 imm))
8845       else ((s_logical_op opc) ^ (if setflags then "s" else ""),
8846             String.concat
8847               [if setflags then s_regz(wide,d) else s_regp(wide,d),", ",
8848                s_regz(wide,n),s_imm 64 imm])
8849     end
8850   | LogicalShiftedRegister''32
8851     (sf,(opc,(invert,(setflags,(shift_type,(imm,(m,(n,d)))))))) =>
8852     let
8853       val wide = (BitsN.size sf) = 64
8854     in
8855       if (opc = LogicalOp_ORR) andalso
8856          ((n = (BitsN.B(0x1F,5))) andalso
8857           ((shift_type = ShiftType_LSL) andalso (imm = 0)))
8858         then (if invert then "mvn" else "mov",
8859               (s_reg2z(wide,(d,m))) ^ (s_shift_amount(shift_type,imm)))
8860       else if (opc = LogicalOp_AND) andalso
8861          ((not invert) andalso (setflags andalso (d = (BitsN.B(0x1F,5)))))
8862         then ("tst",
8863               (s_reg2z(wide,(n,m))) ^ (s_shift_amount(shift_type,imm)))
8864       else ((if invert then s_invert_logical_op opc else s_logical_op opc)
8865               ^
8866               (if setflags then "s" else ""),
8867             (s_reg3z(wide,(d,(n,m)))) ^ (s_shift_amount(shift_type,imm)))
8868     end
8869   | LogicalShiftedRegister''64
8870     (sf,(opc,(invert,(setflags,(shift_type,(imm,(m,(n,d)))))))) =>
8871     let
8872       val wide = (BitsN.size sf) = 64
8873     in
8874       if (opc = LogicalOp_ORR) andalso
8875          ((n = (BitsN.B(0x1F,5))) andalso
8876           ((shift_type = ShiftType_LSL) andalso (imm = 0)))
8877         then (if invert then "mvn" else "mov",
8878               (s_reg2z(wide,(d,m))) ^ (s_shift_amount(shift_type,imm)))
8879       else if (opc = LogicalOp_AND) andalso
8880          ((not invert) andalso (setflags andalso (d = (BitsN.B(0x1F,5)))))
8881         then ("tst",
8882               (s_reg2z(wide,(n,m))) ^ (s_shift_amount(shift_type,imm)))
8883       else ((if invert then s_invert_logical_op opc else s_logical_op opc)
8884               ^
8885               (if setflags then "s" else ""),
8886             (s_reg3z(wide,(d,(n,m)))) ^ (s_shift_amount(shift_type,imm)))
8887     end
8888   | Shift''32(sf,(shift_type,(m,(n,d)))) =>
8889     (s_shift_type shift_type,s_reg3z((BitsN.size sf) = 64,(d,(n,m))))
8890   | Shift''64(sf,(shift_type,(m,(n,d)))) =>
8891     (s_shift_type shift_type,s_reg3z((BitsN.size sf) = 64,(d,(n,m))))
8892   | MoveWide''32(sf,(opc,(hw,(imm,d)))) =>
8893     let
8894       val wide = (BitsN.size sf) = 64
8895       val sh = Nat.*(BitsN.toNat hw,16)
8896     in
8897       if (opc = MoveWideOp_Z) andalso
8898          ((not(imm = (BitsN.B(0x0,16)))) orelse (hw = (BitsN.B(0x0,2))))
8899         then ("mov",
8900               (s_regz(wide,d))
8901                 ^
8902                 (s_imm 64
8903                    (BitsN.<<(BitsN.fromNat(BitsN.toNat imm,64),sh))))
8904       else if (opc = MoveWideOp_N) andalso
8905          (((not(imm = (BitsN.B(0x0,16)))) orelse (hw = (BitsN.B(0x0,2)))) andalso
8906           ((not wide) orelse (not(imm = (BitsN.neg(BitsN.B(0x1,16)))))))
8907         then ("mov",
8908               (s_regz(wide,d))
8909                 ^
8910                 (if wide
8911                    then s_imm 64
8912                           (BitsN.~
8913                              (BitsN.<<
8914                                 (BitsN.fromNat(BitsN.toNat imm,64),sh)))
8915                  else s_imm 32
8916                         (BitsN.~
8917                            (BitsN.<<
8918                               (BitsN.fromNat(BitsN.toNat imm,32),sh)))))
8919       else (s_move_wide_op opc,
8920             String.concat
8921               [s_regz(wide,d),s_imm 16 imm,
8922                if hw = (BitsN.B(0x0,2))
8923                  then ""
8924                else ", lsl " ^ (s_nat sh)])
8925     end
8926   | MoveWide''64(sf,(opc,(hw,(imm,d)))) =>
8927     let
8928       val wide = (BitsN.size sf) = 64
8929       val sh = Nat.*(BitsN.toNat hw,16)
8930     in
8931       if (opc = MoveWideOp_Z) andalso
8932          ((not(imm = (BitsN.B(0x0,16)))) orelse (hw = (BitsN.B(0x0,2))))
8933         then ("mov",
8934               (s_regz(wide,d))
8935                 ^
8936                 (s_imm 64
8937                    (BitsN.<<(BitsN.fromNat(BitsN.toNat imm,64),sh))))
8938       else if (opc = MoveWideOp_N) andalso
8939          (((not(imm = (BitsN.B(0x0,16)))) orelse (hw = (BitsN.B(0x0,2)))) andalso
8940           ((not wide) orelse (not(imm = (BitsN.neg(BitsN.B(0x1,16)))))))
8941         then ("mov",
8942               (s_regz(wide,d))
8943                 ^
8944                 (if wide
8945                    then s_imm 64
8946                           (BitsN.~
8947                              (BitsN.<<
8948                                 (BitsN.fromNat(BitsN.toNat imm,64),sh)))
8949                  else s_imm 32
8950                         (BitsN.~
8951                            (BitsN.<<
8952                               (BitsN.fromNat(BitsN.toNat imm,32),sh)))))
8953       else (s_move_wide_op opc,
8954             String.concat
8955               [s_regz(wide,d),s_imm 16 imm,
8956                if hw = (BitsN.B(0x0,2))
8957                  then ""
8958                else ", lsl " ^ (s_nat sh)])
8959     end
8960   | BitfieldMove''32(sf,(inzero,(extend,(wmask,(tmask,(r,(s,(n,d)))))))) =>
8961     let
8962       val wide = (BitsN.size sf) = 64
8963       val dn = s_reg2z(wide,(d,n))
8964     in
8965       case (inzero,extend) of
8966          (false,false) =>
8967            if Nat.<(s,r)
8968              then ("bfi",
8969                    String.concat
8970                      [dn,", ",
8971                       if wide
8972                         then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6)))
8973                       else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))),
8974                       s_immn(Nat.+(s,1))])
8975            else ("bfxil",
8976                  String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))])
8977        | (true,false) =>
8978          if (wide andalso (s = 63)) orelse ((not wide) andalso (s = 31))
8979            then ("lsr",dn ^ (s_immn r))
8980          else if (Nat.+(s,1)) = r
8981            then ("lsl",dn ^ (s_immn(Nat.-(if wide then 63 else 31,s))))
8982          else if (r = 0) andalso (s = 7)
8983            then ("uxtb",s_reg2z(false,(d,n)))
8984          else if (r = 0) andalso (s = 15)
8985            then ("uxth",s_reg2z(false,(d,n)))
8986          else if Nat.<(s,r)
8987            then ("ubfiz",
8988                  String.concat
8989                    [dn,", ",
8990                     if wide
8991                       then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6)))
8992                     else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))),
8993                     s_immn(Nat.+(s,1))])
8994          else ("ubfx",
8995                String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))])
8996        | (true,true) =>
8997          if (wide andalso (s = 63)) orelse ((not wide) andalso (s = 31))
8998            then ("asr",dn ^ (s_immn r))
8999          else if (r = 0) andalso (s = 7)
9000            then ("sxtb",dn)
9001          else if (r = 0) andalso (s = 15)
9002            then ("sxth",dn)
9003          else if (r = 0) andalso (s = 31)
9004            then ("sxtw",dn)
9005          else if Nat.<(s,r)
9006            then ("sbfiz",
9007                  String.concat
9008                    [dn,", ",
9009                     if wide
9010                       then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6)))
9011                     else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))),
9012                     s_immn(Nat.+(s,1))])
9013          else ("sbfx",
9014                String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))])
9015        | _ => ("??","")
9016     end
9017   | BitfieldMove''64(sf,(inzero,(extend,(wmask,(tmask,(r,(s,(n,d)))))))) =>
9018     let
9019       val wide = (BitsN.size sf) = 64
9020       val dn = s_reg2z(wide,(d,n))
9021     in
9022       case (inzero,extend) of
9023          (false,false) =>
9024            if Nat.<(s,r)
9025              then ("bfi",
9026                    String.concat
9027                      [dn,", ",
9028                       if wide
9029                         then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6)))
9030                       else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))),
9031                       s_immn(Nat.+(s,1))])
9032            else ("bfxil",
9033                  String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))])
9034        | (true,false) =>
9035          if (wide andalso (s = 63)) orelse ((not wide) andalso (s = 31))
9036            then ("lsr",dn ^ (s_immn r))
9037          else if (Nat.+(s,1)) = r
9038            then ("lsl",dn ^ (s_immn(Nat.-(if wide then 63 else 31,s))))
9039          else if (r = 0) andalso (s = 7)
9040            then ("uxtb",s_reg2z(false,(d,n)))
9041          else if (r = 0) andalso (s = 15)
9042            then ("uxth",s_reg2z(false,(d,n)))
9043          else if Nat.<(s,r)
9044            then ("ubfiz",
9045                  String.concat
9046                    [dn,", ",
9047                     if wide
9048                       then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6)))
9049                     else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))),
9050                     s_immn(Nat.+(s,1))])
9051          else ("ubfx",
9052                String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))])
9053        | (true,true) =>
9054          if (wide andalso (s = 63)) orelse ((not wide) andalso (s = 31))
9055            then ("asr",dn ^ (s_immn r))
9056          else if (r = 0) andalso (s = 7)
9057            then ("sxtb",dn)
9058          else if (r = 0) andalso (s = 15)
9059            then ("sxth",dn)
9060          else if (r = 0) andalso (s = 31)
9061            then ("sxtw",dn)
9062          else if Nat.<(s,r)
9063            then ("sbfiz",
9064                  String.concat
9065                    [dn,", ",
9066                     if wide
9067                       then s_dec 6 (BitsN.neg(BitsN.fromNat(r,6)))
9068                     else s_dec 5 (BitsN.neg(BitsN.fromNat(r,5))),
9069                     s_immn(Nat.+(s,1))])
9070          else ("sbfx",
9071                String.concat[dn,s_immn r,s_immn(Nat.+(Nat.-(s,r),1))])
9072        | _ => ("??","")
9073     end
9074   | ConditionalCompareImmediate''32(sf,(sub_op,(imm,(cd,(nzcv,n))))) =>
9075     let
9076       val wide = (BitsN.size sf) = 64
9077     in
9078       (if sub_op then "ccmp" else "ccmn",
9079        String.concat
9080          [s_regz(wide,n),s_imm 32 imm,s_nzcv nzcv,", ",s_cond cd])
9081     end
9082   | ConditionalCompareImmediate''64(sf,(sub_op,(imm,(cd,(nzcv,n))))) =>
9083     let
9084       val wide = (BitsN.size sf) = 64
9085     in
9086       (if sub_op then "ccmp" else "ccmn",
9087        String.concat
9088          [s_regz(wide,n),s_imm 64 imm,s_nzcv nzcv,", ",s_cond cd])
9089     end
9090   | ConditionalCompareRegister''32(sf,(sub_op,(cd,(nzcv,(m,n))))) =>
9091     let
9092       val wide = (BitsN.size sf) = 64
9093     in
9094       (if sub_op then "ccmp" else "ccmn",
9095        String.concat[s_reg2z(wide,(n,m)),s_nzcv nzcv,", ",s_cond cd])
9096     end
9097   | ConditionalCompareRegister''64(sf,(sub_op,(cd,(nzcv,(m,n))))) =>
9098     let
9099       val wide = (BitsN.size sf) = 64
9100     in
9101       (if sub_op then "ccmp" else "ccmn",
9102        String.concat[s_reg2z(wide,(n,m)),s_nzcv nzcv,", ",s_cond cd])
9103     end
9104   | ConditionalSelect''32(sf,(else_inv,(else_inc,(cd,(m,(n,d)))))) =>
9105     let
9106       val wide = (BitsN.size sf) = 64
9107     in
9108       case (else_inv,else_inc) of
9109          (false,false) =>
9110            ("csel",String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd])
9111        | (false,true) =>
9112          if (n = m) andalso
9113             ((not(n = (BitsN.B(0x1F,5)))) andalso
9114              (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))))
9115            then ("cinc",
9116                  String.concat
9117                    [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)])
9118          else if (n = m) andalso
9119             ((n = (BitsN.B(0x1F,5))) andalso
9120              (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))))
9121            then ("cset",
9122                  String.concat
9123                    [s_regz(wide,d),", ",invert_cond(s_cond cd)])
9124          else ("csinc",
9125                String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd])
9126        | (true,false) =>
9127          if (n = m) andalso
9128             ((not(n = (BitsN.B(0x1F,5)))) andalso
9129              (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))))
9130            then ("cinv",
9131                  String.concat
9132                    [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)])
9133          else if (n = m) andalso
9134             ((n = (BitsN.B(0x1F,5))) andalso
9135              (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))))
9136            then ("csetm",
9137                  String.concat
9138                    [s_regz(wide,d),", ",invert_cond(s_cond cd)])
9139          else ("csinv",
9140                String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd])
9141        | (true,true) =>
9142          if (n = m) andalso
9143             (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))
9144            then ("cneg",
9145                  String.concat
9146                    [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)])
9147          else ("csneg",
9148                String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd])
9149     end
9150   | ConditionalSelect''64(sf,(else_inv,(else_inc,(cd,(m,(n,d)))))) =>
9151     let
9152       val wide = (BitsN.size sf) = 64
9153     in
9154       case (else_inv,else_inc) of
9155          (false,false) =>
9156            ("csel",String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd])
9157        | (false,true) =>
9158          if (n = m) andalso
9159             ((not(n = (BitsN.B(0x1F,5)))) andalso
9160              (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))))
9161            then ("cinc",
9162                  String.concat
9163                    [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)])
9164          else if (n = m) andalso
9165             ((n = (BitsN.B(0x1F,5))) andalso
9166              (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))))
9167            then ("cset",
9168                  String.concat
9169                    [s_regz(wide,d),", ",invert_cond(s_cond cd)])
9170          else ("csinc",
9171                String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd])
9172        | (true,false) =>
9173          if (n = m) andalso
9174             ((not(n = (BitsN.B(0x1F,5)))) andalso
9175              (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))))
9176            then ("cinv",
9177                  String.concat
9178                    [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)])
9179          else if (n = m) andalso
9180             ((n = (BitsN.B(0x1F,5))) andalso
9181              (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3)))))
9182            then ("csetm",
9183                  String.concat
9184                    [s_regz(wide,d),", ",invert_cond(s_cond cd)])
9185          else ("csinv",
9186                String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd])
9187        | (true,true) =>
9188          if (n = m) andalso
9189             (not((BitsN.bits(3,1) cd) = (BitsN.B(0x7,3))))
9190            then ("cneg",
9191                  String.concat
9192                    [s_reg2z(wide,(d,n)),", ",invert_cond(s_cond cd)])
9193          else ("csneg",
9194                String.concat[s_reg3z(wide,(d,(n,m))),", ",s_cond cd])
9195     end
9196   | CountLeading''32(sf,(count_clz,(n,d))) =>
9197     (if count_clz then "clz" else "cls",
9198      s_reg2z((BitsN.size sf) = 64,(d,n)))
9199   | CountLeading''64(sf,(count_clz,(n,d))) =>
9200     (if count_clz then "clz" else "cls",
9201      s_reg2z((BitsN.size sf) = 64,(d,n)))
9202   | ExtractRegister''32(sf,(imms,(m,(n,d)))) =>
9203     let
9204       val wide = (BitsN.size sf) = 64
9205     in
9206       if n = m
9207         then ("ror",String.concat[s_reg2z(wide,(d,n)),", ",s_dec 6 imms])
9208       else ("extr",
9209             String.concat[s_reg3z(wide,(d,(n,m))),", ",s_dec 6 imms])
9210     end
9211   | ExtractRegister''64(sf,(imms,(m,(n,d)))) =>
9212     let
9213       val wide = (BitsN.size sf) = 64
9214     in
9215       if n = m
9216         then ("ror",String.concat[s_reg2z(wide,(d,n)),", ",s_dec 6 imms])
9217       else ("extr",
9218             String.concat[s_reg3z(wide,(d,(n,m))),", ",s_dec 6 imms])
9219     end
9220   | Division''32(sf,(unsigned,(m,(n,d)))) =>
9221     (if unsigned then "udiv" else "sdiv",
9222      s_reg3z((BitsN.size sf) = 64,(d,(n,m))))
9223   | Division''64(sf,(unsigned,(m,(n,d)))) =>
9224     (if unsigned then "udiv" else "sdiv",
9225      s_reg3z((BitsN.size sf) = 64,(d,(n,m))))
9226   | MultiplyAddSub''32(sf,(sub_op,(m,(a,(n,d))))) =>
9227     let
9228       val wide = (BitsN.size sf) = 64
9229     in
9230       if a = (BitsN.B(0x1F,5))
9231         then (if sub_op then "mneg" else "mul",s_reg3z(wide,(d,(n,m))))
9232       else (if sub_op then "msub" else "madd",s_reg4z(wide,(d,(n,(m,a)))))
9233     end
9234   | MultiplyAddSub''64(sf,(sub_op,(m,(a,(n,d))))) =>
9235     let
9236       val wide = (BitsN.size sf) = 64
9237     in
9238       if a = (BitsN.B(0x1F,5))
9239         then (if sub_op then "mneg" else "mul",s_reg3z(wide,(d,(n,m))))
9240       else (if sub_op then "msub" else "madd",s_reg4z(wide,(d,(n,(m,a)))))
9241     end
9242   | MultiplyAddSubLong(sub_op,(signed,(m,(a,(n,d))))) =>
9243     let
9244       val pfx = if signed then "s" else "u"
9245     in
9246       if a = (BitsN.B(0x1F,5))
9247         then (pfx ^ (if sub_op then "mnegl" else "mull"),
9248               String.concat[s_regz(true,d),", ",s_reg2z(false,(n,m))])
9249       else (pfx ^ (if sub_op then "msubl" else "maddl"),
9250             String.concat
9251               [s_regz(true,d),", ",s_reg2z(false,(n,m)),", ",
9252                s_regz(true,a)])
9253     end
9254   | MultiplyHigh(signed,(m,(n,d))) =>
9255     (if signed then "smulh" else "umulh",s_reg3z(true,(d,(n,m))))
9256   | Reverse''32(sf,(opc,(n,d))) =>
9257     let
9258       val wide = (BitsN.size sf) = 64
9259     in
9260       (if (not wide) andalso (opc = RevOp_REV32)
9261          then "rev"
9262        else s_rev_op opc,s_reg2z(wide,(d,n)))
9263     end
9264   | Reverse''64(sf,(opc,(n,d))) =>
9265     let
9266       val wide = (BitsN.size sf) = 64
9267     in
9268       (if (not wide) andalso (opc = RevOp_REV32)
9269          then "rev"
9270        else s_rev_op opc,s_reg2z(wide,(d,n)))
9271     end;
9272
9273fun s_crc ast =
9274  case ast of
9275     CRC''8(_,(false,(m,(n,d)))) => ("crc32b",s_reg3z(false,(d,(n,m))))
9276   | CRC''16(_,(false,(m,(n,d)))) => ("crc32h",s_reg3z(false,(d,(n,m))))
9277   | CRC''32(_,(false,(m,(n,d)))) => ("crc32w",s_reg3z(false,(d,(n,m))))
9278   | CRC''64(_,(false,(m,(n,d)))) =>
9279     ("crc32x",String.concat[s_reg2z(false,(d,n)),", ",s_regz(true,m)])
9280   | CRC''8(_,(true,(m,(n,d)))) => ("crc32cb",s_reg3z(false,(d,(n,m))))
9281   | CRC''16(_,(true,(m,(n,d)))) => ("crc32ch",s_reg3z(false,(d,(n,m))))
9282   | CRC''32(_,(true,(m,(n,d)))) => ("crc32cw",s_reg3z(false,(d,(n,m))))
9283   | CRC''64(_,(true,(m,(n,d)))) =>
9284     ("crc32cx",String.concat[s_reg2z(false,(d,n)),", ",s_regz(true,m)]);
9285
9286fun s_branch ast =
9287  case ast of
9288     BranchConditional(offset,cd) => ("b." ^ (s_cond cd),s_offset offset)
9289   | BranchImmediate(offset,branch_type) =>
9290     (if branch_type = BranchType_CALL then "bl" else "b",s_offset offset)
9291   | BranchRegister(n,branch_type) =>
9292     (case branch_type of
9293         BranchType_JMP => "br"
9294       | BranchType_CALL => "blr"
9295       | BranchType_RET => "ret"
9296       | _ => "??",
9297      if (branch_type = BranchType_RET) andalso (n = (BitsN.B(0x1E,5)))
9298        then ""
9299      else s_regz(true,n))
9300   | CompareAndBranch''32(sf,(iszero,(offset,t))) =>
9301     let
9302       val wide = (BitsN.size sf) = 64
9303     in
9304       (if iszero then "cbz" else "cbnz",
9305        String.concat[s_regz(wide,t),", ",s_offset offset])
9306     end
9307   | CompareAndBranch''64(sf,(iszero,(offset,t))) =>
9308     let
9309       val wide = (BitsN.size sf) = 64
9310     in
9311       (if iszero then "cbz" else "cbnz",
9312        String.concat[s_regz(wide,t),", ",s_offset offset])
9313     end
9314   | TestBitAndBranch''32(sf,(bit_pos,(bit_val,(offset,t)))) =>
9315     let
9316       val wide = (BitsN.size sf) = 64
9317     in
9318       (if bit_val then "tbnz" else "tbz",
9319        String.concat
9320          [s_regz(wide,t),", ",s_dec 6 bit_pos,", ",s_offset offset])
9321     end
9322   | TestBitAndBranch''64(sf,(bit_pos,(bit_val,(offset,t)))) =>
9323     let
9324       val wide = (BitsN.size sf) = 64
9325     in
9326       (if bit_val then "tbnz" else "tbz",
9327        String.concat
9328          [s_regz(wide,t),", ",s_dec 6 bit_pos,", ",s_offset offset])
9329     end;
9330
9331fun s_debug ast =
9332  case ast of
9333     Halt imm => ("hlt",s_hex 16 imm)
9334   | DebugSwitch(BitsN.B(0x0,2)) => ("??","")
9335   | DebugSwitch LL => ("dcps" ^ (BitsN.toHexString LL),"")
9336   | DebugRestore => ("drps","")
9337   | Breakpoint imm => ("brk",s_hex 16 imm);
9338
9339fun s_system ast =
9340  case ast of
9341     ExceptionReturn => ("eret","")
9342   | SupervisorCall imm => ("svc",s_hex 16 imm)
9343   | HypervisorCall imm => ("hvc",s_hex 16 imm)
9344   | SecureMonitorCall imm => ("smc",s_hex 16 imm)
9345   | _ => ("?? system ??","");
9346
9347fun s_load_store ast =
9348  case ast of
9349     LoadStoreImmediate''8
9350       (size,
9351        (regsize_word,
9352         (memop,
9353          (acctype,
9354           (signed,
9355            (_,(_,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) =>
9356       (if memop = MemOp_PREFETCH
9357          then ("?? prefetch ??","")
9358        else let
9359               val N = BitsN.size size
9360               val wide =
9361                 (N = 64) orelse
9362                 (signed andalso ((N = 32) orelse (not regsize_word)))
9363               val sfx =
9364                 case N of
9365                    8 => "b"
9366                  | 16 => "h"
9367                  | 32 => if signed then "w" else ""
9368                  | _ => ""
9369             in
9370               (String.concat
9371                  [if memop = MemOp_LOAD then "ld" else "st",
9372                   if acctype = AccType_UNPRIV
9373                     then "t"
9374                   else if unsigned_offset orelse wback then "" else "u",
9375                   if signed then "rs" else "r",sfx],
9376                String.concat
9377                  [s_regz(wide,rt),", [",s_regp(true,rn),
9378                   if postindex
9379                     then "]" ^ (s_signed_imm offset)
9380                   else String.concat
9381                          [if offset = (BitsN.B(0x0,64))
9382                             then ""
9383                           else if unsigned_offset
9384                             then s_imm 64 offset
9385                           else s_signed_imm offset,"]",
9386                           if wback then "!" else ""]])
9387             end)
9388   | LoadStoreImmediate''16
9389     (size,
9390      (regsize_word,
9391       (memop,
9392        (acctype,
9393         (signed,
9394          (_,(_,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) =>
9395     (if memop = MemOp_PREFETCH
9396        then ("?? prefetch ??","")
9397      else let
9398             val N = BitsN.size size
9399             val wide =
9400               (N = 64) orelse
9401               (signed andalso ((N = 32) orelse (not regsize_word)))
9402             val sfx =
9403               case N of
9404                  8 => "b"
9405                | 16 => "h"
9406                | 32 => if signed then "w" else ""
9407                | _ => ""
9408           in
9409             (String.concat
9410                [if memop = MemOp_LOAD then "ld" else "st",
9411                 if acctype = AccType_UNPRIV
9412                   then "t"
9413                 else if unsigned_offset orelse wback then "" else "u",
9414                 if signed then "rs" else "r",sfx],
9415              String.concat
9416                [s_regz(wide,rt),", [",s_regp(true,rn),
9417                 if postindex
9418                   then "]" ^ (s_signed_imm offset)
9419                 else String.concat
9420                        [if offset = (BitsN.B(0x0,64))
9421                           then ""
9422                         else if unsigned_offset
9423                           then s_imm 64 offset
9424                         else s_signed_imm offset,"]",
9425                         if wback then "!" else ""]])
9426           end)
9427   | LoadStoreImmediate''32
9428     (size,
9429      (regsize_word,
9430       (memop,
9431        (acctype,
9432         (signed,
9433          (_,(_,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) =>
9434     (if memop = MemOp_PREFETCH
9435        then ("?? prefetch ??","")
9436      else let
9437             val N = BitsN.size size
9438             val wide =
9439               (N = 64) orelse
9440               (signed andalso ((N = 32) orelse (not regsize_word)))
9441             val sfx =
9442               case N of
9443                  8 => "b"
9444                | 16 => "h"
9445                | 32 => if signed then "w" else ""
9446                | _ => ""
9447           in
9448             (String.concat
9449                [if memop = MemOp_LOAD then "ld" else "st",
9450                 if acctype = AccType_UNPRIV
9451                   then "t"
9452                 else if unsigned_offset orelse wback then "" else "u",
9453                 if signed then "rs" else "r",sfx],
9454              String.concat
9455                [s_regz(wide,rt),", [",s_regp(true,rn),
9456                 if postindex
9457                   then "]" ^ (s_signed_imm offset)
9458                 else String.concat
9459                        [if offset = (BitsN.B(0x0,64))
9460                           then ""
9461                         else if unsigned_offset
9462                           then s_imm 64 offset
9463                         else s_signed_imm offset,"]",
9464                         if wback then "!" else ""]])
9465           end)
9466   | LoadStoreImmediate''64
9467     (size,
9468      (regsize_word,
9469       (memop,
9470        (acctype,
9471         (signed,
9472          (_,(_,(wback,(postindex,(unsigned_offset,(offset,(rn,rt)))))))))))) =>
9473     (if memop = MemOp_PREFETCH
9474        then ("?? prefetch ??","")
9475      else let
9476             val N = BitsN.size size
9477             val wide =
9478               (N = 64) orelse
9479               (signed andalso ((N = 32) orelse (not regsize_word)))
9480             val sfx =
9481               case N of
9482                  8 => "b"
9483                | 16 => "h"
9484                | 32 => if signed then "w" else ""
9485                | _ => ""
9486           in
9487             (String.concat
9488                [if memop = MemOp_LOAD then "ld" else "st",
9489                 if acctype = AccType_UNPRIV
9490                   then "t"
9491                 else if unsigned_offset orelse wback then "" else "u",
9492                 if signed then "rs" else "r",sfx],
9493              String.concat
9494                [s_regz(wide,rt),", [",s_regp(true,rn),
9495                 if postindex
9496                   then "]" ^ (s_signed_imm offset)
9497                 else String.concat
9498                        [if offset = (BitsN.B(0x0,64))
9499                           then ""
9500                         else if unsigned_offset
9501                           then s_imm 64 offset
9502                         else s_signed_imm offset,"]",
9503                         if wback then "!" else ""]])
9504           end)
9505   | LoadStoreRegister''8
9506     (size,
9507      (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) =>
9508     (if memop = MemOp_PREFETCH
9509        then ("?? prefetch ??","")
9510      else let
9511             val N = BitsN.size size
9512             val wide =
9513               (N = 64) orelse
9514               (signed andalso ((N = 32) orelse (not regsize_word)))
9515             val sfx =
9516               case N of
9517                  8 => "b"
9518                | 16 => "h"
9519                | 32 => if signed then "w" else ""
9520                | _ => ""
9521           in
9522             (String.concat
9523                [if memop = MemOp_LOAD then "ldr" else "str",
9524                 if signed then "s" else "",sfx],
9525              String.concat
9526                [s_regz(wide,rt),", [",s_regp(true,rn),", ",
9527                 s_regz
9528                   (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX]),
9529                    rm),
9530                 if extend_type = ExtendType_UXTX
9531                   then if shift = 0 then "" else ", lsl " ^ (s_nat shift)
9532                 else String.concat
9533                        [", ",s_extend_type extend_type," ",s_nat shift],
9534                 "]"])
9535           end)
9536   | LoadStoreRegister''16
9537     (size,
9538      (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) =>
9539     (if memop = MemOp_PREFETCH
9540        then ("?? prefetch ??","")
9541      else let
9542             val N = BitsN.size size
9543             val wide =
9544               (N = 64) orelse
9545               (signed andalso ((N = 32) orelse (not regsize_word)))
9546             val sfx =
9547               case N of
9548                  8 => "b"
9549                | 16 => "h"
9550                | 32 => if signed then "w" else ""
9551                | _ => ""
9552           in
9553             (String.concat
9554                [if memop = MemOp_LOAD then "ldr" else "str",
9555                 if signed then "s" else "",sfx],
9556              String.concat
9557                [s_regz(wide,rt),", [",s_regp(true,rn),", ",
9558                 s_regz
9559                   (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX]),
9560                    rm),
9561                 if extend_type = ExtendType_UXTX
9562                   then if shift = 0 then "" else ", lsl " ^ (s_nat shift)
9563                 else String.concat
9564                        [", ",s_extend_type extend_type," ",s_nat shift],
9565                 "]"])
9566           end)
9567   | LoadStoreRegister''32
9568     (size,
9569      (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) =>
9570     (if memop = MemOp_PREFETCH
9571        then ("?? prefetch ??","")
9572      else let
9573             val N = BitsN.size size
9574             val wide =
9575               (N = 64) orelse
9576               (signed andalso ((N = 32) orelse (not regsize_word)))
9577             val sfx =
9578               case N of
9579                  8 => "b"
9580                | 16 => "h"
9581                | 32 => if signed then "w" else ""
9582                | _ => ""
9583           in
9584             (String.concat
9585                [if memop = MemOp_LOAD then "ldr" else "str",
9586                 if signed then "s" else "",sfx],
9587              String.concat
9588                [s_regz(wide,rt),", [",s_regp(true,rn),", ",
9589                 s_regz
9590                   (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX]),
9591                    rm),
9592                 if extend_type = ExtendType_UXTX
9593                   then if shift = 0 then "" else ", lsl " ^ (s_nat shift)
9594                 else String.concat
9595                        [", ",s_extend_type extend_type," ",s_nat shift],
9596                 "]"])
9597           end)
9598   | LoadStoreRegister''64
9599     (size,
9600      (regsize_word,(memop,(signed,(rm,(extend_type,(shift,(rn,rt)))))))) =>
9601     (if memop = MemOp_PREFETCH
9602        then ("?? prefetch ??","")
9603      else let
9604             val N = BitsN.size size
9605             val wide =
9606               (N = 64) orelse
9607               (signed andalso ((N = 32) orelse (not regsize_word)))
9608             val sfx =
9609               case N of
9610                  8 => "b"
9611                | 16 => "h"
9612                | 32 => if signed then "w" else ""
9613                | _ => ""
9614           in
9615             (String.concat
9616                [if memop = MemOp_LOAD then "ldr" else "str",
9617                 if signed then "s" else "",sfx],
9618              String.concat
9619                [s_regz(wide,rt),", [",s_regp(true,rn),", ",
9620                 s_regz
9621                   (Set.mem(extend_type,[ExtendType_UXTX,ExtendType_SXTX]),
9622                    rm),
9623                 if extend_type = ExtendType_UXTX
9624                   then if shift = 0 then "" else ", lsl " ^ (s_nat shift)
9625                 else String.concat
9626                        [", ",s_extend_type extend_type," ",s_nat shift],
9627                 "]"])
9628           end)
9629   | LoadLiteral''32(size,(memop,(signed,(offset,rt)))) =>
9630     (if memop = MemOp_PREFETCH
9631        then ("?? prefetch ??","")
9632      else ("ldr" ^ (if signed then "sw" else ""),
9633            String.concat
9634              [s_regz(not(size = (BitsN.B(0x0,32))),rt),", ",
9635               s_offset offset]))
9636   | LoadLiteral''64(size,(memop,(signed,(offset,rt)))) =>
9637     (if memop = MemOp_PREFETCH
9638        then ("?? prefetch ??","")
9639      else ("ldr" ^ (if signed then "sw" else ""),
9640            String.concat
9641              [s_regz(not(size = (BitsN.B(0x0,64))),rt),", ",
9642               s_offset offset]))
9643   | LoadStorePair''32
9644     (size,
9645      (memop,
9646       (acctype,
9647        (signed,(_,(_,(wback,(postindex,(offset,(rn,(rt,rt2))))))))))) =>
9648     (String.concat
9649        [if memop = MemOp_LOAD then "ld" else "st",
9650         if acctype = AccType_STREAM then "np" else "p",
9651         if signed andalso (memop = MemOp_LOAD) then "sw" else ""],
9652      String.concat
9653        [s_reg2z(((BitsN.size size) = 64) orelse signed,(rt,rt2)),", [",
9654         s_regp(true,rn),
9655         if postindex
9656           then "]" ^ (s_signed_imm offset)
9657         else String.concat
9658                [if offset = (BitsN.B(0x0,64))
9659                   then ""
9660                 else s_signed_imm offset,"]",if wback then "!" else ""]])
9661   | LoadStorePair''64
9662     (size,
9663      (memop,
9664       (acctype,
9665        (signed,(_,(_,(wback,(postindex,(offset,(rn,(rt,rt2))))))))))) =>
9666     (String.concat
9667        [if memop = MemOp_LOAD then "ld" else "st",
9668         if acctype = AccType_STREAM then "np" else "p",
9669         if signed andalso (memop = MemOp_LOAD) then "sw" else ""],
9670      String.concat
9671        [s_reg2z(((BitsN.size size) = 64) orelse signed,(rt,rt2)),", [",
9672         s_regp(true,rn),
9673         if postindex
9674           then "]" ^ (s_signed_imm offset)
9675         else String.concat
9676                [if offset = (BitsN.B(0x0,64))
9677                   then ""
9678                 else s_signed_imm offset,"]",if wback then "!" else ""]])
9679   | LoadStoreAcquire''8
9680     (size,(memop,(acctype,(excl,(_,(_,(rs,(rn,rt)))))))) =>
9681     let
9682       val N = BitsN.size size
9683       val sfx = case N of 8 => "b" | 16 => "h" | _ => ""
9684     in
9685       (String.concat
9686          [if memop = MemOp_LOAD
9687             then "ld" ^ (if acctype = AccType_ORDERED then "a" else "")
9688           else "st" ^ (if acctype = AccType_ORDERED then "l" else ""),
9689           if excl then "xr" else "r",sfx],
9690        String.concat[s_regz(N = 64,rt),", [",s_regp(true,rn),"]"])
9691     end
9692   | LoadStoreAcquire''16
9693     (size,(memop,(acctype,(excl,(_,(_,(rs,(rn,rt)))))))) =>
9694     let
9695       val N = BitsN.size size
9696       val sfx = case N of 8 => "b" | 16 => "h" | _ => ""
9697     in
9698       (String.concat
9699          [if memop = MemOp_LOAD
9700             then "ld" ^ (if acctype = AccType_ORDERED then "a" else "")
9701           else "st" ^ (if acctype = AccType_ORDERED then "l" else ""),
9702           if excl then "xr" else "r",sfx],
9703        String.concat[s_regz(N = 64,rt),", [",s_regp(true,rn),"]"])
9704     end
9705   | LoadStoreAcquire''32
9706     (size,(memop,(acctype,(excl,(_,(_,(rs,(rn,rt)))))))) =>
9707     let
9708       val N = BitsN.size size
9709       val sfx = case N of 8 => "b" | 16 => "h" | _ => ""
9710     in
9711       (String.concat
9712          [if memop = MemOp_LOAD
9713             then "ld" ^ (if acctype = AccType_ORDERED then "a" else "")
9714           else "st" ^ (if acctype = AccType_ORDERED then "l" else ""),
9715           if excl then "xr" else "r",sfx],
9716        String.concat[s_regz(N = 64,rt),", [",s_regp(true,rn),"]"])
9717     end
9718   | LoadStoreAcquire''64
9719     (size,(memop,(acctype,(excl,(_,(_,(rs,(rn,rt)))))))) =>
9720     let
9721       val N = BitsN.size size
9722       val sfx = case N of 8 => "b" | 16 => "h" | _ => ""
9723     in
9724       (String.concat
9725          [if memop = MemOp_LOAD
9726             then "ld" ^ (if acctype = AccType_ORDERED then "a" else "")
9727           else "st" ^ (if acctype = AccType_ORDERED then "l" else ""),
9728           if excl then "xr" else "r",sfx],
9729        String.concat[s_regz(N = 64,rt),", [",s_regp(true,rn),"]"])
9730     end
9731   | LoadStoreAcquirePair''64
9732     (size,(memop,(acctype,(_,(_,(rs,(rn,(rt,rt2)))))))) =>
9733     ((if memop = MemOp_LOAD
9734         then "ld" ^ (if acctype = AccType_ORDERED then "a" else "")
9735       else "st" ^ (if acctype = AccType_ORDERED then "l" else ""))
9736        ^
9737        "xp",
9738      String.concat
9739        [if memop = MemOp_STORE then (s_regz(false,rs)) ^ ", " else "",
9740         s_reg2z((BitsN.size size) = 128,(rt,rt2)),", [",s_regp(true,rn),
9741         "]"])
9742   | LoadStoreAcquirePair''128
9743     (size,(memop,(acctype,(_,(_,(rs,(rn,(rt,rt2)))))))) =>
9744     ((if memop = MemOp_LOAD
9745         then "ld" ^ (if acctype = AccType_ORDERED then "a" else "")
9746       else "st" ^ (if acctype = AccType_ORDERED then "l" else ""))
9747        ^
9748        "xp",
9749      String.concat
9750        [if memop = MemOp_STORE then (s_regz(false,rs)) ^ ", " else "",
9751         s_reg2z((BitsN.size size) = 128,(rt,rt2)),", [",s_regp(true,rn),
9752         "]"]);
9753
9754fun instructionToString ast =
9755  case ast of
9756     Address(page,(imm,d)) =>
9757       (if page then "adrp" else "adr",
9758        String.concat
9759          [s_regz(true,d),", ",
9760           s_offset(if page then BitsN.>>(imm,12) else imm)])
9761   | Data d => s_data d
9762   | CRCExt c => s_crc c
9763   | Branch b => s_branch b
9764   | Debug b => s_debug b
9765   | Hint h => (s_hint_op h,"")
9766   | LoadStore s => s_load_store s
9767   | MemoryBarrier(opc,crm) => (s_barrier_op opc,s_dec 4 crm)
9768   | System s => s_system s
9769   | ClearExclusive crm => ("clrex",s_dec 4 crm)
9770   | Unallocated => ("?? unallocated ??","")
9771   | Reserved => ("?? reserved ??","");
9772
9773fun diss s =
9774  let
9775    val (m,a) =
9776      instructionToString
9777        (Decode((Option.valOf o BitsN.fromHexString) (s,32)))
9778  in
9779    if a = "" then m else String.concat[m," ",a]
9780  end;
9781
9782end