1(* arm - generated by L3 - Wed Jan 31 15:06:54 2018 *)
2
3structure arm :> arm =
4struct
5
6structure Map = MutableMap
7
8(* -------------------------------------------------------------------------
9   Type declarations
10   ------------------------------------------------------------------------- *)
11
12datatype Architecture
13  = ARMv4 | ARMv4T | ARMv5T | ARMv5TE | ARMv6 | ARMv6K | ARMv6T2 | ARMv7_A
14  | ARMv7_R
15
16datatype Extensions
17  = Extension_ThumbEE | Extension_Security | Extension_Multiprocessing
18  | Extension_Virtualization | Extension_AdvanvedSIMD
19
20type PSR =
21  { A: bool, C: bool, E: bool, F: bool, GE: BitsN.nbit, I: bool,
22    IT: BitsN.nbit, J: bool, M: BitsN.nbit, N: bool, Q: bool, T: bool,
23    V: bool, Z: bool, psr'rst: BitsN.nbit }
24
25type CP14 = { TEEHBR: BitsN.nbit }
26
27type SCTLR =
28  { A: bool, B: bool, BR: bool, C: bool, DZ: bool, EE: bool, FI: bool,
29    I: bool, IE: bool, M: bool, NMFI: bool, RR: bool, SW: bool, TE: bool,
30    U: bool, V: bool, VE: bool, Z: bool, sctlr'rst: BitsN.nbit }
31
32type HSCTLR =
33  { A: bool, C: bool, CP15BEN: bool, EE: bool, FI: bool, I: bool, M: bool,
34    TE: bool, WXN: bool, hsctlr'rst: BitsN.nbit }
35
36type HSR = { EC: BitsN.nbit, IL: bool, ISS: BitsN.nbit }
37
38type SCR =
39  { AW: bool, EA: bool, FIQ: bool, FW: bool, HCE: bool, IRQ: bool,
40    NS: bool, SCD: bool, SIF: bool, nET: bool, scr'rst: BitsN.nbit }
41
42type NSACR =
43  { NSASEDIS: bool, NSD32DIS: bool, NSTRCDIS: bool, RFR: bool,
44    cp: BitsN.nbit, nsacr'rst: BitsN.nbit }
45
46type HCR =
47  { AMO: bool, BSU: BitsN.nbit, DC: bool, FB: bool, FMO: bool, IMO: bool,
48    PTW: bool, SWIO: bool, TAC: bool, TGE: bool, TID: BitsN.nbit,
49    TIDCP: bool, TPC: bool, TPU: bool, TSC: bool, TSW: bool, TTLB: bool,
50    TVM: bool, TWE: bool, TWI: bool, VA: bool, VF: bool, VI: bool,
51    VM: bool, hcr'rst: BitsN.nbit }
52
53type CP15 =
54  { HCR: HCR, HSCTLR: HSCTLR, HSR: HSR, MVBAR: BitsN.nbit, NSACR: NSACR,
55    SCR: SCR, SCTLR: SCTLR, VBAR: BitsN.nbit }
56
57datatype InstrSet
58  = InstrSet_ARM | InstrSet_Thumb | InstrSet_Jazelle | InstrSet_ThumbEE
59
60datatype Encoding = Encoding_Thumb | Encoding_Thumb2 | Encoding_ARM
61
62datatype RName
63  = RName_0usr | RName_1usr | RName_2usr | RName_3usr | RName_4usr
64  | RName_5usr | RName_6usr | RName_7usr | RName_8usr | RName_8fiq
65  | RName_9usr | RName_9fiq | RName_10usr | RName_10fiq | RName_11usr
66  | RName_11fiq | RName_12usr | RName_12fiq | RName_SPusr | RName_SPfiq
67  | RName_SPirq | RName_SPsvc | RName_SPabt | RName_SPund | RName_SPmon
68  | RName_SPhyp | RName_LRusr | RName_LRfiq | RName_LRirq | RName_LRsvc
69  | RName_LRabt | RName_LRund | RName_LRmon | RName_PC
70
71datatype SRType
72  = SRType_LSL | SRType_LSR | SRType_ASR | SRType_ROR | SRType_RRX
73
74datatype offset1
75  = immediate_form1 of BitsN.nbit
76  | register_form1 of BitsN.nbit * (SRType * Nat.nat)
77
78datatype offset2
79  = immediate_form2 of BitsN.nbit | register_form2 of BitsN.nbit
80
81datatype VFPExtension = NoVFP | VFPv2 | VFPv3 | VFPv4
82
83type FPSCR =
84  { AHP: bool, C: bool, DN: bool, DZC: bool, DZE: bool, FZ: bool,
85    IDC: bool, IDE: bool, IOC: bool, IOE: bool, IXC: bool, IXE: bool,
86    N: bool, OFC: bool, OFE: bool, QC: bool, RMode: BitsN.nbit, UFC: bool,
87    UFE: bool, V: bool, Z: bool, fpscr'rst: BitsN.nbit }
88
89type FP = { FPSCR: FPSCR, REG: BitsN.nbit Map.map }
90
91datatype VFPNegMul = VFPNegMul_VNMLA | VFPNegMul_VNMLS | VFPNegMul_VNMUL
92
93datatype VFP
94  = vabs of bool * (BitsN.nbit * BitsN.nbit)
95  | vadd of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
96  | vcmp of bool * (BitsN.nbit * (BitsN.nbit option))
97  | vcvt_float of bool * (BitsN.nbit * BitsN.nbit)
98  | vcvt_from_integer of bool * (bool * (BitsN.nbit * BitsN.nbit))
99  | vcvt_to_integer of bool * (bool * (bool * (BitsN.nbit * BitsN.nbit)))
100  | vdiv of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
101  | vfma_vfms of bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
102  | vfnma_vfnms of
103      bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
104  | vldm of
105      bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
106  | vldr of bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
107  | vmla_vmls of bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
108  | vmov of bool * (BitsN.nbit * BitsN.nbit)
109  | vmov_double of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
110  | vmov_imm of bool * (BitsN.nbit * BitsN.nbit)
111  | vmov_single of bool * (BitsN.nbit * BitsN.nbit)
112  | vmov_two_singles of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
113  | vmrs of BitsN.nbit
114  | vmsr of BitsN.nbit
115  | vmul of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
116  | vneg of bool * (BitsN.nbit * BitsN.nbit)
117  | vneg_mul of
118      bool * (VFPNegMul * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
119  | vsqrt of bool * (BitsN.nbit * BitsN.nbit)
120  | vstm of
121      bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
122  | vstr of bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
123  | vsub of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
124
125datatype Hint
126  = Breakpoint of BitsN.nbit
127  | DataMemoryBarrier of BitsN.nbit
128  | DataSynchronizationBarrier of BitsN.nbit
129  | Debug of BitsN.nbit
130  | InstructionSynchronizationBarrier of BitsN.nbit
131  | PreloadData of bool * (bool * (BitsN.nbit * offset1))
132  | PreloadDataLiteral of bool * BitsN.nbit
133  | PreloadInstruction of bool * (BitsN.nbit * offset1)
134  | SendEvent
135  | WaitForEvent
136  | WaitForInterrupt
137  | Yield
138
139datatype System
140  = ChangeProcessorState of
141      bool * (bool * (bool * (bool * (bool * (BitsN.nbit option)))))
142  | EnterxLeavex of bool
143  | ExceptionReturn
144  | HypervisorCall of BitsN.nbit
145  | MoveToBankedOrSpecialRegister of bool * (BitsN.nbit * BitsN.nbit)
146  | MoveToRegisterFromBankedOrSpecial of bool * (BitsN.nbit * BitsN.nbit)
147  | MoveToRegisterFromSpecial of bool * BitsN.nbit
148  | MoveToSpecialFromImmediate of bool * (BitsN.nbit * BitsN.nbit)
149  | MoveToSpecialFromRegister of bool * (BitsN.nbit * BitsN.nbit)
150  | ReturnFromException of bool * (bool * (bool * BitsN.nbit))
151  | SecureMonitorCall of BitsN.nbit
152  | Setend of bool
153  | StoreReturnState of bool * (bool * (bool * BitsN.nbit))
154  | SupervisorCall of BitsN.nbit
155
156datatype Store
157  = StoreByte of
158      bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1))))
159  | StoreByteUnprivileged of
160      bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1)))
161  | StoreDual of
162      bool *
163      (bool *
164       (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * offset2)))))
165  | StoreExclusive of
166      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
167  | StoreExclusiveByte of BitsN.nbit * (BitsN.nbit * BitsN.nbit)
168  | StoreExclusiveDoubleword of
169      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
170  | StoreExclusiveHalf of BitsN.nbit * (BitsN.nbit * BitsN.nbit)
171  | StoreHalf of
172      bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1))))
173  | StoreHalfUnprivileged of
174      bool * (bool * (BitsN.nbit * (BitsN.nbit * offset2)))
175  | StoreMultiple of bool * (bool * (bool * (BitsN.nbit * BitsN.nbit)))
176  | StoreMultipleUserRegisters of
177      bool * (bool * (BitsN.nbit * BitsN.nbit))
178  | StoreUnprivileged of
179      bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1)))
180  | StoreWord of
181      bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1))))
182
183datatype Load
184  = LoadByte of
185      bool *
186      (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1)))))
187  | LoadByteLiteral of bool * (bool * (BitsN.nbit * BitsN.nbit))
188  | LoadByteUnprivileged of
189      bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1)))
190  | LoadDual of
191      bool *
192      (bool *
193       (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * offset2)))))
194  | LoadDualLiteral of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
195  | LoadExclusive of BitsN.nbit * (BitsN.nbit * BitsN.nbit)
196  | LoadExclusiveByte of BitsN.nbit * BitsN.nbit
197  | LoadExclusiveDoubleword of BitsN.nbit * (BitsN.nbit * BitsN.nbit)
198  | LoadExclusiveHalf of BitsN.nbit * BitsN.nbit
199  | LoadHalf of
200      bool *
201      (bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1)))))
202  | LoadHalfLiteral of bool * (bool * (BitsN.nbit * BitsN.nbit))
203  | LoadHalfUnprivileged of
204      bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * offset2))))
205  | LoadLiteral of bool * (BitsN.nbit * BitsN.nbit)
206  | LoadMultiple of bool * (bool * (bool * (BitsN.nbit * BitsN.nbit)))
207  | LoadMultipleExceptionReturn of
208      bool * (bool * (bool * (BitsN.nbit * BitsN.nbit)))
209  | LoadMultipleUserRegisters of bool * (bool * (BitsN.nbit * BitsN.nbit))
210  | LoadSignedByteUnprivileged of
211      bool * (bool * (BitsN.nbit * (BitsN.nbit * offset2)))
212  | LoadUnprivileged of
213      bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1)))
214  | LoadWord of
215      bool * (bool * (bool * (BitsN.nbit * (BitsN.nbit * offset1))))
216
217datatype Media
218  = BitFieldClearOrInsert of
219      BitsN.nbit * (BitsN.nbit * (Nat.nat * Nat.nat))
220  | BitFieldExtract of
221      bool * (BitsN.nbit * (BitsN.nbit * (Nat.nat * Nat.nat)))
222  | ByteReverse of BitsN.nbit * BitsN.nbit
223  | ByteReversePackedHalfword of BitsN.nbit * BitsN.nbit
224  | ByteReverseSignedHalfword of BitsN.nbit * BitsN.nbit
225  | ExtendByte of
226      bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * Nat.nat)))
227  | ExtendByte16 of
228      bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * Nat.nat)))
229  | ExtendHalfword of
230      bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * Nat.nat)))
231  | PackHalfword of
232      SRType *
233      (Nat.nat * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
234  | ReverseBits of BitsN.nbit * BitsN.nbit
235  | Saturate of
236      SRType * (Nat.nat * (Nat.nat * (bool * (BitsN.nbit * BitsN.nbit))))
237  | Saturate16 of Nat.nat * (bool * (BitsN.nbit * BitsN.nbit))
238  | SaturatingAddSubtract of
239      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
240  | SelectBytes of BitsN.nbit * (BitsN.nbit * BitsN.nbit)
241
242datatype SIMD
243  = SignedAddSub16 of
244      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
245  | SignedAddSub8 of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
246  | SignedHalvingAddSub16 of
247      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
248  | SignedHalvingAddSub8 of
249      bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
250  | SignedSaturatingAddSub16 of
251      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
252  | SignedSaturatingAddSub8 of
253      bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
254  | UnsignedAddSub16 of
255      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
256  | UnsignedAddSub8 of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
257  | UnsignedHalvingAddSub16 of
258      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
259  | UnsignedHalvingAddSub8 of
260      bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
261  | UnsignedSaturatingAddSub16 of
262      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
263  | UnsignedSaturatingAddSub8 of
264      bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
265  | UnsignedSumAbsoluteDifferences of
266      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
267
268datatype Multiply
269  = Multiply32 of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
270  | MultiplyAccumulate of
271      bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
272  | MultiplyAccumulateAccumulate of
273      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
274  | MultiplyLong of
275      bool *
276      (bool *
277       (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))))
278  | MultiplySubtract of
279      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
280  | Signed16Multiply32Accumulate of
281      bool *
282      (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
283  | Signed16Multiply32Result of
284      bool * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
285  | Signed16Multiply64Accumulate of
286      bool *
287      (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
288  | Signed16x32Multiply32Accumulate of
289      bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
290  | Signed16x32Multiply32Result of
291      bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
292  | SignedMostSignificantMultiply of
293      bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
294  | SignedMostSignificantMultiplySubtract of
295      bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
296  | SignedMultiplyDual of
297      bool *
298      (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
299  | SignedMultiplyLongDual of
300      bool *
301      (bool * (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))))
302
303datatype Data
304  = AddSub of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
305  | ArithLogicImmediate of
306      BitsN.nbit * (bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit)))
307  | CountLeadingZeroes of BitsN.nbit * BitsN.nbit
308  | Move of bool * (bool * (BitsN.nbit * BitsN.nbit))
309  | MoveHalfword of bool * (BitsN.nbit * BitsN.nbit)
310  | Register of
311      BitsN.nbit *
312      (bool *
313       (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (SRType * Nat.nat)))))
314  | RegisterShiftedRegister of
315      BitsN.nbit *
316      (bool *
317       (BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (SRType * BitsN.nbit)))))
318  | ShiftImmediate of
319      bool * (bool * (BitsN.nbit * (BitsN.nbit * (SRType * Nat.nat))))
320  | ShiftRegister of
321      bool * (bool * (BitsN.nbit * (BitsN.nbit * (SRType * BitsN.nbit))))
322  | TestCompareImmediate of BitsN.nbit * (BitsN.nbit * BitsN.nbit)
323  | TestCompareRegister of
324      BitsN.nbit * (BitsN.nbit * (BitsN.nbit * (SRType * Nat.nat)))
325
326datatype Branch
327  = BranchExchange of BitsN.nbit
328  | BranchLinkExchangeImmediate of InstrSet * BitsN.nbit
329  | BranchLinkExchangeRegister of BitsN.nbit
330  | BranchTarget of BitsN.nbit
331  | CheckArray of BitsN.nbit * BitsN.nbit
332  | CompareBranch of bool * (BitsN.nbit * BitsN.nbit)
333  | HandlerBranchLink of bool * BitsN.nbit
334  | HandlerBranchLinkParameter of BitsN.nbit * BitsN.nbit
335  | HandlerBranchParameter of BitsN.nbit * BitsN.nbit
336  | TableBranchByte of bool * (BitsN.nbit * BitsN.nbit)
337
338datatype instruction
339  = Branch of Branch
340  | ClearExclusive
341  | Data of Data
342  | Divide of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
343  | Hint of Hint
344  | IfThen of BitsN.nbit * BitsN.nbit
345  | Load of Load
346  | Media of Media
347  | Multiply of Multiply
348  | NoOperation
349  | SIMD of SIMD
350  | Store of Store
351  | Swap of bool * (BitsN.nbit * (BitsN.nbit * BitsN.nbit))
352  | System of System
353  | Undefined of BitsN.nbit
354  | VFP of VFP
355
356datatype MachineCode
357  = ARM of BitsN.nbit
358  | BadCode of string
359  | Thumb of BitsN.nbit
360  | Thumb2 of BitsN.nbit * BitsN.nbit
361  | ThumbEE of BitsN.nbit
362
363datatype enc = Enc_ARM | Enc_Thumb | Enc_Narrow | Enc_Wide
364
365datatype maybe_instruction
366  = FAIL of string
367  | OK of (BitsN.nbit * string) * instruction
368  | PENDING of string * ((BitsN.nbit * string) * instruction)
369  | WORD of BitsN.nbit
370
371datatype nat_or_reg = NAT of Nat.nat | REGISTER of BitsN.nbit
372
373(* -------------------------------------------------------------------------
374   Casting maps (for enumerated types)
375   ------------------------------------------------------------------------- *)
376
377structure Cast =
378struct
379fun natToArchitecture x =
380  case Nat.toInt x of
381     0 => ARMv4
382   | 1 => ARMv4T
383   | 2 => ARMv5T
384   | 3 => ARMv5TE
385   | 4 => ARMv6
386   | 5 => ARMv6K
387   | 6 => ARMv6T2
388   | 7 => ARMv7_A
389   | 8 => ARMv7_R
390   | _ => raise Fail "natToArchitecture"
391
392fun natToExtensions x =
393  case Nat.toInt x of
394     0 => Extension_ThumbEE
395   | 1 => Extension_Security
396   | 2 => Extension_Multiprocessing
397   | 3 => Extension_Virtualization
398   | 4 => Extension_AdvanvedSIMD
399   | _ => raise Fail "natToExtensions"
400
401fun natToInstrSet x =
402  case Nat.toInt x of
403     0 => InstrSet_ARM
404   | 1 => InstrSet_Thumb
405   | 2 => InstrSet_Jazelle
406   | 3 => InstrSet_ThumbEE
407   | _ => raise Fail "natToInstrSet"
408
409fun natToEncoding x =
410  case Nat.toInt x of
411     0 => Encoding_Thumb
412   | 1 => Encoding_Thumb2
413   | 2 => Encoding_ARM
414   | _ => raise Fail "natToEncoding"
415
416fun natToRName x =
417  case Nat.toInt x of
418     0 => RName_0usr
419   | 1 => RName_1usr
420   | 2 => RName_2usr
421   | 3 => RName_3usr
422   | 4 => RName_4usr
423   | 5 => RName_5usr
424   | 6 => RName_6usr
425   | 7 => RName_7usr
426   | 8 => RName_8usr
427   | 9 => RName_8fiq
428   | 10 => RName_9usr
429   | 11 => RName_9fiq
430   | 12 => RName_10usr
431   | 13 => RName_10fiq
432   | 14 => RName_11usr
433   | 15 => RName_11fiq
434   | 16 => RName_12usr
435   | 17 => RName_12fiq
436   | 18 => RName_SPusr
437   | 19 => RName_SPfiq
438   | 20 => RName_SPirq
439   | 21 => RName_SPsvc
440   | 22 => RName_SPabt
441   | 23 => RName_SPund
442   | 24 => RName_SPmon
443   | 25 => RName_SPhyp
444   | 26 => RName_LRusr
445   | 27 => RName_LRfiq
446   | 28 => RName_LRirq
447   | 29 => RName_LRsvc
448   | 30 => RName_LRabt
449   | 31 => RName_LRund
450   | 32 => RName_LRmon
451   | 33 => RName_PC
452   | _ => raise Fail "natToRName"
453
454fun natToSRType x =
455  case Nat.toInt x of
456     0 => SRType_LSL
457   | 1 => SRType_LSR
458   | 2 => SRType_ASR
459   | 3 => SRType_ROR
460   | 4 => SRType_RRX
461   | _ => raise Fail "natToSRType"
462
463fun natToVFPExtension x =
464  case Nat.toInt x of
465     0 => NoVFP
466   | 1 => VFPv2
467   | 2 => VFPv3
468   | 3 => VFPv4
469   | _ => raise Fail "natToVFPExtension"
470
471fun natToVFPNegMul x =
472  case Nat.toInt x of
473     0 => VFPNegMul_VNMLA
474   | 1 => VFPNegMul_VNMLS
475   | 2 => VFPNegMul_VNMUL
476   | _ => raise Fail "natToVFPNegMul"
477
478fun natToenc x =
479  case Nat.toInt x of
480     0 => Enc_ARM
481   | 1 => Enc_Thumb
482   | 2 => Enc_Narrow
483   | 3 => Enc_Wide
484   | _ => raise Fail "natToenc"
485
486fun ArchitectureToNat x =
487  case x of
488     ARMv4 => 0
489   | ARMv4T => 1
490   | ARMv5T => 2
491   | ARMv5TE => 3
492   | ARMv6 => 4
493   | ARMv6K => 5
494   | ARMv6T2 => 6
495   | ARMv7_A => 7
496   | ARMv7_R => 8
497
498fun ExtensionsToNat x =
499  case x of
500     Extension_ThumbEE => 0
501   | Extension_Security => 1
502   | Extension_Multiprocessing => 2
503   | Extension_Virtualization => 3
504   | Extension_AdvanvedSIMD => 4
505
506fun InstrSetToNat x =
507  case x of
508     InstrSet_ARM => 0
509   | InstrSet_Thumb => 1
510   | InstrSet_Jazelle => 2
511   | InstrSet_ThumbEE => 3
512
513fun EncodingToNat x =
514  case x of
515     Encoding_Thumb => 0 | Encoding_Thumb2 => 1 | Encoding_ARM => 2
516
517fun RNameToNat x =
518  case x of
519     RName_0usr => 0
520   | RName_1usr => 1
521   | RName_2usr => 2
522   | RName_3usr => 3
523   | RName_4usr => 4
524   | RName_5usr => 5
525   | RName_6usr => 6
526   | RName_7usr => 7
527   | RName_8usr => 8
528   | RName_8fiq => 9
529   | RName_9usr => 10
530   | RName_9fiq => 11
531   | RName_10usr => 12
532   | RName_10fiq => 13
533   | RName_11usr => 14
534   | RName_11fiq => 15
535   | RName_12usr => 16
536   | RName_12fiq => 17
537   | RName_SPusr => 18
538   | RName_SPfiq => 19
539   | RName_SPirq => 20
540   | RName_SPsvc => 21
541   | RName_SPabt => 22
542   | RName_SPund => 23
543   | RName_SPmon => 24
544   | RName_SPhyp => 25
545   | RName_LRusr => 26
546   | RName_LRfiq => 27
547   | RName_LRirq => 28
548   | RName_LRsvc => 29
549   | RName_LRabt => 30
550   | RName_LRund => 31
551   | RName_LRmon => 32
552   | RName_PC => 33
553
554fun SRTypeToNat x =
555  case x of
556     SRType_LSL => 0
557   | SRType_LSR => 1
558   | SRType_ASR => 2
559   | SRType_ROR => 3
560   | SRType_RRX => 4
561
562fun VFPExtensionToNat x =
563  case x of
564     NoVFP => 0 | VFPv2 => 1 | VFPv3 => 2 | VFPv4 => 3
565
566fun VFPNegMulToNat x =
567  case x of
568     VFPNegMul_VNMLA => 0 | VFPNegMul_VNMLS => 1 | VFPNegMul_VNMUL => 2
569
570fun encToNat x =
571  case x of
572     Enc_ARM => 0 | Enc_Thumb => 1 | Enc_Narrow => 2 | Enc_Wide => 3
573
574fun ArchitectureToString x =
575  case x of
576     ARMv4 => "ARMv4"
577   | ARMv4T => "ARMv4T"
578   | ARMv5T => "ARMv5T"
579   | ARMv5TE => "ARMv5TE"
580   | ARMv6 => "ARMv6"
581   | ARMv6K => "ARMv6K"
582   | ARMv6T2 => "ARMv6T2"
583   | ARMv7_A => "ARMv7_A"
584   | ARMv7_R => "ARMv7_R"
585
586fun ExtensionsToString x =
587  case x of
588     Extension_ThumbEE => "Extension_ThumbEE"
589   | Extension_Security => "Extension_Security"
590   | Extension_Multiprocessing => "Extension_Multiprocessing"
591   | Extension_Virtualization => "Extension_Virtualization"
592   | Extension_AdvanvedSIMD => "Extension_AdvanvedSIMD"
593
594fun InstrSetToString x =
595  case x of
596     InstrSet_ARM => "InstrSet_ARM"
597   | InstrSet_Thumb => "InstrSet_Thumb"
598   | InstrSet_Jazelle => "InstrSet_Jazelle"
599   | InstrSet_ThumbEE => "InstrSet_ThumbEE"
600
601fun EncodingToString x =
602  case x of
603     Encoding_Thumb => "Encoding_Thumb"
604   | Encoding_Thumb2 => "Encoding_Thumb2"
605   | Encoding_ARM => "Encoding_ARM"
606
607fun RNameToString x =
608  case x of
609     RName_0usr => "RName_0usr"
610   | RName_1usr => "RName_1usr"
611   | RName_2usr => "RName_2usr"
612   | RName_3usr => "RName_3usr"
613   | RName_4usr => "RName_4usr"
614   | RName_5usr => "RName_5usr"
615   | RName_6usr => "RName_6usr"
616   | RName_7usr => "RName_7usr"
617   | RName_8usr => "RName_8usr"
618   | RName_8fiq => "RName_8fiq"
619   | RName_9usr => "RName_9usr"
620   | RName_9fiq => "RName_9fiq"
621   | RName_10usr => "RName_10usr"
622   | RName_10fiq => "RName_10fiq"
623   | RName_11usr => "RName_11usr"
624   | RName_11fiq => "RName_11fiq"
625   | RName_12usr => "RName_12usr"
626   | RName_12fiq => "RName_12fiq"
627   | RName_SPusr => "RName_SPusr"
628   | RName_SPfiq => "RName_SPfiq"
629   | RName_SPirq => "RName_SPirq"
630   | RName_SPsvc => "RName_SPsvc"
631   | RName_SPabt => "RName_SPabt"
632   | RName_SPund => "RName_SPund"
633   | RName_SPmon => "RName_SPmon"
634   | RName_SPhyp => "RName_SPhyp"
635   | RName_LRusr => "RName_LRusr"
636   | RName_LRfiq => "RName_LRfiq"
637   | RName_LRirq => "RName_LRirq"
638   | RName_LRsvc => "RName_LRsvc"
639   | RName_LRabt => "RName_LRabt"
640   | RName_LRund => "RName_LRund"
641   | RName_LRmon => "RName_LRmon"
642   | RName_PC => "RName_PC"
643
644fun SRTypeToString x =
645  case x of
646     SRType_LSL => "SRType_LSL"
647   | SRType_LSR => "SRType_LSR"
648   | SRType_ASR => "SRType_ASR"
649   | SRType_ROR => "SRType_ROR"
650   | SRType_RRX => "SRType_RRX"
651
652fun VFPExtensionToString x =
653  case x of
654     NoVFP => "NoVFP"
655   | VFPv2 => "VFPv2"
656   | VFPv3 => "VFPv3"
657   | VFPv4 => "VFPv4"
658
659fun VFPNegMulToString x =
660  case x of
661     VFPNegMul_VNMLA => "VFPNegMul_VNMLA"
662   | VFPNegMul_VNMLS => "VFPNegMul_VNMLS"
663   | VFPNegMul_VNMUL => "VFPNegMul_VNMUL"
664
665fun encToString x =
666  case x of
667     Enc_ARM => "Enc_ARM"
668   | Enc_Thumb => "Enc_Thumb"
669   | Enc_Narrow => "Enc_Narrow"
670   | Enc_Wide => "Enc_Wide"
671
672fun stringToArchitecture x =
673  case x of
674     "ARMv4" => ARMv4
675   | "ARMv4T" => ARMv4T
676   | "ARMv5T" => ARMv5T
677   | "ARMv5TE" => ARMv5TE
678   | "ARMv6" => ARMv6
679   | "ARMv6K" => ARMv6K
680   | "ARMv6T2" => ARMv6T2
681   | "ARMv7_A" => ARMv7_A
682   | "ARMv7_R" => ARMv7_R
683   | _ => raise Fail "stringToArchitecture"
684
685fun stringToExtensions x =
686  case x of
687     "Extension_ThumbEE" => Extension_ThumbEE
688   | "Extension_Security" => Extension_Security
689   | "Extension_Multiprocessing" => Extension_Multiprocessing
690   | "Extension_Virtualization" => Extension_Virtualization
691   | "Extension_AdvanvedSIMD" => Extension_AdvanvedSIMD
692   | _ => raise Fail "stringToExtensions"
693
694fun stringToInstrSet x =
695  case x of
696     "InstrSet_ARM" => InstrSet_ARM
697   | "InstrSet_Thumb" => InstrSet_Thumb
698   | "InstrSet_Jazelle" => InstrSet_Jazelle
699   | "InstrSet_ThumbEE" => InstrSet_ThumbEE
700   | _ => raise Fail "stringToInstrSet"
701
702fun stringToEncoding x =
703  case x of
704     "Encoding_Thumb" => Encoding_Thumb
705   | "Encoding_Thumb2" => Encoding_Thumb2
706   | "Encoding_ARM" => Encoding_ARM
707   | _ => raise Fail "stringToEncoding"
708
709fun stringToRName x =
710  case x of
711     "RName_0usr" => RName_0usr
712   | "RName_1usr" => RName_1usr
713   | "RName_2usr" => RName_2usr
714   | "RName_3usr" => RName_3usr
715   | "RName_4usr" => RName_4usr
716   | "RName_5usr" => RName_5usr
717   | "RName_6usr" => RName_6usr
718   | "RName_7usr" => RName_7usr
719   | "RName_8usr" => RName_8usr
720   | "RName_8fiq" => RName_8fiq
721   | "RName_9usr" => RName_9usr
722   | "RName_9fiq" => RName_9fiq
723   | "RName_10usr" => RName_10usr
724   | "RName_10fiq" => RName_10fiq
725   | "RName_11usr" => RName_11usr
726   | "RName_11fiq" => RName_11fiq
727   | "RName_12usr" => RName_12usr
728   | "RName_12fiq" => RName_12fiq
729   | "RName_SPusr" => RName_SPusr
730   | "RName_SPfiq" => RName_SPfiq
731   | "RName_SPirq" => RName_SPirq
732   | "RName_SPsvc" => RName_SPsvc
733   | "RName_SPabt" => RName_SPabt
734   | "RName_SPund" => RName_SPund
735   | "RName_SPmon" => RName_SPmon
736   | "RName_SPhyp" => RName_SPhyp
737   | "RName_LRusr" => RName_LRusr
738   | "RName_LRfiq" => RName_LRfiq
739   | "RName_LRirq" => RName_LRirq
740   | "RName_LRsvc" => RName_LRsvc
741   | "RName_LRabt" => RName_LRabt
742   | "RName_LRund" => RName_LRund
743   | "RName_LRmon" => RName_LRmon
744   | "RName_PC" => RName_PC
745   | _ => raise Fail "stringToRName"
746
747fun stringToSRType x =
748  case x of
749     "SRType_LSL" => SRType_LSL
750   | "SRType_LSR" => SRType_LSR
751   | "SRType_ASR" => SRType_ASR
752   | "SRType_ROR" => SRType_ROR
753   | "SRType_RRX" => SRType_RRX
754   | _ => raise Fail "stringToSRType"
755
756fun stringToVFPExtension x =
757  case x of
758     "NoVFP" => NoVFP
759   | "VFPv2" => VFPv2
760   | "VFPv3" => VFPv3
761   | "VFPv4" => VFPv4
762   | _ => raise Fail "stringToVFPExtension"
763
764fun stringToVFPNegMul x =
765  case x of
766     "VFPNegMul_VNMLA" => VFPNegMul_VNMLA
767   | "VFPNegMul_VNMLS" => VFPNegMul_VNMLS
768   | "VFPNegMul_VNMUL" => VFPNegMul_VNMUL
769   | _ => raise Fail "stringToVFPNegMul"
770
771fun stringToenc x =
772  case x of
773     "Enc_ARM" => Enc_ARM
774   | "Enc_Thumb" => Enc_Thumb
775   | "Enc_Narrow" => Enc_Narrow
776   | "Enc_Wide" => Enc_Wide
777   | _ => raise Fail "stringToenc"
778end
779
780(* -------------------------------------------------------------------------
781   Record update functions
782   ------------------------------------------------------------------------- *)
783
784fun PSR_A_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
785  : PSR, x') =
786  {A = x', C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = M,
787   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
788
789fun PSR_C_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
790  : PSR, x') =
791  {A = A, C = x', E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = M,
792   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
793
794fun PSR_E_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
795  : PSR, x') =
796  {A = A, C = C, E = x', F = F, GE = GE, I = I, IT = IT, J = J, M = M,
797   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
798
799fun PSR_F_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
800  : PSR, x') =
801  {A = A, C = C, E = E, F = x', GE = GE, I = I, IT = IT, J = J, M = M,
802   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
803
804fun PSR_GE_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
805  : PSR, x') =
806  {A = A, C = C, E = E, F = F, GE = x', I = I, IT = IT, J = J, M = M,
807   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
808
809fun PSR_I_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
810  : PSR, x') =
811  {A = A, C = C, E = E, F = F, GE = GE, I = x', IT = IT, J = J, M = M,
812   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
813
814fun PSR_IT_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
815  : PSR, x') =
816  {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = x', J = J, M = M,
817   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
818
819fun PSR_J_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
820  : PSR, x') =
821  {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = x', M = M,
822   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
823
824fun PSR_M_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
825  : PSR, x') =
826  {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = x',
827   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
828
829fun PSR_N_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
830  : PSR, x') =
831  {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = M,
832   N = x', Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
833
834fun PSR_Q_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
835  : PSR, x') =
836  {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = M,
837   N = N, Q = x', T = T, V = V, Z = Z, psr'rst = psr'rst}: PSR
838
839fun PSR_T_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
840  : PSR, x') =
841  {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = M,
842   N = N, Q = Q, T = x', V = V, Z = Z, psr'rst = psr'rst}: PSR
843
844fun PSR_V_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
845  : PSR, x') =
846  {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = M,
847   N = N, Q = Q, T = T, V = x', Z = Z, psr'rst = psr'rst}: PSR
848
849fun PSR_Z_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
850  : PSR, x') =
851  {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = M,
852   N = N, Q = Q, T = T, V = V, Z = x', psr'rst = psr'rst}: PSR
853
854fun PSR_psr'rst_rupd ({A, C, E, F, GE, I, IT, J, M, N, Q, T, V, Z, psr'rst}
855  : PSR, x') =
856  {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = M,
857   N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = x'}: PSR
858
859fun CP14_TEEHBR_rupd ({TEEHBR}: CP14, x') = {TEEHBR = x'}: CP14
860
861fun SCTLR_A_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE, U,
862   V, VE, Z, sctlr'rst}: SCTLR, x') =
863  {A = x', B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
864   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
865   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
866
867fun SCTLR_B_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE, U,
868   V, VE, Z, sctlr'rst}: SCTLR, x') =
869  {A = A, B = x', BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
870   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
871   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
872
873fun SCTLR_BR_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
874   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
875  {A = A, B = B, BR = x', C = C, DZ = DZ, EE = EE, FI = FI, I = I,
876   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
877   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
878
879fun SCTLR_C_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE, U,
880   V, VE, Z, sctlr'rst}: SCTLR, x') =
881  {A = A, B = B, BR = BR, C = x', DZ = DZ, EE = EE, FI = FI, I = I,
882   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
883   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
884
885fun SCTLR_DZ_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
886   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
887  {A = A, B = B, BR = BR, C = C, DZ = x', EE = EE, FI = FI, I = I,
888   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
889   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
890
891fun SCTLR_EE_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
892   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
893  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = x', FI = FI, I = I,
894   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
895   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
896
897fun SCTLR_FI_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
898   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
899  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = x', I = I,
900   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
901   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
902
903fun SCTLR_I_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE, U,
904   V, VE, Z, sctlr'rst}: SCTLR, x') =
905  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = x',
906   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
907   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
908
909fun SCTLR_IE_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
910   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
911  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
912   IE = x', M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
913   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
914
915fun SCTLR_M_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE, U,
916   V, VE, Z, sctlr'rst}: SCTLR, x') =
917  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
918   IE = IE, M = x', NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
919   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
920
921fun SCTLR_NMFI_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
922   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
923  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
924   IE = IE, M = M, NMFI = x', RR = RR, SW = SW, TE = TE, U = U, V = V,
925   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
926
927fun SCTLR_RR_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
928   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
929  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
930   IE = IE, M = M, NMFI = NMFI, RR = x', SW = SW, TE = TE, U = U, V = V,
931   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
932
933fun SCTLR_SW_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
934   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
935  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
936   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = x', TE = TE, U = U, V = V,
937   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
938
939fun SCTLR_TE_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
940   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
941  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
942   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = x', U = U, V = V,
943   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
944
945fun SCTLR_U_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE, U,
946   V, VE, Z, sctlr'rst}: SCTLR, x') =
947  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
948   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = x', V = V,
949   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
950
951fun SCTLR_V_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE, U,
952   V, VE, Z, sctlr'rst}: SCTLR, x') =
953  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
954   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = x',
955   VE = VE, Z = Z, sctlr'rst = sctlr'rst}: SCTLR
956
957fun SCTLR_VE_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE,
958   U, V, VE, Z, sctlr'rst}: SCTLR, x') =
959  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
960   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
961   VE = x', Z = Z, sctlr'rst = sctlr'rst}: SCTLR
962
963fun SCTLR_Z_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR, SW, TE, U,
964   V, VE, Z, sctlr'rst}: SCTLR, x') =
965  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
966   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
967   VE = VE, Z = x', sctlr'rst = sctlr'rst}: SCTLR
968
969fun SCTLR_sctlr'rst_rupd ({A, B, BR, C, DZ, EE, FI, I, IE, M, NMFI, RR,
970   SW, TE, U, V, VE, Z, sctlr'rst}: SCTLR, x') =
971  {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
972   IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U, V = V,
973   VE = VE, Z = Z, sctlr'rst = x'}: SCTLR
974
975fun HSCTLR_A_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN, hsctlr'rst}
976  : HSCTLR, x') =
977  {A = x', C = C, CP15BEN = CP15BEN, EE = EE, FI = FI, I = I, M = M,
978   TE = TE, WXN = WXN, hsctlr'rst = hsctlr'rst}: HSCTLR
979
980fun HSCTLR_C_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN, hsctlr'rst}
981  : HSCTLR, x') =
982  {A = A, C = x', CP15BEN = CP15BEN, EE = EE, FI = FI, I = I, M = M,
983   TE = TE, WXN = WXN, hsctlr'rst = hsctlr'rst}: HSCTLR
984
985fun HSCTLR_CP15BEN_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN, hsctlr'rst}
986  : HSCTLR, x') =
987  {A = A, C = C, CP15BEN = x', EE = EE, FI = FI, I = I, M = M, TE = TE,
988   WXN = WXN, hsctlr'rst = hsctlr'rst}: HSCTLR
989
990fun HSCTLR_EE_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN, hsctlr'rst}
991  : HSCTLR, x') =
992  {A = A, C = C, CP15BEN = CP15BEN, EE = x', FI = FI, I = I, M = M,
993   TE = TE, WXN = WXN, hsctlr'rst = hsctlr'rst}: HSCTLR
994
995fun HSCTLR_FI_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN, hsctlr'rst}
996  : HSCTLR, x') =
997  {A = A, C = C, CP15BEN = CP15BEN, EE = EE, FI = x', I = I, M = M,
998   TE = TE, WXN = WXN, hsctlr'rst = hsctlr'rst}: HSCTLR
999
1000fun HSCTLR_I_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN, hsctlr'rst}
1001  : HSCTLR, x') =
1002  {A = A, C = C, CP15BEN = CP15BEN, EE = EE, FI = FI, I = x', M = M,
1003   TE = TE, WXN = WXN, hsctlr'rst = hsctlr'rst}: HSCTLR
1004
1005fun HSCTLR_M_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN, hsctlr'rst}
1006  : HSCTLR, x') =
1007  {A = A, C = C, CP15BEN = CP15BEN, EE = EE, FI = FI, I = I, M = x',
1008   TE = TE, WXN = WXN, hsctlr'rst = hsctlr'rst}: HSCTLR
1009
1010fun HSCTLR_TE_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN, hsctlr'rst}
1011  : HSCTLR, x') =
1012  {A = A, C = C, CP15BEN = CP15BEN, EE = EE, FI = FI, I = I, M = M,
1013   TE = x', WXN = WXN, hsctlr'rst = hsctlr'rst}: HSCTLR
1014
1015fun HSCTLR_WXN_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN, hsctlr'rst}
1016  : HSCTLR, x') =
1017  {A = A, C = C, CP15BEN = CP15BEN, EE = EE, FI = FI, I = I, M = M,
1018   TE = TE, WXN = x', hsctlr'rst = hsctlr'rst}: HSCTLR
1019
1020fun HSCTLR_hsctlr'rst_rupd ({A, C, CP15BEN, EE, FI, I, M, TE, WXN,
1021   hsctlr'rst}: HSCTLR, x') =
1022  {A = A, C = C, CP15BEN = CP15BEN, EE = EE, FI = FI, I = I, M = M,
1023   TE = TE, WXN = WXN, hsctlr'rst = x'}: HSCTLR
1024
1025fun HSR_EC_rupd ({EC, IL, ISS}: HSR, x') = {EC = x', IL = IL, ISS = ISS}
1026  : HSR
1027
1028fun HSR_IL_rupd ({EC, IL, ISS}: HSR, x') = {EC = EC, IL = x', ISS = ISS}
1029  : HSR
1030
1031fun HSR_ISS_rupd ({EC, IL, ISS}: HSR, x') = {EC = EC, IL = IL, ISS = x'}
1032  : HSR
1033
1034fun SCR_AW_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1035  : SCR, x') =
1036  {AW = x', EA = EA, FIQ = FIQ, FW = FW, HCE = HCE, IRQ = IRQ, NS = NS,
1037   SCD = SCD, SIF = SIF, nET = nET, scr'rst = scr'rst}: SCR
1038
1039fun SCR_EA_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1040  : SCR, x') =
1041  {AW = AW, EA = x', FIQ = FIQ, FW = FW, HCE = HCE, IRQ = IRQ, NS = NS,
1042   SCD = SCD, SIF = SIF, nET = nET, scr'rst = scr'rst}: SCR
1043
1044fun SCR_FIQ_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1045  : SCR, x') =
1046  {AW = AW, EA = EA, FIQ = x', FW = FW, HCE = HCE, IRQ = IRQ, NS = NS,
1047   SCD = SCD, SIF = SIF, nET = nET, scr'rst = scr'rst}: SCR
1048
1049fun SCR_FW_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1050  : SCR, x') =
1051  {AW = AW, EA = EA, FIQ = FIQ, FW = x', HCE = HCE, IRQ = IRQ, NS = NS,
1052   SCD = SCD, SIF = SIF, nET = nET, scr'rst = scr'rst}: SCR
1053
1054fun SCR_HCE_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1055  : SCR, x') =
1056  {AW = AW, EA = EA, FIQ = FIQ, FW = FW, HCE = x', IRQ = IRQ, NS = NS,
1057   SCD = SCD, SIF = SIF, nET = nET, scr'rst = scr'rst}: SCR
1058
1059fun SCR_IRQ_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1060  : SCR, x') =
1061  {AW = AW, EA = EA, FIQ = FIQ, FW = FW, HCE = HCE, IRQ = x', NS = NS,
1062   SCD = SCD, SIF = SIF, nET = nET, scr'rst = scr'rst}: SCR
1063
1064fun SCR_NS_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1065  : SCR, x') =
1066  {AW = AW, EA = EA, FIQ = FIQ, FW = FW, HCE = HCE, IRQ = IRQ, NS = x',
1067   SCD = SCD, SIF = SIF, nET = nET, scr'rst = scr'rst}: SCR
1068
1069fun SCR_SCD_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1070  : SCR, x') =
1071  {AW = AW, EA = EA, FIQ = FIQ, FW = FW, HCE = HCE, IRQ = IRQ, NS = NS,
1072   SCD = x', SIF = SIF, nET = nET, scr'rst = scr'rst}: SCR
1073
1074fun SCR_SIF_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1075  : SCR, x') =
1076  {AW = AW, EA = EA, FIQ = FIQ, FW = FW, HCE = HCE, IRQ = IRQ, NS = NS,
1077   SCD = SCD, SIF = x', nET = nET, scr'rst = scr'rst}: SCR
1078
1079fun SCR_nET_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET, scr'rst}
1080  : SCR, x') =
1081  {AW = AW, EA = EA, FIQ = FIQ, FW = FW, HCE = HCE, IRQ = IRQ, NS = NS,
1082   SCD = SCD, SIF = SIF, nET = x', scr'rst = scr'rst}: SCR
1083
1084fun SCR_scr'rst_rupd ({AW, EA, FIQ, FW, HCE, IRQ, NS, SCD, SIF, nET,
1085   scr'rst}: SCR, x') =
1086  {AW = AW, EA = EA, FIQ = FIQ, FW = FW, HCE = HCE, IRQ = IRQ, NS = NS,
1087   SCD = SCD, SIF = SIF, nET = nET, scr'rst = x'}: SCR
1088
1089fun NSACR_NSASEDIS_rupd ({NSASEDIS, NSD32DIS, NSTRCDIS, RFR, cp, nsacr'rst}
1090  : NSACR, x') =
1091  {NSASEDIS = x', NSD32DIS = NSD32DIS, NSTRCDIS = NSTRCDIS, RFR = RFR,
1092   cp = cp, nsacr'rst = nsacr'rst}: NSACR
1093
1094fun NSACR_NSD32DIS_rupd ({NSASEDIS, NSD32DIS, NSTRCDIS, RFR, cp, nsacr'rst}
1095  : NSACR, x') =
1096  {NSASEDIS = NSASEDIS, NSD32DIS = x', NSTRCDIS = NSTRCDIS, RFR = RFR,
1097   cp = cp, nsacr'rst = nsacr'rst}: NSACR
1098
1099fun NSACR_NSTRCDIS_rupd ({NSASEDIS, NSD32DIS, NSTRCDIS, RFR, cp, nsacr'rst}
1100  : NSACR, x') =
1101  {NSASEDIS = NSASEDIS, NSD32DIS = NSD32DIS, NSTRCDIS = x', RFR = RFR,
1102   cp = cp, nsacr'rst = nsacr'rst}: NSACR
1103
1104fun NSACR_RFR_rupd ({NSASEDIS, NSD32DIS, NSTRCDIS, RFR, cp, nsacr'rst}
1105  : NSACR, x') =
1106  {NSASEDIS = NSASEDIS, NSD32DIS = NSD32DIS, NSTRCDIS = NSTRCDIS,
1107   RFR = x', cp = cp, nsacr'rst = nsacr'rst}: NSACR
1108
1109fun NSACR_cp_rupd ({NSASEDIS, NSD32DIS, NSTRCDIS, RFR, cp, nsacr'rst}
1110  : NSACR, x') =
1111  {NSASEDIS = NSASEDIS, NSD32DIS = NSD32DIS, NSTRCDIS = NSTRCDIS,
1112   RFR = RFR, cp = x', nsacr'rst = nsacr'rst}: NSACR
1113
1114fun NSACR_nsacr'rst_rupd ({NSASEDIS, NSD32DIS, NSTRCDIS, RFR, cp,
1115   nsacr'rst}: NSACR, x') =
1116  {NSASEDIS = NSASEDIS, NSD32DIS = NSD32DIS, NSTRCDIS = NSTRCDIS,
1117   RFR = RFR, cp = cp, nsacr'rst = x'}: NSACR
1118
1119fun HCR_AMO_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1120   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1121  : HCR, x') =
1122  {AMO = x', BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO, PTW = PTW,
1123   SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP, TPC = TPC,
1124   TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM, TWE = TWE,
1125   TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM, hcr'rst = hcr'rst}: HCR
1126
1127fun HCR_BSU_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1128   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1129  : HCR, x') =
1130  {AMO = AMO, BSU = x', DC = DC, FB = FB, FMO = FMO, IMO = IMO, PTW = PTW,
1131   SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP, TPC = TPC,
1132   TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM, TWE = TWE,
1133   TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM, hcr'rst = hcr'rst}: HCR
1134
1135fun HCR_DC_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1136   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1137  : HCR, x') =
1138  {AMO = AMO, BSU = BSU, DC = x', FB = FB, FMO = FMO, IMO = IMO,
1139   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1140   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1141   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1142   hcr'rst = hcr'rst}: HCR
1143
1144fun HCR_FB_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1145   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1146  : HCR, x') =
1147  {AMO = AMO, BSU = BSU, DC = DC, FB = x', FMO = FMO, IMO = IMO,
1148   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1149   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1150   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1151   hcr'rst = hcr'rst}: HCR
1152
1153fun HCR_FMO_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1154   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1155  : HCR, x') =
1156  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = x', IMO = IMO, PTW = PTW,
1157   SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP, TPC = TPC,
1158   TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM, TWE = TWE,
1159   TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM, hcr'rst = hcr'rst}: HCR
1160
1161fun HCR_IMO_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1162   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1163  : HCR, x') =
1164  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = x', PTW = PTW,
1165   SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP, TPC = TPC,
1166   TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM, TWE = TWE,
1167   TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM, hcr'rst = hcr'rst}: HCR
1168
1169fun HCR_PTW_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1170   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1171  : HCR, x') =
1172  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO, PTW = x',
1173   SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP, TPC = TPC,
1174   TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM, TWE = TWE,
1175   TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM, hcr'rst = hcr'rst}: HCR
1176
1177fun HCR_SWIO_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1178   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1179  : HCR, x') =
1180  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1181   PTW = PTW, SWIO = x', TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1182   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1183   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1184   hcr'rst = hcr'rst}: HCR
1185
1186fun HCR_TAC_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1187   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1188  : HCR, x') =
1189  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1190   PTW = PTW, SWIO = SWIO, TAC = x', TGE = TGE, TID = TID, TIDCP = TIDCP,
1191   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1192   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1193   hcr'rst = hcr'rst}: HCR
1194
1195fun HCR_TGE_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1196   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1197  : HCR, x') =
1198  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1199   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = x', TID = TID, TIDCP = TIDCP,
1200   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1201   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1202   hcr'rst = hcr'rst}: HCR
1203
1204fun HCR_TID_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1205   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1206  : HCR, x') =
1207  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1208   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = x', TIDCP = TIDCP,
1209   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1210   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1211   hcr'rst = hcr'rst}: HCR
1212
1213fun HCR_TIDCP_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1214   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1215  : HCR, x') =
1216  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1217   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = x',
1218   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1219   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1220   hcr'rst = hcr'rst}: HCR
1221
1222fun HCR_TPC_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1223   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1224  : HCR, x') =
1225  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1226   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1227   TPC = x', TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1228   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1229   hcr'rst = hcr'rst}: HCR
1230
1231fun HCR_TPU_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1232   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1233  : HCR, x') =
1234  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1235   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1236   TPC = TPC, TPU = x', TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1237   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1238   hcr'rst = hcr'rst}: HCR
1239
1240fun HCR_TSC_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1241   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1242  : HCR, x') =
1243  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1244   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1245   TPC = TPC, TPU = TPU, TSC = x', TSW = TSW, TTLB = TTLB, TVM = TVM,
1246   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1247   hcr'rst = hcr'rst}: HCR
1248
1249fun HCR_TSW_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1250   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1251  : HCR, x') =
1252  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1253   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1254   TPC = TPC, TPU = TPU, TSC = TSC, TSW = x', TTLB = TTLB, TVM = TVM,
1255   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1256   hcr'rst = hcr'rst}: HCR
1257
1258fun HCR_TTLB_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1259   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1260  : HCR, x') =
1261  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1262   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1263   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = x', TVM = TVM,
1264   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1265   hcr'rst = hcr'rst}: HCR
1266
1267fun HCR_TVM_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1268   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1269  : HCR, x') =
1270  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1271   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1272   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = x',
1273   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1274   hcr'rst = hcr'rst}: HCR
1275
1276fun HCR_TWE_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1277   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1278  : HCR, x') =
1279  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1280   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1281   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1282   TWE = x', TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM,
1283   hcr'rst = hcr'rst}: HCR
1284
1285fun HCR_TWI_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1286   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1287  : HCR, x') =
1288  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1289   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1290   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1291   TWE = TWE, TWI = x', VA = VA, VF = VF, VI = VI, VM = VM,
1292   hcr'rst = hcr'rst}: HCR
1293
1294fun HCR_VA_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1295   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1296  : HCR, x') =
1297  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1298   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1299   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1300   TWE = TWE, TWI = TWI, VA = x', VF = VF, VI = VI, VM = VM,
1301   hcr'rst = hcr'rst}: HCR
1302
1303fun HCR_VF_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1304   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1305  : HCR, x') =
1306  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1307   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1308   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1309   TWE = TWE, TWI = TWI, VA = VA, VF = x', VI = VI, VM = VM,
1310   hcr'rst = hcr'rst}: HCR
1311
1312fun HCR_VI_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1313   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1314  : HCR, x') =
1315  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1316   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1317   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1318   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = x', VM = VM,
1319   hcr'rst = hcr'rst}: HCR
1320
1321fun HCR_VM_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE, TID,
1322   TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM, hcr'rst}
1323  : HCR, x') =
1324  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1325   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1326   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1327   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = x',
1328   hcr'rst = hcr'rst}: HCR
1329
1330fun HCR_hcr'rst_rupd ({AMO, BSU, DC, FB, FMO, IMO, PTW, SWIO, TAC, TGE,
1331   TID, TIDCP, TPC, TPU, TSC, TSW, TTLB, TVM, TWE, TWI, VA, VF, VI, VM,
1332   hcr'rst}: HCR, x') =
1333  {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1334   PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID, TIDCP = TIDCP,
1335   TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW, TTLB = TTLB, TVM = TVM,
1336   TWE = TWE, TWI = TWI, VA = VA, VF = VF, VI = VI, VM = VM, hcr'rst = x'}
1337  : HCR
1338
1339fun CP15_HCR_rupd ({HCR, HSCTLR, HSR, MVBAR, NSACR, SCR, SCTLR, VBAR}
1340  : CP15, x') =
1341  {HCR = x', HSCTLR = HSCTLR, HSR = HSR, MVBAR = MVBAR, NSACR = NSACR,
1342   SCR = SCR, SCTLR = SCTLR, VBAR = VBAR}: CP15
1343
1344fun CP15_HSCTLR_rupd ({HCR, HSCTLR, HSR, MVBAR, NSACR, SCR, SCTLR, VBAR}
1345  : CP15, x') =
1346  {HCR = HCR, HSCTLR = x', HSR = HSR, MVBAR = MVBAR, NSACR = NSACR,
1347   SCR = SCR, SCTLR = SCTLR, VBAR = VBAR}: CP15
1348
1349fun CP15_HSR_rupd ({HCR, HSCTLR, HSR, MVBAR, NSACR, SCR, SCTLR, VBAR}
1350  : CP15, x') =
1351  {HCR = HCR, HSCTLR = HSCTLR, HSR = x', MVBAR = MVBAR, NSACR = NSACR,
1352   SCR = SCR, SCTLR = SCTLR, VBAR = VBAR}: CP15
1353
1354fun CP15_MVBAR_rupd ({HCR, HSCTLR, HSR, MVBAR, NSACR, SCR, SCTLR, VBAR}
1355  : CP15, x') =
1356  {HCR = HCR, HSCTLR = HSCTLR, HSR = HSR, MVBAR = x', NSACR = NSACR,
1357   SCR = SCR, SCTLR = SCTLR, VBAR = VBAR}: CP15
1358
1359fun CP15_NSACR_rupd ({HCR, HSCTLR, HSR, MVBAR, NSACR, SCR, SCTLR, VBAR}
1360  : CP15, x') =
1361  {HCR = HCR, HSCTLR = HSCTLR, HSR = HSR, MVBAR = MVBAR, NSACR = x',
1362   SCR = SCR, SCTLR = SCTLR, VBAR = VBAR}: CP15
1363
1364fun CP15_SCR_rupd ({HCR, HSCTLR, HSR, MVBAR, NSACR, SCR, SCTLR, VBAR}
1365  : CP15, x') =
1366  {HCR = HCR, HSCTLR = HSCTLR, HSR = HSR, MVBAR = MVBAR, NSACR = NSACR,
1367   SCR = x', SCTLR = SCTLR, VBAR = VBAR}: CP15
1368
1369fun CP15_SCTLR_rupd ({HCR, HSCTLR, HSR, MVBAR, NSACR, SCR, SCTLR, VBAR}
1370  : CP15, x') =
1371  {HCR = HCR, HSCTLR = HSCTLR, HSR = HSR, MVBAR = MVBAR, NSACR = NSACR,
1372   SCR = SCR, SCTLR = x', VBAR = VBAR}: CP15
1373
1374fun CP15_VBAR_rupd ({HCR, HSCTLR, HSR, MVBAR, NSACR, SCR, SCTLR, VBAR}
1375  : CP15, x') =
1376  {HCR = HCR, HSCTLR = HSCTLR, HSR = HSR, MVBAR = MVBAR, NSACR = NSACR,
1377   SCR = SCR, SCTLR = SCTLR, VBAR = x'}: CP15
1378
1379fun FPSCR_AHP_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1380   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1381  {AHP = x', C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1382   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1383   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1384   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1385
1386fun FPSCR_C_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC, IXE,
1387   N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1388  {AHP = AHP, C = x', DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1389   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1390   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1391   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1392
1393fun FPSCR_DN_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1394   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1395  {AHP = AHP, C = C, DN = x', DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1396   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1397   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1398   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1399
1400fun FPSCR_DZC_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1401   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1402  {AHP = AHP, C = C, DN = DN, DZC = x', DZE = DZE, FZ = FZ, IDC = IDC,
1403   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1404   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1405   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1406
1407fun FPSCR_DZE_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1408   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1409  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = x', FZ = FZ, IDC = IDC,
1410   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1411   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1412   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1413
1414fun FPSCR_FZ_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1415   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1416  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = x', IDC = IDC,
1417   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1418   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1419   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1420
1421fun FPSCR_IDC_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1422   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1423  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = x',
1424   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1425   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1426   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1427
1428fun FPSCR_IDE_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1429   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1430  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1431   IDE = x', IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N, OFC = OFC,
1432   OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE, V = V, Z = Z,
1433   fpscr'rst = fpscr'rst}: FPSCR
1434
1435fun FPSCR_IOC_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1436   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1437  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1438   IDE = IDE, IOC = x', IOE = IOE, IXC = IXC, IXE = IXE, N = N, OFC = OFC,
1439   OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE, V = V, Z = Z,
1440   fpscr'rst = fpscr'rst}: FPSCR
1441
1442fun FPSCR_IOE_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1443   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1444  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1445   IDE = IDE, IOC = IOC, IOE = x', IXC = IXC, IXE = IXE, N = N, OFC = OFC,
1446   OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE, V = V, Z = Z,
1447   fpscr'rst = fpscr'rst}: FPSCR
1448
1449fun FPSCR_IXC_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1450   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1451  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1452   IDE = IDE, IOC = IOC, IOE = IOE, IXC = x', IXE = IXE, N = N, OFC = OFC,
1453   OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE, V = V, Z = Z,
1454   fpscr'rst = fpscr'rst}: FPSCR
1455
1456fun FPSCR_IXE_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1457   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1458  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1459   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = x', N = N, OFC = OFC,
1460   OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE, V = V, Z = Z,
1461   fpscr'rst = fpscr'rst}: FPSCR
1462
1463fun FPSCR_N_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC, IXE,
1464   N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1465  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1466   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = x',
1467   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1468   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1469
1470fun FPSCR_OFC_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1471   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1472  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1473   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N, OFC = x',
1474   OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE, V = V, Z = Z,
1475   fpscr'rst = fpscr'rst}: FPSCR
1476
1477fun FPSCR_OFE_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1478   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1479  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1480   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1481   OFC = OFC, OFE = x', QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1482   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1483
1484fun FPSCR_QC_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1485   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1486  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1487   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1488   OFC = OFC, OFE = OFE, QC = x', RMode = RMode, UFC = UFC, UFE = UFE,
1489   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1490
1491fun FPSCR_RMode_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1492   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1493  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1494   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1495   OFC = OFC, OFE = OFE, QC = QC, RMode = x', UFC = UFC, UFE = UFE, V = V,
1496   Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1497
1498fun FPSCR_UFC_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1499   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1500  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1501   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1502   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = x', UFE = UFE,
1503   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1504
1505fun FPSCR_UFE_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC,
1506   IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1507  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1508   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1509   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = x',
1510   V = V, Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1511
1512fun FPSCR_V_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC, IXE,
1513   N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1514  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1515   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1516   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1517   V = x', Z = Z, fpscr'rst = fpscr'rst}: FPSCR
1518
1519fun FPSCR_Z_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE, IXC, IXE,
1520   N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}: FPSCR, x') =
1521  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1522   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1523   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1524   V = V, Z = x', fpscr'rst = fpscr'rst}: FPSCR
1525
1526fun FPSCR_fpscr'rst_rupd ({AHP, C, DN, DZC, DZE, FZ, IDC, IDE, IOC, IOE,
1527   IXC, IXE, N, OFC, OFE, QC, RMode, UFC, UFE, V, Z, fpscr'rst}
1528  : FPSCR, x') =
1529  {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
1530   IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
1531   OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
1532   V = V, Z = Z, fpscr'rst = x'}: FPSCR
1533
1534fun FP_FPSCR_rupd ({FPSCR, REG}: FP, x') = {FPSCR = x', REG = REG}: FP
1535
1536fun FP_REG_rupd ({FPSCR, REG}: FP, x') = {FPSCR = FPSCR, REG = x'}: FP
1537
1538(* -------------------------------------------------------------------------
1539   Exceptions
1540   ------------------------------------------------------------------------- *)
1541
1542exception ASSERT of string
1543
1544exception AlignmentFault of BitsN.nbit
1545
1546exception IMPLEMENTATION_DEFINED of string
1547
1548exception UNPREDICTABLE of string
1549
1550exception VFP_EXCEPTION of string
1551
1552(* -------------------------------------------------------------------------
1553   Global variables (state)
1554   ------------------------------------------------------------------------- *)
1555
1556val Architecture = ref (ARMv4): Architecture ref
1557
1558val CP14 = ref ({TEEHBR = BitsN.B(0x0,32)}): CP14 ref
1559
1560val CP15 = ref
1561  ({HCR =
1562      {AMO = false, BSU = BitsN.B(0x0,2), DC = false, FB = false,
1563       FMO = false, IMO = false, PTW = false, SWIO = false, TAC = false,
1564       TGE = false, TID = BitsN.B(0x0,4), TIDCP = false, TPC = false,
1565       TPU = false, TSC = false, TSW = false, TTLB = false, TVM = false,
1566       TWE = false, TWI = false, VA = false, VF = false, VI = false,
1567       VM = false, hcr'rst = BitsN.B(0x0,4)},
1568    HSCTLR =
1569      {A = false, C = false, CP15BEN = false, EE = false, FI = false,
1570       I = false, M = false, TE = false, WXN = false,
1571       hsctlr'rst = BitsN.B(0x0,23)},
1572    HSR = {EC = BitsN.B(0x0,6), IL = false, ISS = BitsN.B(0x0,25)},
1573    MVBAR = BitsN.B(0x0,32),
1574    NSACR =
1575      {NSASEDIS = false, NSD32DIS = false, NSTRCDIS = false, RFR = false,
1576       cp = BitsN.B(0x0,14), nsacr'rst = BitsN.B(0x0,14)},
1577    SCR =
1578      {AW = false, EA = false, FIQ = false, FW = false, HCE = false,
1579       IRQ = false, NS = false, SCD = false, SIF = false, nET = false,
1580       scr'rst = BitsN.B(0x0,22)},
1581    SCTLR =
1582      {A = false, B = false, BR = false, C = false, DZ = false,
1583       EE = false, FI = false, I = false, IE = false, M = false,
1584       NMFI = false, RR = false, SW = false, TE = false, U = false,
1585       V = false, VE = false, Z = false, sctlr'rst = BitsN.B(0x0,14)},
1586    VBAR = BitsN.B(0x0,32)}): CP15 ref
1587
1588val CPSR = ref
1589  ({A = false, C = false, E = false, F = false, GE = BitsN.B(0x0,4),
1590    I = false, IT = BitsN.B(0x0,8), J = false, M = BitsN.B(0x0,5),
1591    N = false, Q = false, T = false, V = false, Z = false,
1592    psr'rst = BitsN.B(0x0,4)}): PSR ref
1593
1594val CurrentCondition = ref (BitsN.B(0x0,4)): BitsN.nbit ref
1595
1596val ELR_hyp = ref (BitsN.B(0x0,32)): BitsN.nbit ref
1597
1598val Encoding = ref (Encoding_ARM): Encoding ref
1599
1600val Extensions = ref ([]): (Extensions list) ref
1601
1602val FP = ref
1603  ({FPSCR =
1604      {AHP = false, C = false, DN = false, DZC = false, DZE = false,
1605       FZ = false, IDC = false, IDE = false, IOC = false, IOE = false,
1606       IXC = false, IXE = false, N = false, OFC = false, OFE = false,
1607       QC = false, RMode = BitsN.B(0x0,2), UFC = false, UFE = false,
1608       V = false, Z = false, fpscr'rst = BitsN.B(0x0,10)},
1609    REG = Map.mkMap(SOME 32,BitsN.B(0x0,64))}): FP ref
1610
1611val MEM = ref (Map.mkMap(SOME 4294967296,BitsN.B(0x0,8)))
1612  : (BitsN.nbit Map.map) ref
1613
1614val REG = ref (Map.mkMap(SOME 34,BitsN.B(0x0,32)))
1615  : (BitsN.nbit Map.map) ref
1616
1617val SPSR_abt = ref
1618  ({A = false, C = false, E = false, F = false, GE = BitsN.B(0x0,4),
1619    I = false, IT = BitsN.B(0x0,8), J = false, M = BitsN.B(0x0,5),
1620    N = false, Q = false, T = false, V = false, Z = false,
1621    psr'rst = BitsN.B(0x0,4)}): PSR ref
1622
1623val SPSR_fiq = ref
1624  ({A = false, C = false, E = false, F = false, GE = BitsN.B(0x0,4),
1625    I = false, IT = BitsN.B(0x0,8), J = false, M = BitsN.B(0x0,5),
1626    N = false, Q = false, T = false, V = false, Z = false,
1627    psr'rst = BitsN.B(0x0,4)}): PSR ref
1628
1629val SPSR_hyp = ref
1630  ({A = false, C = false, E = false, F = false, GE = BitsN.B(0x0,4),
1631    I = false, IT = BitsN.B(0x0,8), J = false, M = BitsN.B(0x0,5),
1632    N = false, Q = false, T = false, V = false, Z = false,
1633    psr'rst = BitsN.B(0x0,4)}): PSR ref
1634
1635val SPSR_irq = ref
1636  ({A = false, C = false, E = false, F = false, GE = BitsN.B(0x0,4),
1637    I = false, IT = BitsN.B(0x0,8), J = false, M = BitsN.B(0x0,5),
1638    N = false, Q = false, T = false, V = false, Z = false,
1639    psr'rst = BitsN.B(0x0,4)}): PSR ref
1640
1641val SPSR_mon = ref
1642  ({A = false, C = false, E = false, F = false, GE = BitsN.B(0x0,4),
1643    I = false, IT = BitsN.B(0x0,8), J = false, M = BitsN.B(0x0,5),
1644    N = false, Q = false, T = false, V = false, Z = false,
1645    psr'rst = BitsN.B(0x0,4)}): PSR ref
1646
1647val SPSR_svc = ref
1648  ({A = false, C = false, E = false, F = false, GE = BitsN.B(0x0,4),
1649    I = false, IT = BitsN.B(0x0,8), J = false, M = BitsN.B(0x0,5),
1650    N = false, Q = false, T = false, V = false, Z = false,
1651    psr'rst = BitsN.B(0x0,4)}): PSR ref
1652
1653val SPSR_und = ref
1654  ({A = false, C = false, E = false, F = false, GE = BitsN.B(0x0,4),
1655    I = false, IT = BitsN.B(0x0,8), J = false, M = BitsN.B(0x0,5),
1656    N = false, Q = false, T = false, V = false, Z = false,
1657    psr'rst = BitsN.B(0x0,4)}): PSR ref
1658
1659val VFPExtension = ref (NoVFP): VFPExtension ref
1660
1661val undefined = ref (false): bool ref
1662
1663(* -------------------------------------------------------------------------
1664   Main specification
1665   ------------------------------------------------------------------------- *)
1666
1667local
1668  fun tuple'5 [t0,t1,t2,t3,t4] = (t0,(t1,(t2,(t3,t4))))
1669    | tuple'5 (_: bool list) = raise Fail "tuple'5"
1670in
1671  val boolify'5 = tuple'5 o BitsN.toList
1672end
1673
1674local
1675  fun tuple'16 [t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15] =
1676    (t0,
1677     (t1,
1678      (t2,
1679       (t3,(t4,(t5,(t6,(t7,(t8,(t9,(t10,(t11,(t12,(t13,(t14,t15)))))))))))))))
1680    | tuple'16 (_: bool list) = raise Fail "tuple'16"
1681in
1682  val boolify'16 = tuple'16 o BitsN.toList
1683end
1684
1685local
1686  fun tuple'4 [t0,t1,t2,t3] = (t0,(t1,(t2,t3)))
1687    | tuple'4 (_: bool list) = raise Fail "tuple'4"
1688in
1689  val boolify'4 = tuple'4 o BitsN.toList
1690end
1691
1692local
1693  fun tuple'28 [t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,
1694                t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27] =
1695    (t0,
1696     (t1,
1697      (t2,
1698       (t3,
1699        (t4,
1700         (t5,
1701          (t6,
1702           (t7,
1703            (t8,
1704             (t9,
1705              (t10,
1706               (t11,
1707                (t12,
1708                 (t13,
1709                  (t14,
1710                   (t15,
1711                    (t16,
1712                     (t17,
1713                      (t18,
1714                       (t19,(t20,(t21,(t22,(t23,(t24,(t25,(t26,t27)))))))))))))))))))))))))))
1715    | tuple'28 (_: bool list) = raise Fail "tuple'28"
1716in
1717  val boolify'28 = tuple'28 o BitsN.toList
1718end
1719
1720local
1721  fun tuple'3 [t0,t1,t2] = (t0,(t1,t2))
1722    | tuple'3 (_: bool list) = raise Fail "tuple'3"
1723in
1724  val boolify'3 = tuple'3 o BitsN.toList
1725end
1726
1727local
1728  fun tuple'8 [t0,t1,t2,t3,t4,t5,t6,t7] =
1729    (t0,(t1,(t2,(t3,(t4,(t5,(t6,t7)))))))
1730    | tuple'8 (_: bool list) = raise Fail "tuple'8"
1731in
1732  val boolify'8 = tuple'8 o BitsN.toList
1733end
1734
1735fun ArchVersion () =
1736  case (!Architecture) of
1737     ARMv4 => 4
1738   | ARMv4T => 4
1739   | ARMv5T => 5
1740   | ARMv5TE => 5
1741   | ARMv6 => 6
1742   | ARMv6K => 6
1743   | ARMv6T2 => 6
1744   | ARMv7_A => 7
1745   | ARMv7_R => 7;
1746
1747fun HaveDSPSupport () =
1748  not(Set.mem((!Architecture),[ARMv4,ARMv4T,ARMv5T]));
1749
1750fun HaveThumb2 () = Set.mem((!Architecture),[ARMv6T2,ARMv7_A,ARMv7_R]);
1751
1752fun HaveThumbEE () =
1753  ((!Architecture) = ARMv7_A) orelse
1754  (((!Architecture) = ARMv7_R) andalso
1755   (Set.mem(Extension_ThumbEE,(!Extensions))));
1756
1757fun HaveMPExt () =
1758  (Nat.>=(ArchVersion (),7)) andalso
1759  (Set.mem(Extension_Multiprocessing,(!Extensions)));
1760
1761fun HaveSecurityExt () =
1762  (Set.mem((!Architecture),[ARMv6K,ARMv7_A])) andalso
1763  (Set.mem(Extension_Security,(!Extensions)));
1764
1765fun HaveVirtExt () =
1766  (Nat.>=(ArchVersion (),7)) andalso
1767  (Set.mem(Extension_Virtualization,(!Extensions)));
1768
1769fun rec'PSR x =
1770  {A = BitsN.bit(x,8), C = BitsN.bit(x,29), E = BitsN.bit(x,9),
1771   F = BitsN.bit(x,6), GE = BitsN.bits(19,16) x, I = BitsN.bit(x,7),
1772   IT = BitsN.@@(BitsN.bits(15,10) x,BitsN.bits(26,25) x),
1773   J = BitsN.bit(x,24), M = BitsN.bits(4,0) x, N = BitsN.bit(x,31),
1774   Q = BitsN.bit(x,27), T = BitsN.bit(x,5), V = BitsN.bit(x,28),
1775   Z = BitsN.bit(x,30), psr'rst = BitsN.bits(23,20) x};
1776
1777fun reg'PSR x =
1778  case x of
1779     {A = A, C = C, E = E, F = F, GE = GE, I = I, IT = IT, J = J, M = M,
1780      N = N, Q = Q, T = T, V = V, Z = Z, psr'rst = psr'rst} =>
1781       BitsN.concat
1782         [BitsN.fromBit N,BitsN.fromBit Z,BitsN.fromBit C,BitsN.fromBit V,
1783          BitsN.fromBit Q,BitsN.bits(1,0) IT,BitsN.fromBit J,psr'rst,GE,
1784          BitsN.bits(7,2) IT,BitsN.fromBit E,BitsN.fromBit A,
1785          BitsN.fromBit I,BitsN.fromBit F,BitsN.fromBit T,M];
1786
1787fun write'rec'PSR (_,x) = reg'PSR x;
1788
1789fun write'reg'PSR (_,x) = rec'PSR x;
1790
1791fun rec'SCTLR x =
1792  {A = BitsN.bit(x,1), B = BitsN.bit(x,7), BR = BitsN.bit(x,17),
1793   C = BitsN.bit(x,2), DZ = BitsN.bit(x,19), EE = BitsN.bit(x,25),
1794   FI = BitsN.bit(x,21), I = BitsN.bit(x,12), IE = BitsN.bit(x,31),
1795   M = BitsN.bit(x,0), NMFI = BitsN.bit(x,27), RR = BitsN.bit(x,14),
1796   SW = BitsN.bit(x,10), TE = BitsN.bit(x,30), U = BitsN.bit(x,22),
1797   V = BitsN.bit(x,13), VE = BitsN.bit(x,24), Z = BitsN.bit(x,11),
1798   sctlr'rst =
1799     BitsN.concat
1800       [BitsN.bits(6,3) x,BitsN.bits(9,8) x,BitsN.bits(16,15) x,
1801        BitsN.bits(18,18) x,BitsN.bits(20,20) x,BitsN.bits(23,23) x,
1802        BitsN.bits(26,26) x,BitsN.bits(29,28) x]};
1803
1804fun reg'SCTLR x =
1805  case x of
1806     {A = A, B = B, BR = BR, C = C, DZ = DZ, EE = EE, FI = FI, I = I,
1807      IE = IE, M = M, NMFI = NMFI, RR = RR, SW = SW, TE = TE, U = U,
1808      V = V, VE = VE, Z = Z, sctlr'rst = sctlr'rst} =>
1809       BitsN.concat
1810         [BitsN.fromBit IE,BitsN.fromBit TE,BitsN.bits(1,0) sctlr'rst,
1811          BitsN.fromBit NMFI,BitsN.bits(2,2) sctlr'rst,BitsN.fromBit EE,
1812          BitsN.fromBit VE,BitsN.bits(3,3) sctlr'rst,BitsN.fromBit U,
1813          BitsN.fromBit FI,BitsN.bits(4,4) sctlr'rst,BitsN.fromBit DZ,
1814          BitsN.bits(5,5) sctlr'rst,BitsN.fromBit BR,
1815          BitsN.bits(7,6) sctlr'rst,BitsN.fromBit RR,BitsN.fromBit V,
1816          BitsN.fromBit I,BitsN.fromBit Z,BitsN.fromBit SW,
1817          BitsN.bits(9,8) sctlr'rst,BitsN.fromBit B,
1818          BitsN.bits(13,10) sctlr'rst,BitsN.fromBit C,BitsN.fromBit A,
1819          BitsN.fromBit M];
1820
1821fun write'rec'SCTLR (_,x) = reg'SCTLR x;
1822
1823fun write'reg'SCTLR (_,x) = rec'SCTLR x;
1824
1825fun rec'HSCTLR x =
1826  {A = BitsN.bit(x,1), C = BitsN.bit(x,2), CP15BEN = BitsN.bit(x,5),
1827   EE = BitsN.bit(x,25), FI = BitsN.bit(x,21), I = BitsN.bit(x,12),
1828   M = BitsN.bit(x,0), TE = BitsN.bit(x,30), WXN = BitsN.bit(x,19),
1829   hsctlr'rst =
1830     BitsN.concat
1831       [BitsN.bits(4,3) x,BitsN.bits(11,6) x,BitsN.bits(18,13) x,
1832        BitsN.bits(20,20) x,BitsN.bits(24,22) x,BitsN.bits(29,26) x,
1833        BitsN.bits(31,31) x]};
1834
1835fun reg'HSCTLR x =
1836  case x of
1837     {A = A, C = C, CP15BEN = CP15BEN, EE = EE, FI = FI, I = I, M = M,
1838      TE = TE, WXN = WXN, hsctlr'rst = hsctlr'rst} =>
1839       BitsN.concat
1840         [BitsN.bits(0,0) hsctlr'rst,BitsN.fromBit TE,
1841          BitsN.bits(4,1) hsctlr'rst,BitsN.fromBit EE,
1842          BitsN.bits(7,5) hsctlr'rst,BitsN.fromBit FI,
1843          BitsN.bits(8,8) hsctlr'rst,BitsN.fromBit WXN,
1844          BitsN.bits(14,9) hsctlr'rst,BitsN.fromBit I,
1845          BitsN.bits(20,15) hsctlr'rst,BitsN.fromBit CP15BEN,
1846          BitsN.bits(22,21) hsctlr'rst,BitsN.fromBit C,BitsN.fromBit A,
1847          BitsN.fromBit M];
1848
1849fun write'rec'HSCTLR (_,x) = reg'HSCTLR x;
1850
1851fun write'reg'HSCTLR (_,x) = rec'HSCTLR x;
1852
1853fun rec'HSR x =
1854  {EC = BitsN.bits(31,26) x, IL = BitsN.bit(x,25),
1855   ISS = BitsN.bits(24,0) x};
1856
1857fun reg'HSR x =
1858  case x of
1859     {EC = EC, IL = IL, ISS = ISS} =>
1860       BitsN.concat[EC,BitsN.fromBit IL,ISS];
1861
1862fun write'rec'HSR (_,x) = reg'HSR x;
1863
1864fun write'reg'HSR (_,x) = rec'HSR x;
1865
1866fun rec'SCR x =
1867  {AW = BitsN.bit(x,5), EA = BitsN.bit(x,3), FIQ = BitsN.bit(x,2),
1868   FW = BitsN.bit(x,4), HCE = BitsN.bit(x,8), IRQ = BitsN.bit(x,1),
1869   NS = BitsN.bit(x,0), SCD = BitsN.bit(x,7), SIF = BitsN.bit(x,9),
1870   nET = BitsN.bit(x,6), scr'rst = BitsN.bits(31,10) x};
1871
1872fun reg'SCR x =
1873  case x of
1874     {AW = AW, EA = EA, FIQ = FIQ, FW = FW, HCE = HCE, IRQ = IRQ, NS = NS,
1875      SCD = SCD, SIF = SIF, nET = nET, scr'rst = scr'rst} =>
1876       BitsN.concat
1877         [scr'rst,BitsN.fromBit SIF,BitsN.fromBit HCE,BitsN.fromBit SCD,
1878          BitsN.fromBit nET,BitsN.fromBit AW,BitsN.fromBit FW,
1879          BitsN.fromBit EA,BitsN.fromBit FIQ,BitsN.fromBit IRQ,
1880          BitsN.fromBit NS];
1881
1882fun write'rec'SCR (_,x) = reg'SCR x;
1883
1884fun write'reg'SCR (_,x) = rec'SCR x;
1885
1886fun rec'NSACR x =
1887  {NSASEDIS = BitsN.bit(x,15), NSD32DIS = BitsN.bit(x,14),
1888   NSTRCDIS = BitsN.bit(x,20), RFR = BitsN.bit(x,19),
1889   cp = BitsN.bits(13,0) x,
1890   nsacr'rst = BitsN.@@(BitsN.bits(18,16) x,BitsN.bits(31,21) x)};
1891
1892fun reg'NSACR x =
1893  case x of
1894     {NSASEDIS = NSASEDIS, NSD32DIS = NSD32DIS, NSTRCDIS = NSTRCDIS,
1895      RFR = RFR, cp = cp, nsacr'rst = nsacr'rst} =>
1896       BitsN.concat
1897         [BitsN.bits(10,0) nsacr'rst,BitsN.fromBit NSTRCDIS,
1898          BitsN.fromBit RFR,BitsN.bits(13,11) nsacr'rst,
1899          BitsN.fromBit NSASEDIS,BitsN.fromBit NSD32DIS,cp];
1900
1901fun write'rec'NSACR (_,x) = reg'NSACR x;
1902
1903fun write'reg'NSACR (_,x) = rec'NSACR x;
1904
1905fun rec'HCR x =
1906  {AMO = BitsN.bit(x,5), BSU = BitsN.bits(11,10) x, DC = BitsN.bit(x,12),
1907   FB = BitsN.bit(x,9), FMO = BitsN.bit(x,3), IMO = BitsN.bit(x,4),
1908   PTW = BitsN.bit(x,2), SWIO = BitsN.bit(x,1), TAC = BitsN.bit(x,21),
1909   TGE = BitsN.bit(x,27), TID = BitsN.bits(18,15) x,
1910   TIDCP = BitsN.bit(x,20), TPC = BitsN.bit(x,23), TPU = BitsN.bit(x,24),
1911   TSC = BitsN.bit(x,19), TSW = BitsN.bit(x,22), TTLB = BitsN.bit(x,25),
1912   TVM = BitsN.bit(x,26), TWE = BitsN.bit(x,14), TWI = BitsN.bit(x,13),
1913   VA = BitsN.bit(x,8), VF = BitsN.bit(x,6), VI = BitsN.bit(x,7),
1914   VM = BitsN.bit(x,0), hcr'rst = BitsN.bits(31,28) x};
1915
1916fun reg'HCR x =
1917  case x of
1918     {AMO = AMO, BSU = BSU, DC = DC, FB = FB, FMO = FMO, IMO = IMO,
1919      PTW = PTW, SWIO = SWIO, TAC = TAC, TGE = TGE, TID = TID,
1920      TIDCP = TIDCP, TPC = TPC, TPU = TPU, TSC = TSC, TSW = TSW,
1921      TTLB = TTLB, TVM = TVM, TWE = TWE, TWI = TWI, VA = VA, VF = VF,
1922      VI = VI, VM = VM, hcr'rst = hcr'rst} =>
1923       BitsN.concat
1924         [hcr'rst,BitsN.fromBit TGE,BitsN.fromBit TVM,BitsN.fromBit TTLB,
1925          BitsN.fromBit TPU,BitsN.fromBit TPC,BitsN.fromBit TSW,
1926          BitsN.fromBit TAC,BitsN.fromBit TIDCP,BitsN.fromBit TSC,TID,
1927          BitsN.fromBit TWE,BitsN.fromBit TWI,BitsN.fromBit DC,BSU,
1928          BitsN.fromBit FB,BitsN.fromBit VA,BitsN.fromBit VI,
1929          BitsN.fromBit VF,BitsN.fromBit AMO,BitsN.fromBit IMO,
1930          BitsN.fromBit FMO,BitsN.fromBit PTW,BitsN.fromBit SWIO,
1931          BitsN.fromBit VM];
1932
1933fun write'rec'HCR (_,x) = reg'HCR x;
1934
1935fun write'reg'HCR (_,x) = rec'HCR x;
1936
1937fun ProcessorID () = 0;
1938
1939fun IsExternalAbort () = false;
1940
1941fun IsSecure () =
1942  (not(HaveSecurityExt ())) orelse
1943  ((not(#NS((#SCR((!CP15) : CP15)) : SCR))) orelse
1944   ((#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))));
1945
1946fun UnalignedSupport () =
1947  let
1948    val v = ArchVersion ()
1949  in
1950    (Nat.>=(v,7)) orelse
1951    ((v = 6) andalso (#U((#SCTLR((!CP15) : CP15)) : SCTLR)))
1952  end;
1953
1954fun BadMode mode =
1955  case mode of
1956     BitsN.B(0x10,_) => false
1957   | BitsN.B(0x11,_) => false
1958   | BitsN.B(0x12,_) => false
1959   | BitsN.B(0x13,_) => false
1960   | BitsN.B(0x16,_) => not(HaveSecurityExt ())
1961   | BitsN.B(0x17,_) => false
1962   | BitsN.B(0x1A,_) => not(HaveVirtExt ())
1963   | BitsN.B(0x1B,_) => false
1964   | BitsN.B(0x1F,_) => false
1965   | _ => true;
1966
1967fun CurrentModeIsNotUser () =
1968  ( if BadMode(#M((!CPSR) : PSR))
1969      then raise UNPREDICTABLE
1970             ("BadMode: " ^ (BitsN.toHexString(#M((!CPSR) : PSR))))
1971    else ()
1972  ; not((#M((!CPSR) : PSR)) = (BitsN.B(0x10,5)))
1973  );
1974
1975fun CurrentModeIsUserOrSystem () =
1976  ( if BadMode(#M((!CPSR) : PSR))
1977      then raise UNPREDICTABLE
1978             ("BadMode: " ^ (BitsN.toHexString(#M((!CPSR) : PSR))))
1979    else ()
1980  ; Set.mem(#M((!CPSR) : PSR),[BitsN.B(0x10,5),BitsN.B(0x1F,5)])
1981  );
1982
1983fun CurrentModeIsHyp () =
1984  ( if BadMode(#M((!CPSR) : PSR))
1985      then raise UNPREDICTABLE
1986             ("BadMode: " ^ (BitsN.toHexString(#M((!CPSR) : PSR))))
1987    else ()
1988  ; (#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5))
1989  );
1990
1991fun IntegerZeroDivideTrappingEnabled () =
1992  #DZ((#SCTLR((!CP15) : CP15)) : SCTLR);
1993
1994fun ISETSTATE () =
1995  BitsN.@@
1996    (BitsN.fromBit(#J((!CPSR) : PSR)),BitsN.fromBit(#T((!CPSR) : PSR)));
1997
1998fun write'ISETSTATE value =
1999  ( CPSR := (PSR_J_rupd((!CPSR),BitsN.bit(value,1)))
2000  ; CPSR := (PSR_T_rupd((!CPSR),BitsN.bit(value,0)))
2001  );
2002
2003fun CurrentInstrSet () =
2004  case ISETSTATE () of
2005     BitsN.B(0x0,_) => InstrSet_ARM
2006   | BitsN.B(0x1,_) => InstrSet_Thumb
2007   | BitsN.B(0x2,_) => InstrSet_Jazelle
2008   | BitsN.B(0x3,_) => InstrSet_ThumbEE
2009   | _ => raise General.Bind;
2010
2011fun SelectInstrSet iset =
2012  case iset of
2013     InstrSet_ARM =>
2014       if (CurrentInstrSet ()) = InstrSet_ThumbEE
2015         then raise UNPREDICTABLE "SelectInstrSet"
2016       else write'ISETSTATE(BitsN.B(0x0,2))
2017   | InstrSet_Thumb => write'ISETSTATE(BitsN.B(0x1,2))
2018   | InstrSet_Jazelle => write'ISETSTATE(BitsN.B(0x2,2))
2019   | InstrSet_ThumbEE => write'ISETSTATE(BitsN.B(0x3,2));
2020
2021fun ITSTATE () =
2022  if HaveThumb2 () then #IT((!CPSR) : PSR) else BitsN.B(0x0,8);
2023
2024fun write'ITSTATE value = CPSR := (PSR_IT_rupd((!CPSR),value));
2025
2026fun ITAdvance () =
2027  if (HaveThumb2 ()) andalso (not((!Encoding) = Encoding_ARM))
2028    then if (BitsN.bits(2,0) (ITSTATE ())) = (BitsN.B(0x0,3))
2029           then write'ITSTATE(BitsN.B(0x0,8))
2030         else let
2031                val w = ITSTATE ()
2032              in
2033                write'ITSTATE
2034                  (BitsN.bitFieldInsert(4,0)
2035                     (w,BitsN.<<(BitsN.bits(4,0) (ITSTATE ()),1)))
2036              end
2037  else ();
2038
2039fun InITBlock () = not((BitsN.bits(3,0) (ITSTATE ())) = (BitsN.B(0x0,4)));
2040
2041fun LastInITBlock () = (BitsN.bits(3,0) (ITSTATE ())) = (BitsN.B(0x8,4));
2042
2043fun ThumbCondition () =
2044  if (ITSTATE ()) = (BitsN.B(0x0,8))
2045    then BitsN.B(0xE,4)
2046  else if not((BitsN.bits(3,0) (#IT((!CPSR) : PSR))) = (BitsN.B(0x0,4)))
2047    then BitsN.bits(7,4) (#IT((!CPSR) : PSR))
2048  else raise UNPREDICTABLE "ThumbCondition";
2049
2050fun BigEndian () = #E((!CPSR) : PSR);
2051
2052fun SetExclusiveMonitors (address,n) = ();
2053
2054fun ExclusiveMonitorsPass (address,n) = false;
2055
2056fun ClearExclusiveLocal id = ();
2057
2058fun CurrentCond () = (!CurrentCondition);
2059
2060fun ConditionPassed () =
2061  let
2062    val cond = CurrentCond ()
2063    val result =
2064      case BitsN.bits(3,1) cond of
2065         BitsN.B(0x0,_) => #Z((!CPSR) : PSR)
2066       | BitsN.B(0x1,_) => #C((!CPSR) : PSR)
2067       | BitsN.B(0x2,_) => #N((!CPSR) : PSR)
2068       | BitsN.B(0x3,_) => #V((!CPSR) : PSR)
2069       | BitsN.B(0x4,_) =>
2070         (#C((!CPSR) : PSR)) andalso (not(#Z((!CPSR) : PSR)))
2071       | BitsN.B(0x5,_) => (#N((!CPSR) : PSR)) = (#V((!CPSR) : PSR))
2072       | BitsN.B(0x6,_) =>
2073         ((#N((!CPSR) : PSR)) = (#V((!CPSR) : PSR))) andalso
2074         (not(#Z((!CPSR) : PSR)))
2075       | BitsN.B(0x7,_) => true
2076       | _ => raise General.Bind
2077  in
2078    if (BitsN.bit(cond,0)) andalso (not(cond = (BitsN.B(0xF,4))))
2079      then not result
2080    else result
2081  end;
2082
2083fun SPSR () =
2084  if BadMode(#M((!CPSR) : PSR))
2085    then raise UNPREDICTABLE
2086           ("SPSR: BadMode: " ^ (BitsN.toHexString(#M((!CPSR) : PSR))))
2087  else case #M((!CPSR) : PSR) of
2088          BitsN.B(0x11,_) => (!SPSR_fiq)
2089        | BitsN.B(0x12,_) => (!SPSR_irq)
2090        | BitsN.B(0x13,_) => (!SPSR_svc)
2091        | BitsN.B(0x16,_) => (!SPSR_mon)
2092        | BitsN.B(0x17,_) => (!SPSR_abt)
2093        | BitsN.B(0x1A,_) => (!SPSR_hyp)
2094        | BitsN.B(0x1B,_) => (!SPSR_und)
2095        | _ => raise UNPREDICTABLE "SPSR";
2096
2097fun write'SPSR value =
2098  if BadMode(#M((!CPSR) : PSR))
2099    then raise UNPREDICTABLE
2100           ("SPSR: BadMode: " ^ (BitsN.toHexString(#M((!CPSR) : PSR))))
2101  else case #M((!CPSR) : PSR) of
2102          BitsN.B(0x11,_) => SPSR_fiq := value
2103        | BitsN.B(0x12,_) => SPSR_irq := value
2104        | BitsN.B(0x13,_) => SPSR_svc := value
2105        | BitsN.B(0x16,_) => SPSR_mon := value
2106        | BitsN.B(0x17,_) => SPSR_abt := value
2107        | BitsN.B(0x1A,_) => SPSR_hyp := value
2108        | BitsN.B(0x1B,_) => SPSR_und := value
2109        | _ => raise UNPREDICTABLE "SPSR";
2110
2111fun CPSRWriteByInstr (value,(bytemask,is_excpt_return)) =
2112  let
2113    val privileged = CurrentModeIsNotUser ()
2114    val nmfi = #NMFI((#SCTLR((!CP15) : CP15)) : SCTLR)
2115  in
2116    ( if BitsN.bit(bytemask,3)
2117        then ( let
2118                 val w = reg'PSR (!CPSR)
2119               in
2120                 CPSR :=
2121                 (write'reg'PSR
2122                    ((!CPSR),
2123                     BitsN.bitFieldInsert(31,27)
2124                       (w,BitsN.bits(31,27) value)))
2125               end
2126             ; if is_excpt_return
2127                 then let
2128                        val w = reg'PSR (!CPSR)
2129                      in
2130                        CPSR :=
2131                        (write'reg'PSR
2132                           ((!CPSR),
2133                            BitsN.bitFieldInsert(26,24)
2134                              (w,BitsN.bits(26,24) value)))
2135                      end
2136               else ()
2137             )
2138      else ()
2139    ; if BitsN.bit(bytemask,2)
2140        then let
2141               val w = reg'PSR (!CPSR)
2142             in
2143               CPSR :=
2144               (write'reg'PSR
2145                  ((!CPSR),
2146                   BitsN.bitFieldInsert(19,16) (w,BitsN.bits(19,16) value)))
2147             end
2148      else ()
2149    ; if BitsN.bit(bytemask,1)
2150        then ( if is_excpt_return
2151                 then let
2152                        val w = reg'PSR (!CPSR)
2153                      in
2154                        CPSR :=
2155                        (write'reg'PSR
2156                           ((!CPSR),
2157                            BitsN.bitFieldInsert(15,10)
2158                              (w,BitsN.bits(15,10) value)))
2159                      end
2160               else ()
2161             ; let
2162                 val w = reg'PSR (!CPSR)
2163               in
2164                 CPSR :=
2165                 (write'reg'PSR
2166                    ((!CPSR),
2167                     BitsN.bitFieldInsert(9,9)
2168                       (w,BitsN.fromBit(BitsN.bit(value,9)))))
2169               end
2170             ; if privileged andalso
2171                  ((IsSecure ()) orelse
2172                   (#AW((#SCR((!CP15) : CP15)) : SCR)))
2173                 then let
2174                        val w = reg'PSR (!CPSR)
2175                      in
2176                        CPSR :=
2177                        (write'reg'PSR
2178                           ((!CPSR),
2179                            BitsN.bitFieldInsert(8,8)
2180                              (w,BitsN.fromBit(BitsN.bit(value,8)))))
2181                      end
2182               else ()
2183             )
2184      else ()
2185    ; if BitsN.bit(bytemask,0)
2186        then ( if privileged
2187                 then let
2188                        val w = reg'PSR (!CPSR)
2189                      in
2190                        CPSR :=
2191                        (write'reg'PSR
2192                           ((!CPSR),
2193                            BitsN.bitFieldInsert(7,7)
2194                              (w,BitsN.fromBit(BitsN.bit(value,7)))))
2195                      end
2196               else ()
2197             ; if privileged andalso
2198                  (((not nmfi) orelse (not(BitsN.bit(value,6)))) andalso
2199                   ((IsSecure ()) orelse
2200                    ((#FW((#SCR((!CP15) : CP15)) : SCR)) orelse
2201                     (HaveVirtExt ()))))
2202                 then let
2203                        val w = reg'PSR (!CPSR)
2204                      in
2205                        CPSR :=
2206                        (write'reg'PSR
2207                           ((!CPSR),
2208                            BitsN.bitFieldInsert(6,6)
2209                              (w,BitsN.fromBit(BitsN.bit(value,6)))))
2210                      end
2211               else ()
2212             ; if is_excpt_return
2213                 then let
2214                        val w = reg'PSR (!CPSR)
2215                      in
2216                        CPSR :=
2217                        (write'reg'PSR
2218                           ((!CPSR),
2219                            BitsN.bitFieldInsert(5,5)
2220                              (w,BitsN.fromBit(BitsN.bit(value,5)))))
2221                      end
2222               else ()
2223             ; if privileged
2224                 then if BadMode(BitsN.bits(4,0) value)
2225                        then raise UNPREDICTABLE
2226                               ("CPSRWriteByInstr: BadMode: "
2227                                  ^
2228                                  (BitsN.toHexString
2229                                     (BitsN.bits(4,0) value)))
2230                      else ( if (not(IsSecure ())) andalso
2231                                ((BitsN.bits(4,0) value) =
2232                                 (BitsN.B(0x16,5)))
2233                               then raise UNPREDICTABLE "CPSRWriteByInstr"
2234                             else ()
2235                           ; if (not(IsSecure ())) andalso
2236                                (((BitsN.bits(4,0) value) =
2237                                  (BitsN.B(0x11,5))) andalso
2238                                 (#RFR((#NSACR((!CP15) : CP15)) : NSACR)))
2239                               then raise UNPREDICTABLE "CPSRWriteByInstr"
2240                             else ()
2241                           ; if (not(#NS((#SCR((!CP15) : CP15)) : SCR))) andalso
2242                                ((BitsN.bits(4,0) value) =
2243                                 (BitsN.B(0x1A,5)))
2244                               then raise UNPREDICTABLE "CPSRWriteByInstr"
2245                             else ()
2246                           ; if (not(IsSecure ())) andalso
2247                                ((not((#M((!CPSR) : PSR)) =
2248                                      (BitsN.B(0x1A,5)))) andalso
2249                                 ((BitsN.bits(4,0) value) =
2250                                  (BitsN.B(0x1A,5))))
2251                               then raise UNPREDICTABLE "CPSRWriteByInstr"
2252                             else ()
2253                           ; if ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5))) andalso
2254                                ((not((BitsN.bits(4,0) value) =
2255                                      (BitsN.B(0x1A,5)))) andalso
2256                                 (not is_excpt_return))
2257                               then raise UNPREDICTABLE "CPSRWriteByInstr"
2258                             else ()
2259                           ; let
2260                               val w = reg'PSR (!CPSR)
2261                             in
2262                               CPSR :=
2263                               (write'reg'PSR
2264                                  ((!CPSR),
2265                                   BitsN.bitFieldInsert(4,0)
2266                                     (w,BitsN.bits(4,0) value)))
2267                             end
2268                           )
2269               else ()
2270             )
2271      else ()
2272    )
2273  end;
2274
2275fun SPSRWriteByInstr (value,bytemask) =
2276  ( if CurrentModeIsUserOrSystem ()
2277      then raise UNPREDICTABLE "SPSRWriteByInstr"
2278    else ()
2279  ; if BitsN.bit(bytemask,3)
2280      then let
2281             val x = SPSR ()
2282             val w = reg'PSR x
2283           in
2284             write'SPSR
2285               (write'reg'PSR
2286                  (x,
2287                   BitsN.bitFieldInsert(31,24) (w,BitsN.bits(31,24) value)))
2288           end
2289    else ()
2290  ; if BitsN.bit(bytemask,2)
2291      then let
2292             val x = SPSR ()
2293             val w = reg'PSR x
2294           in
2295             write'SPSR
2296               (write'reg'PSR
2297                  (x,
2298                   BitsN.bitFieldInsert(19,16) (w,BitsN.bits(19,16) value)))
2299           end
2300    else ()
2301  ; if BitsN.bit(bytemask,1)
2302      then let
2303             val x = SPSR ()
2304             val w = reg'PSR x
2305           in
2306             write'SPSR
2307               (write'reg'PSR
2308                  (x,BitsN.bitFieldInsert(15,8) (w,BitsN.bits(15,8) value)))
2309           end
2310    else ()
2311  ; if BitsN.bit(bytemask,0)
2312      then ( let
2313               val x = SPSR ()
2314               val w = reg'PSR x
2315             in
2316               write'SPSR
2317                 (write'reg'PSR
2318                    (x,BitsN.bitFieldInsert(7,5) (w,BitsN.bits(7,5) value)))
2319             end
2320           ; if BadMode(BitsN.bits(4,0) value)
2321               then raise UNPREDICTABLE
2322                      ("SPSRWriteByInstr: BadMode: "
2323                         ^
2324                         (BitsN.toHexString(BitsN.bits(4,0) value)))
2325             else let
2326                    val x = SPSR ()
2327                    val w = reg'PSR x
2328                  in
2329                    write'SPSR
2330                      (write'reg'PSR
2331                         (x,
2332                          BitsN.bitFieldInsert(4,0)
2333                            (w,BitsN.bits(4,0) value)))
2334                  end
2335           )
2336    else ()
2337  );
2338
2339fun RBankSelect (mode,(usr,(fiq,(irq,(svc,(abt,(und,(mon,hyp)))))))) =
2340  if BadMode mode
2341    then raise UNPREDICTABLE
2342           ("RBankSelect: BadMode" ^ (BitsN.toHexString mode))
2343  else case mode of
2344          BitsN.B(0x10,_) => usr
2345        | BitsN.B(0x11,_) => fiq
2346        | BitsN.B(0x12,_) => irq
2347        | BitsN.B(0x13,_) => svc
2348        | BitsN.B(0x16,_) => mon
2349        | BitsN.B(0x17,_) => abt
2350        | BitsN.B(0x1A,_) => hyp
2351        | BitsN.B(0x1B,_) => und
2352        | BitsN.B(0x1F,_) => usr
2353        | _ => raise General.Bind;
2354
2355fun RfiqBankSelect (mode,(usr,fiq)) =
2356  RBankSelect(mode,(usr,(fiq,(usr,(usr,(usr,(usr,(usr,usr))))))));
2357
2358fun LookUpRName (n,mode) =
2359  case n of
2360     BitsN.B(0x0,_) => RName_0usr
2361   | BitsN.B(0x1,_) => RName_1usr
2362   | BitsN.B(0x2,_) => RName_2usr
2363   | BitsN.B(0x3,_) => RName_3usr
2364   | BitsN.B(0x4,_) => RName_4usr
2365   | BitsN.B(0x5,_) => RName_5usr
2366   | BitsN.B(0x6,_) => RName_6usr
2367   | BitsN.B(0x7,_) => RName_7usr
2368   | BitsN.B(0x8,_) => RfiqBankSelect(mode,(RName_8usr,RName_8fiq))
2369   | BitsN.B(0x9,_) => RfiqBankSelect(mode,(RName_9usr,RName_9fiq))
2370   | BitsN.B(0xA,_) => RfiqBankSelect(mode,(RName_10usr,RName_10fiq))
2371   | BitsN.B(0xB,_) => RfiqBankSelect(mode,(RName_11usr,RName_11fiq))
2372   | BitsN.B(0xC,_) => RfiqBankSelect(mode,(RName_12usr,RName_12fiq))
2373   | BitsN.B(0xD,_) =>
2374     RBankSelect
2375       (mode,
2376        (RName_SPusr,
2377         (RName_SPfiq,
2378          (RName_SPirq,
2379           (RName_SPsvc,
2380            (RName_SPabt,(RName_SPund,(RName_SPmon,RName_SPhyp))))))))
2381   | BitsN.B(0xE,_) =>
2382     RBankSelect
2383       (mode,
2384        (RName_LRusr,
2385         (RName_LRfiq,
2386          (RName_LRirq,
2387           (RName_LRsvc,
2388            (RName_LRabt,(RName_LRund,(RName_LRmon,RName_LRusr))))))))
2389   | BitsN.B(0xF,_) => raise ASSERT "LookUpRName: n >= 0 and n <= 14"
2390   | _ => raise General.Bind;
2391
2392fun Rmode (n,mode) =
2393  let
2394    val notSecure = not(IsSecure ())
2395  in
2396    ( if notSecure andalso (mode = (BitsN.B(0x16,5)))
2397        then raise UNPREDICTABLE "Rmode"
2398      else ()
2399    ; if notSecure andalso
2400         ((mode = (BitsN.B(0x11,5))) andalso
2401          (#RFR((#NSACR((!CP15) : CP15)) : NSACR)))
2402        then raise UNPREDICTABLE "Rmode"
2403      else ()
2404    ; Map.lookup((!REG),Cast.RNameToNat(LookUpRName(n,mode)))
2405    )
2406  end;
2407
2408fun write'Rmode (value,(n,mode)) =
2409  let
2410    val notSecure = not(IsSecure ())
2411  in
2412    ( if notSecure andalso (mode = (BitsN.B(0x16,5)))
2413        then raise UNPREDICTABLE "Rmode"
2414      else ()
2415    ; if notSecure andalso
2416         ((mode = (BitsN.B(0x11,5))) andalso
2417          (#RFR((#NSACR((!CP15) : CP15)) : NSACR)))
2418        then raise UNPREDICTABLE "Rmode"
2419      else ()
2420    ; if (n = (BitsN.B(0xD,4))) andalso
2421         ((not((BitsN.bits(1,0) value) = (BitsN.B(0x0,2)))) andalso
2422          (not((CurrentInstrSet ()) = InstrSet_ARM)))
2423        then raise UNPREDICTABLE "Rmode"
2424      else ()
2425    ; let
2426        val x = LookUpRName(n,mode)
2427      in
2428        REG := (Map.update((!REG),Cast.RNameToNat x,value))
2429      end
2430    )
2431  end;
2432
2433fun R n =
2434  if n = (BitsN.B(0xF,4))
2435    then let
2436           val offset =
2437             if (CurrentInstrSet ()) = InstrSet_ARM
2438               then BitsN.B(0x8,32)
2439             else BitsN.B(0x4,32)
2440         in
2441           BitsN.+(Map.lookup((!REG),Cast.RNameToNat RName_PC),offset)
2442         end
2443  else Rmode(n,#M((!CPSR) : PSR));
2444
2445fun write'R (value,n) =
2446  let val x = (n,#M((!CPSR) : PSR)) in write'Rmode(value,x) end;
2447
2448fun SP () = R(BitsN.B(0xD,4));
2449
2450fun write'SP value = write'R(value,BitsN.B(0xD,4));
2451
2452fun LR () = R(BitsN.B(0xE,4));
2453
2454fun write'LR value = write'R(value,BitsN.B(0xE,4));
2455
2456fun PC () = R(BitsN.B(0xF,4));
2457
2458fun BranchTo address =
2459  REG := (Map.update((!REG),Cast.RNameToNat RName_PC,address));
2460
2461fun PCStoreValue () = PC ();
2462
2463fun BranchWritePC address =
2464  if (CurrentInstrSet ()) = InstrSet_ARM
2465    then ( if (Nat.<(ArchVersion (),6)) andalso
2466              (not((BitsN.bits(1,0) address) = (BitsN.B(0x0,2))))
2467             then raise UNPREDICTABLE "BranchWritePC"
2468           else ()
2469         ; BranchTo(BitsN.@@(BitsN.bits(31,2) address,BitsN.B(0x0,2)))
2470         )
2471  else BranchTo(BitsN.@@(BitsN.bits(31,1) address,BitsN.B(0x0,1)));
2472
2473fun BXWritePC address =
2474  if (CurrentInstrSet ()) = InstrSet_ThumbEE
2475    then if BitsN.bit(address,0)
2476           then BranchTo
2477                  (BitsN.@@(BitsN.bits(31,1) address,BitsN.B(0x0,1)))
2478         else raise UNPREDICTABLE "BXWritePC"
2479  else if BitsN.bit(address,0)
2480    then ( SelectInstrSet InstrSet_Thumb
2481         ; BranchTo(BitsN.@@(BitsN.bits(31,1) address,BitsN.B(0x0,1)))
2482         )
2483  else if not(BitsN.bit(address,1))
2484    then ( SelectInstrSet InstrSet_ARM; BranchTo address )
2485  else raise UNPREDICTABLE "BXWritePC";
2486
2487fun LoadWritePC address =
2488  if Nat.>=(ArchVersion (),5)
2489    then BXWritePC address
2490  else BranchWritePC address;
2491
2492fun ALUWritePC address =
2493  if (Nat.>=(ArchVersion (),7)) andalso
2494     ((CurrentInstrSet ()) = InstrSet_ARM)
2495    then BXWritePC address
2496  else BranchWritePC address;
2497
2498fun ThisInstrLength () = if (!Encoding) = Encoding_Thumb then 16 else 32;
2499
2500fun IncPC () =
2501  BranchTo
2502    (BitsN.+
2503       (Map.lookup((!REG),Cast.RNameToNat RName_PC),
2504        if (ThisInstrLength ()) = 16
2505          then BitsN.B(0x2,32)
2506        else BitsN.B(0x4,32)));
2507
2508fun mem1 address =
2509  BitsN.toBitstring(Map.lookup((!MEM),BitsN.toNat address));
2510
2511fun mem (address,size) =
2512  case size of
2513     1 => Bitstring.bits(7,0) (mem1(BitsN.+(address,BitsN.B(0x0,32))))
2514   | 2 =>
2515     Bitstring.bits(15,0)
2516       ((mem1(BitsN.+(address,BitsN.B(0x1,32))))
2517          @
2518          (mem1(BitsN.+(address,BitsN.B(0x0,32)))))
2519   | 4 =>
2520     Bitstring.bits(31,0)
2521       (List.concat
2522          [mem1(BitsN.+(address,BitsN.B(0x3,32))),
2523           mem1(BitsN.+(address,BitsN.B(0x2,32))),
2524           mem1(BitsN.+(address,BitsN.B(0x1,32))),
2525           mem1(BitsN.+(address,BitsN.B(0x0,32)))])
2526   | 8 =>
2527     Bitstring.bits(63,0)
2528       (List.concat
2529          [mem1(BitsN.+(address,BitsN.B(0x7,32))),
2530           mem1(BitsN.+(address,BitsN.B(0x6,32))),
2531           mem1(BitsN.+(address,BitsN.B(0x5,32))),
2532           mem1(BitsN.+(address,BitsN.B(0x4,32))),
2533           mem1(BitsN.+(address,BitsN.B(0x3,32))),
2534           mem1(BitsN.+(address,BitsN.B(0x2,32))),
2535           mem1(BitsN.+(address,BitsN.B(0x1,32))),
2536           mem1(BitsN.+(address,BitsN.B(0x0,32)))])
2537   | _ => raise ASSERT "mem: size in {1, 2, 4, 8}";
2538
2539fun write'mem (value,(address,size)) =
2540  case size of
2541     1 =>
2542       let
2543         val x = BitsN.+(address,BitsN.B(0x0,32))
2544       in
2545         MEM :=
2546         (Map.update
2547            ((!MEM),BitsN.toNat x,
2548             BitsN.fromBitstring(Bitstring.bits(7,0) value,8)))
2549       end
2550   | 2 =>
2551     ( let
2552         val x = BitsN.+(address,BitsN.B(0x0,32))
2553       in
2554         MEM :=
2555         (Map.update
2556            ((!MEM),BitsN.toNat x,
2557             BitsN.fromBitstring(Bitstring.bits(7,0) value,8)))
2558       end
2559     ; let
2560         val x = BitsN.+(address,BitsN.B(0x1,32))
2561       in
2562         MEM :=
2563         (Map.update
2564            ((!MEM),BitsN.toNat x,
2565             BitsN.fromBitstring(Bitstring.bits(15,8) value,8)))
2566       end
2567     )
2568   | 4 =>
2569     ( let
2570         val x = BitsN.+(address,BitsN.B(0x0,32))
2571       in
2572         MEM :=
2573         (Map.update
2574            ((!MEM),BitsN.toNat x,
2575             BitsN.fromBitstring(Bitstring.bits(7,0) value,8)))
2576       end
2577     ; let
2578         val x = BitsN.+(address,BitsN.B(0x1,32))
2579       in
2580         MEM :=
2581         (Map.update
2582            ((!MEM),BitsN.toNat x,
2583             BitsN.fromBitstring(Bitstring.bits(15,8) value,8)))
2584       end
2585     ; let
2586         val x = BitsN.+(address,BitsN.B(0x2,32))
2587       in
2588         MEM :=
2589         (Map.update
2590            ((!MEM),BitsN.toNat x,
2591             BitsN.fromBitstring(Bitstring.bits(23,16) value,8)))
2592       end
2593     ; let
2594         val x = BitsN.+(address,BitsN.B(0x3,32))
2595       in
2596         MEM :=
2597         (Map.update
2598            ((!MEM),BitsN.toNat x,
2599             BitsN.fromBitstring(Bitstring.bits(31,24) value,8)))
2600       end
2601     )
2602   | 8 =>
2603     ( let
2604         val x = BitsN.+(address,BitsN.B(0x0,32))
2605       in
2606         MEM :=
2607         (Map.update
2608            ((!MEM),BitsN.toNat x,
2609             BitsN.fromBitstring(Bitstring.bits(7,0) value,8)))
2610       end
2611     ; let
2612         val x = BitsN.+(address,BitsN.B(0x1,32))
2613       in
2614         MEM :=
2615         (Map.update
2616            ((!MEM),BitsN.toNat x,
2617             BitsN.fromBitstring(Bitstring.bits(15,8) value,8)))
2618       end
2619     ; let
2620         val x = BitsN.+(address,BitsN.B(0x2,32))
2621       in
2622         MEM :=
2623         (Map.update
2624            ((!MEM),BitsN.toNat x,
2625             BitsN.fromBitstring(Bitstring.bits(23,16) value,8)))
2626       end
2627     ; let
2628         val x = BitsN.+(address,BitsN.B(0x3,32))
2629       in
2630         MEM :=
2631         (Map.update
2632            ((!MEM),BitsN.toNat x,
2633             BitsN.fromBitstring(Bitstring.bits(31,24) value,8)))
2634       end
2635     ; let
2636         val x = BitsN.+(address,BitsN.B(0x4,32))
2637       in
2638         MEM :=
2639         (Map.update
2640            ((!MEM),BitsN.toNat x,
2641             BitsN.fromBitstring(Bitstring.bits(39,32) value,8)))
2642       end
2643     ; let
2644         val x = BitsN.+(address,BitsN.B(0x5,32))
2645       in
2646         MEM :=
2647         (Map.update
2648            ((!MEM),BitsN.toNat x,
2649             BitsN.fromBitstring(Bitstring.bits(47,40) value,8)))
2650       end
2651     ; let
2652         val x = BitsN.+(address,BitsN.B(0x6,32))
2653       in
2654         MEM :=
2655         (Map.update
2656            ((!MEM),BitsN.toNat x,
2657             BitsN.fromBitstring(Bitstring.bits(55,48) value,8)))
2658       end
2659     ; let
2660         val x = BitsN.+(address,BitsN.B(0x7,32))
2661       in
2662         MEM :=
2663         (Map.update
2664            ((!MEM),BitsN.toNat x,
2665             BitsN.fromBitstring(Bitstring.bits(63,56) value,8)))
2666       end
2667     )
2668   | _ => raise ASSERT "mem: size in {1, 2, 4, 8}";
2669
2670fun BigEndianReverse (value,n) =
2671  case n of
2672     1 => Bitstring.bits(7,0) value
2673   | 2 => (Bitstring.bits(7,0) value) @ (Bitstring.bits(15,8) value)
2674   | 4 =>
2675     List.concat
2676       [Bitstring.bits(7,0) value,Bitstring.bits(15,8) value,
2677        Bitstring.bits(23,16) value,Bitstring.bits(31,24) value]
2678   | 8 =>
2679     List.concat
2680       [Bitstring.bits(7,0) value,Bitstring.bits(15,8) value,
2681        Bitstring.bits(23,16) value,Bitstring.bits(31,24) value,
2682        Bitstring.bits(39,32) value,Bitstring.bits(47,40) value,
2683        Bitstring.bits(55,48) value,Bitstring.bits(63,56) value]
2684   | _ => raise ASSERT "BigEndianReverse: n in {1, 2, 4, 8}";
2685
2686fun Align N (w,n) = BitsN.fromNat(Nat.*(n,Nat.div(BitsN.toNat w,n)),N);
2687
2688fun Aligned N (w,n) = w = (Align N (w,n));
2689
2690fun MemA_with_priv N (address,(size,privileged)) =
2691  let
2692    val VA = ref (BitsN.B(0x0,32))
2693  in
2694    ( if Aligned 32 (address,size)
2695        then VA := address
2696      else if (#A((#SCTLR((!CP15) : CP15)) : SCTLR)) orelse
2697         (#U((#SCTLR((!CP15) : CP15)) : SCTLR))
2698        then raise AlignmentFault address
2699      else VA := (Align 32 (address,size))
2700    ; let
2701        val value = ref (mem((!VA),size))
2702      in
2703        ( if #E((!CPSR) : PSR)
2704            then value := (BigEndianReverse((!value),size))
2705          else ()
2706        ; BitsN.fromBitstring((!value),N)
2707        )
2708      end
2709    )
2710  end;
2711
2712fun write'MemA_with_priv N (value,(address,(size,privileged))) =
2713  let
2714    val VA = ref (BitsN.B(0x0,32))
2715  in
2716    ( if Aligned 32 (address,size)
2717        then VA := address
2718      else if (#A((#SCTLR((!CP15) : CP15)) : SCTLR)) orelse
2719         (#U((#SCTLR((!CP15) : CP15)) : SCTLR))
2720        then raise AlignmentFault address
2721      else VA := (Align 32 (address,size))
2722    ; let
2723        val end_value =
2724          if #E((!CPSR) : PSR)
2725            then BigEndianReverse(BitsN.toBitstring value,size)
2726          else BitsN.toBitstring value
2727        val x = ((!VA),size)
2728      in
2729        write'mem(end_value,x)
2730      end
2731    )
2732  end;
2733
2734fun MemA_unpriv N (address,size) =
2735  MemA_with_priv N (address,(size,false));
2736
2737fun write'MemA_unpriv N (value,(address,size)) =
2738  let
2739    val x = (address,(size,false))
2740  in
2741    write'MemA_with_priv N (value,x)
2742  end;
2743
2744fun MemA N (address,size) =
2745  MemA_with_priv N (address,(size,CurrentModeIsNotUser ()));
2746
2747fun write'MemA N (value,(address,size)) =
2748  let
2749    val x = (address,(size,CurrentModeIsNotUser ()))
2750  in
2751    write'MemA_with_priv N (value,x)
2752  end;
2753
2754fun MemU_with_priv N (address,(size,privileged)) =
2755  let
2756    val value = ref (Bitstring.replicate([false],64))
2757  in
2758    let
2759      val VA =
2760        if (not(#A((#SCTLR((!CP15) : CP15)) : SCTLR))) andalso
2761           (not(#U((#SCTLR((!CP15) : CP15)) : SCTLR)))
2762          then Align 32 (address,size)
2763        else address
2764    in
2765      ( if Aligned 32 (VA,size)
2766          then value :=
2767               (BitsN.toBitstring(MemA_with_priv N (VA,(size,privileged))))
2768        else if #A((#SCTLR((!CP15) : CP15)) : SCTLR)
2769          then raise AlignmentFault address
2770        else ( L3.for
2771                 (0,Nat.-(size,1),
2772                  fn i =>
2773                    let
2774                      val h = Nat.+(Nat.*(8,i),7)
2775                      val l = Nat.*(8,i)
2776                    in
2777                      value :=
2778                      (Bitstring.bitFieldInsert(h,l)
2779                         ((!value),
2780                          BitsN.toBitstring
2781                            (MemA_with_priv 8
2782                               (BitsN.+(VA,BitsN.fromNat(i,32)),
2783                                (1,privileged)))))
2784                    end)
2785             ; if #E((!CPSR) : PSR)
2786                 then value := (BigEndianReverse((!value),size))
2787               else ()
2788             )
2789      ; BitsN.fromBitstring((!value),N)
2790      )
2791    end
2792  end;
2793
2794fun write'MemU_with_priv N (value,(address,(size,privileged))) =
2795  let
2796    val VA =
2797      if (not(#A((#SCTLR((!CP15) : CP15)) : SCTLR))) andalso
2798         (not(#U((#SCTLR((!CP15) : CP15)) : SCTLR)))
2799        then Align 32 (address,size)
2800      else address
2801  in
2802    if Aligned 32 (VA,size)
2803      then let
2804             val x = (VA,(size,privileged))
2805           in
2806             write'MemA_with_priv N (value,x)
2807           end
2808    else if #A((#SCTLR((!CP15) : CP15)) : SCTLR)
2809      then raise AlignmentFault address
2810    else let
2811           val v =
2812             if #E((!CPSR) : PSR)
2813               then BigEndianReverse(BitsN.toBitstring value,size)
2814             else BitsN.toBitstring value
2815         in
2816           L3.for
2817             (0,Nat.-(size,1),
2818              fn i =>
2819                let
2820                  val x = (BitsN.+(VA,BitsN.fromNat(i,32)),(1,privileged))
2821                in
2822                  write'MemA_with_priv 8
2823                    (BitsN.fromBitstring
2824                       (Bitstring.bits(Nat.+(Nat.*(8,i),7),Nat.*(8,i)) v,8),
2825                     x)
2826                end)
2827         end
2828  end;
2829
2830fun MemU_unpriv N (address,size) =
2831  MemU_with_priv N (address,(size,false));
2832
2833fun write'MemU_unpriv N (value,(address,size)) =
2834  let
2835    val x = (address,(size,false))
2836  in
2837    write'MemU_with_priv N (value,x)
2838  end;
2839
2840fun MemU N (address,size) =
2841  MemU_with_priv N (address,(size,CurrentModeIsNotUser ()));
2842
2843fun write'MemU N (value,(address,size)) =
2844  let
2845    val x = (address,(size,CurrentModeIsNotUser ()))
2846  in
2847    write'MemU_with_priv N (value,x)
2848  end;
2849
2850fun NullCheckIfThumbEE n =
2851  let
2852    val EndOfInstruction = ref false
2853  in
2854    ( if (CurrentInstrSet ()) = InstrSet_ThumbEE
2855        then if n = (BitsN.B(0xF,4))
2856               then if (Align 32 (PC (),4)) = (BitsN.B(0x0,32))
2857                      then raise UNPREDICTABLE "NullCheckIfThumbEE"
2858                    else ()
2859             else if n = (BitsN.B(0xD,4))
2860               then if (SP ()) = (BitsN.B(0x0,32))
2861                      then raise UNPREDICTABLE "NullCheckIfThumbEE"
2862                    else ()
2863             else if (R n) = (BitsN.B(0x0,32))
2864               then ( write'LR
2865                        (BitsN.@@(BitsN.bits(31,1) (PC ()),BitsN.B(0x1,1)))
2866                    ; write'ITSTATE(BitsN.B(0x0,8))
2867                    ; BranchWritePC
2868                        (BitsN.-(#TEEHBR((!CP14) : CP14),BitsN.B(0x4,32)))
2869                    ; EndOfInstruction := true
2870                    )
2871             else ()
2872      else ()
2873    ; not (!EndOfInstruction)
2874    )
2875  end;
2876
2877fun HighestSetBit N w =
2878  if w = (BitsN.BV(0x0,N)) then IntInf.~ 1 else BitsN.toInt(BitsN.log2 w);
2879
2880fun CountLeadingZeroBits N w =
2881  Nat.fromInt
2882    (IntInf.-
2883       (IntInf.-(Nat.toInt(BitsN.size(BitsN.BV(0x0,N))),1),
2884        HighestSetBit N w));
2885
2886fun LowestSetBit N w = CountLeadingZeroBits N (BitsN.reverse w);
2887
2888fun BitCount N w =
2889  let
2890    val result = ref 0
2891  in
2892    ( L3.for
2893        (0,Nat.-(BitsN.size(BitsN.BV(0x0,N)),1),
2894         fn i =>
2895           if BitsN.bit(w,i) then result := (Nat.+((!result),1)) else ())
2896    ; (!result)
2897    )
2898  end;
2899
2900fun SignExtendFrom N (w,p) =
2901  let
2902    val s = Nat.-(Nat.-(BitsN.size(BitsN.BV(0x0,N)),1),p)
2903  in
2904    BitsN.>>(BitsN.<<(w,s),s)
2905  end;
2906
2907fun Extend (M,N) (unsigned,w) =
2908  if unsigned then BitsN.zeroExtend N w else BitsN.signExtend N w;
2909
2910fun UInt N w = Nat.toInt(BitsN.toNat w);
2911
2912fun SignedSatQ M (i,N) =
2913  ( if Nat.<(BitsN.size(BitsN.BV(0x0,M)),N)
2914      then raise ASSERT "SignedSatQ: M < N"
2915    else ()
2916  ; let
2917      val max = Nat.toInt(Nat.pow(2,Nat.-(N,1)))
2918    in
2919      if IntInf.>(i,IntInf.-(max,1))
2920        then (BitsN.fromInt(IntInf.-(max,1),M),true)
2921      else if IntInf.<(i,IntInf.~ max)
2922        then (BitsN.fromInt(IntInf.~ max,M),true)
2923      else (BitsN.fromInt(i,M),false)
2924    end
2925  );
2926
2927fun UnsignedSatQ M (i,N) =
2928  ( if Nat.<(BitsN.size(BitsN.BV(0x0,M)),N)
2929      then raise ASSERT "UnsignedSatQ: M < N"
2930    else ()
2931  ; let
2932      val max = Nat.toInt(Nat.-(Nat.pow(2,N),1))
2933    in
2934      if IntInf.>(i,max)
2935        then (BitsN.fromInt(max,M),true)
2936      else if IntInf.<(i,0)
2937        then (BitsN.BV(0x0,M),true)
2938      else (BitsN.fromInt(i,M),false)
2939    end
2940  );
2941
2942fun SatQ M (i,(N,unsigned)) =
2943  if unsigned then UnsignedSatQ M (i,N) else SignedSatQ M (i,N);
2944
2945fun SignedSat M (i,N) = L3.fst(SignedSatQ M (i,N));
2946
2947fun UnsignedSat M (i,N) = L3.fst(UnsignedSatQ M (i,N));
2948
2949fun LSL_C N (x,shift) =
2950  ( if shift = 0 then raise ASSERT "LSL_C" else ()
2951  ; let
2952      val extended_x =
2953        (BitsN.toBitstring x) @ (Bitstring.replicate([false],shift))
2954    in
2955      (BitsN.<<(x,shift),
2956       Bitstring.bit(extended_x,BitsN.size(BitsN.BV(0x0,N))))
2957    end
2958  );
2959
2960fun LSL N (x,shift) = if shift = 0 then x else L3.fst(LSL_C N (x,shift));
2961
2962fun LSR_C N (x,shift) =
2963  ( if shift = 0 then raise ASSERT "LSR_C" else ()
2964  ; (BitsN.>>+(x,shift),
2965     (Nat.<=(shift,BitsN.size(BitsN.BV(0x0,N)))) andalso
2966     (BitsN.bit(x,Nat.-(shift,1))))
2967  );
2968
2969fun LSR N (x,shift) = if shift = 0 then x else L3.fst(LSR_C N (x,shift));
2970
2971fun ASR_C N (x,shift) =
2972  ( if shift = 0 then raise ASSERT "ASR_C" else ()
2973  ; (BitsN.>>(x,shift),
2974     BitsN.bit(x,Nat.-(Nat.min(BitsN.size(BitsN.BV(0x0,N)),shift),1)))
2975  );
2976
2977fun ASR N (x,shift) = if shift = 0 then x else L3.fst(ASR_C N (x,shift));
2978
2979fun ROR_C N (x,shift) =
2980  ( if shift = 0 then raise ASSERT "ROR_C" else ()
2981  ; let val result = BitsN.#>>(x,shift) in (result,BitsN.msb result) end
2982  );
2983
2984fun ROR N (x,shift) = if shift = 0 then x else L3.fst(ROR_C N (x,shift));
2985
2986fun RRX_C N (x,carry_in) =
2987  let
2988    val result =
2989      BitsN.fromBitstring
2990        ((Bitstring.fromBool carry_in)
2991           @
2992           (Bitstring.bits(Nat.-(BitsN.size(BitsN.BV(0x0,N)),1),1)
2993              (BitsN.toBitstring x)),N)
2994  in
2995    (result,BitsN.bit(x,0))
2996  end;
2997
2998fun RRX N (x,carry_in) = L3.fst(RRX_C N (x,carry_in));
2999
3000fun DecodeImmShift (typ,imm5) =
3001  case typ of
3002     BitsN.B(0x0,_) => (SRType_LSL,BitsN.toNat imm5)
3003   | BitsN.B(0x1,_) =>
3004     (SRType_LSR,if imm5 = (BitsN.B(0x0,5)) then 32 else BitsN.toNat imm5)
3005   | BitsN.B(0x2,_) =>
3006     (SRType_ASR,if imm5 = (BitsN.B(0x0,5)) then 32 else BitsN.toNat imm5)
3007   | BitsN.B(0x3,_) =>
3008     if imm5 = (BitsN.B(0x0,5))
3009       then (SRType_RRX,1)
3010     else (SRType_ROR,BitsN.toNat imm5)
3011   | _ => raise General.Bind;
3012
3013fun DecodeRegShift typ =
3014  case typ of
3015     BitsN.B(0x0,_) => SRType_LSL
3016   | BitsN.B(0x1,_) => SRType_LSR
3017   | BitsN.B(0x2,_) => SRType_ASR
3018   | BitsN.B(0x3,_) => SRType_ROR
3019   | _ => raise General.Bind;
3020
3021fun Shift_C N (value,(typ,(amount,carry_in))) =
3022  if amount = 0
3023    then (value,carry_in)
3024  else case typ of
3025          SRType_LSL => LSL_C N (value,amount)
3026        | SRType_LSR => LSR_C N (value,amount)
3027        | SRType_ASR => ASR_C N (value,amount)
3028        | SRType_ROR => ROR_C N (value,amount)
3029        | SRType_RRX => RRX_C N (value,carry_in);
3030
3031fun Shift N (value,(typ,(amount,carry_in))) =
3032  L3.fst(Shift_C N (value,(typ,(amount,carry_in))));
3033
3034fun ARMExpandImm_C (imm12,carry_in) =
3035  let
3036    val unroatated_value = BitsN.zeroExtend 32 (BitsN.bits(7,0) imm12)
3037  in
3038    Shift_C 32
3039      (unroatated_value,
3040       (SRType_ROR,(Nat.*(2,BitsN.toNat(BitsN.bits(11,8) imm12)),carry_in)))
3041  end;
3042
3043fun ARMExpandImm imm12 = L3.fst(ARMExpandImm_C(imm12,#C((!CPSR) : PSR)));
3044
3045fun ThumbExpandImm_C (imm12,carry_in) =
3046  if (BitsN.bits(11,10) imm12) = (BitsN.B(0x0,2))
3047    then let
3048           val imm32 =
3049             case BitsN.bits(9,8) imm12 of
3050                BitsN.B(0x0,_) =>
3051                  BitsN.zeroExtend 32 (BitsN.bits(7,0) imm12)
3052              | BitsN.B(0x1,_) =>
3053                if (BitsN.bits(7,0) imm12) = (BitsN.B(0x0,8))
3054                  then raise UNPREDICTABLE "ThumbExpandImm_C"
3055                else BitsN.concat
3056                       [BitsN.B(0x0,8),BitsN.bits(7,0) imm12,
3057                        BitsN.B(0x0,8),BitsN.bits(7,0) imm12]
3058              | BitsN.B(0x2,_) =>
3059                if (BitsN.bits(7,0) imm12) = (BitsN.B(0x0,8))
3060                  then raise UNPREDICTABLE "ThumbExpandImm_C"
3061                else BitsN.concat
3062                       [BitsN.bits(7,0) imm12,BitsN.B(0x0,8),
3063                        BitsN.bits(7,0) imm12,BitsN.B(0x0,8)]
3064              | BitsN.B(0x3,_) =>
3065                if (BitsN.bits(7,0) imm12) = (BitsN.B(0x0,8))
3066                  then raise UNPREDICTABLE "ThumbExpandImm_C"
3067                else BitsN.concat
3068                       [BitsN.bits(7,0) imm12,BitsN.bits(7,0) imm12,
3069                        BitsN.bits(7,0) imm12,BitsN.bits(7,0) imm12]
3070              | _ => raise General.Bind
3071         in
3072           (imm32,carry_in)
3073         end
3074  else let
3075         val unroatated_value =
3076           BitsN.zeroExtend 32
3077             (BitsN.@@(BitsN.B(0x1,1),BitsN.bits(6,0) imm12))
3078       in
3079         ROR_C 32 (unroatated_value,BitsN.toNat(BitsN.bits(11,7) imm12))
3080       end;
3081
3082fun ExpandImm_C (imm12,carry_in) =
3083  if (!Encoding) = Encoding_Thumb2
3084    then ThumbExpandImm_C(imm12,carry_in)
3085  else ARMExpandImm_C(imm12,carry_in);
3086
3087fun AddWithCarry N (x,(y,carry_in)) =
3088  let
3089    val unsigned_sum =
3090      Nat.+(Nat.+(BitsN.toNat x,BitsN.toNat y),Nat.fromBool carry_in)
3091    val signed_sum =
3092      IntInf.+
3093        (IntInf.+(BitsN.toInt x,BitsN.toInt y),IntExtra.fromBool carry_in)
3094    val result = BitsN.fromNat(unsigned_sum,N)
3095    val carry_out = not((BitsN.toNat result) = unsigned_sum)
3096    val overflow = not((BitsN.toInt result) = signed_sum)
3097  in
3098    (result,(carry_out,overflow))
3099  end;
3100
3101fun DataProcessingALU (opc,(a,(b,c))) =
3102  case opc of
3103     BitsN.B(0x0,_) => (BitsN.&&(a,b),(c,false))
3104   | BitsN.B(0x8,_) => (BitsN.&&(a,b),(c,false))
3105   | BitsN.B(0x1,_) => (BitsN.??(a,b),(c,false))
3106   | BitsN.B(0x9,_) => (BitsN.??(a,b),(c,false))
3107   | BitsN.B(0x2,_) => AddWithCarry 32 (a,(BitsN.~ b,true))
3108   | BitsN.B(0xA,_) => AddWithCarry 32 (a,(BitsN.~ b,true))
3109   | BitsN.B(0x3,_) => AddWithCarry 32 (BitsN.~ a,(b,true))
3110   | BitsN.B(0x4,_) => AddWithCarry 32 (a,(b,false))
3111   | BitsN.B(0xB,_) => AddWithCarry 32 (a,(b,false))
3112   | BitsN.B(0x5,_) => AddWithCarry 32 (a,(b,c))
3113   | BitsN.B(0x6,_) => AddWithCarry 32 (a,(BitsN.~ b,c))
3114   | BitsN.B(0x7,_) => AddWithCarry 32 (BitsN.~ a,(b,c))
3115   | BitsN.B(0xC,_) => (BitsN.||(a,b),(c,false))
3116   | BitsN.B(0xD,_) => (b,(c,false))
3117   | BitsN.B(0xE,_) => (BitsN.&&(a,BitsN.~ b),(c,false))
3118   | BitsN.B(0xF,_) => (BitsN.||(a,BitsN.~ b),(c,false))
3119   | _ => raise General.Bind;
3120
3121fun ArithmeticOpcode opc =
3122  ((BitsN.bit(opc,2)) orelse (BitsN.bit(opc,1))) andalso
3123  (not((BitsN.bit(opc,3)) andalso (BitsN.bit(opc,2))));
3124
3125fun ExcVectorBase () =
3126  if #V((#SCTLR((!CP15) : CP15)) : SCTLR)
3127    then BitsN.B(0xFFFF000,32)
3128  else if HaveSecurityExt ()
3129    then #VBAR((!CP15) : CP15)
3130  else BitsN.B(0x0,32);
3131
3132fun EnterMonitorMode (new_spsr_value,(new_lr_value,vect_offset)) =
3133  ( CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x16,5)))
3134  ; write'SPSR new_spsr_value
3135  ; write'R(new_lr_value,BitsN.B(0xE,4))
3136  ; CPSR := (PSR_J_rupd((!CPSR),false))
3137  ; CPSR := (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3138  ; CPSR := (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3139  ; CPSR := (PSR_A_rupd((!CPSR),true))
3140  ; CPSR := (PSR_F_rupd((!CPSR),true))
3141  ; CPSR := (PSR_I_rupd((!CPSR),true))
3142  ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3143  ; BranchTo(BitsN.+(#MVBAR((!CP15) : CP15),vect_offset))
3144  );
3145
3146fun EnterHypMode (new_spsr_value,(new_lr_value,vect_offset)) =
3147  ( CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x1A,5)))
3148  ; write'SPSR new_spsr_value
3149  ; write'R(new_lr_value,BitsN.B(0xE,4))
3150  ; CPSR := (PSR_J_rupd((!CPSR),false))
3151  ; CPSR := (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3152  ; CPSR := (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3153  ; CPSR := (PSR_A_rupd((!CPSR),true))
3154  ; CPSR := (PSR_F_rupd((!CPSR),true))
3155  ; CPSR := (PSR_I_rupd((!CPSR),true))
3156  ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3157  ; BranchTo(BitsN.+(#MVBAR((!CP15) : CP15),vect_offset))
3158  );
3159
3160fun TakeReset () =
3161  ( CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x13,5)))
3162  ; if HaveSecurityExt ()
3163      then let
3164             val x0 = #SCR((!CP15) : CP15)
3165           in
3166             CP15 := (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3167           end
3168    else ()
3169  ; CPSR := (PSR_I_rupd((!CPSR),true))
3170  ; CPSR := (PSR_F_rupd((!CPSR),true))
3171  ; CPSR := (PSR_A_rupd((!CPSR),true))
3172  ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3173  ; CPSR := (PSR_J_rupd((!CPSR),false))
3174  ; CPSR := (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3175  ; CPSR := (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3176  ; BranchTo(BitsN.+(ExcVectorBase (),BitsN.B(0x0,32)))
3177  );
3178
3179fun TakeUndefInstrException () =
3180  let
3181    val new_lr_value =
3182      if #T((!CPSR) : PSR)
3183        then BitsN.-(PC (),BitsN.B(0x2,32))
3184      else BitsN.-(PC (),BitsN.B(0x4,32))
3185    val new_spsr_value = (!CPSR)
3186    val vect_offset = BitsN.B(0x4,32)
3187    val take_to_hyp =
3188      (HaveVirtExt ()) andalso
3189      ((HaveSecurityExt ()) andalso
3190       ((#NS((#SCR((!CP15) : CP15)) : SCR)) andalso
3191        ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5)))))
3192    val route_to_hyp =
3193      (HaveVirtExt ()) andalso
3194      ((HaveSecurityExt ()) andalso
3195       ((not(IsSecure ())) andalso
3196        ((#TGE((#HCR((!CP15) : CP15)) : HCR)) andalso
3197         ((#M((!CPSR) : PSR)) = (BitsN.B(0x10,5))))))
3198    val return_offset =
3199      if #T((!CPSR) : PSR) then BitsN.B(0x2,32) else BitsN.B(0x4,32)
3200    val preferred_exceptn_return = BitsN.-(new_lr_value,return_offset)
3201  in
3202    if take_to_hyp
3203      then EnterHypMode
3204             (new_spsr_value,(preferred_exceptn_return,vect_offset))
3205    else if route_to_hyp
3206      then EnterHypMode
3207             (new_spsr_value,(preferred_exceptn_return,BitsN.B(0x14,32)))
3208    else ( if (#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))
3209             then let
3210                    val x0 = #SCR((!CP15) : CP15)
3211                  in
3212                    CP15 := (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3213                  end
3214           else ()
3215         ; CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x1B,5)))
3216         ; write'SPSR new_spsr_value
3217         ; write'R(new_lr_value,BitsN.B(0xE,4))
3218         ; CPSR := (PSR_I_rupd((!CPSR),true))
3219         ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3220         ; CPSR := (PSR_J_rupd((!CPSR),false))
3221         ; CPSR :=
3222           (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3223         ; CPSR :=
3224           (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3225         ; BranchTo(BitsN.+(ExcVectorBase (),vect_offset))
3226         )
3227  end;
3228
3229fun TakeSVCException () =
3230  ( ITAdvance ()
3231  ; let
3232      val new_lr_value =
3233        if #T((!CPSR) : PSR)
3234          then BitsN.-(PC (),BitsN.B(0x2,32))
3235        else BitsN.-(PC (),BitsN.B(0x4,32))
3236      val new_spsr_value = (!CPSR)
3237      val vect_offset = BitsN.B(0x8,32)
3238      val take_to_hyp =
3239        (HaveVirtExt ()) andalso
3240        ((HaveSecurityExt ()) andalso
3241         ((#NS((#SCR((!CP15) : CP15)) : SCR)) andalso
3242          ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5)))))
3243      val route_to_hyp =
3244        (HaveVirtExt ()) andalso
3245        ((HaveSecurityExt ()) andalso
3246         ((not(IsSecure ())) andalso
3247          ((#TGE((#HCR((!CP15) : CP15)) : HCR)) andalso
3248           ((#M((!CPSR) : PSR)) = (BitsN.B(0x10,5))))))
3249      val preferred_exceptn_return = new_lr_value
3250    in
3251      if take_to_hyp
3252        then EnterHypMode
3253               (new_spsr_value,(preferred_exceptn_return,vect_offset))
3254      else if route_to_hyp
3255        then EnterHypMode
3256               (new_spsr_value,(preferred_exceptn_return,BitsN.B(0x14,32)))
3257      else ( if (#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))
3258               then let
3259                      val x0 = #SCR((!CP15) : CP15)
3260                    in
3261                      CP15 :=
3262                      (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3263                    end
3264             else ()
3265           ; CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x13,5)))
3266           ; write'SPSR new_spsr_value
3267           ; write'R(new_lr_value,BitsN.B(0xE,4))
3268           ; CPSR := (PSR_I_rupd((!CPSR),true))
3269           ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3270           ; CPSR := (PSR_J_rupd((!CPSR),false))
3271           ; CPSR :=
3272             (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3273           ; CPSR :=
3274             (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3275           ; BranchTo(BitsN.+(ExcVectorBase (),vect_offset))
3276           )
3277    end
3278  );
3279
3280fun TakeSMCException () =
3281  ( ITAdvance ()
3282  ; let
3283      val new_lr_value =
3284        if #T((!CPSR) : PSR)
3285          then PC ()
3286        else BitsN.-(PC (),BitsN.B(0x4,32))
3287      val new_spsr_value = (!CPSR)
3288      val vect_offset = BitsN.B(0x8,32)
3289    in
3290      ( if (#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))
3291          then let
3292                 val x0 = #SCR((!CP15) : CP15)
3293               in
3294                 CP15 := (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3295               end
3296        else ()
3297      ; CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x16,5)))
3298      ; EnterMonitorMode(new_spsr_value,(new_lr_value,vect_offset))
3299      )
3300    end
3301  );
3302
3303fun TakeHVCException () =
3304  ( ITAdvance ()
3305  ; let
3306      val preferred_exceptn_return =
3307        if #T((!CPSR) : PSR)
3308          then PC ()
3309        else BitsN.-(PC (),BitsN.B(0x4,32))
3310      val new_spsr_value = (!CPSR)
3311    in
3312      if (#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5))
3313        then EnterHypMode
3314               (new_spsr_value,(preferred_exceptn_return,BitsN.B(0x8,32)))
3315      else EnterHypMode
3316             (new_spsr_value,(preferred_exceptn_return,BitsN.B(0x14,32)))
3317    end
3318  );
3319
3320fun TakeDataAbortException () =
3321  let
3322    val new_lr_value =
3323      if #T((!CPSR) : PSR) then BitsN.+(PC (),BitsN.B(0x4,32)) else PC ()
3324    val new_spsr_value = (!CPSR)
3325    val vect_offset = BitsN.B(0x10,32)
3326    val preferred_exceptn_return = BitsN.-(new_lr_value,BitsN.B(0x8,32))
3327    val route_to_monitor =
3328      (HaveSecurityExt ()) andalso
3329      ((#EA((#SCR((!CP15) : CP15)) : SCR)) andalso (IsExternalAbort ()))
3330    val take_to_hyp =
3331      (HaveVirtExt ()) andalso
3332      ((HaveSecurityExt ()) andalso
3333       ((#NS((#SCR((!CP15) : CP15)) : SCR)) andalso
3334        ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5)))))
3335    val route_to_hyp = false
3336  in
3337    if route_to_monitor
3338      then ( if (#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))
3339               then let
3340                      val x0 = #SCR((!CP15) : CP15)
3341                    in
3342                      CP15 :=
3343                      (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3344                    end
3345             else ()
3346           ; EnterMonitorMode(new_spsr_value,(new_lr_value,vect_offset))
3347           )
3348    else if take_to_hyp
3349      then EnterHypMode
3350             (new_spsr_value,(preferred_exceptn_return,vect_offset))
3351    else if route_to_hyp
3352      then EnterHypMode
3353             (new_spsr_value,(preferred_exceptn_return,BitsN.B(0x14,32)))
3354    else ( if (HaveSecurityExt ()) andalso
3355              ((#M((!CPSR) : PSR)) = (BitsN.B(0x16,5)))
3356             then let
3357                    val x0 = #SCR((!CP15) : CP15)
3358                  in
3359                    CP15 := (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3360                  end
3361           else ()
3362         ; CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x17,5)))
3363         ; write'SPSR new_spsr_value
3364         ; write'R(new_lr_value,BitsN.B(0xE,4))
3365         ; CPSR := (PSR_I_rupd((!CPSR),true))
3366         ; if (not(HaveSecurityExt ())) orelse
3367              ((HaveVirtExt ()) orelse
3368               ((not(#NS((#SCR((!CP15) : CP15)) : SCR))) orelse
3369                (#AW((#SCR((!CP15) : CP15)) : SCR))))
3370             then CPSR := (PSR_A_rupd((!CPSR),true))
3371           else ()
3372         ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3373         ; CPSR := (PSR_J_rupd((!CPSR),false))
3374         ; CPSR :=
3375           (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3376         ; CPSR :=
3377           (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3378         ; BranchTo(BitsN.+(ExcVectorBase (),vect_offset))
3379         )
3380  end;
3381
3382fun TakePrefetchAbortException () =
3383  let
3384    val new_lr_value =
3385      if #T((!CPSR) : PSR) then PC () else BitsN.-(PC (),BitsN.B(0x4,32))
3386    val new_spsr_value = (!CPSR)
3387    val vect_offset = BitsN.B(0xC,32)
3388    val preferred_exceptn_return = BitsN.-(new_lr_value,BitsN.B(0x4,32))
3389    val route_to_monitor =
3390      (HaveSecurityExt ()) andalso
3391      ((#EA((#SCR((!CP15) : CP15)) : SCR)) andalso (IsExternalAbort ()))
3392    val take_to_hyp =
3393      (HaveVirtExt ()) andalso
3394      ((HaveSecurityExt ()) andalso
3395       ((#NS((#SCR((!CP15) : CP15)) : SCR)) andalso
3396        ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5)))))
3397    val route_to_hyp = false
3398  in
3399    if route_to_monitor
3400      then ( if (#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))
3401               then let
3402                      val x0 = #SCR((!CP15) : CP15)
3403                    in
3404                      CP15 :=
3405                      (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3406                    end
3407             else ()
3408           ; EnterMonitorMode(new_spsr_value,(new_lr_value,vect_offset))
3409           )
3410    else if take_to_hyp
3411      then EnterHypMode
3412             (new_spsr_value,(preferred_exceptn_return,vect_offset))
3413    else if route_to_hyp
3414      then EnterHypMode
3415             (new_spsr_value,(preferred_exceptn_return,BitsN.B(0x14,32)))
3416    else ( if (HaveSecurityExt ()) andalso
3417              ((#M((!CPSR) : PSR)) = (BitsN.B(0x16,5)))
3418             then let
3419                    val x0 = #SCR((!CP15) : CP15)
3420                  in
3421                    CP15 := (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3422                  end
3423           else ()
3424         ; CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x17,5)))
3425         ; write'SPSR new_spsr_value
3426         ; write'R(new_lr_value,BitsN.B(0xE,4))
3427         ; CPSR := (PSR_I_rupd((!CPSR),true))
3428         ; if (not(HaveSecurityExt ())) orelse
3429              ((HaveVirtExt ()) orelse
3430               ((not(#NS((#SCR((!CP15) : CP15)) : SCR))) orelse
3431                (#AW((#SCR((!CP15) : CP15)) : SCR))))
3432             then CPSR := (PSR_A_rupd((!CPSR),true))
3433           else ()
3434         ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3435         ; CPSR := (PSR_J_rupd((!CPSR),false))
3436         ; CPSR :=
3437           (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3438         ; CPSR :=
3439           (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3440         ; BranchTo(BitsN.+(ExcVectorBase (),vect_offset))
3441         )
3442  end;
3443
3444fun TakePhysicalIRQException () =
3445  let
3446    val new_lr_value =
3447      if #T((!CPSR) : PSR) then PC () else BitsN.-(PC (),BitsN.B(0x4,32))
3448    val new_spsr_value = (!CPSR)
3449    val vect_offset = BitsN.B(0x18,32)
3450    val route_to_monitor =
3451      (HaveSecurityExt ()) andalso (#IRQ((#SCR((!CP15) : CP15)) : SCR))
3452    val route_to_hyp =
3453      ((HaveVirtExt ()) andalso
3454       ((HaveSecurityExt ()) andalso
3455        ((not(#IRQ((#SCR((!CP15) : CP15)) : SCR))) andalso
3456         ((#IMO((#HCR((!CP15) : CP15)) : HCR)) andalso (not(IsSecure ())))))) orelse
3457      ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5)))
3458  in
3459    if route_to_monitor
3460      then ( if (#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))
3461               then let
3462                      val x0 = #SCR((!CP15) : CP15)
3463                    in
3464                      CP15 :=
3465                      (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3466                    end
3467             else ()
3468           ; EnterMonitorMode(new_spsr_value,(new_lr_value,vect_offset))
3469           )
3470    else if route_to_hyp
3471      then ( CP15 :=
3472             (CP15_HSR_rupd
3473                ((!CP15),
3474                 {EC = BitsN.B(0x0,6), IL = false, ISS = BitsN.B(0x0,25)}))
3475           ; let
3476               val preferred_exceptn_return =
3477                 BitsN.-(new_lr_value,BitsN.B(0x4,32))
3478             in
3479               EnterHypMode
3480                 (new_spsr_value,(preferred_exceptn_return,vect_offset))
3481             end
3482           )
3483    else ( if (#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))
3484             then let
3485                    val x0 = #SCR((!CP15) : CP15)
3486                  in
3487                    CP15 := (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3488                  end
3489           else ()
3490         ; CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x12,5)))
3491         ; write'SPSR new_spsr_value
3492         ; write'R(new_lr_value,BitsN.B(0xE,4))
3493         ; CPSR := (PSR_I_rupd((!CPSR),true))
3494         ; if (not(HaveSecurityExt ())) orelse
3495              ((HaveVirtExt ()) orelse
3496               ((not(#NS((#SCR((!CP15) : CP15)) : SCR))) orelse
3497                (#AW((#SCR((!CP15) : CP15)) : SCR))))
3498             then CPSR := (PSR_A_rupd((!CPSR),true))
3499           else ()
3500         ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3501         ; CPSR := (PSR_J_rupd((!CPSR),false))
3502         ; CPSR :=
3503           (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3504         ; CPSR :=
3505           (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3506         ; if #VE((#SCTLR((!CP15) : CP15)) : SCTLR)
3507             then raise IMPLEMENTATION_DEFINED "branch to an IRQ vector"
3508           else BranchTo(BitsN.+(ExcVectorBase (),vect_offset))
3509         )
3510  end;
3511
3512fun TakeVirtualIRQException () =
3513  let
3514    val new_lr_value =
3515      if #T((!CPSR) : PSR) then PC () else BitsN.-(PC (),BitsN.B(0x4,32))
3516    val new_spsr_value = (!CPSR)
3517    val vect_offset = BitsN.B(0x18,32)
3518  in
3519    ( CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x12,5)))
3520    ; write'SPSR new_spsr_value
3521    ; write'R(new_lr_value,BitsN.B(0xE,4))
3522    ; CPSR := (PSR_I_rupd((!CPSR),true))
3523    ; CPSR := (PSR_A_rupd((!CPSR),true))
3524    ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3525    ; CPSR := (PSR_J_rupd((!CPSR),false))
3526    ; CPSR := (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3527    ; CPSR := (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3528    ; if #VE((#SCTLR((!CP15) : CP15)) : SCTLR)
3529        then raise IMPLEMENTATION_DEFINED "branch to an IRQ vector"
3530      else BranchTo(BitsN.+(ExcVectorBase (),vect_offset))
3531    )
3532  end;
3533
3534fun TakePhysicalFIQException () =
3535  let
3536    val new_lr_value =
3537      if #T((!CPSR) : PSR) then PC () else BitsN.-(PC (),BitsN.B(0x4,32))
3538    val new_spsr_value = (!CPSR)
3539    val vect_offset = BitsN.B(0x1C,32)
3540    val route_to_monitor =
3541      (HaveSecurityExt ()) andalso (#FIQ((#SCR((!CP15) : CP15)) : SCR))
3542    val route_to_hyp =
3543      ((HaveVirtExt ()) andalso
3544       ((HaveSecurityExt ()) andalso
3545        ((not(#FIQ((#SCR((!CP15) : CP15)) : SCR))) andalso
3546         ((#FMO((#HCR((!CP15) : CP15)) : HCR)) andalso (not(IsSecure ())))))) orelse
3547      ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5)))
3548  in
3549    if route_to_monitor
3550      then ( if (#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))
3551               then let
3552                      val x0 = #SCR((!CP15) : CP15)
3553                    in
3554                      CP15 :=
3555                      (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3556                    end
3557             else ()
3558           ; EnterMonitorMode(new_spsr_value,(new_lr_value,vect_offset))
3559           )
3560    else if route_to_hyp
3561      then ( CP15 :=
3562             (CP15_HSR_rupd
3563                ((!CP15),
3564                 {EC = BitsN.B(0x0,6), IL = false, ISS = BitsN.B(0x0,25)}))
3565           ; let
3566               val preferred_exceptn_return =
3567                 BitsN.-(new_lr_value,BitsN.B(0x4,32))
3568             in
3569               EnterHypMode
3570                 (new_spsr_value,(preferred_exceptn_return,vect_offset))
3571             end
3572           )
3573    else ( if (#M((!CPSR) : PSR)) = (BitsN.B(0x16,5))
3574             then let
3575                    val x0 = #SCR((!CP15) : CP15)
3576                  in
3577                    CP15 := (CP15_SCR_rupd((!CP15),SCR_NS_rupd(x0,false)))
3578                  end
3579           else ()
3580         ; CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x11,5)))
3581         ; write'SPSR new_spsr_value
3582         ; write'R(new_lr_value,BitsN.B(0xE,4))
3583         ; CPSR := (PSR_I_rupd((!CPSR),true))
3584         ; if (not(HaveSecurityExt ())) orelse
3585              ((HaveVirtExt ()) orelse
3586               ((not(#NS((#SCR((!CP15) : CP15)) : SCR))) orelse
3587                (#FW((#SCR((!CP15) : CP15)) : SCR))))
3588             then CPSR := (PSR_F_rupd((!CPSR),true))
3589           else ()
3590         ; if (not(HaveSecurityExt ())) orelse
3591              ((HaveVirtExt ()) orelse
3592               ((not(#NS((#SCR((!CP15) : CP15)) : SCR))) orelse
3593                (#AW((#SCR((!CP15) : CP15)) : SCR))))
3594             then CPSR := (PSR_A_rupd((!CPSR),true))
3595           else ()
3596         ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3597         ; CPSR := (PSR_J_rupd((!CPSR),false))
3598         ; CPSR :=
3599           (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3600         ; CPSR :=
3601           (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3602         ; if #VE((#SCTLR((!CP15) : CP15)) : SCTLR)
3603             then raise IMPLEMENTATION_DEFINED "branch to an FIQ vector"
3604           else BranchTo(BitsN.+(ExcVectorBase (),vect_offset))
3605         )
3606  end;
3607
3608fun TakeVirtualFIQException () =
3609  let
3610    val new_lr_value =
3611      if #T((!CPSR) : PSR) then PC () else BitsN.-(PC (),BitsN.B(0x4,32))
3612    val new_spsr_value = (!CPSR)
3613    val vect_offset = BitsN.B(0x1C,32)
3614  in
3615    ( CPSR := (PSR_M_rupd((!CPSR),BitsN.B(0x11,5)))
3616    ; write'SPSR new_spsr_value
3617    ; write'R(new_lr_value,BitsN.B(0xE,4))
3618    ; CPSR := (PSR_I_rupd((!CPSR),true))
3619    ; CPSR := (PSR_F_rupd((!CPSR),true))
3620    ; CPSR := (PSR_A_rupd((!CPSR),true))
3621    ; CPSR := (PSR_IT_rupd((!CPSR),BitsN.B(0x0,8)))
3622    ; CPSR := (PSR_J_rupd((!CPSR),false))
3623    ; CPSR := (PSR_T_rupd((!CPSR),#TE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3624    ; CPSR := (PSR_E_rupd((!CPSR),#EE((#SCTLR((!CP15) : CP15)) : SCTLR)))
3625    ; if #VE((#SCTLR((!CP15) : CP15)) : SCTLR)
3626        then raise IMPLEMENTATION_DEFINED "branch to an FIQ vector"
3627      else BranchTo(BitsN.+(ExcVectorBase (),vect_offset))
3628    )
3629  end;
3630
3631fun TakeHypTrapException () =
3632  let
3633    val preferred_exceptn_return =
3634      if #T((!CPSR) : PSR)
3635        then BitsN.-(PC (),BitsN.B(0x4,32))
3636      else BitsN.-(PC (),BitsN.B(0x8,32))
3637    val new_spsr_value = (!CPSR)
3638  in
3639    EnterHypMode
3640      (new_spsr_value,(preferred_exceptn_return,BitsN.B(0x14,32)))
3641  end;
3642
3643fun WriteHSR (ec,HSRString) =
3644  let
3645    val HSRValue = ref (BitsN.B(0x0,32))
3646  in
3647    ( HSRValue := (BitsN.bitFieldInsert(31,26) ((!HSRValue),ec))
3648    ; if (not((BitsN.bits(5,3) ec) = (BitsN.B(0x4,3)))) orelse
3649         ((BitsN.bit(ec,2)) andalso (BitsN.bit(HSRString,24)))
3650        then HSRValue :=
3651             (BitsN.bitFieldInsert(25,25)
3652                ((!HSRValue),BitsN.fromBit((ThisInstrLength ()) = 32)))
3653      else ()
3654    ; if ((BitsN.bits(5,4) ec) = (BitsN.B(0x0,2))) andalso
3655         (not((BitsN.bits(3,0) ec) = (BitsN.B(0x0,4))))
3656        then if (CurrentInstrSet ()) = InstrSet_ARM
3657               then ( HSRValue :=
3658                      (BitsN.bitFieldInsert(24,24)
3659                         ((!HSRValue),BitsN.fromBit true))
3660                    ; HSRValue :=
3661                      (BitsN.bitFieldInsert(23,20)
3662                         ((!HSRValue),CurrentCond ()))
3663                    )
3664             else ( HSRValue :=
3665                    (BitsN.bitFieldInsert(24,24)
3666                       ((!HSRValue),BitsN.fromBit false))
3667                  ; if BitsN.bit((!HSRValue),24)
3668                      then if ConditionPassed ()
3669                             then HSRValue :=
3670                                  (BitsN.bitFieldInsert(23,20)
3671                                     ((!HSRValue),
3672                                      if false
3673                                        then CurrentCond ()
3674                                      else BitsN.B(0xE,4)))
3675                           else HSRValue :=
3676                                (BitsN.bitFieldInsert(23,20)
3677                                   ((!HSRValue),CurrentCond ()))
3678                    else ()
3679                  ; HSRValue :=
3680                    (BitsN.bitFieldInsert(19,0)
3681                       ((!HSRValue),BitsN.bits(19,0) HSRString))
3682                  )
3683      else HSRValue :=
3684           (BitsN.bitFieldInsert(24,0) ((!HSRValue),HSRString))
3685    ; let
3686        val x0 = #HSR((!CP15) : CP15)
3687      in
3688        CP15 := (CP15_HSR_rupd((!CP15),write'reg'HSR(x0,(!HSRValue))))
3689      end
3690    )
3691  end;
3692
3693fun CallSupervisor immediate =
3694  ( if (CurrentModeIsHyp ()) orelse
3695       ((HaveVirtExt ()) andalso
3696        ((not(IsSecure ())) andalso
3697         ((not(CurrentModeIsNotUser ())) andalso
3698          (#TGE((#HCR((!CP15) : CP15)) : HCR)))))
3699      then let
3700             val HSRString = ref (BitsN.B(0x0,25))
3701           in
3702             ( HSRString :=
3703               (BitsN.bitFieldInsert(15,0)
3704                  ((!HSRString),
3705                   if (CurrentCond ()) = (BitsN.B(0xE,4))
3706                     then immediate
3707                   else BitsN.B(0x0,16)))
3708             ; WriteHSR(BitsN.B(0x12,6),(!HSRString))
3709             )
3710           end
3711    else ()
3712  ; TakeSVCException ()
3713  );
3714
3715fun CallHypervisor immediate =
3716  let
3717    val HSRString = BitsN.@@(immediate,BitsN.B(0x0,9))
3718  in
3719    ( WriteHSR(BitsN.B(0x12,6),HSRString); TakeHVCException () )
3720  end;
3721
3722fun BankedRegisterAccessValid (SYSm,mode) =
3723  if (BitsN.bits(4,3) SYSm) = (BitsN.B(0x0,2))
3724    then if (BitsN.bits(2,0) SYSm) = (BitsN.B(0x7,3))
3725           then raise UNPREDICTABLE "BankedRegisterAccessValid"
3726         else if (BitsN.bits(2,0) SYSm) = (BitsN.B(0x6,3))
3727           then if Set.mem(mode,[BitsN.B(0x1A,5),BitsN.B(0x1F,5)])
3728                  then raise UNPREDICTABLE "BankedRegisterAccessValid"
3729                else ()
3730         else if (BitsN.bits(2,0) SYSm) = (BitsN.B(0x5,3))
3731           then if mode = (BitsN.B(0x1F,5))
3732                  then raise UNPREDICTABLE "BankedRegisterAccessValid"
3733                else ()
3734         else if not(mode = (BitsN.B(0x11,5)))
3735           then raise UNPREDICTABLE "BankedRegisterAccessValid"
3736         else ()
3737  else if (BitsN.bits(4,3) SYSm) = (BitsN.B(0x1,2))
3738    then if ((BitsN.bits(2,0) SYSm) = (BitsN.B(0x7,3))) orelse
3739            ((mode = (BitsN.B(0x11,5))) orelse
3740             ((#RFR((#NSACR((!CP15) : CP15)) : NSACR)) andalso
3741              (not(IsSecure ()))))
3742           then raise UNPREDICTABLE "BankedRegisterAccessValid"
3743         else ()
3744  else if (BitsN.bits(4,3) SYSm) = (BitsN.B(0x3,2))
3745    then if not(BitsN.bit(SYSm,2))
3746           then raise UNPREDICTABLE "BankedRegisterAccessValid"
3747         else if not(BitsN.bit(SYSm,1))
3748           then if (not(IsSecure ())) orelse (mode = (BitsN.B(0x16,5)))
3749                  then raise UNPREDICTABLE "BankedRegisterAccessValid"
3750                else ()
3751         else if not(mode = (BitsN.B(0x16,5)))
3752           then raise UNPREDICTABLE "BankedRegisterAccessValid"
3753         else ()
3754  else ();
3755
3756fun SPSRAccessValid (SYSm,mode) =
3757  case SYSm of
3758     BitsN.B(0xE,_) =>
3759       if ((not(IsSecure ())) andalso
3760           (#RFR((#NSACR((!CP15) : CP15)) : NSACR))) orelse
3761          (mode = (BitsN.B(0x11,5)))
3762         then raise UNPREDICTABLE "SPSRAccessValid"
3763       else ()
3764   | BitsN.B(0x10,_) =>
3765     if mode = (BitsN.B(0x12,5))
3766       then raise UNPREDICTABLE "SPSRAccessValid"
3767     else ()
3768   | BitsN.B(0x12,_) =>
3769     if mode = (BitsN.B(0x13,5))
3770       then raise UNPREDICTABLE "SPSRAccessValid"
3771     else ()
3772   | BitsN.B(0x14,_) =>
3773     if mode = (BitsN.B(0x17,5))
3774       then raise UNPREDICTABLE "SPSRAccessValid"
3775     else ()
3776   | BitsN.B(0x16,_) =>
3777     if mode = (BitsN.B(0x1B,5))
3778       then raise UNPREDICTABLE "SPSRAccessValid"
3779     else ()
3780   | BitsN.B(0x1C,_) =>
3781     if (mode = (BitsN.B(0x16,5))) orelse (not(IsSecure ()))
3782       then raise UNPREDICTABLE "SPSRAccessValid"
3783     else ()
3784   | BitsN.B(0x1E,_) =>
3785     if not(mode = (BitsN.B(0x16,5)))
3786       then raise UNPREDICTABLE "SPSRAccessValid"
3787     else ()
3788   | _ => raise UNPREDICTABLE "SPSRAccessValid";
3789
3790fun dfn'BranchTarget imm32 = BranchWritePC(BitsN.+(PC (),imm32));
3791
3792fun dfn'BranchExchange m = BXWritePC(R m);
3793
3794fun dfn'BranchLinkExchangeImmediate (targetInstrSet,imm32) =
3795  ( if (CurrentInstrSet ()) = InstrSet_ARM
3796      then write'LR(BitsN.-(PC (),BitsN.B(0x4,32)))
3797    else write'LR(BitsN.@@(BitsN.bits(31,1) (PC ()),BitsN.B(0x1,1)))
3798  ; let
3799      val targetAddress =
3800        if targetInstrSet = InstrSet_ARM
3801          then BitsN.+(Align 32 (PC (),4),imm32)
3802        else BitsN.+(PC (),imm32)
3803    in
3804      ( SelectInstrSet targetInstrSet; BranchWritePC targetAddress )
3805    end
3806  );
3807
3808fun dfn'BranchLinkExchangeRegister m =
3809  let
3810    val target = R m
3811  in
3812    ( if (CurrentInstrSet ()) = InstrSet_ARM
3813        then let
3814               val next_instr_addr = BitsN.-(PC (),BitsN.B(0x4,32))
3815             in
3816               write'LR next_instr_addr
3817             end
3818      else let
3819             val next_instr_addr = BitsN.-(PC (),BitsN.B(0x2,32))
3820           in
3821             write'LR
3822               (BitsN.@@(BitsN.bits(31,1) next_instr_addr,BitsN.B(0x1,1)))
3823           end
3824    ; BXWritePC target
3825    )
3826  end;
3827
3828fun dfn'CompareBranch (nonzero,(n,imm32)) =
3829  if not(nonzero = ((R n) = (BitsN.B(0x0,32))))
3830    then BranchWritePC(BitsN.+(PC (),imm32))
3831  else IncPC ();
3832
3833fun dfn'TableBranchByte (is_tbh,(m,n)) =
3834  if NullCheckIfThumbEE n
3835    then let
3836           val halfwords =
3837             if is_tbh
3838               then MemU 16 (BitsN.+(R n,LSL 32 (R m,1)),2)
3839             else MemU 16 (BitsN.+(R n,R m),1)
3840         in
3841           BranchWritePC
3842             (BitsN.+
3843                (PC (),
3844                 BitsN.*
3845                   (BitsN.B(0x2,32),
3846                    BitsN.fromNat(BitsN.toNat halfwords,32))))
3847         end
3848  else ();
3849
3850fun dfn'CheckArray (m,n) =
3851  if BitsN.<=+(R n,R m)
3852    then ( write'LR(BitsN.@@(BitsN.bits(31,1) (PC ()),BitsN.B(0x1,1)))
3853         ; write'ITSTATE(BitsN.B(0x0,8))
3854         ; BranchWritePC(BitsN.-(#TEEHBR((!CP14) : CP14),BitsN.B(0x8,32)))
3855         )
3856  else IncPC ();
3857
3858fun dfn'HandlerBranchLink (generate_link,handler_offset) =
3859  ( if generate_link
3860      then let
3861             val next_instr_addr = BitsN.-(PC (),BitsN.B(0x2,32))
3862           in
3863             write'LR
3864               (BitsN.@@(BitsN.bits(31,1) next_instr_addr,BitsN.B(0x1,1)))
3865           end
3866    else ()
3867  ; BranchWritePC(BitsN.+(#TEEHBR((!CP14) : CP14),handler_offset))
3868  );
3869
3870fun dfn'HandlerBranchLinkParameter (imm32,handler_offset) =
3871  ( write'R(imm32,BitsN.B(0x8,4))
3872  ; let
3873      val next_instr_addr = BitsN.-(PC (),BitsN.B(0x2,32))
3874    in
3875      ( write'LR
3876          (BitsN.@@(BitsN.bits(31,1) next_instr_addr,BitsN.B(0x1,1)))
3877      ; BranchWritePC(BitsN.+(#TEEHBR((!CP14) : CP14),handler_offset))
3878      )
3879    end
3880  );
3881
3882fun dfn'HandlerBranchParameter (imm32,handler_offset) =
3883  ( write'R(imm32,BitsN.B(0x8,4))
3884  ; BranchWritePC(BitsN.+(#TEEHBR((!CP14) : CP14),handler_offset))
3885  );
3886
3887fun dfn'EnterxLeavex is_enterx =
3888  if is_enterx
3889    then if CurrentModeIsHyp ()
3890           then TakeUndefInstrException ()
3891         else ( SelectInstrSet InstrSet_ThumbEE; IncPC () )
3892  else ( SelectInstrSet InstrSet_Thumb; IncPC () );
3893
3894fun dfn'IfThen (firstcond,mask) =
3895  ( CPSR := (PSR_IT_rupd((!CPSR),BitsN.@@(firstcond,mask)))
3896  ; IncPC ()
3897  ; Encoding := Encoding_ARM
3898  );
3899
3900fun dfn'CountLeadingZeroes (d,m) =
3901  ( write'R(BitsN.fromNat(CountLeadingZeroBits 32 (R m),32),d); IncPC () );
3902
3903fun dfn'MoveHalfword (high,(d,imm16)) =
3904  ( if high
3905      then let
3906             val w = R d
3907           in
3908             write'R(BitsN.bitFieldInsert(31,16) (w,imm16),d)
3909           end
3910    else write'R(BitsN.zeroExtend 32 imm16,d)
3911  ; IncPC ()
3912  );
3913
3914fun DataProcessing (opc,(setflags,(d,(n,(imm32,C))))) =
3915  let
3916    val rn =
3917      if (opc = (BitsN.B(0xD,4))) orelse
3918         ((opc = (BitsN.B(0xF,4))) andalso (n = (BitsN.B(0xF,4))))
3919        then BitsN.B(0x0,32)
3920      else if (Set.mem(opc,[BitsN.B(0x4,4),BitsN.B(0x2,4)])) andalso
3921         ((n = (BitsN.B(0xF,4))) andalso (not setflags))
3922        then Align 32 (PC (),4)
3923      else R n
3924    val (result,(carry,overflow)) =
3925      DataProcessingALU(opc,(rn,(imm32,#C((!CPSR) : PSR))))
3926  in
3927    ( if not((BitsN.bits(3,2) opc) = (BitsN.B(0x2,2)))
3928        then write'R(result,d)
3929      else ()
3930    ; if setflags
3931        then ( CPSR := (PSR_N_rupd((!CPSR),BitsN.bit(result,31)))
3932             ; CPSR := (PSR_Z_rupd((!CPSR),result = (BitsN.B(0x0,32))))
3933             ; if ArithmeticOpcode opc
3934                 then ( CPSR := (PSR_C_rupd((!CPSR),carry))
3935                      ; CPSR := (PSR_V_rupd((!CPSR),overflow))
3936                      )
3937               else CPSR := (PSR_C_rupd((!CPSR),C))
3938             )
3939      else ()
3940    ; IncPC ()
3941    )
3942  end;
3943
3944fun DataProcessingPC (opc,(setflags,(n,imm32))) =
3945  let
3946    val rn =
3947      if (opc = (BitsN.B(0xD,4))) orelse
3948         ((opc = (BitsN.B(0xF,4))) andalso (n = (BitsN.B(0xF,4))))
3949        then BitsN.B(0x0,32)
3950      else if (Set.mem(opc,[BitsN.B(0x4,4),BitsN.B(0x2,4)])) andalso
3951         ((n = (BitsN.B(0xF,4))) andalso (not setflags))
3952        then Align 32 (PC (),4)
3953      else R n
3954    val (result,_) = DataProcessingALU(opc,(rn,(imm32,#C((!CPSR) : PSR))))
3955  in
3956    if setflags
3957      then if CurrentModeIsHyp ()
3958             then TakeUndefInstrException ()
3959           else if CurrentModeIsUserOrSystem ()
3960             then raise UNPREDICTABLE "DataProcessingPC"
3961           else ( CPSRWriteByInstr(reg'PSR(SPSR ()),(BitsN.B(0xF,4),true))
3962                ; if ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5))) andalso
3963                     ((CurrentInstrSet ()) = InstrSet_ThumbEE)
3964                    then raise UNPREDICTABLE "DataProcessingPC"
3965                  else BranchWritePC result
3966                )
3967    else ALUWritePC result
3968  end;
3969
3970fun dfn'Move (setflags,(negate,(d,imm12))) =
3971  let
3972    val opc =
3973      BitsN.concat[BitsN.B(0x3,2),BitsN.fromBit negate,BitsN.B(0x1,1)]
3974    val (imm32,carry) = ExpandImm_C(imm12,#C((!CPSR) : PSR))
3975  in
3976    if d = (BitsN.B(0xF,4))
3977      then DataProcessingPC(opc,(setflags,(BitsN.B(0xF,4),imm32)))
3978    else DataProcessing(opc,(setflags,(d,(BitsN.B(0xF,4),(imm32,carry)))))
3979  end;
3980
3981fun dfn'TestCompareImmediate (op',(n,imm12)) =
3982  let
3983    val (imm32,carry) = ExpandImm_C(imm12,#C((!CPSR) : PSR))
3984  in
3985    DataProcessing
3986      (BitsN.@@(BitsN.B(0x2,2),op'),
3987       (true,(BitsN.B(0x0,4),(n,(imm32,carry)))))
3988  end;
3989
3990fun dfn'ArithLogicImmediate (opc,(setflags,(d,(n,imm12)))) =
3991  let
3992    val (imm32,carry) = ExpandImm_C(imm12,#C((!CPSR) : PSR))
3993  in
3994    if d = (BitsN.B(0xF,4))
3995      then DataProcessingPC(opc,(setflags,(n,imm32)))
3996    else DataProcessing(opc,(setflags,(d,(n,(imm32,carry)))))
3997  end;
3998
3999fun doRegister (opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))) =
4000  let
4001    val (shifted,carry) =
4002      Shift_C 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
4003  in
4004    if d = (BitsN.B(0xF,4))
4005      then DataProcessingPC(opc,(setflags,(n,shifted)))
4006    else DataProcessing(opc,(setflags,(d,(n,(shifted,carry)))))
4007  end;
4008
4009fun dfn'Register (opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))) =
4010  doRegister(opc,(setflags,(d,(n,(m,(shift_t,shift_n))))));
4011
4012fun dfn'TestCompareRegister (opc,(n,(m,(shift_t,shift_n)))) =
4013  doRegister
4014    (BitsN.@@(BitsN.B(0x2,2),opc),
4015     (true,(BitsN.B(0x0,4),(n,(m,(shift_t,shift_n))))));
4016
4017fun dfn'ShiftImmediate (negate,(setflags,(d,(m,(shift_t,shift_n))))) =
4018  if negate
4019    then doRegister
4020           (BitsN.B(0xF,4),
4021            (setflags,(d,(BitsN.B(0xF,4),(m,(shift_t,shift_n))))))
4022  else doRegister
4023         (BitsN.B(0xD,4),
4024          (setflags,(d,(BitsN.B(0x0,4),(m,(shift_t,shift_n))))));
4025
4026fun doRegisterShiftedRegister (opc,(setflags,(d,(n,(m,(shift_t,s)))))) =
4027  let
4028    val (shifted,carry) =
4029      Shift_C 32
4030        (R m,
4031         (shift_t,(BitsN.toNat(BitsN.bits(7,0) (R s)),#C((!CPSR) : PSR))))
4032  in
4033    DataProcessing(opc,(setflags,(d,(n,(shifted,carry)))))
4034  end;
4035
4036fun dfn'RegisterShiftedRegister (opc,(setflags,(d,(n,(m,(shift_t,s)))))) =
4037  doRegisterShiftedRegister(opc,(setflags,(d,(n,(m,(shift_t,s))))));
4038
4039fun dfn'ShiftRegister (negate,(setflags,(d,(n,(shift_t,m))))) =
4040  if negate
4041    then doRegisterShiftedRegister
4042           (BitsN.B(0xF,4),(setflags,(d,(BitsN.B(0xF,4),(n,(shift_t,m))))))
4043  else doRegisterShiftedRegister
4044         (BitsN.B(0xD,4),(setflags,(d,(BitsN.B(0x0,4),(n,(shift_t,m))))));
4045
4046fun dfn'AddSub (sub,(d,(n,imm12))) =
4047  let
4048    val opc = if sub then BitsN.B(0x2,4) else BitsN.B(0x4,4)
4049    val imm32 = BitsN.zeroExtend 32 imm12
4050  in
4051    DataProcessing(opc,(false,(d,(n,(imm32,false)))))
4052  end;
4053
4054fun dfn'SaturatingAddSubtract (opc,(d,(m,n))) =
4055  let
4056    val result = ref (BitsN.B(0x0,32))
4057  in
4058    let
4059      val sat = ref false
4060    in
4061      ( case opc of
4062           BitsN.B(0x0,_) =>
4063             let
4064               val (r,s) =
4065                 SignedSatQ 32
4066                   (IntInf.+(BitsN.toInt(R m),BitsN.toInt(R n)),32)
4067             in
4068               ( result := r; sat := s )
4069             end
4070         | BitsN.B(0x1,_) =>
4071           let
4072             val (r,s) =
4073               SignedSatQ 32
4074                 (IntInf.-(BitsN.toInt(R m),BitsN.toInt(R n)),32)
4075           in
4076             ( result := r; sat := s )
4077           end
4078         | BitsN.B(0x2,_) =>
4079           let
4080             val (doubled,sat1) =
4081               SignedSatQ 32 (IntInf.*(2,BitsN.toInt(R n)),32)
4082             val (r,sat2) =
4083               SignedSatQ 32
4084                 (IntInf.+(BitsN.toInt(R m),BitsN.toInt doubled),32)
4085           in
4086             ( result := r; sat := (sat1 orelse sat2) )
4087           end
4088         | BitsN.B(0x3,_) =>
4089           let
4090             val (doubled,sat1) =
4091               SignedSatQ 32 (IntInf.*(2,BitsN.toInt(R n)),32)
4092             val (r,sat2) =
4093               SignedSatQ 32
4094                 (IntInf.-(BitsN.toInt(R m),BitsN.toInt doubled),32)
4095           in
4096             ( result := r; sat := (sat1 orelse sat2) )
4097           end
4098         | _ => raise General.Bind
4099      ; write'R((!result),d)
4100      ; if (!sat) then CPSR := (PSR_Q_rupd((!CPSR),true)) else ()
4101      ; IncPC ()
4102      )
4103    end
4104  end;
4105
4106fun dfn'Multiply32 (setflags,(d,(n,m))) =
4107  let
4108    val rn = R n
4109    val rm = R m
4110    val result = BitsN.*(rn,rm)
4111  in
4112    ( write'R(result,d)
4113    ; if setflags
4114        then ( CPSR := (PSR_N_rupd((!CPSR),BitsN.bit(result,31)))
4115             ; CPSR := (PSR_Z_rupd((!CPSR),result = (BitsN.B(0x0,32))))
4116             ; if (ArchVersion ()) = 4
4117                 then CPSR :=
4118                      (PSR_C_rupd
4119                         ((!CPSR),(L3.K false) (rn,(rm,#C((!CPSR) : PSR)))))
4120               else ()
4121             )
4122      else ()
4123    ; IncPC ()
4124    )
4125  end;
4126
4127fun dfn'MultiplyAccumulate (setflags,(d,(n,(m,a)))) =
4128  let
4129    val rn = R n
4130    val rm = R m
4131    val ra = R a
4132    val result = BitsN.+(BitsN.*(rn,rm),ra)
4133  in
4134    ( write'R(result,d)
4135    ; if setflags
4136        then ( CPSR := (PSR_N_rupd((!CPSR),BitsN.bit(result,31)))
4137             ; CPSR := (PSR_Z_rupd((!CPSR),result = (BitsN.B(0x0,32))))
4138             ; if (ArchVersion ()) = 4
4139                 then CPSR :=
4140                      (PSR_C_rupd
4141                         ((!CPSR),
4142                          (L3.K false) (rn,(rm,(ra,#C((!CPSR) : PSR))))))
4143               else ()
4144             )
4145      else ()
4146    ; IncPC ()
4147    )
4148  end;
4149
4150fun dfn'MultiplyLong (accumulate,(signed,(setflags,(dhi,(dlo,(n,m)))))) =
4151  let
4152    val rn = R n
4153    val rm = R m
4154    val rdhi = R dhi
4155    val rdlo = R dlo
4156    val result =
4157      BitsN.+
4158        (if signed
4159           then BitsN.*(BitsN.signExtend 64 rn,BitsN.signExtend 64 rm)
4160         else BitsN.*(BitsN.zeroExtend 64 rn,BitsN.zeroExtend 64 rm),
4161         if accumulate then BitsN.@@(rdhi,rdlo) else BitsN.B(0x0,64))
4162  in
4163    ( write'R(BitsN.bits(63,32) result,dhi)
4164    ; write'R(BitsN.bits(31,0) result,dlo)
4165    ; if setflags
4166        then ( CPSR := (PSR_N_rupd((!CPSR),BitsN.bit(result,63)))
4167             ; CPSR := (PSR_Z_rupd((!CPSR),result = (BitsN.B(0x0,64))))
4168             ; if (ArchVersion ()) = 4
4169                 then ( CPSR :=
4170                        (PSR_C_rupd
4171                           ((!CPSR),
4172                            (L3.K false)
4173                              (rn,(rm,(rdhi,(rdlo,#C((!CPSR) : PSR)))))))
4174                      ; CPSR :=
4175                        (PSR_V_rupd
4176                           ((!CPSR),
4177                            (L3.K false)
4178                              (rn,(rm,(rdhi,(rdlo,#V((!CPSR) : PSR)))))))
4179                      )
4180               else ()
4181             )
4182      else ()
4183    ; IncPC ()
4184    )
4185  end;
4186
4187fun dfn'MultiplyAccumulateAccumulate (dhi,(dlo,(n,m))) =
4188  let
4189    val result =
4190      BitsN.+
4191        (BitsN.+
4192           (BitsN.*(BitsN.zeroExtend 64 (R n),BitsN.zeroExtend 64 (R m)),
4193            BitsN.zeroExtend 64 (R dhi)),BitsN.zeroExtend 64 (R dlo))
4194  in
4195    ( write'R(BitsN.bits(63,32) result,dhi)
4196    ; write'R(BitsN.bits(31,0) result,dlo)
4197    ; IncPC ()
4198    )
4199  end;
4200
4201fun dfn'MultiplySubtract (d,(n,(m,a))) =
4202  ( write'R(BitsN.-(R a,BitsN.*(R m,R n)),d); IncPC () );
4203
4204fun dfn'Signed16Multiply32Accumulate (m_high,(n_high,(d,(n,(m,a))))) =
4205  let
4206    val operand1 =
4207      if n_high then BitsN.bits(31,16) (R n) else BitsN.bits(15,0) (R n)
4208    val operand2 =
4209      if m_high then BitsN.bits(31,16) (R m) else BitsN.bits(15,0) (R m)
4210    val result =
4211      IntInf.+
4212        (IntInf.*(BitsN.toInt operand1,BitsN.toInt operand2),
4213         BitsN.toInt(R a))
4214    val result32 = BitsN.fromInt(result,32)
4215  in
4216    ( write'R(result32,d)
4217    ; if not(result = (BitsN.toInt result32))
4218        then CPSR := (PSR_Q_rupd((!CPSR),true))
4219      else ()
4220    ; IncPC ()
4221    )
4222  end;
4223
4224fun dfn'Signed16Multiply32Result (m_high,(n_high,(d,(n,m)))) =
4225  let
4226    val operand1 =
4227      if n_high then BitsN.bits(31,16) (R n) else BitsN.bits(15,0) (R n)
4228    val operand2 =
4229      if m_high then BitsN.bits(31,16) (R m) else BitsN.bits(15,0) (R m)
4230    val result = IntInf.*(BitsN.toInt operand1,BitsN.toInt operand2)
4231  in
4232    ( write'R(BitsN.fromInt(result,32),d); IncPC () )
4233  end;
4234
4235fun dfn'Signed16x32Multiply32Accumulate (m_high,(d,(n,(m,a)))) =
4236  let
4237    val operand2 =
4238      if m_high then BitsN.bits(31,16) (R m) else BitsN.bits(15,0) (R m)
4239    val sh16 = IntExtra.pow(2,16)
4240    val result =
4241      IntInf.div
4242        (IntInf.+
4243           (IntInf.*(BitsN.toInt(R n),BitsN.toInt operand2),
4244            IntInf.*(BitsN.toInt(R a),sh16)),sh16)
4245    val result32 = BitsN.fromInt(result,32)
4246  in
4247    ( write'R(result32,d)
4248    ; if not(result = (BitsN.toInt result32))
4249        then CPSR := (PSR_Q_rupd((!CPSR),true))
4250      else ()
4251    ; IncPC ()
4252    )
4253  end;
4254
4255fun dfn'Signed16x32Multiply32Result (m_high,(d,(n,m))) =
4256  let
4257    val operand2 =
4258      if m_high then BitsN.bits(31,16) (R m) else BitsN.bits(15,0) (R m)
4259    val result =
4260      IntInf.div
4261        (IntInf.*(BitsN.toInt(R n),BitsN.toInt operand2),
4262         IntExtra.pow(2,16))
4263  in
4264    ( write'R(BitsN.fromInt(result,32),d); IncPC () )
4265  end;
4266
4267fun dfn'Signed16Multiply64Accumulate (m_high,(n_high,(dhi,(dlo,(n,m))))) =
4268  let
4269    val operand1 =
4270      if n_high then BitsN.bits(31,16) (R n) else BitsN.bits(15,0) (R n)
4271    val operand2 =
4272      if m_high then BitsN.bits(31,16) (R m) else BitsN.bits(15,0) (R m)
4273    val result =
4274      IntInf.+
4275        (IntInf.*(BitsN.toInt operand1,BitsN.toInt operand2),
4276         BitsN.toInt(BitsN.@@(R dhi,R dlo)))
4277    val result64 = BitsN.fromInt(result,64)
4278  in
4279    ( write'R(BitsN.bits(63,32) result64,dhi)
4280    ; write'R(BitsN.bits(31,0) result64,dlo)
4281    ; IncPC ()
4282    )
4283  end;
4284
4285fun dfn'SignedMultiplyDual (sub,(m_swap,(d,(n,(m,a))))) =
4286  let
4287    val operand2 = if m_swap then ROR 32 (R m,16) else R m
4288    val product1 =
4289      IntInf.*
4290        (BitsN.toInt(BitsN.bits(15,0) (R n)),
4291         BitsN.toInt(BitsN.bits(15,0) operand2))
4292    val product2 =
4293      IntInf.*
4294        (BitsN.toInt(BitsN.bits(31,16) (R n)),
4295         BitsN.toInt(BitsN.bits(31,16) operand2))
4296    val acc = if a = (BitsN.B(0xF,4)) then BitsN.B(0x0,32) else R a
4297    val result =
4298      if sub
4299        then IntInf.+(IntInf.-(product1,product2),BitsN.toInt acc)
4300      else IntInf.+(IntInf.+(product1,product2),BitsN.toInt acc)
4301    val result32 = BitsN.fromInt(result,32)
4302  in
4303    ( write'R(result32,d)
4304    ; if not(result = (BitsN.toInt result32))
4305        then CPSR := (PSR_Q_rupd((!CPSR),true))
4306      else ()
4307    ; IncPC ()
4308    )
4309  end;
4310
4311fun dfn'SignedMultiplyLongDual (sub,(m_swap,(dhi,(dlo,(n,m))))) =
4312  let
4313    val Rn = R n
4314    val operand2 = if m_swap then ROR 32 (R m,16) else R m
4315    val product1 =
4316      IntInf.*
4317        (BitsN.toInt(BitsN.bits(15,0) Rn),
4318         BitsN.toInt(BitsN.bits(15,0) operand2))
4319    val product2 =
4320      IntInf.*
4321        (BitsN.toInt(BitsN.bits(31,16) Rn),
4322         BitsN.toInt(BitsN.bits(31,16) operand2))
4323    val acc = BitsN.@@(R dhi,R dlo)
4324    val result =
4325      if sub
4326        then IntInf.+(IntInf.-(product1,product2),BitsN.toInt acc)
4327      else IntInf.+(IntInf.+(product1,product2),BitsN.toInt acc)
4328    val result64 = BitsN.fromInt(result,64)
4329  in
4330    ( write'R(BitsN.bits(63,32) result64,dhi)
4331    ; write'R(BitsN.bits(31,0) result64,dlo)
4332    ; IncPC ()
4333    )
4334  end;
4335
4336fun dfn'SignedMostSignificantMultiply (round,(d,(n,(m,a)))) =
4337  let
4338    val acc = if a = (BitsN.B(0xF,4)) then BitsN.B(0x0,32) else R a
4339    val result =
4340      IntInf.+
4341        (BitsN.toInt(BitsN.<<(BitsN.fromNat(BitsN.toNat acc,64),32)),
4342         IntInf.*(BitsN.toInt(R n),BitsN.toInt(R m)))
4343    val result = if round then IntInf.+(result,2147483648) else result
4344  in
4345    ( write'R(BitsN.bits(63,32) (BitsN.fromInt(result,64)),d); IncPC () )
4346  end;
4347
4348fun dfn'SignedMostSignificantMultiplySubtract (round,(d,(n,(m,a)))) =
4349  let
4350    val result =
4351      IntInf.-
4352        (BitsN.toInt(BitsN.<<(BitsN.fromNat(BitsN.toNat(R a),64),32)),
4353         IntInf.*(BitsN.toInt(R n),BitsN.toInt(R m)))
4354    val result = if round then IntInf.+(result,2147483648) else result
4355  in
4356    ( write'R(BitsN.bits(63,32) (BitsN.fromInt(result,64)),d); IncPC () )
4357  end;
4358
4359fun SignedParallelAddSub16 (op',(n,m)) =
4360  let
4361    val Rn = R n
4362    val Rm = R m
4363  in
4364    case op' of
4365       BitsN.B(0x0,_) =>
4366         (IntInf.+
4367            (BitsN.toInt(BitsN.bits(15,0) Rn),
4368             BitsN.toInt(BitsN.bits(15,0) Rm)),
4369          IntInf.+
4370            (BitsN.toInt(BitsN.bits(31,16) Rn),
4371             BitsN.toInt(BitsN.bits(31,16) Rm)))
4372     | BitsN.B(0x1,_) =>
4373       (IntInf.-
4374          (BitsN.toInt(BitsN.bits(15,0) Rn),
4375           BitsN.toInt(BitsN.bits(31,16) Rm)),
4376        IntInf.+
4377          (BitsN.toInt(BitsN.bits(31,16) Rn),
4378           BitsN.toInt(BitsN.bits(15,0) Rm)))
4379     | BitsN.B(0x2,_) =>
4380       (IntInf.+
4381          (BitsN.toInt(BitsN.bits(15,0) Rn),
4382           BitsN.toInt(BitsN.bits(31,16) Rm)),
4383        IntInf.-
4384          (BitsN.toInt(BitsN.bits(31,16) Rn),
4385           BitsN.toInt(BitsN.bits(15,0) Rm)))
4386     | BitsN.B(0x3,_) =>
4387       (IntInf.-
4388          (BitsN.toInt(BitsN.bits(15,0) Rn),
4389           BitsN.toInt(BitsN.bits(15,0) Rm)),
4390        IntInf.-
4391          (BitsN.toInt(BitsN.bits(31,16) Rn),
4392           BitsN.toInt(BitsN.bits(31,16) Rm)))
4393     | _ => raise General.Bind
4394  end;
4395
4396fun dfn'SignedAddSub16 (op',(d,(n,m))) =
4397  let
4398    val (res1,res2) = SignedParallelAddSub16(op',(n,m))
4399  in
4400    ( write'R(BitsN.@@(BitsN.fromInt(res2,16),BitsN.fromInt(res1,16)),d)
4401    ; let
4402        val w = #GE((!CPSR) : PSR)
4403      in
4404        CPSR :=
4405        (PSR_GE_rupd
4406           ((!CPSR),
4407            BitsN.bitFieldInsert(1,0)
4408              (w,
4409               if IntInf.>=(res1,0)
4410                 then BitsN.B(0x3,2)
4411               else BitsN.B(0x0,2))))
4412      end
4413    ; let
4414        val w = #GE((!CPSR) : PSR)
4415      in
4416        CPSR :=
4417        (PSR_GE_rupd
4418           ((!CPSR),
4419            BitsN.bitFieldInsert(3,2)
4420              (w,
4421               if IntInf.>=(res2,0)
4422                 then BitsN.B(0x3,2)
4423               else BitsN.B(0x0,2))))
4424      end
4425    ; IncPC ()
4426    )
4427  end;
4428
4429fun dfn'SignedSaturatingAddSub16 (op',(d,(n,m))) =
4430  let
4431    val (res1,res2) = SignedParallelAddSub16(op',(n,m))
4432  in
4433    ( write'R(BitsN.@@(SignedSat 16 (res2,16),SignedSat 16 (res1,16)),d)
4434    ; IncPC ()
4435    )
4436  end;
4437
4438fun dfn'SignedHalvingAddSub16 (op',(d,(n,m))) =
4439  let
4440    val (res1,res2) = SignedParallelAddSub16(op',(n,m))
4441  in
4442    ( write'R
4443        (BitsN.@@
4444           (BitsN.fromInt(IntInf.div(res2,2),16),
4445            BitsN.fromInt(IntInf.div(res1,2),16)),d)
4446    ; IncPC ()
4447    )
4448  end;
4449
4450fun SignedParallelAddSub8 (sub,(n,m)) =
4451  let
4452    val Rn = R n
4453    val Rm = R m
4454  in
4455    if sub
4456      then (IntInf.-
4457              (BitsN.toInt(BitsN.bits(7,0) Rn),
4458               BitsN.toInt(BitsN.bits(7,0) Rm)),
4459            (IntInf.-
4460               (BitsN.toInt(BitsN.bits(15,8) Rn),
4461                BitsN.toInt(BitsN.bits(15,8) Rm)),
4462             (IntInf.-
4463                (BitsN.toInt(BitsN.bits(23,16) Rn),
4464                 BitsN.toInt(BitsN.bits(23,16) Rm)),
4465              IntInf.-
4466                (BitsN.toInt(BitsN.bits(31,24) Rn),
4467                 BitsN.toInt(BitsN.bits(31,24) Rm)))))
4468    else (IntInf.+
4469            (BitsN.toInt(BitsN.bits(7,0) Rn),
4470             BitsN.toInt(BitsN.bits(7,0) Rm)),
4471          (IntInf.+
4472             (BitsN.toInt(BitsN.bits(15,8) Rn),
4473              BitsN.toInt(BitsN.bits(15,8) Rm)),
4474           (IntInf.+
4475              (BitsN.toInt(BitsN.bits(23,16) Rn),
4476               BitsN.toInt(BitsN.bits(23,16) Rm)),
4477            IntInf.+
4478              (BitsN.toInt(BitsN.bits(31,24) Rn),
4479               BitsN.toInt(BitsN.bits(31,24) Rm)))))
4480  end;
4481
4482fun dfn'SignedAddSub8 (sub,(d,(n,m))) =
4483  let
4484    val (res1,(res2,(res3,res4))) = SignedParallelAddSub8(sub,(n,m))
4485  in
4486    ( write'R
4487        (BitsN.concat
4488           [BitsN.fromInt(res4,8),BitsN.fromInt(res3,8),
4489            BitsN.fromInt(res2,8),BitsN.fromInt(res1,8)],d)
4490    ; let
4491        val w = #GE((!CPSR) : PSR)
4492      in
4493        CPSR :=
4494        (PSR_GE_rupd
4495           ((!CPSR),
4496            BitsN.bitFieldInsert(0,0) (w,BitsN.fromBit(IntInf.>=(res1,0)))))
4497      end
4498    ; let
4499        val w = #GE((!CPSR) : PSR)
4500      in
4501        CPSR :=
4502        (PSR_GE_rupd
4503           ((!CPSR),
4504            BitsN.bitFieldInsert(1,1) (w,BitsN.fromBit(IntInf.>=(res2,0)))))
4505      end
4506    ; let
4507        val w = #GE((!CPSR) : PSR)
4508      in
4509        CPSR :=
4510        (PSR_GE_rupd
4511           ((!CPSR),
4512            BitsN.bitFieldInsert(2,2) (w,BitsN.fromBit(IntInf.>=(res3,0)))))
4513      end
4514    ; let
4515        val w = #GE((!CPSR) : PSR)
4516      in
4517        CPSR :=
4518        (PSR_GE_rupd
4519           ((!CPSR),
4520            BitsN.bitFieldInsert(3,3) (w,BitsN.fromBit(IntInf.>=(res4,0)))))
4521      end
4522    ; IncPC ()
4523    )
4524  end;
4525
4526fun dfn'SignedSaturatingAddSub8 (sub,(d,(n,m))) =
4527  let
4528    val (res1,(res2,(res3,res4))) = SignedParallelAddSub8(sub,(n,m))
4529  in
4530    ( write'R
4531        (BitsN.concat
4532           [SignedSat 8 (res4,8),SignedSat 8 (res3,8),
4533            SignedSat 8 (res2,8),SignedSat 8 (res1,8)],d)
4534    ; IncPC ()
4535    )
4536  end;
4537
4538fun dfn'SignedHalvingAddSub8 (sub,(d,(n,m))) =
4539  let
4540    val (res1,(res2,(res3,res4))) = SignedParallelAddSub8(sub,(n,m))
4541  in
4542    ( write'R
4543        (BitsN.concat
4544           [BitsN.fromInt(IntInf.div(res4,2),8),
4545            BitsN.fromInt(IntInf.div(res3,2),8),
4546            BitsN.fromInt(IntInf.div(res2,2),8),
4547            BitsN.fromInt(IntInf.div(res1,2),8)],d)
4548    ; IncPC ()
4549    )
4550  end;
4551
4552fun UnsignedParallelAddSub16 (op',(n,m)) =
4553  let
4554    val Rn = R n
4555    val Rm = R m
4556  in
4557    case op' of
4558       BitsN.B(0x0,_) =>
4559         (IntInf.+
4560            (UInt 16 (BitsN.bits(15,0) Rn),UInt 16 (BitsN.bits(15,0) Rm)),
4561          IntInf.+
4562            (UInt 16 (BitsN.bits(31,16) Rn),UInt 16 (BitsN.bits(31,16) Rm)))
4563     | BitsN.B(0x1,_) =>
4564       (IntInf.-
4565          (UInt 16 (BitsN.bits(15,0) Rn),UInt 16 (BitsN.bits(31,16) Rm)),
4566        IntInf.+
4567          (UInt 16 (BitsN.bits(31,16) Rn),UInt 16 (BitsN.bits(15,0) Rm)))
4568     | BitsN.B(0x2,_) =>
4569       (IntInf.+
4570          (UInt 16 (BitsN.bits(15,0) Rn),UInt 16 (BitsN.bits(31,16) Rm)),
4571        IntInf.-
4572          (UInt 16 (BitsN.bits(31,16) Rn),UInt 16 (BitsN.bits(15,0) Rm)))
4573     | BitsN.B(0x3,_) =>
4574       (IntInf.-
4575          (UInt 16 (BitsN.bits(15,0) Rn),UInt 16 (BitsN.bits(15,0) Rm)),
4576        IntInf.-
4577          (UInt 16 (BitsN.bits(31,16) Rn),UInt 16 (BitsN.bits(31,16) Rm)))
4578     | _ => raise General.Bind
4579  end;
4580
4581fun dfn'UnsignedAddSub16 (op',(d,(n,m))) =
4582  let
4583    val (res1,res2) = UnsignedParallelAddSub16(op',(n,m))
4584  in
4585    ( write'R(BitsN.@@(BitsN.fromInt(res2,16),BitsN.fromInt(res1,16)),d)
4586    ; let
4587        val w = #GE((!CPSR) : PSR)
4588      in
4589        CPSR :=
4590        (PSR_GE_rupd
4591           ((!CPSR),
4592            BitsN.bitFieldInsert(1,0)
4593              (w,
4594               if IntInf.>=
4595                    (res1,
4596                     if Set.mem(op',[BitsN.B(0x1,2),BitsN.B(0x3,2)])
4597                       then 0
4598                     else 65536)
4599                 then BitsN.B(0x3,2)
4600               else BitsN.B(0x0,2))))
4601      end
4602    ; let
4603        val w = #GE((!CPSR) : PSR)
4604      in
4605        CPSR :=
4606        (PSR_GE_rupd
4607           ((!CPSR),
4608            BitsN.bitFieldInsert(3,2)
4609              (w,
4610               if IntInf.>=
4611                    (res2,
4612                     if Set.mem(op',[BitsN.B(0x2,2),BitsN.B(0x3,2)])
4613                       then 0
4614                     else 65536)
4615                 then BitsN.B(0x3,2)
4616               else BitsN.B(0x0,2))))
4617      end
4618    ; IncPC ()
4619    )
4620  end;
4621
4622fun dfn'UnsignedSaturatingAddSub16 (op',(d,(n,m))) =
4623  let
4624    val (res1,res2) = UnsignedParallelAddSub16(op',(n,m))
4625  in
4626    ( write'R
4627        (BitsN.@@(UnsignedSat 16 (res2,16),UnsignedSat 16 (res1,16)),d)
4628    ; IncPC ()
4629    )
4630  end;
4631
4632fun dfn'UnsignedHalvingAddSub16 (op',(d,(n,m))) =
4633  let
4634    val (res1,res2) = UnsignedParallelAddSub16(op',(n,m))
4635  in
4636    ( write'R
4637        (BitsN.@@
4638           (BitsN.fromInt(IntInf.div(res2,2),16),
4639            BitsN.fromInt(IntInf.div(res1,2),16)),d)
4640    ; IncPC ()
4641    )
4642  end;
4643
4644fun UnsignedParallelAddSub8 (sub,(n,m)) =
4645  let
4646    val Rn = R n
4647    val Rm = R m
4648  in
4649    if sub
4650      then (IntInf.-
4651              (UInt 8 (BitsN.bits(7,0) Rn),UInt 8 (BitsN.bits(7,0) Rm)),
4652            (IntInf.-
4653               (UInt 8 (BitsN.bits(15,8) Rn),UInt 8 (BitsN.bits(15,8) Rm)),
4654             (IntInf.-
4655                (UInt 8 (BitsN.bits(23,16) Rn),
4656                 UInt 8 (BitsN.bits(23,16) Rm)),
4657              IntInf.-
4658                (UInt 8 (BitsN.bits(31,24) Rn),
4659                 UInt 8 (BitsN.bits(31,24) Rm)))))
4660    else (IntInf.+
4661            (UInt 8 (BitsN.bits(7,0) Rn),UInt 8 (BitsN.bits(7,0) Rm)),
4662          (IntInf.+
4663             (UInt 8 (BitsN.bits(15,8) Rn),UInt 8 (BitsN.bits(15,8) Rm)),
4664           (IntInf.+
4665              (UInt 8 (BitsN.bits(23,16) Rn),UInt 8 (BitsN.bits(23,16) Rm)),
4666            IntInf.+
4667              (UInt 8 (BitsN.bits(31,24) Rn),UInt 8 (BitsN.bits(31,24) Rm)))))
4668  end;
4669
4670fun dfn'UnsignedAddSub8 (sub,(d,(n,m))) =
4671  let
4672    val (res1,(res2,(res3,res4))) = UnsignedParallelAddSub8(sub,(n,m))
4673  in
4674    ( write'R
4675        (BitsN.concat
4676           [BitsN.fromInt(res4,8),BitsN.fromInt(res3,8),
4677            BitsN.fromInt(res2,8),BitsN.fromInt(res1,8)],d)
4678    ; let
4679        val ge_lim = if sub then 0 else 256
4680      in
4681        ( let
4682            val w = #GE((!CPSR) : PSR)
4683          in
4684            CPSR :=
4685            (PSR_GE_rupd
4686               ((!CPSR),
4687                BitsN.bitFieldInsert(0,0)
4688                  (w,BitsN.fromBit(IntInf.>=(res1,ge_lim)))))
4689          end
4690        ; let
4691            val w = #GE((!CPSR) : PSR)
4692          in
4693            CPSR :=
4694            (PSR_GE_rupd
4695               ((!CPSR),
4696                BitsN.bitFieldInsert(1,1)
4697                  (w,BitsN.fromBit(IntInf.>=(res2,ge_lim)))))
4698          end
4699        ; let
4700            val w = #GE((!CPSR) : PSR)
4701          in
4702            CPSR :=
4703            (PSR_GE_rupd
4704               ((!CPSR),
4705                BitsN.bitFieldInsert(2,2)
4706                  (w,BitsN.fromBit(IntInf.>=(res3,ge_lim)))))
4707          end
4708        ; let
4709            val w = #GE((!CPSR) : PSR)
4710          in
4711            CPSR :=
4712            (PSR_GE_rupd
4713               ((!CPSR),
4714                BitsN.bitFieldInsert(3,3)
4715                  (w,BitsN.fromBit(IntInf.>=(res4,ge_lim)))))
4716          end
4717        ; IncPC ()
4718        )
4719      end
4720    )
4721  end;
4722
4723fun dfn'UnsignedSaturatingAddSub8 (sub,(d,(n,m))) =
4724  let
4725    val (res1,(res2,(res3,res4))) = UnsignedParallelAddSub8(sub,(n,m))
4726  in
4727    ( write'R
4728        (BitsN.concat
4729           [UnsignedSat 8 (res4,8),UnsignedSat 8 (res3,8),
4730            UnsignedSat 8 (res2,8),UnsignedSat 8 (res1,8)],d)
4731    ; IncPC ()
4732    )
4733  end;
4734
4735fun dfn'UnsignedHalvingAddSub8 (sub,(d,(n,m))) =
4736  let
4737    val (res1,(res2,(res3,res4))) = UnsignedParallelAddSub8(sub,(n,m))
4738  in
4739    ( write'R
4740        (BitsN.concat
4741           [BitsN.fromInt(IntInf.div(res4,2),8),
4742            BitsN.fromInt(IntInf.div(res3,2),8),
4743            BitsN.fromInt(IntInf.div(res2,2),8),
4744            BitsN.fromInt(IntInf.div(res1,2),8)],d)
4745    ; IncPC ()
4746    )
4747  end;
4748
4749fun dfn'UnsignedSumAbsoluteDifferences (d,(n,(m,a))) =
4750  let
4751    val acc = if a = (BitsN.B(0xF,4)) then BitsN.B(0x0,32) else R a
4752    val Rn = R n
4753    val Rm = R m
4754    val absdiff1 =
4755      IntInf.abs
4756        (IntInf.-(UInt 8 (BitsN.bits(7,0) Rn),UInt 8 (BitsN.bits(7,0) Rm)))
4757    val absdiff2 =
4758      IntInf.abs
4759        (IntInf.-
4760           (UInt 8 (BitsN.bits(15,8) Rn),UInt 8 (BitsN.bits(15,8) Rm)))
4761    val absdiff3 =
4762      IntInf.abs
4763        (IntInf.-
4764           (UInt 8 (BitsN.bits(23,16) Rn),UInt 8 (BitsN.bits(23,16) Rm)))
4765    val absdiff4 =
4766      IntInf.abs
4767        (IntInf.-
4768           (UInt 8 (BitsN.bits(31,24) Rn),UInt 8 (BitsN.bits(31,24) Rm)))
4769    val result =
4770      IntInf.+
4771        (IntInf.+
4772           (IntInf.+(IntInf.+(UInt 32 acc,absdiff1),absdiff2),absdiff3),
4773         absdiff4)
4774  in
4775    ( write'R(BitsN.fromInt(result,32),d); IncPC () )
4776  end;
4777
4778fun GenerateIntegerZeroDivide () = TakeUndefInstrException ();
4779
4780fun dfn'Divide (unsigned,(d,(n,m))) =
4781  if (R m) = (BitsN.B(0x0,32))
4782    then if IntegerZeroDivideTrappingEnabled ()
4783           then GenerateIntegerZeroDivide ()
4784         else ( write'R(BitsN.B(0x0,32),d); IncPC () )
4785  else ( write'R
4786           (if unsigned then BitsN.div(R n,R m) else BitsN.quot(R n,R m),d)
4787       ; IncPC ()
4788       );
4789
4790fun dfn'PackHalfword (shift_t,(shift_n,(tbform,(d,(n,m))))) =
4791  let
4792    val operand2 = Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
4793    val bot =
4794      if tbform then BitsN.bits(15,0) operand2 else BitsN.bits(15,0) (R n)
4795    val top =
4796      if tbform
4797        then BitsN.bits(31,16) (R n)
4798      else BitsN.bits(31,16) operand2
4799  in
4800    ( write'R(BitsN.@@(top,bot),d); IncPC () )
4801  end;
4802
4803fun dfn'Saturate (shift_t,(shift_n,(saturate_to,(unsigned,(d,n))))) =
4804  let
4805    val operand = Shift 32 (R n,(shift_t,(shift_n,#C((!CPSR) : PSR))))
4806    val (result,sat) =
4807      if unsigned
4808        then UnsignedSatQ 32 (BitsN.toInt operand,saturate_to)
4809      else SignedSatQ 32 (BitsN.toInt operand,saturate_to)
4810  in
4811    ( write'R
4812        (if unsigned
4813           then result
4814         else SignExtendFrom 32 (result,saturate_to),d)
4815    ; if sat then CPSR := (PSR_Q_rupd((!CPSR),true)) else ()
4816    ; IncPC ()
4817    )
4818  end;
4819
4820fun dfn'Saturate16 (saturate_to,(unsigned,(d,n))) =
4821  let
4822    val Rn = R n
4823    val ((result1,sat1),(result2,sat2)) =
4824      if unsigned
4825        then (UnsignedSatQ 16
4826                (BitsN.toInt(BitsN.bits(15,0) Rn),saturate_to),
4827              UnsignedSatQ 16
4828                (BitsN.toInt(BitsN.bits(31,16) Rn),saturate_to))
4829      else (SignedSatQ 16 (BitsN.toInt(BitsN.bits(15,0) Rn),saturate_to),
4830            SignedSatQ 16 (BitsN.toInt(BitsN.bits(31,16) Rn),saturate_to))
4831  in
4832    ( write'R
4833        (if unsigned
4834           then BitsN.@@(result2,result1)
4835         else BitsN.@@
4836                (SignExtendFrom 16 (result2,saturate_to),
4837                 SignExtendFrom 16 (result1,saturate_to)),d)
4838    ; if sat1 orelse sat2 then CPSR := (PSR_Q_rupd((!CPSR),true)) else ()
4839    ; IncPC ()
4840    )
4841  end;
4842
4843fun dfn'ExtendByte (unsigned,(d,(n,(m,rotation)))) =
4844  let
4845    val acc = if n = (BitsN.B(0xF,4)) then BitsN.B(0x0,32) else R n
4846    val rotated = ROR 32 (R m,rotation)
4847  in
4848    ( write'R
4849        (BitsN.+(acc,Extend (8,32) (unsigned,BitsN.bits(7,0) rotated)),d)
4850    ; IncPC ()
4851    )
4852  end;
4853
4854fun dfn'ExtendByte16 (unsigned,(d,(n,(m,rotation)))) =
4855  let
4856    val acc = if n = (BitsN.B(0xF,4)) then BitsN.B(0x0,32) else R n
4857    val rotated = ROR 32 (R m,rotation)
4858    val r1 =
4859      BitsN.+
4860        (BitsN.bits(15,0) acc,
4861         Extend (8,16) (unsigned,BitsN.bits(7,0) rotated))
4862    val r2 =
4863      BitsN.+
4864        (BitsN.bits(31,16) acc,
4865         Extend (8,16) (unsigned,BitsN.bits(23,16) rotated))
4866  in
4867    ( write'R(BitsN.@@(r2,r1),d); IncPC () )
4868  end;
4869
4870fun dfn'ExtendHalfword (unsigned,(d,(n,(m,rotation)))) =
4871  let
4872    val acc = if n = (BitsN.B(0xF,4)) then BitsN.B(0x0,32) else R n
4873    val rotated = ROR 32 (R m,rotation)
4874  in
4875    ( write'R
4876        (BitsN.+(acc,Extend (16,32) (unsigned,BitsN.bits(15,0) rotated)),d)
4877    ; IncPC ()
4878    )
4879  end;
4880
4881fun dfn'SelectBytes (d,(n,m)) =
4882  let
4883    val Rn = R n
4884    val Rm = R m
4885    val r1 =
4886      if BitsN.bit(#GE((!CPSR) : PSR),0)
4887        then BitsN.bits(7,0) Rn
4888      else BitsN.bits(7,0) Rm
4889    val r2 =
4890      if BitsN.bit(#GE((!CPSR) : PSR),1)
4891        then BitsN.bits(15,8) Rn
4892      else BitsN.bits(15,8) Rm
4893    val r3 =
4894      if BitsN.bit(#GE((!CPSR) : PSR),2)
4895        then BitsN.bits(23,16) Rn
4896      else BitsN.bits(23,16) Rm
4897    val r4 =
4898      if BitsN.bit(#GE((!CPSR) : PSR),3)
4899        then BitsN.bits(31,24) Rn
4900      else BitsN.bits(31,24) Rm
4901  in
4902    ( write'R(BitsN.concat[r4,r3,r2,r1],d); IncPC () )
4903  end;
4904
4905fun dfn'ByteReverse (d,m) =
4906  let
4907    val Rm = R m
4908  in
4909    ( write'R
4910        (BitsN.concat
4911           [BitsN.bits(7,0) Rm,BitsN.bits(15,8) Rm,BitsN.bits(23,16) Rm,
4912            BitsN.bits(31,24) Rm],d)
4913    ; IncPC ()
4914    )
4915  end;
4916
4917fun dfn'ByteReversePackedHalfword (d,m) =
4918  let
4919    val Rm = R m
4920  in
4921    ( write'R
4922        (BitsN.concat
4923           [BitsN.bits(23,16) Rm,BitsN.bits(31,24) Rm,BitsN.bits(7,0) Rm,
4924            BitsN.bits(15,8) Rm],d)
4925    ; IncPC ()
4926    )
4927  end;
4928
4929fun dfn'ByteReverseSignedHalfword (d,m) =
4930  let
4931    val Rm = R m
4932  in
4933    ( write'R
4934        (BitsN.@@
4935           (BitsN.signExtend 24 (BitsN.bits(7,0) Rm),BitsN.bits(15,8) Rm),
4936         d)
4937    ; IncPC ()
4938    )
4939  end;
4940
4941fun dfn'ReverseBits (d,m) = ( write'R(BitsN.reverse(R m),d); IncPC () );
4942
4943fun dfn'BitFieldExtract (unsigned,(d,(n,(lsbit,widthminus1)))) =
4944  let
4945    val msbit = Nat.+(lsbit,widthminus1)
4946  in
4947    ( write'R
4948        (if unsigned
4949           then BitsN.resize 32 (BitsN.bits(msbit,lsbit) (R n))
4950         else SignExtendFrom 32
4951                (BitsN.resize 32 (BitsN.bits(msbit,lsbit) (R n)),
4952                 widthminus1),d)
4953    ; IncPC ()
4954    )
4955  end;
4956
4957fun dfn'BitFieldClearOrInsert (d,(n,(lsbit,msbit))) =
4958  let
4959    val field =
4960      BitsN.toBitstring
4961        (if n = (BitsN.B(0xF,4)) then BitsN.B(0x0,32) else R n)
4962  in
4963    let
4964      val result = ref (BitsN.toBitstring(R d))
4965    in
4966      ( result :=
4967        (Bitstring.bitFieldInsert(msbit,lsbit)
4968           ((!result),Bitstring.bits(Nat.-(msbit,lsbit),0) field))
4969      ; write'R(BitsN.fromBitstring((!result),32),d)
4970      ; IncPC ()
4971      )
4972    end
4973  end;
4974
4975fun dfn'LoadWord (add,(index,(wback,(t,(n,m))))) =
4976  if NullCheckIfThumbEE n
4977    then let
4978           val Rn = R n
4979           val offset =
4980             case m of
4981                register_form1(m,(shift_t,shift_n)) =>
4982                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
4983              | immediate_form1 imm32 => imm32
4984           val offset_addr =
4985             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
4986           val address = if index then offset_addr else Rn
4987           val data = MemU 32 (address,4)
4988         in
4989           ( if wback then write'R(offset_addr,n) else ()
4990           ; if t = (BitsN.B(0xF,4))
4991               then if Aligned 32 (address,4)
4992                      then LoadWritePC data
4993                    else raise UNPREDICTABLE "Load"
4994             else ( write'R
4995                      (if (UnalignedSupport ()) orelse
4996                          (Aligned 32 (address,4))
4997                         then data
4998                       else if (!Encoding) = Encoding_ARM
4999                         then ROR 32
5000                                (data,
5001                                 Nat.*
5002                                   (8,BitsN.toNat(BitsN.bits(1,0) address)))
5003                       else BitsN.B(0x0,32),t)
5004                  ; IncPC ()
5005                  )
5006           )
5007         end
5008  else ();
5009
5010fun dfn'LoadLiteral (add,(t,imm32)) =
5011  if NullCheckIfThumbEE(BitsN.B(0xF,4))
5012    then let
5013           val base = Align 32 (PC (),4)
5014           val address =
5015             if add then BitsN.+(base,imm32) else BitsN.-(base,imm32)
5016           val data = MemU 32 (address,4)
5017         in
5018           if t = (BitsN.B(0xF,4))
5019             then if Aligned 32 (address,4)
5020                    then LoadWritePC data
5021                  else raise UNPREDICTABLE "LoadLiteral"
5022           else ( write'R
5023                    (if (UnalignedSupport ()) orelse
5024                        (Aligned 32 (address,4))
5025                       then data
5026                     else if (!Encoding) = Encoding_ARM
5027                       then ROR 32
5028                              (data,
5029                               Nat.*
5030                                 (8,BitsN.toNat(BitsN.bits(1,0) address)))
5031                     else BitsN.B(0x0,32),t)
5032                ; IncPC ()
5033                )
5034         end
5035  else ();
5036
5037fun dfn'LoadUnprivileged (add,(postindex,(t,(n,m)))) =
5038  if NullCheckIfThumbEE n
5039    then let
5040           val Rn = R n
5041           val offset =
5042             case m of
5043                register_form1(m,(shift_t,shift_n)) =>
5044                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
5045              | immediate_form1 imm32 => imm32
5046           val offset_addr =
5047             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5048           val address = if postindex then Rn else offset_addr
5049           val data = MemU_unpriv 32 (address,4)
5050         in
5051           ( if postindex then write'R(offset_addr,n) else ()
5052           ; write'R
5053               (if (UnalignedSupport ()) orelse (Aligned 32 (address,4))
5054                  then data
5055                else if (!Encoding) = Encoding_ARM
5056                  then ROR 32
5057                         (data,
5058                          Nat.*(8,BitsN.toNat(BitsN.bits(1,0) address)))
5059                else BitsN.B(0x0,32),t)
5060           ; IncPC ()
5061           )
5062         end
5063  else ();
5064
5065fun dfn'LoadByte (unsigned,(add,(index,(wback,(t,(n,m)))))) =
5066  if NullCheckIfThumbEE n
5067    then let
5068           val Rn = R n
5069           val offset =
5070             case m of
5071                register_form1(m,(shift_t,shift_n)) =>
5072                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
5073              | immediate_form1 imm32 => imm32
5074           val offset_addr =
5075             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5076           val address = if index then offset_addr else Rn
5077         in
5078           ( write'R(Extend (8,32) (unsigned,MemU 8 (address,1)),t)
5079           ; if wback then write'R(offset_addr,n) else ()
5080           ; IncPC ()
5081           )
5082         end
5083  else ();
5084
5085fun dfn'LoadByteLiteral (unsigned,(add,(t,imm32))) =
5086  if NullCheckIfThumbEE(BitsN.B(0xF,4))
5087    then let
5088           val base = Align 32 (PC (),4)
5089           val address =
5090             if add then BitsN.+(base,imm32) else BitsN.-(base,imm32)
5091         in
5092           ( write'R(Extend (8,32) (unsigned,MemU 8 (address,1)),t)
5093           ; IncPC ()
5094           )
5095         end
5096  else ();
5097
5098fun dfn'LoadByteUnprivileged (add,(postindex,(t,(n,m)))) =
5099  if NullCheckIfThumbEE n
5100    then let
5101           val Rn = R n
5102           val offset =
5103             case m of
5104                register_form1(m,(shift_t,shift_n)) =>
5105                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
5106              | immediate_form1 imm32 => imm32
5107           val offset_addr =
5108             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5109           val address = if postindex then Rn else offset_addr
5110         in
5111           ( write'R(BitsN.zeroExtend 32 (MemU_unpriv 8 (address,1)),t)
5112           ; if postindex then write'R(offset_addr,n) else ()
5113           ; IncPC ()
5114           )
5115         end
5116  else ();
5117
5118fun dfn'LoadSignedByteUnprivileged (add,(postindex,(t,(n,m)))) =
5119  if NullCheckIfThumbEE n
5120    then let
5121           val Rn = R n
5122           val offset =
5123             case m of
5124                register_form2 m => R m
5125              | immediate_form2 imm32 => imm32
5126           val offset_addr =
5127             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5128           val address = if postindex then Rn else offset_addr
5129         in
5130           ( write'R(BitsN.signExtend 32 (MemU_unpriv 8 (address,1)),t)
5131           ; if postindex then write'R(offset_addr,n) else ()
5132           ; IncPC ()
5133           )
5134         end
5135  else ();
5136
5137fun dfn'LoadHalf (unsigned,(add,(index,(wback,(t,(n,m)))))) =
5138  if NullCheckIfThumbEE n
5139    then let
5140           val Rn = R n
5141           val offset =
5142             case m of
5143                register_form1(m,(shift_t,shift_n)) =>
5144                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
5145              | immediate_form1 imm32 => imm32
5146           val offset_addr =
5147             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5148           val address = if index then offset_addr else Rn
5149           val data = MemU 16 (address,2)
5150         in
5151           ( if wback then write'R(offset_addr,n) else ()
5152           ; write'R
5153               (if (UnalignedSupport ()) orelse (Aligned 32 (address,2))
5154                  then Extend (16,32) (unsigned,data)
5155                else BitsN.B(0x0,32),t)
5156           ; IncPC ()
5157           )
5158         end
5159  else ();
5160
5161fun dfn'LoadHalfLiteral (unsigned,(add,(t,imm32))) =
5162  if NullCheckIfThumbEE(BitsN.B(0xF,4))
5163    then let
5164           val base = Align 32 (PC (),4)
5165           val address =
5166             if add then BitsN.+(base,imm32) else BitsN.-(base,imm32)
5167           val data = MemU 16 (address,2)
5168         in
5169           ( write'R
5170               (if (UnalignedSupport ()) orelse (Aligned 32 (address,2))
5171                  then Extend (16,32) (unsigned,data)
5172                else BitsN.B(0x0,32),t)
5173           ; IncPC ()
5174           )
5175         end
5176  else ();
5177
5178fun dfn'LoadHalfUnprivileged (unsigned,(add,(postindex,(t,(n,m))))) =
5179  if NullCheckIfThumbEE n
5180    then let
5181           val Rn = R n
5182           val offset =
5183             case m of
5184                register_form2 m => R m
5185              | immediate_form2 imm32 => imm32
5186           val offset_addr =
5187             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5188           val address = if postindex then Rn else offset_addr
5189           val data = MemU_unpriv 16 (address,2)
5190         in
5191           ( if postindex then write'R(offset_addr,n) else ()
5192           ; write'R
5193               (if (UnalignedSupport ()) orelse (Aligned 32 (address,2))
5194                  then Extend (16,32) (unsigned,data)
5195                else BitsN.B(0x0,32),t)
5196           ; IncPC ()
5197           )
5198         end
5199  else ();
5200
5201fun dfn'LoadMultiple (increment,(index,(wback,(n,registers)))) =
5202  if NullCheckIfThumbEE n
5203    then let
5204           val Rn = R n
5205           val length =
5206             BitsN.*
5207               (BitsN.B(0x4,32),BitsN.fromNat(BitCount 16 registers,32))
5208         in
5209           let
5210             val address = ref (if increment
5211                then Rn
5212              else BitsN.-(Rn,length))
5213           in
5214             ( if index = increment
5215                 then address := (BitsN.+((!address),BitsN.B(0x4,32)))
5216               else ()
5217             ; L3.for
5218                 (0,14,
5219                  fn i =>
5220                    if BitsN.bit(registers,i)
5221                      then ( let
5222                               val x = BitsN.fromNat(i,4)
5223                             in
5224                               write'R(MemA 32 ((!address),4),x)
5225                             end
5226                           ; address :=
5227                             (BitsN.+((!address),BitsN.B(0x4,32)))
5228                           )
5229                    else ())
5230             ; if BitsN.bit(registers,15)
5231                 then LoadWritePC(MemA 32 ((!address),4))
5232               else IncPC ()
5233             ; if wback
5234                 then if BitsN.bit(registers,BitsN.toNat n)
5235                        then write'R(BitsN.B(0x0,32),n)
5236                      else write'R
5237                             (if increment
5238                                then BitsN.+(Rn,length)
5239                              else BitsN.-(Rn,length),n)
5240               else ()
5241             )
5242           end
5243         end
5244  else ();
5245
5246fun dfn'LoadMultipleExceptionReturn
5247  (increment,(wordhigher,(wback,(n,registers)))) =
5248  ( if CurrentModeIsHyp () then TakeUndefInstrException () else ()
5249  ; if CurrentModeIsUserOrSystem ()
5250      then raise UNPREDICTABLE "LoadMultipleExceptionReturn"
5251    else ()
5252  ; let
5253      val Rn = R n
5254      val length =
5255        BitsN.+
5256          (BitsN.*
5257             (BitsN.B(0x4,32),BitsN.fromNat(BitCount 15 registers,32)),
5258           BitsN.B(0x4,32))
5259    in
5260      let
5261        val address = ref (if increment then Rn else BitsN.-(Rn,length))
5262      in
5263        ( if wordhigher
5264            then address := (BitsN.+((!address),BitsN.B(0x4,32)))
5265          else ()
5266        ; L3.for
5267            (0,14,
5268             fn i =>
5269               if BitsN.bit(registers,i)
5270                 then ( let
5271                          val x = BitsN.fromNat(i,4)
5272                        in
5273                          write'R(MemA 32 ((!address),4),x)
5274                        end
5275                      ; address := (BitsN.+((!address),BitsN.B(0x4,32)))
5276                      )
5277               else ())
5278        ; let
5279            val new_pc_value = MemA 32 ((!address),4)
5280          in
5281            ( if wback
5282                then if BitsN.bit(registers,BitsN.toNat n)
5283                       then write'R(BitsN.B(0x0,32),n)
5284                     else write'R
5285                            (if increment
5286                               then BitsN.+(Rn,length)
5287                             else BitsN.-(Rn,length),n)
5288              else ()
5289            ; CPSRWriteByInstr(reg'PSR(SPSR ()),(BitsN.B(0xF,4),true))
5290            ; BranchWritePC new_pc_value
5291            )
5292          end
5293        )
5294      end
5295    end
5296  );
5297
5298fun dfn'LoadMultipleUserRegisters (increment,(wordhigher,(n,registers))) =
5299  ( if CurrentModeIsHyp () then TakeUndefInstrException () else ()
5300  ; if CurrentModeIsUserOrSystem ()
5301      then raise UNPREDICTABLE "LoadMultipleUserRegisters"
5302    else ()
5303  ; let
5304      val length =
5305        BitsN.*(BitsN.B(0x4,32),BitsN.fromNat(BitCount 15 registers,32))
5306    in
5307      let
5308        val address = ref (if increment then R n else BitsN.-(R n,length))
5309      in
5310        ( if wordhigher
5311            then address := (BitsN.+((!address),BitsN.B(0x4,32)))
5312          else ()
5313        ; L3.for
5314            (0,14,
5315             fn i =>
5316               if BitsN.bit(registers,i)
5317                 then ( let
5318                          val x = (BitsN.fromNat(i,4),BitsN.B(0x10,5))
5319                        in
5320                          write'Rmode(MemA 32 ((!address),4),x)
5321                        end
5322                      ; address := (BitsN.+((!address),BitsN.B(0x4,32)))
5323                      )
5324               else ())
5325        ; IncPC ()
5326        )
5327      end
5328    end
5329  );
5330
5331fun dfn'LoadDual (add,(index,(wback,(t,(t2,(n,m)))))) =
5332  if NullCheckIfThumbEE n
5333    then let
5334           val Rn = R n
5335           val offset =
5336             case m of
5337                register_form2 m => R m
5338              | immediate_form2 imm32 => imm32
5339           val offset_addr =
5340             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5341           val address = if index then offset_addr else Rn
5342         in
5343           ( write'R(MemA 32 (address,4),t)
5344           ; write'R(MemA 32 (BitsN.+(address,BitsN.B(0x4,32)),4),t2)
5345           ; if wback then write'R(offset_addr,n) else ()
5346           ; IncPC ()
5347           )
5348         end
5349  else ();
5350
5351fun dfn'LoadDualLiteral (add,(t,(t2,imm32))) =
5352  if NullCheckIfThumbEE(BitsN.B(0xF,4))
5353    then let
5354           val address =
5355             if add
5356               then BitsN.+(Align 32 (PC (),4),imm32)
5357             else BitsN.-(Align 32 (PC (),4),imm32)
5358         in
5359           ( write'R(MemA 32 (address,4),t)
5360           ; write'R(MemA 32 (BitsN.+(address,BitsN.B(0x4,32)),4),t2)
5361           ; IncPC ()
5362           )
5363         end
5364  else ();
5365
5366fun dfn'LoadExclusive (t,(n,imm32)) =
5367  if NullCheckIfThumbEE n
5368    then let
5369           val address = BitsN.+(R n,imm32)
5370         in
5371           ( SetExclusiveMonitors(address,4)
5372           ; write'R(MemA 32 (address,4),t)
5373           ; IncPC ()
5374           )
5375         end
5376  else ();
5377
5378fun dfn'LoadExclusiveByte (t,n) =
5379  if NullCheckIfThumbEE n
5380    then let
5381           val address = R n
5382         in
5383           ( SetExclusiveMonitors(address,1)
5384           ; write'R(BitsN.zeroExtend 32 (MemA 8 (address,1)),t)
5385           ; IncPC ()
5386           )
5387         end
5388  else ();
5389
5390fun dfn'LoadExclusiveHalf (t,n) =
5391  if NullCheckIfThumbEE n
5392    then let
5393           val address = R n
5394         in
5395           ( SetExclusiveMonitors(address,2)
5396           ; write'R(BitsN.zeroExtend 32 (MemA 16 (address,2)),t)
5397           ; IncPC ()
5398           )
5399         end
5400  else ();
5401
5402fun dfn'LoadExclusiveDoubleword (t,(t2,n)) =
5403  if NullCheckIfThumbEE n
5404    then let
5405           val address = R n
5406         in
5407           ( SetExclusiveMonitors(address,8)
5408           ; let
5409               val value = MemA 64 (address,8)
5410             in
5411               ( write'R
5412                   (if BigEndian ()
5413                      then BitsN.bits(63,32) value
5414                    else BitsN.bits(31,0) value,t)
5415               ; write'R
5416                   (if BigEndian ()
5417                      then BitsN.bits(31,0) value
5418                    else BitsN.bits(63,32) value,t2)
5419               ; IncPC ()
5420               )
5421             end
5422           )
5423         end
5424  else ();
5425
5426fun dfn'StoreWord (add,(index,(wback,(t,(n,m))))) =
5427  if NullCheckIfThumbEE n
5428    then let
5429           val Rn = R n
5430           val offset =
5431             case m of
5432                register_form1(m,(shift_t,shift_n)) =>
5433                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
5434              | immediate_form1 imm32 => imm32
5435           val offset_addr =
5436             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5437           val address = if index then offset_addr else Rn
5438           val data =
5439             if t = (BitsN.B(0xF,4)) then PCStoreValue () else R t
5440         in
5441           ( if (UnalignedSupport ()) orelse
5442                ((Aligned 32 (address,4)) orelse
5443                 ((CurrentInstrSet ()) = InstrSet_ARM))
5444               then let val x = (address,4) in write'MemU 32 (data,x) end
5445             else let
5446                    val x = (address,4)
5447                  in
5448                    write'MemU 32 (BitsN.B(0x0,32),x)
5449                  end
5450           ; if wback then write'R(offset_addr,n) else ()
5451           ; IncPC ()
5452           )
5453         end
5454  else ();
5455
5456fun dfn'StoreUnprivileged (add,(postindex,(t,(n,m)))) =
5457  if NullCheckIfThumbEE n
5458    then let
5459           val Rn = R n
5460           val offset =
5461             case m of
5462                register_form1(m,(shift_t,shift_n)) =>
5463                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
5464              | immediate_form1 imm32 => imm32
5465           val offset_addr =
5466             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5467           val address = if postindex then Rn else offset_addr
5468           val data =
5469             if t = (BitsN.B(0xF,4)) then PCStoreValue () else R t
5470         in
5471           ( if (UnalignedSupport ()) orelse
5472                ((Aligned 32 (address,4)) orelse
5473                 ((CurrentInstrSet ()) = InstrSet_ARM))
5474               then let
5475                      val x = (address,4)
5476                    in
5477                      write'MemU_unpriv 32 (data,x)
5478                    end
5479             else let
5480                    val x = (address,4)
5481                  in
5482                    write'MemU_unpriv 32 (BitsN.B(0x0,32),x)
5483                  end
5484           ; if postindex then write'R(offset_addr,n) else ()
5485           ; IncPC ()
5486           )
5487         end
5488  else ();
5489
5490fun dfn'StoreByte (add,(index,(wback,(t,(n,m))))) =
5491  if NullCheckIfThumbEE n
5492    then let
5493           val Rn = R n
5494           val offset =
5495             case m of
5496                register_form1(m,(shift_t,shift_n)) =>
5497                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
5498              | immediate_form1 imm32 => imm32
5499           val offset_addr =
5500             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5501           val address = if index then offset_addr else Rn
5502         in
5503           ( let
5504               val x = (address,1)
5505             in
5506               write'MemU 8 (BitsN.bits(7,0) (R t),x)
5507             end
5508           ; if wback then write'R(offset_addr,n) else ()
5509           ; IncPC ()
5510           )
5511         end
5512  else ();
5513
5514fun dfn'StoreByteUnprivileged (add,(postindex,(t,(n,m)))) =
5515  if NullCheckIfThumbEE n
5516    then let
5517           val Rn = R n
5518           val offset =
5519             case m of
5520                register_form1(m,(shift_t,shift_n)) =>
5521                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
5522              | immediate_form1 imm32 => imm32
5523           val offset_addr =
5524             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5525           val address = if postindex then Rn else offset_addr
5526         in
5527           ( let
5528               val x = (address,1)
5529             in
5530               write'MemU_unpriv 8 (BitsN.bits(7,0) (R t),x)
5531             end
5532           ; if postindex then write'R(offset_addr,n) else ()
5533           ; IncPC ()
5534           )
5535         end
5536  else ();
5537
5538fun dfn'StoreHalf (add,(index,(wback,(t,(n,m))))) =
5539  if NullCheckIfThumbEE n
5540    then let
5541           val Rn = R n
5542           val offset =
5543             case m of
5544                register_form1(m,(shift_t,shift_n)) =>
5545                  Shift 32 (R m,(shift_t,(shift_n,#C((!CPSR) : PSR))))
5546              | immediate_form1 imm32 => imm32
5547           val offset_addr =
5548             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5549           val address = if index then offset_addr else Rn
5550         in
5551           ( if (UnalignedSupport ()) orelse (Aligned 32 (address,2))
5552               then let
5553                      val x = (address,2)
5554                    in
5555                      write'MemU 16 (BitsN.bits(15,0) (R t),x)
5556                    end
5557             else let
5558                    val x = (address,2)
5559                  in
5560                    write'MemU 16 (BitsN.B(0x0,16),x)
5561                  end
5562           ; if wback then write'R(offset_addr,n) else ()
5563           ; IncPC ()
5564           )
5565         end
5566  else ();
5567
5568fun dfn'StoreHalfUnprivileged (add,(postindex,(t,(n,m)))) =
5569  if NullCheckIfThumbEE n
5570    then let
5571           val Rn = R n
5572           val offset =
5573             case m of
5574                register_form2 m => R m
5575              | immediate_form2 imm32 => imm32
5576           val offset_addr =
5577             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5578           val address = if postindex then Rn else offset_addr
5579         in
5580           ( if (UnalignedSupport ()) orelse (Aligned 32 (address,2))
5581               then let
5582                      val x = (address,2)
5583                    in
5584                      write'MemU_unpriv 16 (BitsN.bits(15,0) (R t),x)
5585                    end
5586             else let
5587                    val x = (address,2)
5588                  in
5589                    write'MemU_unpriv 16 (BitsN.B(0x0,16),x)
5590                  end
5591           ; if postindex then write'R(offset_addr,n) else ()
5592           ; IncPC ()
5593           )
5594         end
5595  else ();
5596
5597fun dfn'StoreMultiple (increment,(index,(wback,(n,registers)))) =
5598  if NullCheckIfThumbEE n
5599    then let
5600           val Rn = R n
5601           val length =
5602             BitsN.*
5603               (BitsN.B(0x4,32),BitsN.fromNat(BitCount 16 registers,32))
5604           val lowest = LowestSetBit 16 registers
5605         in
5606           let
5607             val address = ref (if increment
5608                then Rn
5609              else BitsN.-(Rn,length))
5610           in
5611             ( if index = increment
5612                 then address := (BitsN.+((!address),BitsN.B(0x4,32)))
5613               else ()
5614             ; L3.for
5615                 (0,14,
5616                  fn i =>
5617                    if BitsN.bit(registers,i)
5618                      then ( if ((BitsN.fromNat(i,4)) = n) andalso
5619                                (wback andalso (not(i = lowest)))
5620                               then let
5621                                      val x = ((!address),4)
5622                                    in
5623                                      write'MemA 32 (BitsN.B(0x0,32),x)
5624                                    end
5625                             else let
5626                                    val x = ((!address),4)
5627                                  in
5628                                    write'MemA 32
5629                                      (R(BitsN.fromNat(i,4)),x)
5630                                  end
5631                           ; address :=
5632                             (BitsN.+((!address),BitsN.B(0x4,32)))
5633                           )
5634                    else ())
5635             ; if BitsN.bit(registers,15)
5636                 then let
5637                        val x = ((!address),4)
5638                      in
5639                        write'MemA 32 (PCStoreValue (),x)
5640                      end
5641               else ()
5642             ; if wback
5643                 then write'R
5644                        (if increment
5645                           then BitsN.+(Rn,length)
5646                         else BitsN.-(Rn,length),n)
5647               else ()
5648             ; IncPC ()
5649             )
5650           end
5651         end
5652  else ();
5653
5654fun dfn'StoreMultipleUserRegisters
5655  (increment,(wordhigher,(n,registers))) =
5656  ( if CurrentModeIsHyp () then TakeUndefInstrException () else ()
5657  ; if CurrentModeIsUserOrSystem ()
5658      then raise UNPREDICTABLE "StoreMultipleUserRegisters"
5659    else ()
5660  ; let
5661      val length =
5662        BitsN.*(BitsN.B(0x4,32),BitsN.fromNat(BitCount 16 registers,32))
5663    in
5664      let
5665        val address = ref (if increment then R n else BitsN.-(R n,length))
5666      in
5667        ( if wordhigher
5668            then address := (BitsN.+((!address),BitsN.B(0x4,32)))
5669          else ()
5670        ; L3.for
5671            (0,14,
5672             fn i =>
5673               if BitsN.bit(registers,i)
5674                 then ( let
5675                          val x = ((!address),4)
5676                        in
5677                          write'MemA 32
5678                            (Rmode(BitsN.fromNat(i,4),BitsN.B(0x10,5)),x)
5679                        end
5680                      ; address := (BitsN.+((!address),BitsN.B(0x4,32)))
5681                      )
5682               else ())
5683        ; if BitsN.bit(registers,15)
5684            then let
5685                   val x = ((!address),4)
5686                 in
5687                   write'MemA 32 (PCStoreValue (),x)
5688                 end
5689          else ()
5690        ; IncPC ()
5691        )
5692      end
5693    end
5694  );
5695
5696fun dfn'StoreDual (add,(index,(wback,(t,(t2,(n,m)))))) =
5697  if NullCheckIfThumbEE n
5698    then let
5699           val Rn = R n
5700           val offset =
5701             case m of
5702                register_form2 m => R m
5703              | immediate_form2 imm32 => imm32
5704           val offset_addr =
5705             if add then BitsN.+(Rn,offset) else BitsN.-(Rn,offset)
5706           val address = if index then offset_addr else Rn
5707         in
5708           ( let val x = (address,4) in write'MemA 32 (R t,x) end
5709           ; let
5710               val x = (BitsN.+(address,BitsN.B(0x4,32)),4)
5711             in
5712               write'MemA 32 (R t2,x)
5713             end
5714           ; if wback then write'R(offset_addr,n) else ()
5715           ; IncPC ()
5716           )
5717         end
5718  else ();
5719
5720fun dfn'StoreExclusive (d,(t,(n,imm32))) =
5721  if NullCheckIfThumbEE n
5722    then let
5723           val address = BitsN.+(R n,imm32)
5724         in
5725           ( if ExclusiveMonitorsPass(address,4)
5726               then ( let val x = (address,4) in write'MemA 32 (R t,x) end
5727                    ; write'R(BitsN.B(0x0,32),d)
5728                    )
5729             else write'R(BitsN.B(0x1,32),d)
5730           ; IncPC ()
5731           )
5732         end
5733  else ();
5734
5735fun dfn'StoreExclusiveByte (d,(t,n)) =
5736  if NullCheckIfThumbEE n
5737    then let
5738           val address = R n
5739         in
5740           ( if ExclusiveMonitorsPass(address,1)
5741               then ( let
5742                        val x = (address,1)
5743                      in
5744                        write'MemA 8 (BitsN.bits(7,0) (R t),x)
5745                      end
5746                    ; write'R(BitsN.B(0x0,32),d)
5747                    )
5748             else write'R(BitsN.B(0x1,32),d)
5749           ; IncPC ()
5750           )
5751         end
5752  else ();
5753
5754fun dfn'StoreExclusiveHalf (d,(t,n)) =
5755  if NullCheckIfThumbEE n
5756    then let
5757           val address = R n
5758         in
5759           ( if ExclusiveMonitorsPass(address,2)
5760               then ( let
5761                        val x = (address,2)
5762                      in
5763                        write'MemA 16 (BitsN.bits(15,0) (R t),x)
5764                      end
5765                    ; write'R(BitsN.B(0x0,32),d)
5766                    )
5767             else write'R(BitsN.B(0x1,32),d)
5768           ; IncPC ()
5769           )
5770         end
5771  else ();
5772
5773fun dfn'StoreExclusiveDoubleword (d,(t,(t2,n))) =
5774  if NullCheckIfThumbEE n
5775    then let
5776           val address = R n
5777           val value =
5778             if BigEndian ()
5779               then BitsN.@@(R t,R t2)
5780             else BitsN.@@(R t2,R t)
5781         in
5782           ( if ExclusiveMonitorsPass(address,8)
5783               then ( let
5784                        val x = (address,8)
5785                      in
5786                        write'MemA 64 (value,x)
5787                      end
5788                    ; write'R(BitsN.B(0x0,32),d)
5789                    )
5790             else write'R(BitsN.B(0x1,32),d)
5791           ; IncPC ()
5792           )
5793         end
5794  else ();
5795
5796fun dfn'ClearExclusive () =
5797  ( ClearExclusiveLocal(ProcessorID ()); IncPC () );
5798
5799fun dfn'Swap (b,(t,(t2,n))) =
5800  let
5801    val Rn = R n
5802  in
5803    ( if b
5804        then let
5805               val data = MemA 8 (Rn,1)
5806             in
5807               ( let
5808                   val x = (Rn,1)
5809                 in
5810                   write'MemA 8 (BitsN.bits(7,0) (R t2),x)
5811                 end
5812               ; write'R(BitsN.zeroExtend 32 data,t)
5813               )
5814             end
5815      else let
5816             val data = MemA 32 (Rn,4)
5817           in
5818             ( let val x = (Rn,4) in write'MemA 32 (R t2,x) end
5819             ; write'R
5820                 (ROR 32 (data,Nat.*(8,BitsN.toNat(BitsN.bits(1,0) Rn))),t)
5821             )
5822           end
5823    ; IncPC ()
5824    )
5825  end;
5826
5827fun dfn'ChangeProcessorState
5828  (enable,(disable,(affectA,(affectI,(affectF,changemode))))) =
5829  ( if CurrentModeIsNotUser ()
5830      then let
5831             val cpsr_val = ref (!CPSR)
5832           in
5833             ( if enable
5834                 then ( if affectA
5835                          then cpsr_val := (PSR_A_rupd((!cpsr_val),false))
5836                        else ()
5837                      ; if affectI
5838                          then cpsr_val := (PSR_I_rupd((!cpsr_val),false))
5839                        else ()
5840                      ; if affectF
5841                          then cpsr_val := (PSR_F_rupd((!cpsr_val),false))
5842                        else ()
5843                      )
5844               else ()
5845             ; if disable
5846                 then ( if affectA
5847                          then cpsr_val := (PSR_A_rupd((!cpsr_val),true))
5848                        else ()
5849                      ; if affectI
5850                          then cpsr_val := (PSR_I_rupd((!cpsr_val),true))
5851                        else ()
5852                      ; if affectF
5853                          then cpsr_val := (PSR_F_rupd((!cpsr_val),true))
5854                        else ()
5855                      )
5856               else ()
5857             ; case changemode of
5858                  Option.SOME mode =>
5859                    cpsr_val := (PSR_M_rupd((!cpsr_val),mode))
5860                | NONE => ()
5861             ; CPSRWriteByInstr
5862                 (reg'PSR (!cpsr_val),(BitsN.B(0xF,4),false))
5863             ; if ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5))) andalso
5864                  ((CurrentInstrSet ()) = InstrSet_ThumbEE)
5865                 then raise UNPREDICTABLE "ChangeProcessorState"
5866               else ()
5867             )
5868           end
5869    else ()
5870  ; IncPC ()
5871  );
5872
5873fun dfn'ExceptionReturn () =
5874  if (CurrentModeIsUserOrSystem ()) orelse
5875     ((CurrentInstrSet ()) = InstrSet_ThumbEE)
5876    then raise UNPREDICTABLE "ExceptionReturn"
5877  else let
5878         val new_pc_value =
5879           if CurrentModeIsHyp () then (!ELR_hyp) else R(BitsN.B(0xE,4))
5880       in
5881         ( CPSRWriteByInstr(reg'PSR(SPSR ()),(BitsN.B(0xF,4),true))
5882         ; if ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5))) andalso
5883              ((CurrentInstrSet ()) = InstrSet_ThumbEE)
5884             then raise UNPREDICTABLE "ExceptionReturn"
5885           else BranchWritePC new_pc_value
5886         )
5887       end;
5888
5889fun dfn'HypervisorCall imm16 =
5890  if (not(HaveVirtExt ())) orelse
5891     ((IsSecure ()) orelse (not(CurrentModeIsNotUser ())))
5892    then raise UNPREDICTABLE "HypervisorCall"
5893  else if not(#HCE((#SCR((!CP15) : CP15)) : SCR))
5894    then if CurrentModeIsHyp ()
5895           then raise UNPREDICTABLE "HypervisorCall"
5896         else TakeUndefInstrException ()
5897  else CallHypervisor imm16;
5898
5899fun dfn'MoveToRegisterFromSpecial (read_spsr,d) =
5900  ( if read_spsr
5901      then if CurrentModeIsUserOrSystem ()
5902             then raise UNPREDICTABLE "MoveToRegisterFromSpecial"
5903           else write'R(reg'PSR(SPSR ()),d)
5904    else write'R(BitsN.&&(reg'PSR (!CPSR),BitsN.B(0xF8FF03DF,32)),d)
5905  ; IncPC ()
5906  );
5907
5908fun dfn'MoveToRegisterFromBankedOrSpecial (read_spsr,(SYSm,d)) =
5909  if not(CurrentModeIsNotUser ())
5910    then raise UNPREDICTABLE "MoveToRegisterFromBankedOrSpecial"
5911  else let
5912         val mode = #M((!CPSR) : PSR)
5913       in
5914         ( if read_spsr
5915             then ( SPSRAccessValid(SYSm,mode)
5916                  ; case SYSm of
5917                       BitsN.B(0xE,_) => write'R(reg'PSR (!SPSR_fiq),d)
5918                     | BitsN.B(0x10,_) => write'R(reg'PSR (!SPSR_irq),d)
5919                     | BitsN.B(0x12,_) => write'R(reg'PSR (!SPSR_svc),d)
5920                     | BitsN.B(0x14,_) => write'R(reg'PSR (!SPSR_abt),d)
5921                     | BitsN.B(0x16,_) => write'R(reg'PSR (!SPSR_und),d)
5922                     | BitsN.B(0x1C,_) => write'R(reg'PSR (!SPSR_mon),d)
5923                     | BitsN.B(0x1E,_) => write'R(reg'PSR (!SPSR_hyp),d)
5924                     | _ => ()
5925                  )
5926           else ( BankedRegisterAccessValid(SYSm,mode)
5927                ; if (BitsN.bits(4,3) SYSm) = (BitsN.B(0x0,2))
5928                    then let
5929                           val m =
5930                             BitsN.+
5931                               (BitsN.fromNat
5932                                  (BitsN.toNat(BitsN.bits(2,0) SYSm),4),
5933                                BitsN.B(0x8,4))
5934                         in
5935                           write'R(Rmode(m,BitsN.B(0x10,5)),d)
5936                         end
5937                  else if (BitsN.bits(4,3) SYSm) = (BitsN.B(0x1,2))
5938                    then let
5939                           val m =
5940                             BitsN.+
5941                               (BitsN.fromNat
5942                                  (BitsN.toNat(BitsN.bits(2,0) SYSm),4),
5943                                BitsN.B(0x8,4))
5944                         in
5945                           write'R(Rmode(m,BitsN.B(0x11,5)),d)
5946                         end
5947                  else if (BitsN.bits(4,3) SYSm) = (BitsN.B(0x3,2))
5948                    then if not(BitsN.bit(SYSm,1))
5949                           then let
5950                                  val m =
5951                                    BitsN.-
5952                                      (BitsN.B(0xE,4),
5953                                       BitsN.fromBool 4
5954                                         (BitsN.bit(SYSm,0)))
5955                                in
5956                                  write'R(Rmode(m,BitsN.B(0x16,5)),d)
5957                                end
5958                         else if BitsN.bit(SYSm,0)
5959                           then write'R
5960                                  (Rmode(BitsN.B(0xD,4),BitsN.B(0x1A,5)),d)
5961                         else write'R((!ELR_hyp),d)
5962                  else let
5963                         val targetmode = ref (BitsN.B(0x0,5))
5964                       in
5965                         ( targetmode :=
5966                           (BitsN.bitFieldInsert(0,0)
5967                              ((!targetmode),
5968                               BitsN.fromBit
5969                                 ((BitsN.bit(SYSm,2)) orelse
5970                                  (BitsN.bit(SYSm,1)))))
5971                         ; targetmode :=
5972                           (BitsN.bitFieldInsert(1,1)
5973                              ((!targetmode),BitsN.fromBit true))
5974                         ; targetmode :=
5975                           (BitsN.bitFieldInsert(2,2)
5976                              ((!targetmode),
5977                               BitsN.fromBit
5978                                 ((BitsN.bit(SYSm,2)) andalso
5979                                  (not(BitsN.bit(SYSm,1))))))
5980                         ; targetmode :=
5981                           (BitsN.bitFieldInsert(3,3)
5982                              ((!targetmode),
5983                               BitsN.fromBit
5984                                 ((BitsN.bit(SYSm,2)) andalso
5985                                  (BitsN.bit(SYSm,1)))))
5986                         ; targetmode :=
5987                           (BitsN.bitFieldInsert(4,4)
5988                              ((!targetmode),BitsN.fromBit true))
5989                         ; if mode = (!targetmode)
5990                             then raise UNPREDICTABLE
5991                                    "MoveToRegisterFromBankedOrSpecial"
5992                           else let
5993                                  val m =
5994                                    BitsN.-
5995                                      (BitsN.B(0xE,4),
5996                                       BitsN.fromBool 4
5997                                         (BitsN.bit(SYSm,0)))
5998                                in
5999                                  write'R(Rmode(m,(!targetmode)),d)
6000                                end
6001                         )
6002                       end
6003                )
6004         ; IncPC ()
6005         )
6006       end;
6007
6008fun dfn'MoveToSpecialFromImmediate (write_spsr,(imm32,mask)) =
6009  ( if write_spsr
6010      then SPSRWriteByInstr(imm32,mask)
6011    else ( CPSRWriteByInstr(imm32,(mask,false))
6012         ; if ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5))) andalso
6013              ((CurrentInstrSet ()) = InstrSet_ThumbEE)
6014             then raise UNPREDICTABLE "MoveToSpecialFromImmediate"
6015           else ()
6016         )
6017  ; IncPC ()
6018  );
6019
6020fun dfn'MoveToSpecialFromRegister (write_spsr,(n,mask)) =
6021  ( if write_spsr
6022      then SPSRWriteByInstr(R n,mask)
6023    else ( CPSRWriteByInstr(R n,(mask,false))
6024         ; if ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5))) andalso
6025              ((CurrentInstrSet ()) = InstrSet_ThumbEE)
6026             then raise UNPREDICTABLE "MoveToSpecialFromRegister"
6027           else ()
6028         )
6029  ; IncPC ()
6030  );
6031
6032fun dfn'MoveToBankedOrSpecialRegister (write_spsr,(SYSm,n)) =
6033  if not(CurrentModeIsNotUser ())
6034    then raise UNPREDICTABLE "MoveToBankedOrSpecialRegister"
6035  else let
6036         val mode = #M((!CPSR) : PSR)
6037       in
6038         ( if write_spsr
6039             then ( SPSRAccessValid(SYSm,mode)
6040                  ; case SYSm of
6041                       BitsN.B(0xE,_) =>
6042                         SPSR_fiq := (write'reg'PSR((!SPSR_fiq),R n))
6043                     | BitsN.B(0x10,_) =>
6044                       SPSR_irq := (write'reg'PSR((!SPSR_irq),R n))
6045                     | BitsN.B(0x12,_) =>
6046                       SPSR_svc := (write'reg'PSR((!SPSR_svc),R n))
6047                     | BitsN.B(0x14,_) =>
6048                       SPSR_abt := (write'reg'PSR((!SPSR_abt),R n))
6049                     | BitsN.B(0x16,_) =>
6050                       SPSR_und := (write'reg'PSR((!SPSR_und),R n))
6051                     | BitsN.B(0x1C,_) =>
6052                       SPSR_mon := (write'reg'PSR((!SPSR_mon),R n))
6053                     | BitsN.B(0x1E,_) =>
6054                       SPSR_hyp := (write'reg'PSR((!SPSR_hyp),R n))
6055                     | _ => ()
6056                  )
6057           else ( BankedRegisterAccessValid(SYSm,mode)
6058                ; if (BitsN.bits(4,3) SYSm) = (BitsN.B(0x0,2))
6059                    then let
6060                           val m =
6061                             BitsN.+
6062                               (BitsN.fromNat
6063                                  (BitsN.toNat(BitsN.bits(2,0) SYSm),4),
6064                                BitsN.B(0x8,4))
6065                           val x = (m,BitsN.B(0x10,5))
6066                         in
6067                           write'Rmode(R n,x)
6068                         end
6069                  else if (BitsN.bits(4,3) SYSm) = (BitsN.B(0x1,2))
6070                    then let
6071                           val m =
6072                             BitsN.+
6073                               (BitsN.fromNat
6074                                  (BitsN.toNat(BitsN.bits(2,0) SYSm),4),
6075                                BitsN.B(0x8,4))
6076                           val x = (m,BitsN.B(0x11,5))
6077                         in
6078                           write'Rmode(R n,x)
6079                         end
6080                  else if (BitsN.bits(4,3) SYSm) = (BitsN.B(0x3,2))
6081                    then if not(BitsN.bit(SYSm,1))
6082                           then let
6083                                  val m =
6084                                    BitsN.-
6085                                      (BitsN.B(0xE,4),
6086                                       BitsN.fromBool 4
6087                                         (BitsN.bit(SYSm,0)))
6088                                  val x = (m,BitsN.B(0x16,5))
6089                                in
6090                                  write'Rmode(R n,x)
6091                                end
6092                         else if BitsN.bit(SYSm,0)
6093                           then let
6094                                  val x = (BitsN.B(0xD,4),BitsN.B(0x1A,5))
6095                                in
6096                                  write'Rmode(R n,x)
6097                                end
6098                         else ELR_hyp := (R n)
6099                  else let
6100                         val targetmode = ref (BitsN.B(0x0,5))
6101                       in
6102                         ( targetmode :=
6103                           (BitsN.bitFieldInsert(0,0)
6104                              ((!targetmode),
6105                               BitsN.fromBit
6106                                 ((BitsN.bit(SYSm,2)) orelse
6107                                  (BitsN.bit(SYSm,1)))))
6108                         ; targetmode :=
6109                           (BitsN.bitFieldInsert(1,1)
6110                              ((!targetmode),BitsN.fromBit true))
6111                         ; targetmode :=
6112                           (BitsN.bitFieldInsert(2,2)
6113                              ((!targetmode),
6114                               BitsN.fromBit
6115                                 ((BitsN.bit(SYSm,2)) andalso
6116                                  (not(BitsN.bit(SYSm,1))))))
6117                         ; targetmode :=
6118                           (BitsN.bitFieldInsert(3,3)
6119                              ((!targetmode),
6120                               BitsN.fromBit
6121                                 ((BitsN.bit(SYSm,2)) andalso
6122                                  (BitsN.bit(SYSm,1)))))
6123                         ; targetmode :=
6124                           (BitsN.bitFieldInsert(4,4)
6125                              ((!targetmode),BitsN.fromBit true))
6126                         ; if mode = (!targetmode)
6127                             then raise UNPREDICTABLE
6128                                    "MoveToBankedOrSpecialRegister"
6129                           else let
6130                                  val m =
6131                                    BitsN.-
6132                                      (BitsN.B(0xE,4),
6133                                       BitsN.fromBool 4
6134                                         (BitsN.bit(SYSm,0)))
6135                                  val x = (m,(!targetmode))
6136                                in
6137                                  write'Rmode(R n,x)
6138                                end
6139                         )
6140                       end
6141                )
6142         ; IncPC ()
6143         )
6144       end;
6145
6146fun dfn'ReturnFromException (increment,(wordhigher,(wback,n))) =
6147  if CurrentModeIsHyp ()
6148    then TakeUndefInstrException ()
6149  else if (not(CurrentModeIsNotUser ())) orelse
6150     ((CurrentInstrSet ()) = InstrSet_ThumbEE)
6151    then raise UNPREDICTABLE "ReturnFromException"
6152  else let
6153         val Rn = R n
6154         val address =
6155           if increment then Rn else BitsN.-(Rn,BitsN.B(0x8,32))
6156         val address =
6157           if wordhigher
6158             then BitsN.+(address,BitsN.B(0x4,32))
6159           else address
6160       in
6161         ( if wback
6162             then write'R
6163                    (if increment
6164                       then BitsN.+(Rn,BitsN.B(0x8,32))
6165                     else BitsN.-(Rn,BitsN.B(0x8,32)),n)
6166           else ()
6167         ; let
6168             val new_pc_value = MemA 32 (address,4)
6169           in
6170             ( CPSRWriteByInstr
6171                 (MemA 32 (BitsN.+(address,BitsN.B(0x4,32)),4),
6172                  (BitsN.B(0xF,4),true))
6173             ; if ((#M((!CPSR) : PSR)) = (BitsN.B(0x1A,5))) andalso
6174                  ((#J((!CPSR) : PSR)) andalso (#T((!CPSR) : PSR)))
6175                 then raise UNPREDICTABLE "ReturnFromException"
6176               else BranchWritePC new_pc_value
6177             )
6178           end
6179         )
6180       end;
6181
6182fun dfn'SecureMonitorCall imm4 =
6183  if (HaveSecurityExt ()) andalso (CurrentModeIsNotUser ())
6184    then if (HaveVirtExt ()) andalso
6185            ((not(IsSecure ())) andalso
6186             ((not(CurrentModeIsHyp ())) andalso
6187              (#TSC((#HCR((!CP15) : CP15)) : HCR))))
6188           then let
6189                  val HSRString = BitsN.B(0x0,25)
6190                in
6191                  ( WriteHSR(BitsN.B(0x13,6),HSRString)
6192                  ; TakeHypTrapException ()
6193                  )
6194                end
6195         else if #SCD((#SCR((!CP15) : CP15)) : SCR)
6196           then if IsSecure ()
6197                  then raise UNPREDICTABLE "SecureMonitorCall"
6198                else TakeUndefInstrException ()
6199         else TakeSMCException ()
6200  else TakeUndefInstrException ();
6201
6202fun dfn'SupervisorCall imm32 = CallSupervisor(BitsN.bits(15,0) imm32);
6203
6204fun dfn'StoreReturnState (increment,(wordhigher,(wback,mode))) =
6205  if CurrentModeIsHyp ()
6206    then TakeUndefInstrException ()
6207  else if (CurrentModeIsUserOrSystem ()) orelse
6208     ((CurrentInstrSet ()) = InstrSet_ThumbEE)
6209    then raise UNPREDICTABLE "StoreReturnState"
6210  else if mode = (BitsN.B(0x1A,5))
6211    then raise UNPREDICTABLE "StoreReturnState"
6212  else ( if not(IsSecure ())
6213           then if (mode = (BitsN.B(0x16,5))) orelse
6214                   ((mode = (BitsN.B(0x11,5))) andalso
6215                    (#RFR((#NSACR((!CP15) : CP15)) : NSACR)))
6216                  then raise UNPREDICTABLE "StoreReturnState"
6217                else ()
6218         else ()
6219       ; let
6220           val base = Rmode(BitsN.B(0xD,4),mode)
6221           val address =
6222             if increment then base else BitsN.-(base,BitsN.B(0x8,32))
6223           val address =
6224             if wordhigher
6225               then BitsN.+(address,BitsN.B(0x4,32))
6226             else address
6227         in
6228           ( let val x = (address,4) in write'MemA 32 (LR (),x) end
6229           ; let
6230               val x = (BitsN.+(address,BitsN.B(0x4,32)),4)
6231             in
6232               write'MemA 32 (reg'PSR(SPSR ()),x)
6233             end
6234           ; if wback
6235               then let
6236                      val x = (BitsN.B(0xD,4),mode)
6237                    in
6238                      write'Rmode
6239                        (if increment
6240                           then BitsN.+(base,BitsN.B(0x8,32))
6241                         else BitsN.-(base,BitsN.B(0x8,32)),x)
6242                    end
6243             else ()
6244           ; IncPC ()
6245           )
6246         end
6247       );
6248
6249fun dfn'Setend set_bigend =
6250  ( CPSR := (PSR_E_rupd((!CPSR),set_bigend)); IncPC () );
6251
6252fun dfn'Undefined imm32 = TakeUndefInstrException ();
6253
6254fun dfn'NoOperation () = IncPC ();
6255
6256fun dfn'Breakpoint imm32 = IncPC ();
6257
6258fun dfn'Debug option = IncPC ();
6259
6260fun dfn'DataMemoryBarrier option = IncPC ();
6261
6262fun dfn'DataSynchronizationBarrier option = IncPC ();
6263
6264fun dfn'InstructionSynchronizationBarrier option = IncPC ();
6265
6266fun dfn'PreloadData (add,(is_pldw,(n,m))) = IncPC ();
6267
6268fun dfn'PreloadDataLiteral (add,imm32) = IncPC ();
6269
6270fun dfn'PreloadInstruction (add,(n,m)) = IncPC ();
6271
6272fun dfn'SendEvent () = IncPC ();
6273
6274fun dfn'WaitForEvent () = IncPC ();
6275
6276fun dfn'WaitForInterrupt () = IncPC ();
6277
6278fun dfn'Yield () = IncPC ();
6279
6280fun rec'FPSCR x =
6281  {AHP = BitsN.bit(x,26), C = BitsN.bit(x,29), DN = BitsN.bit(x,25),
6282   DZC = BitsN.bit(x,1), DZE = BitsN.bit(x,9), FZ = BitsN.bit(x,24),
6283   IDC = BitsN.bit(x,7), IDE = BitsN.bit(x,15), IOC = BitsN.bit(x,0),
6284   IOE = BitsN.bit(x,8), IXC = BitsN.bit(x,4), IXE = BitsN.bit(x,12),
6285   N = BitsN.bit(x,31), OFC = BitsN.bit(x,2), OFE = BitsN.bit(x,10),
6286   QC = BitsN.bit(x,27), RMode = BitsN.bits(23,22) x,
6287   UFC = BitsN.bit(x,3), UFE = BitsN.bit(x,11), V = BitsN.bit(x,28),
6288   Z = BitsN.bit(x,30),
6289   fpscr'rst =
6290     BitsN.concat
6291       [BitsN.bits(6,5) x,BitsN.bits(14,13) x,BitsN.bits(21,16) x]};
6292
6293fun reg'FPSCR x =
6294  case x of
6295     {AHP = AHP, C = C, DN = DN, DZC = DZC, DZE = DZE, FZ = FZ, IDC = IDC,
6296      IDE = IDE, IOC = IOC, IOE = IOE, IXC = IXC, IXE = IXE, N = N,
6297      OFC = OFC, OFE = OFE, QC = QC, RMode = RMode, UFC = UFC, UFE = UFE,
6298      V = V, Z = Z, fpscr'rst = fpscr'rst} =>
6299       BitsN.concat
6300         [BitsN.fromBit N,BitsN.fromBit Z,BitsN.fromBit C,BitsN.fromBit V,
6301          BitsN.fromBit QC,BitsN.fromBit AHP,BitsN.fromBit DN,
6302          BitsN.fromBit FZ,RMode,BitsN.bits(5,0) fpscr'rst,
6303          BitsN.fromBit IDE,BitsN.bits(7,6) fpscr'rst,BitsN.fromBit IXE,
6304          BitsN.fromBit UFE,BitsN.fromBit OFE,BitsN.fromBit DZE,
6305          BitsN.fromBit IOE,BitsN.fromBit IDC,BitsN.bits(9,8) fpscr'rst,
6306          BitsN.fromBit IXC,BitsN.fromBit UFC,BitsN.fromBit OFC,
6307          BitsN.fromBit DZC,BitsN.fromBit IOC];
6308
6309fun write'rec'FPSCR (_,x) = reg'FPSCR x;
6310
6311fun write'reg'FPSCR (_,x) = rec'FPSCR x;
6312
6313fun RoundingMode () =
6314  case #RMode((#FPSCR((!FP) : FP)) : FPSCR) of
6315     BitsN.B(0x0,_) => IEEEReal.TO_NEAREST
6316   | BitsN.B(0x1,_) => IEEEReal.TO_POSINF
6317   | BitsN.B(0x2,_) => IEEEReal.TO_NEGINF
6318   | BitsN.B(0x3,_) => IEEEReal.TO_ZERO
6319   | _ => raise General.Bind;
6320
6321fun FPAdd32 (op1,op2) = (L3.snd o FP32.add) (RoundingMode (),(op1,op2));
6322
6323fun FPSub32 (op1,op2) = (L3.snd o FP32.sub) (RoundingMode (),(op1,op2));
6324
6325fun FPMul32 (op1,op2) = (L3.snd o FP32.mul) (RoundingMode (),(op1,op2));
6326
6327fun FPAdd64 (op1,op2) = (L3.snd o FP64.add) (RoundingMode (),(op1,op2));
6328
6329fun FPSub64 (op1,op2) = (L3.snd o FP64.sub) (RoundingMode (),(op1,op2));
6330
6331fun FPMul64 (op1,op2) = (L3.snd o FP64.mul) (RoundingMode (),(op1,op2));
6332
6333fun FPToFixed32 (operand,(unsigned,round_towards_zero)) =
6334  let
6335    val mode =
6336      if round_towards_zero then IEEEReal.TO_ZERO else RoundingMode ()
6337  in
6338    case FP32.toInt(mode,operand) of
6339       Option.SOME i =>
6340         let
6341           val (result,overflow) = SatQ 32 (i,(32,unsigned))
6342         in
6343           if overflow
6344             then raise VFP_EXCEPTION "FPToFixed32: overflow exception"
6345           else result
6346         end
6347     | NONE => raise VFP_EXCEPTION "FPToFixed32: NaN or infinity"
6348  end;
6349
6350fun FPToFixed64 (operand,(unsigned,round_towards_zero)) =
6351  let
6352    val mode =
6353      if round_towards_zero then IEEEReal.TO_ZERO else RoundingMode ()
6354  in
6355    case FP64.toInt(mode,operand) of
6356       Option.SOME i =>
6357         let
6358           val (result,overflow) = SatQ 32 (i,(32,unsigned))
6359         in
6360           if overflow
6361             then raise VFP_EXCEPTION "FPToFixed64: overflow exception"
6362           else result
6363         end
6364     | NONE => raise VFP_EXCEPTION "FPToFixed64: NaN or infinity"
6365  end;
6366
6367fun FixedToFP32 (operand,(unsigned,round_to_nearest)) =
6368  let
6369    val mode =
6370      if round_to_nearest then IEEEReal.TO_NEAREST else RoundingMode ()
6371    val int_operand =
6372      if unsigned
6373        then Nat.toInt(BitsN.toNat operand)
6374      else BitsN.toInt operand
6375  in
6376    FP32.fromInt(mode,int_operand)
6377  end;
6378
6379fun FixedToFP64 (operand,(unsigned,round_to_nearest)) =
6380  let
6381    val mode =
6382      if round_to_nearest then IEEEReal.TO_NEAREST else RoundingMode ()
6383    val int_operand =
6384      if unsigned
6385        then Nat.toInt(BitsN.toNat operand)
6386      else BitsN.toInt operand
6387  in
6388    FP64.fromInt(mode,int_operand)
6389  end;
6390
6391fun D n = Map.lookup(#REG((!FP) : FP),BitsN.toNat n);
6392
6393fun write'D (value,n) =
6394  let
6395    val f = Map.copy(#REG((!FP) : FP))
6396  in
6397    FP := (FP_REG_rupd((!FP),Map.update(f,BitsN.toNat n,value)))
6398  end;
6399
6400fun S n =
6401  if BitsN.bit(n,0)
6402    then BitsN.bits(63,32) (D(BitsN.div(n,BitsN.B(0x2,5))))
6403  else BitsN.bits(31,0) (D(BitsN.div(n,BitsN.B(0x2,5))));
6404
6405fun write'S (value,n) =
6406  if BitsN.bit(n,0)
6407    then let
6408           val x = BitsN.div(n,BitsN.B(0x2,5))
6409           val w = D x
6410         in
6411           write'D(BitsN.bitFieldInsert(63,32) (w,value),x)
6412         end
6413  else let
6414         val x = BitsN.div(n,BitsN.B(0x2,5))
6415         val w = D x
6416       in
6417         write'D(BitsN.bitFieldInsert(31,0) (w,value),x)
6418       end;
6419
6420fun VFPExpandImm (imm8,single) =
6421  if single
6422    then BitsN.zeroExtend 64
6423           (BitsN.concat
6424              [BitsN.bits(7,7) imm8,BitsN.~(BitsN.bits(6,6) imm8),
6425               BitsN.resize_replicate 5 (BitsN.bits(6,6) imm8,5),
6426               BitsN.bits(5,0) imm8,
6427               BitsN.resize_replicate 19 (BitsN.B(0x0,1),19)])
6428  else BitsN.concat
6429         [BitsN.bits(7,7) imm8,BitsN.~(BitsN.bits(6,6) imm8),
6430          BitsN.resize_replicate 8 (BitsN.bits(6,6) imm8,8),
6431          BitsN.bits(5,0) imm8,
6432          BitsN.resize_replicate 48 (BitsN.B(0x0,1),48)];
6433
6434fun FPCompare32 (op1,op2) =
6435  if (FP32.isNan op1) orelse (FP32.isNan op2)
6436    then BitsN.B(0x3,4)
6437  else if FP32.equal(op1,op2)
6438    then BitsN.B(0x6,4)
6439  else if FP32.lessThan(op1,op2) then BitsN.B(0x8,4) else BitsN.B(0x2,4);
6440
6441fun FPCompare64 (op1,op2) =
6442  if (FP64.isNan op1) orelse (FP64.isNan op2)
6443    then BitsN.B(0x3,4)
6444  else if FP64.equal(op1,op2)
6445    then BitsN.B(0x6,4)
6446  else if FP64.lessThan(op1,op2) then BitsN.B(0x8,4) else BitsN.B(0x2,4);
6447
6448fun FPZero32 sign = BitsN.@@(sign,BitsN.B(0x0,31));
6449
6450fun FPZero64 sign = BitsN.@@(sign,BitsN.B(0x0,63));
6451
6452fun dfn'vmov_imm (single_register,(d,imm64)) =
6453  ( if single_register
6454      then write'S(BitsN.bits(31,0) imm64,d)
6455    else write'D(imm64,d)
6456  ; IncPC ()
6457  );
6458
6459fun dfn'vmov (single_register,(d,m)) =
6460  ( if single_register then write'S(S m,d) else write'D(D m,d); IncPC () );
6461
6462fun dfn'vmov_single (to_arm_register,(t,n)) =
6463  ( if to_arm_register then write'R(S n,t) else write'S(R t,n); IncPC () );
6464
6465fun dfn'vmov_two_singles (to_arm_registers,(t,(t2,m))) =
6466  ( if to_arm_registers
6467      then ( write'R(S m,t); write'R(S(BitsN.+(m,BitsN.B(0x1,5))),t2) )
6468    else ( write'S(R t,m)
6469         ; let val x = BitsN.+(m,BitsN.B(0x1,5)) in write'S(R t2,x) end
6470         )
6471  ; IncPC ()
6472  );
6473
6474fun dfn'vmov_double (to_arm_registers,(t,(t2,m))) =
6475  ( if to_arm_registers
6476      then ( write'R(BitsN.bits(31,0) (D m),t)
6477           ; write'R(BitsN.bits(63,32) (D m),t2)
6478           )
6479    else ( let
6480             val w = D m
6481           in
6482             write'D(BitsN.bitFieldInsert(31,0) (w,R t),m)
6483           end
6484         ; let
6485             val w = D m
6486           in
6487             write'D(BitsN.bitFieldInsert(63,32) (w,R t2),m)
6488           end
6489         )
6490  ; IncPC ()
6491  );
6492
6493fun dfn'vabs (dp_operation,(d,m)) =
6494  ( if dp_operation
6495      then write'D(FP64.abs(D m),d)
6496    else write'S(FP32.abs(S m),d)
6497  ; IncPC ()
6498  );
6499
6500fun dfn'vneg (dp_operation,(d,m)) =
6501  ( if dp_operation
6502      then write'D(FP64.neg(D m),d)
6503    else write'S(FP32.neg(S m),d)
6504  ; IncPC ()
6505  );
6506
6507fun dfn'vsqrt (dp_operation,(d,m)) =
6508  ( if dp_operation
6509      then write'D((L3.snd o FP64.sqrt) (RoundingMode (),D m),d)
6510    else write'S((L3.snd o FP32.sqrt) (RoundingMode (),S m),d)
6511  ; IncPC ()
6512  );
6513
6514fun dfn'vcvt_float (double_to_single,(d,m)) =
6515  ( if double_to_single
6516      then write'S(FPConvert.fp64_to_fp32(RoundingMode (),D m),d)
6517    else write'D(FPConvert.fp32_to_fp64(S m),d)
6518  ; IncPC ()
6519  );
6520
6521fun dfn'vcvt_to_integer (dp_operation,(unsigned,(round_zero,(d,m)))) =
6522  ( if dp_operation
6523      then write'S(FPToFixed64(D m,(unsigned,round_zero)),d)
6524    else write'S(FPToFixed32(S m,(unsigned,round_zero)),d)
6525  ; IncPC ()
6526  );
6527
6528fun dfn'vcvt_from_integer (dp_operation,(unsigned,(d,m))) =
6529  ( if dp_operation
6530      then write'D(FixedToFP64(S m,(unsigned,false)),d)
6531    else write'S(FixedToFP32(S m,(unsigned,false)),d)
6532  ; IncPC ()
6533  );
6534
6535fun dfn'vcmp (dp_operation,(d,m_with_zero)) =
6536  ( if dp_operation
6537      then let
6538             val op2 =
6539               case m_with_zero of
6540                  Option.SOME m => D m
6541                | NONE => FPZero64(BitsN.B(0x0,1))
6542             val x0 = #FPSCR((!FP) : FP)
6543             val w = reg'FPSCR x0
6544           in
6545             FP :=
6546             (FP_FPSCR_rupd
6547                ((!FP),
6548                 write'reg'FPSCR
6549                   (x0,
6550                    BitsN.bitFieldInsert(31,28) (w,FPCompare64(D d,op2)))))
6551           end
6552    else let
6553           val op2 =
6554             case m_with_zero of
6555                Option.SOME m => S m
6556              | NONE => FPZero32(BitsN.B(0x0,1))
6557           val x0 = #FPSCR((!FP) : FP)
6558           val w = reg'FPSCR x0
6559         in
6560           FP :=
6561           (FP_FPSCR_rupd
6562              ((!FP),
6563               write'reg'FPSCR
6564                 (x0,BitsN.bitFieldInsert(31,28) (w,FPCompare32(S d,op2)))))
6565         end
6566  ; IncPC ()
6567  );
6568
6569fun dfn'vmsr t =
6570  ( let
6571      val x0 = #FPSCR((!FP) : FP)
6572    in
6573      FP := (FP_FPSCR_rupd((!FP),write'reg'FPSCR(x0,R t)))
6574    end
6575  ; IncPC ()
6576  );
6577
6578fun dfn'vmrs t =
6579  ( if not(t = (BitsN.B(0xF,4)))
6580      then write'R(reg'FPSCR(#FPSCR((!FP) : FP)),t)
6581    else ( CPSR := (PSR_N_rupd((!CPSR),#N((#FPSCR((!FP) : FP)) : FPSCR)))
6582         ; CPSR := (PSR_Z_rupd((!CPSR),#Z((#FPSCR((!FP) : FP)) : FPSCR)))
6583         ; CPSR := (PSR_C_rupd((!CPSR),#C((#FPSCR((!FP) : FP)) : FPSCR)))
6584         ; CPSR := (PSR_V_rupd((!CPSR),#V((#FPSCR((!FP) : FP)) : FPSCR)))
6585         )
6586  ; IncPC ()
6587  );
6588
6589fun dfn'vadd (dp_operation,(d,(n,m))) =
6590  ( if dp_operation
6591      then write'D(FPAdd64(D n,D m),d)
6592    else write'S(FPAdd32(S n,S m),d)
6593  ; IncPC ()
6594  );
6595
6596fun dfn'vsub (dp_operation,(d,(n,m))) =
6597  ( if dp_operation
6598      then write'D(FPSub64(D n,D m),d)
6599    else write'S(FPSub32(S n,S m),d)
6600  ; IncPC ()
6601  );
6602
6603fun dfn'vmul (dp_operation,(d,(n,m))) =
6604  ( if dp_operation
6605      then write'D(FPMul64(D n,D m),d)
6606    else write'S(FPMul32(S n,S m),d)
6607  ; IncPC ()
6608  );
6609
6610fun dfn'vdiv (dp_operation,(d,(n,m))) =
6611  ( if dp_operation
6612      then write'D((L3.snd o FP64.div) (RoundingMode (),(D n,D m)),d)
6613    else write'S((L3.snd o FP32.div) (RoundingMode (),(S n,S m)),d)
6614  ; IncPC ()
6615  );
6616
6617fun dfn'vmla_vmls (dp_operation,(add,(d,(n,m)))) =
6618  ( if dp_operation
6619      then let
6620             val product = FPMul64(D n,D m)
6621             val addend = if add then product else FP64.neg product
6622           in
6623             write'D(FPAdd64(D n,addend),d)
6624           end
6625    else let
6626           val product = FPMul32(S n,S m)
6627           val addend = if add then product else FP32.neg product
6628         in
6629           write'S(FPAdd32(S n,addend),d)
6630         end
6631  ; IncPC ()
6632  );
6633
6634fun dfn'vfma_vfms (dp_operation,(add,(d,(n,m)))) =
6635  ( if dp_operation
6636      then let
6637             val op64 = D n
6638             val op64 = if add then op64 else FP64.neg op64
6639           in
6640             write'D
6641               ((L3.snd o FP64.mul_add) (RoundingMode (),(op64,(D m,D d))),
6642                d)
6643           end
6644    else let
6645           val op32 = S n
6646           val op32 = if add then op32 else FP32.neg op32
6647         in
6648           write'S
6649             ((L3.snd o FP32.mul_add) (RoundingMode (),(op32,(S m,S d))),d)
6650         end
6651  ; IncPC ()
6652  );
6653
6654fun dfn'vfnma_vfnms (dp_operation,(add,(d,(n,m)))) =
6655  ( if dp_operation
6656      then let
6657             val op64 = D n
6658             val op64 = if add then op64 else FP64.neg op64
6659           in
6660             write'D
6661               ((L3.snd o FP64.mul_add)
6662                  (RoundingMode (),(op64,(D m,FP64.neg(D d)))),d)
6663           end
6664    else let
6665           val op32 = S n
6666           val op32 = if add then op32 else FP32.neg op32
6667         in
6668           write'S
6669             ((L3.snd o FP32.mul_add)
6670                (RoundingMode (),(op32,(S m,FP32.neg(S d)))),d)
6671         end
6672  ; IncPC ()
6673  );
6674
6675fun dfn'vneg_mul (dp_operation,(typ,(d,(n,m)))) =
6676  ( if dp_operation
6677      then let
6678             val product = FPMul64(D n,D m)
6679           in
6680             case typ of
6681                VFPNegMul_VNMLA =>
6682                  write'D(FPAdd64(FP64.neg(D d),FP64.neg product),d)
6683              | VFPNegMul_VNMLS =>
6684                write'D(FPAdd64(FP64.neg(D d),product),d)
6685              | VFPNegMul_VNMUL => write'D(FP64.neg product,d)
6686           end
6687    else let
6688           val product = FPMul32(S n,S m)
6689         in
6690           case typ of
6691              VFPNegMul_VNMLA =>
6692                write'S(FPAdd32(FP32.neg(S d),FP32.neg product),d)
6693            | VFPNegMul_VNMLS => write'S(FPAdd32(FP32.neg(S d),product),d)
6694            | VFPNegMul_VNMUL => write'S(FP32.neg product,d)
6695         end
6696  ; IncPC ()
6697  );
6698
6699fun dfn'vldr (single_reg,(add,(d,(n,imm32)))) =
6700  let
6701    val base = if n = (BitsN.B(0xF,4)) then Align 32 (PC (),4) else R n
6702    val address = if add then BitsN.+(base,imm32) else BitsN.-(base,imm32)
6703  in
6704    ( if single_reg
6705        then write'S(MemA 32 (address,4),d)
6706      else let
6707             val word1 = MemA 32 (address,4)
6708             val word2 = MemA 32 (BitsN.+(address,BitsN.B(0x4,32)),4)
6709           in
6710             write'D
6711               (if BigEndian ()
6712                  then BitsN.@@(word1,word2)
6713                else BitsN.@@(word2,word1),d)
6714           end
6715    ; IncPC ()
6716    )
6717  end;
6718
6719fun dfn'vstr (single_reg,(add,(d,(n,imm32)))) =
6720  let
6721    val address = if add then BitsN.+(R n,imm32) else BitsN.-(R n,imm32)
6722  in
6723    ( if single_reg
6724        then let val x = (address,4) in write'MemA 32 (S d,x) end
6725      else let
6726             val word = D d
6727           in
6728             ( let
6729                 val x = (address,4)
6730               in
6731                 write'MemA 32
6732                   (if BigEndian ()
6733                      then BitsN.bits(63,32) word
6734                    else BitsN.bits(31,0) word,x)
6735               end
6736             ; let
6737                 val x = (BitsN.+(address,BitsN.B(0x4,32)),4)
6738               in
6739                 write'MemA 32
6740                   (if BigEndian ()
6741                      then BitsN.bits(31,0) word
6742                    else BitsN.bits(63,32) word,x)
6743               end
6744             )
6745           end
6746    ; IncPC ()
6747    )
6748  end;
6749
6750fun dfn'vldm (single_regs,(add,(wback,(d,(n,imm8))))) =
6751  let
6752    val imm32 = BitsN.zeroExtend 32 (BitsN.@@(imm8,BitsN.B(0x0,2)))
6753    val regs =
6754      if single_regs
6755        then BitsN.toNat imm8
6756      else Nat.div(BitsN.toNat imm8,2)
6757  in
6758    let
6759      val address = ref (if add then R n else BitsN.-(R n,imm32))
6760    in
6761      ( L3.for
6762          (0,Nat.-(regs,1),
6763           fn r =>
6764             if single_regs
6765               then ( let
6766                        val x = BitsN.+(d,BitsN.fromNat(r,5))
6767                      in
6768                        write'S(MemA 32 ((!address),4),x)
6769                      end
6770                    ; address := (BitsN.+((!address),BitsN.B(0x4,32)))
6771                    )
6772             else let
6773                    val word1 = MemA 32 ((!address),4)
6774                    val word2 =
6775                      MemA 32 (BitsN.+((!address),BitsN.B(0x4,32)),4)
6776                  in
6777                    ( address := (BitsN.+((!address),BitsN.B(0x8,32)))
6778                    ; let
6779                        val x = BitsN.+(d,BitsN.fromNat(r,5))
6780                      in
6781                        write'D
6782                          (if BigEndian ()
6783                             then BitsN.@@(word1,word2)
6784                           else BitsN.@@(word2,word1),x)
6785                      end
6786                    )
6787                  end)
6788      ; if wback
6789          then write'R
6790                 (if add then BitsN.+(R n,imm32) else BitsN.-(R n,imm32),n)
6791        else ()
6792      ; IncPC ()
6793      )
6794    end
6795  end;
6796
6797fun dfn'vstm (single_regs,(add,(wback,(d,(n,imm8))))) =
6798  let
6799    val imm32 = BitsN.zeroExtend 32 (BitsN.@@(imm8,BitsN.B(0x0,2)))
6800    val regs =
6801      if single_regs
6802        then BitsN.toNat imm8
6803      else Nat.div(BitsN.toNat imm8,2)
6804  in
6805    let
6806      val address = ref (if add then R n else BitsN.-(R n,imm32))
6807    in
6808      ( L3.for
6809          (0,Nat.-(regs,1),
6810           fn r =>
6811             if single_regs
6812               then ( let
6813                        val x = ((!address),4)
6814                      in
6815                        write'MemA 32 (S(BitsN.+(d,BitsN.fromNat(r,5))),x)
6816                      end
6817                    ; address := (BitsN.+((!address),BitsN.B(0x4,32)))
6818                    )
6819             else let
6820                    val d = D(BitsN.+(d,BitsN.fromNat(r,5)))
6821                  in
6822                    ( let
6823                        val x = ((!address),4)
6824                      in
6825                        write'MemA 32
6826                          (if BigEndian ()
6827                             then BitsN.bits(63,32) d
6828                           else BitsN.bits(31,0) d,x)
6829                      end
6830                    ; let
6831                        val x = (BitsN.+((!address),BitsN.B(0x4,32)),4)
6832                      in
6833                        write'MemA 32
6834                          (if BigEndian ()
6835                             then BitsN.bits(31,0) d
6836                           else BitsN.bits(63,32) d,x)
6837                      end
6838                    ; address := (BitsN.+((!address),BitsN.B(0x8,32)))
6839                    )
6840                  end)
6841      ; if wback
6842          then write'R
6843                 (if add then BitsN.+(R n,imm32) else BitsN.-(R n,imm32),n)
6844        else ()
6845      ; IncPC ()
6846      )
6847    end
6848  end;
6849
6850fun Run v0 =
6851  case v0 of
6852     ClearExclusive => dfn'ClearExclusive ()
6853   | NoOperation => dfn'NoOperation ()
6854   | Divide v152 => dfn'Divide v152
6855   | IfThen v153 => dfn'IfThen v153
6856   | Swap v154 => dfn'Swap v154
6857   | Undefined v155 => dfn'Undefined v155
6858   | Branch v1 =>
6859     (case v1 of
6860         BranchExchange v2 => dfn'BranchExchange v2
6861       | BranchLinkExchangeImmediate v3 =>
6862         dfn'BranchLinkExchangeImmediate v3
6863       | BranchLinkExchangeRegister v4 =>
6864         dfn'BranchLinkExchangeRegister v4
6865       | BranchTarget v5 => dfn'BranchTarget v5
6866       | CheckArray v6 => dfn'CheckArray v6
6867       | CompareBranch v7 => dfn'CompareBranch v7
6868       | HandlerBranchLink v8 => dfn'HandlerBranchLink v8
6869       | HandlerBranchLinkParameter v9 =>
6870         dfn'HandlerBranchLinkParameter v9
6871       | HandlerBranchParameter v10 => dfn'HandlerBranchParameter v10
6872       | TableBranchByte v11 => dfn'TableBranchByte v11)
6873   | Data v12 =>
6874     (case v12 of
6875         AddSub v13 => dfn'AddSub v13
6876       | ArithLogicImmediate v14 => dfn'ArithLogicImmediate v14
6877       | CountLeadingZeroes v15 => dfn'CountLeadingZeroes v15
6878       | Move v16 => dfn'Move v16
6879       | MoveHalfword v17 => dfn'MoveHalfword v17
6880       | Register v18 => dfn'Register v18
6881       | RegisterShiftedRegister v19 => dfn'RegisterShiftedRegister v19
6882       | ShiftImmediate v20 => dfn'ShiftImmediate v20
6883       | ShiftRegister v21 => dfn'ShiftRegister v21
6884       | TestCompareImmediate v22 => dfn'TestCompareImmediate v22
6885       | TestCompareRegister v23 => dfn'TestCompareRegister v23)
6886   | Hint v24 =>
6887     (case v24 of
6888         SendEvent => dfn'SendEvent ()
6889       | WaitForEvent => dfn'WaitForEvent ()
6890       | WaitForInterrupt => dfn'WaitForInterrupt ()
6891       | Yield => dfn'Yield ()
6892       | Breakpoint v25 => dfn'Breakpoint v25
6893       | DataMemoryBarrier v26 => dfn'DataMemoryBarrier v26
6894       | DataSynchronizationBarrier v27 =>
6895         dfn'DataSynchronizationBarrier v27
6896       | Debug v28 => dfn'Debug v28
6897       | InstructionSynchronizationBarrier v29 =>
6898         dfn'InstructionSynchronizationBarrier v29
6899       | PreloadData v30 => dfn'PreloadData v30
6900       | PreloadDataLiteral v31 => dfn'PreloadDataLiteral v31
6901       | PreloadInstruction v32 => dfn'PreloadInstruction v32)
6902   | Load v33 =>
6903     (case v33 of
6904         LoadByte v34 => dfn'LoadByte v34
6905       | LoadByteLiteral v35 => dfn'LoadByteLiteral v35
6906       | LoadByteUnprivileged v36 => dfn'LoadByteUnprivileged v36
6907       | LoadDual v37 => dfn'LoadDual v37
6908       | LoadDualLiteral v38 => dfn'LoadDualLiteral v38
6909       | LoadExclusive v39 => dfn'LoadExclusive v39
6910       | LoadExclusiveByte v40 => dfn'LoadExclusiveByte v40
6911       | LoadExclusiveDoubleword v41 => dfn'LoadExclusiveDoubleword v41
6912       | LoadExclusiveHalf v42 => dfn'LoadExclusiveHalf v42
6913       | LoadHalf v43 => dfn'LoadHalf v43
6914       | LoadHalfLiteral v44 => dfn'LoadHalfLiteral v44
6915       | LoadHalfUnprivileged v45 => dfn'LoadHalfUnprivileged v45
6916       | LoadLiteral v46 => dfn'LoadLiteral v46
6917       | LoadMultiple v47 => dfn'LoadMultiple v47
6918       | LoadMultipleExceptionReturn v48 =>
6919         dfn'LoadMultipleExceptionReturn v48
6920       | LoadMultipleUserRegisters v49 =>
6921         dfn'LoadMultipleUserRegisters v49
6922       | LoadSignedByteUnprivileged v50 =>
6923         dfn'LoadSignedByteUnprivileged v50
6924       | LoadUnprivileged v51 => dfn'LoadUnprivileged v51
6925       | LoadWord v52 => dfn'LoadWord v52)
6926   | Media v53 =>
6927     (case v53 of
6928         BitFieldClearOrInsert v54 => dfn'BitFieldClearOrInsert v54
6929       | BitFieldExtract v55 => dfn'BitFieldExtract v55
6930       | ByteReverse v56 => dfn'ByteReverse v56
6931       | ByteReversePackedHalfword v57 =>
6932         dfn'ByteReversePackedHalfword v57
6933       | ByteReverseSignedHalfword v58 =>
6934         dfn'ByteReverseSignedHalfword v58
6935       | ExtendByte v59 => dfn'ExtendByte v59
6936       | ExtendByte16 v60 => dfn'ExtendByte16 v60
6937       | ExtendHalfword v61 => dfn'ExtendHalfword v61
6938       | PackHalfword v62 => dfn'PackHalfword v62
6939       | ReverseBits v63 => dfn'ReverseBits v63
6940       | Saturate v64 => dfn'Saturate v64
6941       | Saturate16 v65 => dfn'Saturate16 v65
6942       | SaturatingAddSubtract v66 => dfn'SaturatingAddSubtract v66
6943       | SelectBytes v67 => dfn'SelectBytes v67)
6944   | Multiply v68 =>
6945     (case v68 of
6946         Multiply32 v69 => dfn'Multiply32 v69
6947       | MultiplyAccumulate v70 => dfn'MultiplyAccumulate v70
6948       | MultiplyAccumulateAccumulate v71 =>
6949         dfn'MultiplyAccumulateAccumulate v71
6950       | MultiplyLong v72 => dfn'MultiplyLong v72
6951       | MultiplySubtract v73 => dfn'MultiplySubtract v73
6952       | Signed16Multiply32Accumulate v74 =>
6953         dfn'Signed16Multiply32Accumulate v74
6954       | Signed16Multiply32Result v75 => dfn'Signed16Multiply32Result v75
6955       | Signed16Multiply64Accumulate v76 =>
6956         dfn'Signed16Multiply64Accumulate v76
6957       | Signed16x32Multiply32Accumulate v77 =>
6958         dfn'Signed16x32Multiply32Accumulate v77
6959       | Signed16x32Multiply32Result v78 =>
6960         dfn'Signed16x32Multiply32Result v78
6961       | SignedMostSignificantMultiply v79 =>
6962         dfn'SignedMostSignificantMultiply v79
6963       | SignedMostSignificantMultiplySubtract v80 =>
6964         dfn'SignedMostSignificantMultiplySubtract v80
6965       | SignedMultiplyDual v81 => dfn'SignedMultiplyDual v81
6966       | SignedMultiplyLongDual v82 => dfn'SignedMultiplyLongDual v82)
6967   | SIMD v83 =>
6968     (case v83 of
6969         SignedAddSub16 v84 => dfn'SignedAddSub16 v84
6970       | SignedAddSub8 v85 => dfn'SignedAddSub8 v85
6971       | SignedHalvingAddSub16 v86 => dfn'SignedHalvingAddSub16 v86
6972       | SignedHalvingAddSub8 v87 => dfn'SignedHalvingAddSub8 v87
6973       | SignedSaturatingAddSub16 v88 => dfn'SignedSaturatingAddSub16 v88
6974       | SignedSaturatingAddSub8 v89 => dfn'SignedSaturatingAddSub8 v89
6975       | UnsignedAddSub16 v90 => dfn'UnsignedAddSub16 v90
6976       | UnsignedAddSub8 v91 => dfn'UnsignedAddSub8 v91
6977       | UnsignedHalvingAddSub16 v92 => dfn'UnsignedHalvingAddSub16 v92
6978       | UnsignedHalvingAddSub8 v93 => dfn'UnsignedHalvingAddSub8 v93
6979       | UnsignedSaturatingAddSub16 v94 =>
6980         dfn'UnsignedSaturatingAddSub16 v94
6981       | UnsignedSaturatingAddSub8 v95 =>
6982         dfn'UnsignedSaturatingAddSub8 v95
6983       | UnsignedSumAbsoluteDifferences v96 =>
6984         dfn'UnsignedSumAbsoluteDifferences v96)
6985   | Store v97 =>
6986     (case v97 of
6987         StoreByte v98 => dfn'StoreByte v98
6988       | StoreByteUnprivileged v99 => dfn'StoreByteUnprivileged v99
6989       | StoreDual v100 => dfn'StoreDual v100
6990       | StoreExclusive v101 => dfn'StoreExclusive v101
6991       | StoreExclusiveByte v102 => dfn'StoreExclusiveByte v102
6992       | StoreExclusiveDoubleword v103 =>
6993         dfn'StoreExclusiveDoubleword v103
6994       | StoreExclusiveHalf v104 => dfn'StoreExclusiveHalf v104
6995       | StoreHalf v105 => dfn'StoreHalf v105
6996       | StoreHalfUnprivileged v106 => dfn'StoreHalfUnprivileged v106
6997       | StoreMultiple v107 => dfn'StoreMultiple v107
6998       | StoreMultipleUserRegisters v108 =>
6999         dfn'StoreMultipleUserRegisters v108
7000       | StoreUnprivileged v109 => dfn'StoreUnprivileged v109
7001       | StoreWord v110 => dfn'StoreWord v110)
7002   | System v111 =>
7003     (case v111 of
7004         ExceptionReturn => dfn'ExceptionReturn ()
7005       | ChangeProcessorState v112 => dfn'ChangeProcessorState v112
7006       | EnterxLeavex v113 => dfn'EnterxLeavex v113
7007       | HypervisorCall v114 => dfn'HypervisorCall v114
7008       | MoveToBankedOrSpecialRegister v115 =>
7009         dfn'MoveToBankedOrSpecialRegister v115
7010       | MoveToRegisterFromBankedOrSpecial v116 =>
7011         dfn'MoveToRegisterFromBankedOrSpecial v116
7012       | MoveToRegisterFromSpecial v117 =>
7013         dfn'MoveToRegisterFromSpecial v117
7014       | MoveToSpecialFromImmediate v118 =>
7015         dfn'MoveToSpecialFromImmediate v118
7016       | MoveToSpecialFromRegister v119 =>
7017         dfn'MoveToSpecialFromRegister v119
7018       | ReturnFromException v120 => dfn'ReturnFromException v120
7019       | SecureMonitorCall v121 => dfn'SecureMonitorCall v121
7020       | Setend v122 => dfn'Setend v122
7021       | StoreReturnState v123 => dfn'StoreReturnState v123
7022       | SupervisorCall v124 => dfn'SupervisorCall v124)
7023   | VFP v125 =>
7024     (case v125 of
7025         vabs v126 => dfn'vabs v126
7026       | vadd v127 => dfn'vadd v127
7027       | vcmp v128 => dfn'vcmp v128
7028       | vcvt_float v129 => dfn'vcvt_float v129
7029       | vcvt_from_integer v130 => dfn'vcvt_from_integer v130
7030       | vcvt_to_integer v131 => dfn'vcvt_to_integer v131
7031       | vdiv v132 => dfn'vdiv v132
7032       | vfma_vfms v133 => dfn'vfma_vfms v133
7033       | vfnma_vfnms v134 => dfn'vfnma_vfnms v134
7034       | vldm v135 => dfn'vldm v135
7035       | vldr v136 => dfn'vldr v136
7036       | vmla_vmls v137 => dfn'vmla_vmls v137
7037       | vmov v138 => dfn'vmov v138
7038       | vmov_double v139 => dfn'vmov_double v139
7039       | vmov_imm v140 => dfn'vmov_imm v140
7040       | vmov_single v141 => dfn'vmov_single v141
7041       | vmov_two_singles v142 => dfn'vmov_two_singles v142
7042       | vmrs v143 => dfn'vmrs v143
7043       | vmsr v144 => dfn'vmsr v144
7044       | vmul v145 => dfn'vmul v145
7045       | vneg v146 => dfn'vneg v146
7046       | vneg_mul v147 => dfn'vneg_mul v147
7047       | vsqrt v148 => dfn'vsqrt v148
7048       | vstm v149 => dfn'vstm v149
7049       | vstr v150 => dfn'vstr v150
7050       | vsub v151 => dfn'vsub v151);
7051
7052fun Fetch () =
7053  let
7054    val iset = CurrentInstrSet ()
7055  in
7056    if (iset = InstrSet_ARM) orelse ((!Architecture) = ARMv4)
7057      then ( Encoding := Encoding_ARM
7058           ; ARM(MemA 32 (Map.lookup((!REG),Cast.RNameToNat RName_PC),4))
7059           )
7060    else if iset = InstrSet_Jazelle
7061      then BadCode "Fetch"
7062    else let
7063           val fpc = Map.lookup((!REG),Cast.RNameToNat RName_PC)
7064           val ireg = MemA 16 (fpc,2)
7065         in
7066           if ((BitsN.bits(15,13) ireg) = (BitsN.B(0x7,3))) andalso
7067              (not((BitsN.bits(12,11) ireg) = (BitsN.B(0x0,2))))
7068             then ( Encoding := Encoding_Thumb2
7069                  ; Thumb2(ireg,MemA 16 (BitsN.+(fpc,BitsN.B(0x2,32)),2))
7070                  )
7071           else ( Encoding := Encoding_Thumb
7072                ; if (iset = InstrSet_Thumb) orelse (not(HaveThumbEE ()))
7073                    then Thumb ireg
7074                  else ThumbEE ireg
7075                )
7076         end
7077  end;
7078
7079fun Do (cond,defined) =
7080  ( CurrentCondition := cond
7081  ; let
7082      val pass = ConditionPassed ()
7083    in
7084      ( undefined := (pass andalso (not defined)); pass andalso defined )
7085    end
7086  );
7087
7088fun Skip () =
7089  if (!undefined) then Undefined(BitsN.B(0x0,32)) else NoOperation;
7090
7091fun UndefinedARM cond =
7092  ( CurrentCondition := cond
7093  ; if ConditionPassed () then Undefined(BitsN.B(0x0,32)) else NoOperation
7094  );
7095
7096fun UndefinedThumb () = UndefinedARM(ThumbCondition ());
7097
7098fun DECODE_UNPREDICTABLE (mc,s) =
7099  raise UNPREDICTABLE
7100    (String.concat
7101       ["Decode ",
7102        case mc of
7103           ARM opc =>
7104             (Bitstring.toBinString(BitsN.toBitstring opc)) ^ "; ARM; "
7105         | Thumb opc =>
7106           (Bitstring.toBinString(BitsN.toBitstring opc)) ^ "; Thumb; "
7107         | ThumbEE opc =>
7108           (Bitstring.toBinString(BitsN.toBitstring opc)) ^ "; ThumbEE; "
7109         | Thumb2(opc1,opc2) =>
7110           String.concat
7111             [Bitstring.toBinString(BitsN.toBitstring opc1),", ",
7112              Bitstring.toBinString(BitsN.toBitstring opc2),"; Thumb2; "]
7113         | BadCode x => x,s]);
7114
7115fun DecodeHint (cond,op') =
7116  if ((!Architecture) = ARMv6T2) orelse
7117     (((BitsN.bits(7,4) op') = (BitsN.B(0xF,4))) andalso
7118      (((!Encoding) = Encoding_ARM) andalso ((!Architecture) = ARMv6K)))
7119    then NoOperation
7120  else if Do(cond,
7121        (Nat.>=(ArchVersion (),7)) orelse
7122        (((!Encoding) = Encoding_ARM) andalso ((!Architecture) = ARMv6K)))
7123    then case boolify'8 op' of
7124            (false,(false,(false,(false,(false,(false,(false,true))))))) =>
7125              Hint Yield
7126          | (false,(false,(false,(false,(false,(false,(true,false))))))) =>
7127            Hint WaitForEvent
7128          | (false,(false,(false,(false,(false,(false,(true,true))))))) =>
7129            Hint WaitForInterrupt
7130          | (false,(false,(false,(false,(false,(true,(false,false))))))) =>
7131            Hint SendEvent
7132          | (true,
7133           (true,(true,(true,(option'3,(option'2,(option'1,option'0))))))) =>
7134            Hint
7135              (Debug
7136                 (BitsN.fromBitstring
7137                    ([option'3,option'2,option'1,option'0],4)))
7138          | _ => NoOperation
7139  else Skip ();
7140
7141fun DecodeParallelAdditionSubtraction (op1,(op2,(U,(Rd,(Rn,Rm))))) =
7142  if U = (BitsN.B(0x1,1))
7143    then case (op1,boolify'3 op2) of
7144            (BitsN.B(0x1,_),(false,(x'1,x'0))) =>
7145              SIMD
7146                (UnsignedAddSub16
7147                   (BitsN.fromBitstring([x'1,x'0],2),(Rd,(Rn,Rm))))
7148          | (BitsN.B(0x1,_),(true,(false,false))) =>
7149            SIMD(UnsignedAddSub8(false,(Rd,(Rn,Rm))))
7150          | (BitsN.B(0x1,_),(true,(true,true))) =>
7151            SIMD(UnsignedAddSub8(true,(Rd,(Rn,Rm))))
7152          | (BitsN.B(0x2,_),(false,(x'1,x'0))) =>
7153            SIMD
7154              (UnsignedSaturatingAddSub16
7155                 (BitsN.fromBitstring([x'1,x'0],2),(Rd,(Rn,Rm))))
7156          | (BitsN.B(0x2,_),(true,(false,false))) =>
7157            SIMD(UnsignedSaturatingAddSub8(false,(Rd,(Rn,Rm))))
7158          | (BitsN.B(0x2,_),(true,(true,true))) =>
7159            SIMD(UnsignedSaturatingAddSub8(true,(Rd,(Rn,Rm))))
7160          | (BitsN.B(0x3,_),(false,(x'1,x'0))) =>
7161            SIMD
7162              (UnsignedHalvingAddSub16
7163                 (BitsN.fromBitstring([x'1,x'0],2),(Rd,(Rn,Rm))))
7164          | (BitsN.B(0x3,_),(true,(false,false))) =>
7165            SIMD(UnsignedHalvingAddSub8(false,(Rd,(Rn,Rm))))
7166          | (BitsN.B(0x3,_),(true,(true,true))) =>
7167            SIMD(UnsignedHalvingAddSub8(true,(Rd,(Rn,Rm))))
7168          | _ => Undefined(BitsN.B(0x0,32))
7169  else case (op1,boolify'3 op2) of
7170          (BitsN.B(0x1,_),(false,(x'1,x'0))) =>
7171            SIMD
7172              (SignedAddSub16
7173                 (BitsN.fromBitstring([x'1,x'0],2),(Rd,(Rn,Rm))))
7174        | (BitsN.B(0x1,_),(true,(false,false))) =>
7175          SIMD(SignedAddSub8(false,(Rd,(Rn,Rm))))
7176        | (BitsN.B(0x1,_),(true,(true,true))) =>
7177          SIMD(SignedAddSub8(true,(Rd,(Rn,Rm))))
7178        | (BitsN.B(0x2,_),(false,(x'1,x'0))) =>
7179          SIMD
7180            (SignedSaturatingAddSub16
7181               (BitsN.fromBitstring([x'1,x'0],2),(Rd,(Rn,Rm))))
7182        | (BitsN.B(0x2,_),(true,(false,false))) =>
7183          SIMD(SignedSaturatingAddSub8(false,(Rd,(Rn,Rm))))
7184        | (BitsN.B(0x2,_),(true,(true,true))) =>
7185          SIMD(SignedSaturatingAddSub8(true,(Rd,(Rn,Rm))))
7186        | (BitsN.B(0x3,_),(false,(x'1,x'0))) =>
7187          SIMD
7188            (SignedHalvingAddSub16
7189               (BitsN.fromBitstring([x'1,x'0],2),(Rd,(Rn,Rm))))
7190        | (BitsN.B(0x3,_),(true,(false,false))) =>
7191          SIMD(SignedHalvingAddSub8(false,(Rd,(Rn,Rm))))
7192        | (BitsN.B(0x3,_),(true,(true,true))) =>
7193          SIMD(SignedHalvingAddSub8(true,(Rd,(Rn,Rm))))
7194        | _ => Undefined(BitsN.B(0x0,32));
7195
7196fun DecodeVFP w =
7197  case boolify'28(BitsN.bits(27,0) w) of
7198     (true,
7199      (true,
7200       (false,
7201        (false,
7202         (true,
7203          (D'0,
7204           (W'0,
7205            (L'0,
7206             (Rn'3,
7207              (Rn'2,
7208               (Rn'1,
7209                (Rn'0,
7210                 (Vd'3,
7211                  (Vd'2,
7212                   (Vd'1,
7213                    (Vd'0,
7214                     (true,
7215                      (false,
7216                       (true,
7217                        (sz'0,
7218                         (imm8'7,
7219                          (imm8'6,
7220                           (imm8'5,
7221                            (imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))))))))))))))) =>
7222       let
7223         val imm8 =
7224           BitsN.fromBitstring
7225             ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,imm8'1,imm8'0],8)
7226         val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7227         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
7228         val D = BitsN.fromBitstring([D'0],1)
7229         val single_regs =
7230           (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x0,1))
7231         val wback = (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
7232         val (d,regs) =
7233           if single_regs
7234             then (BitsN.@@(Vd,D),BitsN.toNat imm8)
7235           else (BitsN.@@(D,Vd),Nat.div(BitsN.toNat imm8,2))
7236         val unpred =
7237           if (regs = 0) orelse
7238              ((Nat.>(Nat.+(BitsN.toNat d,regs),32)) orelse
7239               ((wback andalso (Rn = (BitsN.B(0xF,4)))) orelse
7240                ((not single_regs) andalso
7241                 ((Nat.>(regs,16)) orelse (BitsN.bit(imm8,0))))))
7242             then "vpush/vpop"
7243           else ""
7244         val args = (single_regs,(true,(wback,(d,(Rn,imm8)))))
7245       in
7246         (not((!VFPExtension) = NoVFP),
7247          (unpred,
7248           VFP(if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
7249                 then vldm args
7250               else vstm args)))
7251       end
7252   | (true,
7253    (true,
7254     (false,
7255      (true,
7256       (false,
7257        (D'0,
7258         (true,
7259          (L'0,
7260           (Rn'3,
7261            (Rn'2,
7262             (Rn'1,
7263              (Rn'0,
7264               (Vd'3,
7265                (Vd'2,
7266                 (Vd'1,
7267                  (Vd'0,
7268                   (true,
7269                    (false,
7270                     (true,
7271                      (sz'0,
7272                       (imm8'7,
7273                        (imm8'6,
7274                         (imm8'5,
7275                          (imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))))))))))))))) =>
7276     let
7277       val imm8 =
7278         BitsN.fromBitstring
7279           ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,imm8'1,imm8'0],8)
7280       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7281       val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
7282       val D = BitsN.fromBitstring([D'0],1)
7283       val single_regs =
7284         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x0,1))
7285       val wback = true
7286       val (d,regs) =
7287         if single_regs
7288           then (BitsN.@@(Vd,D),BitsN.toNat imm8)
7289         else (BitsN.@@(D,Vd),Nat.div(BitsN.toNat imm8,2))
7290       val unpred =
7291         if (regs = 0) orelse
7292            ((Nat.>(Nat.+(BitsN.toNat d,regs),32)) orelse
7293             ((wback andalso (Rn = (BitsN.B(0xF,4)))) orelse
7294              ((not single_regs) andalso
7295               ((Nat.>(regs,16)) orelse (BitsN.bit(imm8,0))))))
7296           then "vpush/vpop"
7297         else ""
7298       val args = (single_regs,(false,(wback,(d,(Rn,imm8)))))
7299     in
7300       (not((!VFPExtension) = NoVFP),
7301        (unpred,
7302         VFP(if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
7303               then vldm args
7304             else vstm args)))
7305     end
7306   | (true,
7307    (true,
7308     (false,
7309      (true,
7310       (U'0,
7311        (D'0,
7312         (false,
7313          (L'0,
7314           (Rn'3,
7315            (Rn'2,
7316             (Rn'1,
7317              (Rn'0,
7318               (Vd'3,
7319                (Vd'2,
7320                 (Vd'1,
7321                  (Vd'0,
7322                   (true,
7323                    (false,
7324                     (true,
7325                      (sz'0,
7326                       (imm8'7,
7327                        (imm8'6,
7328                         (imm8'5,
7329                          (imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))))))))))))))) =>
7330     let
7331       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7332       val D = BitsN.fromBitstring([D'0],1)
7333       val single_reg = (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x0,1))
7334       val add = (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
7335       val imm32 =
7336         BitsN.zeroExtend 32
7337           (BitsN.@@
7338              (BitsN.fromBitstring
7339                 ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,imm8'1,imm8'0],
7340                  8),BitsN.B(0x0,2)))
7341       val d = if single_reg then BitsN.@@(Vd,D) else BitsN.@@(D,Vd)
7342       val args =
7343         (single_reg,
7344          (add,(d,(BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),imm32))))
7345     in
7346       (not((!VFPExtension) = NoVFP),
7347        ("",
7348         VFP(if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
7349               then vldr args
7350             else vstr args)))
7351     end
7352   | (true,
7353    (true,
7354     (true,
7355      (false,
7356       (false,
7357        (D'0,
7358         (op1'1,
7359          (op1'0,
7360           (Vn'3,
7361            (Vn'2,
7362             (Vn'1,
7363              (Vn'0,
7364               (Vd'3,
7365                (Vd'2,
7366                 (Vd'1,
7367                  (Vd'0,
7368                   (true,
7369                    (false,
7370                     (true,
7371                      (sz'0,
7372                       (N'0,
7373                        (op2'0,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7374     let
7375       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7376       val M = BitsN.fromBitstring([M'0],1)
7377       val op2 = BitsN.fromBitstring([op2'0],1)
7378       val N = BitsN.fromBitstring([N'0],1)
7379       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7380       val Vn = BitsN.fromBitstring([Vn'3,Vn'2,Vn'1,Vn'0],4)
7381       val D = BitsN.fromBitstring([D'0],1)
7382       val dp_operation =
7383         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7384       val (d,(n,m)) =
7385         if dp_operation
7386           then (BitsN.@@(D,Vd),(BitsN.@@(N,Vn),BitsN.@@(M,Vm)))
7387         else (BitsN.@@(Vd,D),(BitsN.@@(Vn,N),BitsN.@@(Vm,M)))
7388       val typ =
7389         if op2 = (BitsN.B(0x1,1))
7390           then VFPNegMul_VNMLA
7391         else VFPNegMul_VNMLS
7392     in
7393       (not((!VFPExtension) = NoVFP),
7394        ("",
7395         VFP(case BitsN.fromBitstring([op1'1,op1'0],2) of
7396                BitsN.B(0x0,_) =>
7397                  vmla_vmls
7398                    (dp_operation,(op2 = (BitsN.B(0x0,1)),(d,(n,m))))
7399              | BitsN.B(0x1,_) => vneg_mul(dp_operation,(typ,(d,(n,m))))
7400              | BitsN.B(0x2,_) =>
7401                if op2 = (BitsN.B(0x1,1))
7402                  then vneg_mul(dp_operation,(VFPNegMul_VNMUL,(d,(n,m))))
7403                else vmul(dp_operation,(d,(n,m)))
7404              | BitsN.B(0x3,_) =>
7405                if op2 = (BitsN.B(0x1,1))
7406                  then vsub(dp_operation,(d,(n,m)))
7407                else vadd(dp_operation,(d,(n,m)))
7408              | _ => raise General.Bind)))
7409     end
7410   | (true,
7411    (true,
7412     (true,
7413      (false,
7414       (true,
7415        (D'0,
7416         (false,
7417          (false,
7418           (Vn'3,
7419            (Vn'2,
7420             (Vn'1,
7421              (Vn'0,
7422               (Vd'3,
7423                (Vd'2,
7424                 (Vd'1,
7425                  (Vd'0,
7426                   (true,
7427                    (false,
7428                     (true,
7429                      (sz'0,
7430                       (N'0,
7431                        (false,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7432     let
7433       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7434       val M = BitsN.fromBitstring([M'0],1)
7435       val N = BitsN.fromBitstring([N'0],1)
7436       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7437       val Vn = BitsN.fromBitstring([Vn'3,Vn'2,Vn'1,Vn'0],4)
7438       val D = BitsN.fromBitstring([D'0],1)
7439       val dp_operation =
7440         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7441       val (d,(n,m)) =
7442         if dp_operation
7443           then (BitsN.@@(D,Vd),(BitsN.@@(N,Vn),BitsN.@@(M,Vm)))
7444         else (BitsN.@@(Vd,D),(BitsN.@@(Vn,N),BitsN.@@(Vm,M)))
7445     in
7446       (not((!VFPExtension) = NoVFP),
7447        ("",VFP(vdiv(dp_operation,(d,(n,m))))))
7448     end
7449   | (true,
7450    (true,
7451     (true,
7452      (false,
7453       (true,
7454        (D'0,
7455         (false,
7456          (true,
7457           (Vn'3,
7458            (Vn'2,
7459             (Vn'1,
7460              (Vn'0,
7461               (Vd'3,
7462                (Vd'2,
7463                 (Vd'1,
7464                  (Vd'0,
7465                   (true,
7466                    (false,
7467                     (true,
7468                      (sz'0,
7469                       (N'0,(op'0,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7470     let
7471       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7472       val M = BitsN.fromBitstring([M'0],1)
7473       val N = BitsN.fromBitstring([N'0],1)
7474       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7475       val Vn = BitsN.fromBitstring([Vn'3,Vn'2,Vn'1,Vn'0],4)
7476       val D = BitsN.fromBitstring([D'0],1)
7477       val dp_operation =
7478         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7479       val add = (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x0,1))
7480       val (d,(n,m)) =
7481         if dp_operation
7482           then (BitsN.@@(D,Vd),(BitsN.@@(N,Vn),BitsN.@@(M,Vm)))
7483         else (BitsN.@@(Vd,D),(BitsN.@@(Vn,N),BitsN.@@(Vm,M)))
7484     in
7485       ((!VFPExtension) = VFPv4,
7486        ("",VFP(vfnma_vfnms(dp_operation,(add,(d,(n,m)))))))
7487     end
7488   | (true,
7489    (true,
7490     (true,
7491      (false,
7492       (true,
7493        (D'0,
7494         (true,
7495          (false,
7496           (Vn'3,
7497            (Vn'2,
7498             (Vn'1,
7499              (Vn'0,
7500               (Vd'3,
7501                (Vd'2,
7502                 (Vd'1,
7503                  (Vd'0,
7504                   (true,
7505                    (false,
7506                     (true,
7507                      (sz'0,
7508                       (N'0,(op'0,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7509     let
7510       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7511       val M = BitsN.fromBitstring([M'0],1)
7512       val N = BitsN.fromBitstring([N'0],1)
7513       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7514       val Vn = BitsN.fromBitstring([Vn'3,Vn'2,Vn'1,Vn'0],4)
7515       val D = BitsN.fromBitstring([D'0],1)
7516       val dp_operation =
7517         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7518       val add = (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x0,1))
7519       val (d,(n,m)) =
7520         if dp_operation
7521           then (BitsN.@@(D,Vd),(BitsN.@@(N,Vn),BitsN.@@(M,Vm)))
7522         else (BitsN.@@(Vd,D),(BitsN.@@(Vn,N),BitsN.@@(Vm,M)))
7523     in
7524       ((!VFPExtension) = VFPv4,
7525        ("",VFP(vfma_vfms(dp_operation,(add,(d,(n,m)))))))
7526     end
7527   | (true,
7528    (true,
7529     (true,
7530      (false,
7531       (true,
7532        (D'0,
7533         (true,
7534          (true,
7535           (false,
7536            (false,
7537             (false,
7538              (false,
7539               (Vd'3,
7540                (Vd'2,
7541                 (Vd'1,
7542                  (Vd'0,
7543                   (true,
7544                    (false,
7545                     (true,
7546                      (sz'0,
7547                       (false,
7548                        (true,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7549     let
7550       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7551       val M = BitsN.fromBitstring([M'0],1)
7552       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7553       val D = BitsN.fromBitstring([D'0],1)
7554       val single_register =
7555         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x0,1))
7556       val (d,m) =
7557         if single_register
7558           then (BitsN.@@(Vd,D),BitsN.@@(Vm,M))
7559         else (BitsN.@@(D,Vd),BitsN.@@(M,Vm))
7560     in
7561       (not((!VFPExtension) = NoVFP),("",VFP(vmov(single_register,(d,m)))))
7562     end
7563   | (true,
7564    (true,
7565     (true,
7566      (false,
7567       (true,
7568        (D'0,
7569         (true,
7570          (true,
7571           (false,
7572            (false,
7573             (false,
7574              (false,
7575               (Vd'3,
7576                (Vd'2,
7577                 (Vd'1,
7578                  (Vd'0,
7579                   (true,
7580                    (false,
7581                     (true,
7582                      (sz'0,
7583                       (true,
7584                        (true,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7585     let
7586       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7587       val M = BitsN.fromBitstring([M'0],1)
7588       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7589       val D = BitsN.fromBitstring([D'0],1)
7590       val dp_operation =
7591         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7592       val (d,m) =
7593         if dp_operation
7594           then (BitsN.@@(D,Vd),BitsN.@@(M,Vm))
7595         else (BitsN.@@(Vd,D),BitsN.@@(Vm,M))
7596     in
7597       (not((!VFPExtension) = NoVFP),("",VFP(vabs(dp_operation,(d,m)))))
7598     end
7599   | (true,
7600    (true,
7601     (true,
7602      (false,
7603       (true,
7604        (D'0,
7605         (true,
7606          (true,
7607           (false,
7608            (false,
7609             (false,
7610              (true,
7611               (Vd'3,
7612                (Vd'2,
7613                 (Vd'1,
7614                  (Vd'0,
7615                   (true,
7616                    (false,
7617                     (true,
7618                      (sz'0,
7619                       (false,
7620                        (true,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7621     let
7622       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7623       val M = BitsN.fromBitstring([M'0],1)
7624       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7625       val D = BitsN.fromBitstring([D'0],1)
7626       val dp_operation =
7627         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7628       val (d,m) =
7629         if dp_operation
7630           then (BitsN.@@(D,Vd),BitsN.@@(M,Vm))
7631         else (BitsN.@@(Vd,D),BitsN.@@(Vm,M))
7632     in
7633       (not((!VFPExtension) = NoVFP),("",VFP(vneg(dp_operation,(d,m)))))
7634     end
7635   | (true,
7636    (true,
7637     (true,
7638      (false,
7639       (true,
7640        (D'0,
7641         (true,
7642          (true,
7643           (false,
7644            (false,
7645             (false,
7646              (true,
7647               (Vd'3,
7648                (Vd'2,
7649                 (Vd'1,
7650                  (Vd'0,
7651                   (true,
7652                    (false,
7653                     (true,
7654                      (sz'0,
7655                       (true,
7656                        (true,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7657     let
7658       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7659       val M = BitsN.fromBitstring([M'0],1)
7660       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7661       val D = BitsN.fromBitstring([D'0],1)
7662       val dp_operation =
7663         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7664       val (d,m) =
7665         if dp_operation
7666           then (BitsN.@@(D,Vd),BitsN.@@(M,Vm))
7667         else (BitsN.@@(Vd,D),BitsN.@@(Vm,M))
7668     in
7669       (not((!VFPExtension) = NoVFP),("",VFP(vsqrt(dp_operation,(d,m)))))
7670     end
7671   | (true,
7672    (true,
7673     (true,
7674      (false,
7675       (true,
7676        (D'0,
7677         (true,
7678          (true,
7679           (false,
7680            (true,
7681             (false,
7682              (false,
7683               (Vd'3,
7684                (Vd'2,
7685                 (Vd'1,
7686                  (Vd'0,
7687                   (true,
7688                    (false,
7689                     (true,
7690                      (sz'0,
7691                       (E'0,(true,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7692     let
7693       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7694       val M = BitsN.fromBitstring([M'0],1)
7695       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7696       val D = BitsN.fromBitstring([D'0],1)
7697     in
7698       if (BitsN.fromBitstring([E'0],1)) = (BitsN.B(0x1,1))
7699         then let
7700                val dp_operation =
7701                  (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7702                val (d,m) =
7703                  if dp_operation
7704                    then (BitsN.@@(D,Vd),BitsN.@@(M,Vm))
7705                  else (BitsN.@@(Vd,D),BitsN.@@(Vm,M))
7706              in
7707                (not((!VFPExtension) = NoVFP),
7708                 ("",VFP(vcmp(dp_operation,(d,Option.SOME m)))))
7709              end
7710       else (false,("",Undefined(BitsN.B(0x0,32))))
7711     end
7712   | (true,
7713    (true,
7714     (true,
7715      (false,
7716       (true,
7717        (D'0,
7718         (true,
7719          (true,
7720           (false,
7721            (true,
7722             (false,
7723              (true,
7724               (Vd'3,
7725                (Vd'2,
7726                 (Vd'1,
7727                  (Vd'0,
7728                   (true,
7729                    (false,
7730                     (true,
7731                      (sz'0,
7732                       (E'0,
7733                        (true,
7734                         (sb'0'0'0,
7735                          (false,
7736                           (sb'1'0000'3,
7737                            (sb'1'0000'2,(sb'1'0000'1,sb'1'0000'0))))))))))))))))))))))))))) =>
7738     let
7739       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7740       val D = BitsN.fromBitstring([D'0],1)
7741       val GOOD_MATCH =
7742         ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
7743         ((BitsN.fromBitstring
7744             ([sb'1'0000'3,sb'1'0000'2,sb'1'0000'1,sb'1'0000'0],4)) =
7745          (BitsN.B(0x0,4)))
7746     in
7747       if (BitsN.fromBitstring([E'0],1)) = (BitsN.B(0x1,1))
7748         then let
7749                val dp_operation =
7750                  (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7751                val d =
7752                  if dp_operation then BitsN.@@(D,Vd) else BitsN.@@(Vd,D)
7753              in
7754                (not((!VFPExtension) = NoVFP),
7755                 (if GOOD_MATCH then "" else "vcmp",
7756                  VFP(vcmp(dp_operation,(d,NONE)))))
7757              end
7758       else (false,("",Undefined(BitsN.B(0x0,32))))
7759     end
7760   | (true,
7761    (true,
7762     (true,
7763      (false,
7764       (true,
7765        (D'0,
7766         (true,
7767          (true,
7768           (false,
7769            (true,
7770             (true,
7771              (true,
7772               (Vd'3,
7773                (Vd'2,
7774                 (Vd'1,
7775                  (Vd'0,
7776                   (true,
7777                    (false,
7778                     (true,
7779                      (sz'0,
7780                       (true,
7781                        (true,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7782     let
7783       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7784       val M = BitsN.fromBitstring([M'0],1)
7785       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7786       val D = BitsN.fromBitstring([D'0],1)
7787       val double_to_single =
7788         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7789       val (d,m) =
7790         if double_to_single
7791           then (BitsN.@@(Vd,D),BitsN.@@(M,Vm))
7792         else (BitsN.@@(D,Vd),BitsN.@@(Vm,M))
7793     in
7794       (not((!VFPExtension) = NoVFP),
7795        ("",VFP(vcvt_float(double_to_single,(d,m)))))
7796     end
7797   | (true,
7798    (true,
7799     (true,
7800      (false,
7801       (true,
7802        (D'0,
7803         (true,
7804          (true,
7805           (true,
7806            (false,
7807             (false,
7808              (false,
7809               (Vd'3,
7810                (Vd'2,
7811                 (Vd'1,
7812                  (Vd'0,
7813                   (true,
7814                    (false,
7815                     (true,
7816                      (sz'0,
7817                       (op'0,
7818                        (true,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7819     let
7820       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7821       val D = BitsN.fromBitstring([D'0],1)
7822       val unsigned = (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x0,1))
7823       val dp_operation =
7824         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7825       val m =
7826         BitsN.@@
7827           (BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4),
7828            BitsN.fromBitstring([M'0],1))
7829       val d = if dp_operation then BitsN.@@(D,Vd) else BitsN.@@(Vd,D)
7830     in
7831       (not((!VFPExtension) = NoVFP),
7832        ("",VFP(vcvt_from_integer(dp_operation,(unsigned,(d,m))))))
7833     end
7834   | (true,
7835    (true,
7836     (true,
7837      (false,
7838       (true,
7839        (D'0,
7840         (true,
7841          (true,
7842           (true,
7843            (true,
7844             (false,
7845              (u'0,
7846               (Vd'3,
7847                (Vd'2,
7848                 (Vd'1,
7849                  (Vd'0,
7850                   (true,
7851                    (false,
7852                     (true,
7853                      (sz'0,
7854                       (op'0,
7855                        (true,(M'0,(false,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7856     let
7857       val Vm = BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4)
7858       val M = BitsN.fromBitstring([M'0],1)
7859       val unsigned = (BitsN.fromBitstring([u'0],1)) = (BitsN.B(0x0,1))
7860       val round_zero = (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x1,1))
7861       val dp_operation =
7862         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x1,1))
7863       val d =
7864         BitsN.@@
7865           (BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4),
7866            BitsN.fromBitstring([D'0],1))
7867       val m = if dp_operation then BitsN.@@(M,Vm) else BitsN.@@(Vm,M)
7868     in
7869       (not((!VFPExtension) = NoVFP),
7870        ("",
7871         VFP(vcvt_to_integer(dp_operation,(unsigned,(round_zero,(d,m)))))))
7872     end
7873   | (true,
7874    (true,
7875     (true,
7876      (false,
7877       (true,
7878        (D'0,
7879         (true,
7880          (true,
7881           (imm4H'3,
7882            (imm4H'2,
7883             (imm4H'1,
7884              (imm4H'0,
7885               (Vd'3,
7886                (Vd'2,
7887                 (Vd'1,
7888                  (Vd'0,
7889                   (true,
7890                    (false,
7891                     (true,
7892                      (sz'0,
7893                       (sb'0'0'0,
7894                        (false,
7895                         (sb'1'0'0,
7896                          (false,(imm4L'3,(imm4L'2,(imm4L'1,imm4L'0))))))))))))))))))))))))))) =>
7897     let
7898       val Vd = BitsN.fromBitstring([Vd'3,Vd'2,Vd'1,Vd'0],4)
7899       val D = BitsN.fromBitstring([D'0],1)
7900       val GOOD_MATCH =
7901         ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
7902         ((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1)))
7903       val single_register =
7904         (BitsN.fromBitstring([sz'0],1)) = (BitsN.B(0x0,1))
7905       val imm64 =
7906         VFPExpandImm
7907           (BitsN.@@
7908              (BitsN.fromBitstring([imm4H'3,imm4H'2,imm4H'1,imm4H'0],4),
7909               BitsN.fromBitstring([imm4L'3,imm4L'2,imm4L'1,imm4L'0],4)),
7910            single_register)
7911       val d = if single_register then BitsN.@@(Vd,D) else BitsN.@@(D,Vd)
7912     in
7913       (Set.mem((!VFPExtension),[VFPv3,VFPv4]),
7914        (if GOOD_MATCH then "" else "vmov (imm",
7915         VFP(vmov_imm(single_register,(d,imm64)))))
7916     end
7917   | (true,
7918    (true,
7919     (true,
7920      (false,
7921       (false,
7922        (false,
7923         (false,
7924          (op'0,
7925           (Vn'3,
7926            (Vn'2,
7927             (Vn'1,
7928              (Vn'0,
7929               (Rt'3,
7930                (Rt'2,
7931                 (Rt'1,
7932                  (Rt'0,
7933                   (true,
7934                    (false,
7935                     (true,
7936                      (false,
7937                       (N'0,
7938                        (sb'0'00'1,
7939                         (sb'0'00'0,
7940                          (true,
7941                           (sb'1'0000'3,
7942                            (sb'1'0000'2,(sb'1'0000'1,sb'1'0000'0))))))))))))))))))))))))))) =>
7943     let
7944       val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
7945       val GOOD_MATCH =
7946         ((BitsN.fromBitstring([sb'0'00'1,sb'0'00'0],2)) =
7947          (BitsN.B(0x0,2))) andalso
7948         ((BitsN.fromBitstring
7949             ([sb'1'0000'3,sb'1'0000'2,sb'1'0000'1,sb'1'0000'0],4)) =
7950          (BitsN.B(0x0,4)))
7951       val to_arm_register =
7952         (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x1,1))
7953       val n =
7954         BitsN.@@
7955           (BitsN.fromBitstring([Vn'3,Vn'2,Vn'1,Vn'0],4),
7956            BitsN.fromBitstring([N'0],1))
7957       val unpred =
7958         if (Rt = (BitsN.B(0xF,4))) andalso (not GOOD_MATCH)
7959           then "vmov_single"
7960         else ""
7961     in
7962       (not((!VFPExtension) = NoVFP),
7963        (unpred,VFP(vmov_single(to_arm_register,(Rt,n)))))
7964     end
7965   | (true,
7966    (true,
7967     (false,
7968      (false,
7969       (false,
7970        (true,
7971         (false,
7972          (op'0,
7973           (Rt2'3,
7974            (Rt2'2,
7975             (Rt2'1,
7976              (Rt2'0,
7977               (Rt'3,
7978                (Rt'2,
7979                 (Rt'1,
7980                  (Rt'0,
7981                   (true,
7982                    (false,
7983                     (true,
7984                      (false,
7985                       (false,
7986                        (false,(M'0,(true,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
7987     let
7988       val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
7989       val Rt2 = BitsN.fromBitstring([Rt2'3,Rt2'2,Rt2'1,Rt2'0],4)
7990       val m =
7991         BitsN.@@
7992           (BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4),
7993            BitsN.fromBitstring([M'0],1))
7994       val to_arm_registers =
7995         (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x1,1))
7996       val unpred =
7997         if (Rt = (BitsN.B(0xF,4))) orelse
7998            ((Rt2 = (BitsN.B(0xF,4))) orelse
7999             ((m = (BitsN.B(0x1F,5))) orelse
8000              (to_arm_registers andalso (Rt = Rt2))))
8001           then "vmov_two_singles"
8002         else ""
8003     in
8004       (not((!VFPExtension) = NoVFP),
8005        (unpred,VFP(vmov_two_singles(to_arm_registers,(Rt,(Rt2,m))))))
8006     end
8007   | (true,
8008    (true,
8009     (false,
8010      (false,
8011       (false,
8012        (true,
8013         (false,
8014          (op'0,
8015           (Rt2'3,
8016            (Rt2'2,
8017             (Rt2'1,
8018              (Rt2'0,
8019               (Rt'3,
8020                (Rt'2,
8021                 (Rt'1,
8022                  (Rt'0,
8023                   (true,
8024                    (false,
8025                     (true,
8026                      (true,
8027                       (false,
8028                        (false,(M'0,(true,(Vm'3,(Vm'2,(Vm'1,Vm'0))))))))))))))))))))))))))) =>
8029     let
8030       val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
8031       val Rt2 = BitsN.fromBitstring([Rt2'3,Rt2'2,Rt2'1,Rt2'0],4)
8032       val m =
8033         BitsN.@@
8034           (BitsN.fromBitstring([M'0],1),
8035            BitsN.fromBitstring([Vm'3,Vm'2,Vm'1,Vm'0],4))
8036       val to_arm_registers =
8037         (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x1,1))
8038       val unpred =
8039         if (Rt = (BitsN.B(0xF,4))) orelse
8040            ((Rt2 = (BitsN.B(0xF,4))) orelse
8041             (to_arm_registers andalso (Rt = Rt2)))
8042           then "vmov_double"
8043         else ""
8044     in
8045       (not((!VFPExtension) = NoVFP),
8046        (unpred,VFP(vmov_double(to_arm_registers,(Rt,(Rt2,m))))))
8047     end
8048   | (true,
8049    (true,
8050     (true,
8051      (false,
8052       (true,
8053        (true,
8054         (true,
8055          (L'0,
8056           (false,
8057            (false,
8058             (false,
8059              (true,
8060               (Rt'3,
8061                (Rt'2,
8062                 (Rt'1,
8063                  (Rt'0,
8064                   (true,
8065                    (false,
8066                     (true,
8067                      (false,
8068                       (sb'0'000'2,
8069                        (sb'0'000'1,
8070                         (sb'0'000'0,
8071                          (true,
8072                           (sb'1'0000'3,
8073                            (sb'1'0000'2,(sb'1'0000'1,sb'1'0000'0))))))))))))))))))))))))))) =>
8074     let
8075       val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
8076       val GOOD_MATCH =
8077         ((BitsN.fromBitstring([sb'0'000'2,sb'0'000'1,sb'0'000'0],3)) =
8078          (BitsN.B(0x0,3))) andalso
8079         ((BitsN.fromBitstring
8080             ([sb'1'0000'3,sb'1'0000'2,sb'1'0000'1,sb'1'0000'0],4)) =
8081          (BitsN.B(0x0,4)))
8082     in
8083       if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
8084         then (not((!VFPExtension) = NoVFP),
8085               (if GOOD_MATCH then "" else "mrs",VFP(vmrs Rt)))
8086       else let
8087              val unpred =
8088                if (Rt = (BitsN.B(0xF,4))) andalso (not GOOD_MATCH)
8089                  then "msr"
8090                else ""
8091            in
8092              (not((!VFPExtension) = NoVFP),(unpred,VFP(vmsr Rt)))
8093            end
8094     end
8095   | _ => (false,("",Undefined(BitsN.B(0x0,32))));
8096
8097fun DecodeARM w =
8098  let
8099    val mc = ARM w
8100    val cond = BitsN.bits(31,28) w
8101  in
8102    if cond = (BitsN.B(0xF,4))
8103      then case boolify'28(BitsN.bits(27,0) w) of
8104              (false,
8105               (false,
8106                (false,
8107                 (true,
8108                  (false,
8109                   (false,
8110                    (false,
8111                     (false,
8112                      (sb'0'000'2,
8113                       (sb'0'000'1,
8114                        (sb'0'000'0,
8115                         (true,
8116                          (sb'1'000000'5,
8117                           (sb'1'000000'4,
8118                            (sb'1'000000'3,
8119                             (sb'1'000000'2,
8120                              (sb'1'000000'1,
8121                               (sb'1'000000'0,
8122                                (E'0,
8123                                 (sb'2'0'0,
8124                                  (false,
8125                                   (false,
8126                                    (false,
8127                                     (false,
8128                                      (sb'3'0000'3,
8129                                       (sb'3'0000'2,
8130                                        (sb'3'0000'1,sb'3'0000'0))))))))))))))))))))))))))) =>
8131                let
8132                  val GOOD_MATCH =
8133                    ((BitsN.fromBitstring
8134                        ([sb'0'000'2,sb'0'000'1,sb'0'000'0],3)) =
8135                     (BitsN.B(0x0,3))) andalso
8136                    (((BitsN.fromBitstring
8137                         ([sb'1'000000'5,sb'1'000000'4,sb'1'000000'3,
8138                           sb'1'000000'2,sb'1'000000'1,sb'1'000000'0],6)) =
8139                      (BitsN.B(0x0,6))) andalso
8140                     (((BitsN.fromBitstring([sb'2'0'0],1)) =
8141                       (BitsN.B(0x0,1))) andalso
8142                      ((BitsN.fromBitstring
8143                          ([sb'3'0000'3,sb'3'0000'2,sb'3'0000'1,
8144                            sb'3'0000'0],4)) = (BitsN.B(0x0,4)))))
8145                in
8146                  if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),6))
8147                    then ( if not GOOD_MATCH
8148                             then DECODE_UNPREDICTABLE(mc,"SETEND")
8149                           else ()
8150                         ; System
8151                             (Setend
8152                                ((BitsN.fromBitstring([E'0],1)) =
8153                                 (BitsN.B(0x1,1))))
8154                         )
8155                  else Skip ()
8156                end
8157            | (false,
8158             (false,
8159              (false,
8160               (true,
8161                (false,
8162                 (false,
8163                  (false,
8164                   (false,
8165                    (imod'1,
8166                     (imod'0,
8167                      (M'0,
8168                       (false,
8169                        (sb'0'0000000'6,
8170                         (sb'0'0000000'5,
8171                          (sb'0'0000000'4,
8172                           (sb'0'0000000'3,
8173                            (sb'0'0000000'2,
8174                             (sb'0'0000000'1,
8175                              (sb'0'0000000'0,
8176                               (A'0,
8177                                (I'0,
8178                                 (F'0,
8179                                  (false,
8180                                   (mode'4,
8181                                    (mode'3,(mode'2,(mode'1,mode'0))))))))))))))))))))))))))) =>
8182              let
8183                val mode =
8184                  BitsN.fromBitstring
8185                    ([mode'4,mode'3,mode'2,mode'1,mode'0],5)
8186                val F = BitsN.fromBitstring([F'0],1)
8187                val I = BitsN.fromBitstring([I'0],1)
8188                val A = BitsN.fromBitstring([A'0],1)
8189                val M = BitsN.fromBitstring([M'0],1)
8190                val imod = BitsN.fromBitstring([imod'1,imod'0],2)
8191                val GOOD_MATCH =
8192                  (BitsN.fromBitstring
8193                     ([sb'0'0000000'6,sb'0'0000000'5,sb'0'0000000'4,
8194                       sb'0'0000000'3,sb'0'0000000'2,sb'0'0000000'1,
8195                       sb'0'0000000'0],7)) = (BitsN.B(0x0,7))
8196              in
8197                if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),6))
8198                  then ( if ((not(mode = (BitsN.B(0x0,5)))) andalso
8199                             (M = (BitsN.B(0x0,1)))) orelse
8200                            (((BitsN.bit(imod,1)) =
8201                              ((BitsN.concat[A,I,F]) = (BitsN.B(0x0,3)))) orelse
8202                             (((imod = (BitsN.B(0x0,2))) andalso
8203                               (M = (BitsN.B(0x0,1)))) orelse
8204                              ((imod = (BitsN.B(0x1,2))) orelse
8205                               (not GOOD_MATCH))))
8206                           then DECODE_UNPREDICTABLE
8207                                  (mc,"ChangeProcessorState")
8208                         else ()
8209                       ; let
8210                           val enable = imod = (BitsN.B(0x2,2))
8211                           val disable = imod = (BitsN.B(0x3,2))
8212                           val affectA = A = (BitsN.B(0x1,1))
8213                           val affectI = I = (BitsN.B(0x1,1))
8214                           val affectF = F = (BitsN.B(0x1,1))
8215                           val changemode =
8216                             if M = (BitsN.B(0x1,1))
8217                               then Option.SOME mode
8218                             else NONE
8219                         in
8220                           System
8221                             (ChangeProcessorState
8222                                (enable,
8223                                 (disable,
8224                                  (affectA,(affectI,(affectF,changemode))))))
8225                         end
8226                       )
8227                else Skip ()
8228              end
8229            | (false,
8230             (true,
8231              (false,
8232               (false,
8233                (U'0,
8234                 (true,
8235                  (false,
8236                   (true,
8237                    (Rn'3,
8238                     (Rn'2,
8239                      (Rn'1,
8240                       (Rn'0,
8241                        (sb'0'1111'3,
8242                         (sb'0'1111'2,
8243                          (sb'0'1111'1,
8244                           (sb'0'1111'0,
8245                            (imm12'11,
8246                             (imm12'10,
8247                              (imm12'9,
8248                               (imm12'8,
8249                                (imm12'7,
8250                                 (imm12'6,
8251                                  (imm12'5,
8252                                   (imm12'4,
8253                                    (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
8254              let
8255                val GOOD_MATCH =
8256                  (BitsN.fromBitstring
8257                     ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
8258                  (BitsN.B(0xF,4))
8259              in
8260                if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),7))
8261                  then ( if not GOOD_MATCH
8262                           then DECODE_UNPREDICTABLE(mc,"PLI")
8263                         else ()
8264                       ; let
8265                           val add =
8266                             (BitsN.fromBitstring([U'0],1)) =
8267                             (BitsN.B(0x1,1))
8268                           val imm32 =
8269                             BitsN.zeroExtend 32
8270                               (BitsN.fromBitstring
8271                                  ([imm12'11,imm12'10,imm12'9,imm12'8,
8272                                    imm12'7,imm12'6,imm12'5,imm12'4,
8273                                    imm12'3,imm12'2,imm12'1,imm12'0],12))
8274                         in
8275                           Hint
8276                             (PreloadInstruction
8277                                (add,
8278                                 (BitsN.fromBitstring
8279                                    ([Rn'3,Rn'2,Rn'1,Rn'0],4),
8280                                  immediate_form1 imm32)))
8281                         end
8282                       )
8283                else Skip ()
8284              end
8285            | (false,
8286             (true,
8287              (true,
8288               (false,
8289                (U'0,
8290                 (true,
8291                  (false,
8292                   (true,
8293                    (Rn'3,
8294                     (Rn'2,
8295                      (Rn'1,
8296                       (Rn'0,
8297                        (sb'0'1111'3,
8298                         (sb'0'1111'2,
8299                          (sb'0'1111'1,
8300                           (sb'0'1111'0,
8301                            (imm5'4,
8302                             (imm5'3,
8303                              (imm5'2,
8304                               (imm5'1,
8305                                (imm5'0,
8306                                 (typ'1,
8307                                  (typ'0,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
8308              let
8309                val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
8310                val GOOD_MATCH =
8311                  (BitsN.fromBitstring
8312                     ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
8313                  (BitsN.B(0xF,4))
8314              in
8315                if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),7))
8316                  then ( if (Rm = (BitsN.B(0xF,4))) orelse
8317                            (not GOOD_MATCH)
8318                           then DECODE_UNPREDICTABLE
8319                                  (mc,"PreloadInstruction (register)")
8320                         else ()
8321                       ; let
8322                           val add =
8323                             (BitsN.fromBitstring([U'0],1)) =
8324                             (BitsN.B(0x1,1))
8325                           val (shift_t,shift_n) =
8326                             DecodeImmShift
8327                               (BitsN.fromBitstring([typ'1,typ'0],2),
8328                                BitsN.fromBitstring
8329                                  ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
8330                           val m = register_form1(Rm,(shift_t,shift_n))
8331                         in
8332                           Hint
8333                             (PreloadInstruction
8334                                (add,
8335                                 (BitsN.fromBitstring
8336                                    ([Rn'3,Rn'2,Rn'1,Rn'0],4),m)))
8337                         end
8338                       )
8339                else Skip ()
8340              end
8341            | (false,
8342             (true,
8343              (false,
8344               (true,
8345                (false,
8346                 (true,
8347                  (true,
8348                   (true,
8349                    (sb'0'1'0,
8350                     (sb'1'111'2,
8351                      (sb'1'111'1,
8352                       (sb'1'111'0,
8353                        (sb'2'1111'3,
8354                         (sb'2'1111'2,
8355                          (sb'2'1111'1,
8356                           (sb'2'1111'0,
8357                            (sb'3'0000'3,
8358                             (sb'3'0000'2,
8359                              (sb'3'0000'1,
8360                               (sb'3'0000'0,
8361                                (false,
8362                                 (false,
8363                                  (false,
8364                                   (true,
8365                                    (sb'4'1111'3,
8366                                     (sb'4'1111'2,
8367                                      (sb'4'1111'1,sb'4'1111'0))))))))))))))))))))))))))) =>
8368              let
8369                val GOOD_MATCH =
8370                  ((BitsN.fromBitstring([sb'0'1'0],1)) = (BitsN.B(0x1,1))) andalso
8371                  (((BitsN.fromBitstring
8372                       ([sb'1'111'2,sb'1'111'1,sb'1'111'0],3)) =
8373                    (BitsN.B(0x7,3))) andalso
8374                   (((BitsN.fromBitstring
8375                        ([sb'2'1111'3,sb'2'1111'2,sb'2'1111'1,sb'2'1111'0],
8376                         4)) = (BitsN.B(0xF,4))) andalso
8377                    (((BitsN.fromBitstring
8378                         ([sb'3'0000'3,sb'3'0000'2,sb'3'0000'1,sb'3'0000'0],
8379                          4)) = (BitsN.B(0x0,4))) andalso
8380                     ((BitsN.fromBitstring
8381                         ([sb'4'1111'3,sb'4'1111'2,sb'4'1111'1,sb'4'1111'0],
8382                          4)) = (BitsN.B(0xF,4))))))
8383              in
8384                if Do(BitsN.B(0xE,4),
8385                      Set.mem((!Architecture),[ARMv6K,ARMv7_A,ARMv7_R]))
8386                  then ( if not GOOD_MATCH
8387                           then DECODE_UNPREDICTABLE(mc,"CLREX")
8388                         else ()
8389                       ; ClearExclusive
8390                       )
8391                else Skip ()
8392              end
8393            | (false,
8394             (true,
8395              (false,
8396               (true,
8397                (false,
8398                 (true,
8399                  (true,
8400                   (true,
8401                    (true,
8402                     (true,
8403                      (true,
8404                       (true,
8405                        (true,
8406                         (true,
8407                          (true,
8408                           (true,
8409                            (false,
8410                             (false,
8411                              (false,
8412                               (false,
8413                                (false,
8414                                 (true,
8415                                  (false,
8416                                   (false,
8417                                    (option'3,
8418                                     (option'2,(option'1,option'0))))))))))))))))))))))))))) =>
8419              (if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),7))
8420                 then Hint
8421                        (DataSynchronizationBarrier
8422                           (BitsN.fromBitstring
8423                              ([option'3,option'2,option'1,option'0],4)))
8424               else Skip ())
8425            | (false,
8426             (true,
8427              (false,
8428               (true,
8429                (false,
8430                 (true,
8431                  (true,
8432                   (true,
8433                    (sb'0'1111'3,
8434                     (sb'0'1111'2,
8435                      (sb'0'1111'1,
8436                       (sb'0'1111'0,
8437                        (sb'1'1111'3,
8438                         (sb'1'1111'2,
8439                          (sb'1'1111'1,
8440                           (sb'1'1111'0,
8441                            (sb'2'0000'3,
8442                             (sb'2'0000'2,
8443                              (sb'2'0000'1,
8444                               (sb'2'0000'0,
8445                                (false,
8446                                 (true,
8447                                  (false,
8448                                   (true,
8449                                    (option'3,
8450                                     (option'2,(option'1,option'0))))))))))))))))))))))))))) =>
8451              let
8452                val GOOD_MATCH =
8453                  ((BitsN.fromBitstring
8454                      ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
8455                   (BitsN.B(0xF,4))) andalso
8456                  (((BitsN.fromBitstring
8457                       ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],
8458                        4)) = (BitsN.B(0xF,4))) andalso
8459                   ((BitsN.fromBitstring
8460                       ([sb'2'0000'3,sb'2'0000'2,sb'2'0000'1,sb'2'0000'0],
8461                        4)) = (BitsN.B(0x0,4))))
8462              in
8463                if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),7))
8464                  then ( if not GOOD_MATCH
8465                           then DECODE_UNPREDICTABLE(mc,"DMB")
8466                         else ()
8467                       ; Hint
8468                           (DataMemoryBarrier
8469                              (BitsN.fromBitstring
8470                                 ([option'3,option'2,option'1,option'0],4)))
8471                       )
8472                else Skip ()
8473              end
8474            | (false,
8475             (true,
8476              (false,
8477               (true,
8478                (false,
8479                 (true,
8480                  (true,
8481                   (true,
8482                    (sb'0'1111'3,
8483                     (sb'0'1111'2,
8484                      (sb'0'1111'1,
8485                       (sb'0'1111'0,
8486                        (sb'1'1111'3,
8487                         (sb'1'1111'2,
8488                          (sb'1'1111'1,
8489                           (sb'1'1111'0,
8490                            (sb'2'0000'3,
8491                             (sb'2'0000'2,
8492                              (sb'2'0000'1,
8493                               (sb'2'0000'0,
8494                                (false,
8495                                 (true,
8496                                  (true,
8497                                   (false,
8498                                    (option'3,
8499                                     (option'2,(option'1,option'0))))))))))))))))))))))))))) =>
8500              let
8501                val GOOD_MATCH =
8502                  ((BitsN.fromBitstring
8503                      ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
8504                   (BitsN.B(0xF,4))) andalso
8505                  (((BitsN.fromBitstring
8506                       ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],
8507                        4)) = (BitsN.B(0xF,4))) andalso
8508                   ((BitsN.fromBitstring
8509                       ([sb'2'0000'3,sb'2'0000'2,sb'2'0000'1,sb'2'0000'0],
8510                        4)) = (BitsN.B(0x0,4))))
8511              in
8512                if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),7))
8513                  then ( if not GOOD_MATCH
8514                           then DECODE_UNPREDICTABLE(mc,"ISB")
8515                         else ()
8516                       ; Hint
8517                           (InstructionSynchronizationBarrier
8518                              (BitsN.fromBitstring
8519                                 ([option'3,option'2,option'1,option'0],4)))
8520                       )
8521                else Skip ()
8522              end
8523            | (false,
8524             (true,
8525              (false,
8526               (true,
8527                (U'0,
8528                 (sb'0'1'0,
8529                  (false,
8530                   (true,
8531                    (true,
8532                     (true,
8533                      (true,
8534                       (true,
8535                        (sb'1'1111'3,
8536                         (sb'1'1111'2,
8537                          (sb'1'1111'1,
8538                           (sb'1'1111'0,
8539                            (imm12'11,
8540                             (imm12'10,
8541                              (imm12'9,
8542                               (imm12'8,
8543                                (imm12'7,
8544                                 (imm12'6,
8545                                  (imm12'5,
8546                                   (imm12'4,
8547                                    (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
8548              let
8549                val GOOD_MATCH =
8550                  ((BitsN.fromBitstring([sb'0'1'0],1)) = (BitsN.B(0x1,1))) andalso
8551                  ((BitsN.fromBitstring
8552                      ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
8553                   (BitsN.B(0xF,4)))
8554              in
8555                if Do(BitsN.B(0xE,4),HaveDSPSupport ())
8556                  then ( if not GOOD_MATCH
8557                           then DECODE_UNPREDICTABLE(mc,"PLD")
8558                         else ()
8559                       ; let
8560                           val add =
8561                             (BitsN.fromBitstring([U'0],1)) =
8562                             (BitsN.B(0x1,1))
8563                           val imm32 =
8564                             BitsN.zeroExtend 32
8565                               (BitsN.fromBitstring
8566                                  ([imm12'11,imm12'10,imm12'9,imm12'8,
8567                                    imm12'7,imm12'6,imm12'5,imm12'4,
8568                                    imm12'3,imm12'2,imm12'1,imm12'0],12))
8569                         in
8570                           Hint(PreloadDataLiteral(add,imm32))
8571                         end
8572                       )
8573                else Skip ()
8574              end
8575            | (false,
8576             (true,
8577              (false,
8578               (true,
8579                (U'0,
8580                 (R'0,
8581                  (false,
8582                   (true,
8583                    (Rn'3,
8584                     (Rn'2,
8585                      (Rn'1,
8586                       (Rn'0,
8587                        (sb'0'1111'3,
8588                         (sb'0'1111'2,
8589                          (sb'0'1111'1,
8590                           (sb'0'1111'0,
8591                            (imm12'11,
8592                             (imm12'10,
8593                              (imm12'9,
8594                               (imm12'8,
8595                                (imm12'7,
8596                                 (imm12'6,
8597                                  (imm12'5,
8598                                   (imm12'4,
8599                                    (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
8600              let
8601                val R = BitsN.fromBitstring([R'0],1)
8602                val GOOD_MATCH =
8603                  (BitsN.fromBitstring
8604                     ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
8605                  (BitsN.B(0xF,4))
8606              in
8607                if Do(BitsN.B(0xE,4),
8608                      ((R = (BitsN.B(0x1,1))) andalso
8609                       ((Nat.>=(ArchVersion (),7)) andalso
8610                        (Set.mem(Extension_Multiprocessing,(!Extensions))))) orelse
8611                      ((R = (BitsN.B(0x0,1))) andalso (HaveDSPSupport ())))
8612                  then ( if not GOOD_MATCH
8613                           then DECODE_UNPREDICTABLE(mc,"PLD")
8614                         else ()
8615                       ; let
8616                           val add =
8617                             (BitsN.fromBitstring([U'0],1)) =
8618                             (BitsN.B(0x1,1))
8619                           val is_pldw = R = (BitsN.B(0x0,1))
8620                           val imm32 =
8621                             BitsN.zeroExtend 32
8622                               (BitsN.fromBitstring
8623                                  ([imm12'11,imm12'10,imm12'9,imm12'8,
8624                                    imm12'7,imm12'6,imm12'5,imm12'4,
8625                                    imm12'3,imm12'2,imm12'1,imm12'0],12))
8626                         in
8627                           Hint
8628                             (PreloadData
8629                                (add,
8630                                 (is_pldw,
8631                                  (BitsN.fromBitstring
8632                                     ([Rn'3,Rn'2,Rn'1,Rn'0],4),
8633                                   immediate_form1 imm32))))
8634                         end
8635                       )
8636                else Skip ()
8637              end
8638            | (false,
8639             (true,
8640              (true,
8641               (true,
8642                (U'0,
8643                 (R'0,
8644                  (false,
8645                   (true,
8646                    (Rn'3,
8647                     (Rn'2,
8648                      (Rn'1,
8649                       (Rn'0,
8650                        (sb'0'1111'3,
8651                         (sb'0'1111'2,
8652                          (sb'0'1111'1,
8653                           (sb'0'1111'0,
8654                            (imm5'4,
8655                             (imm5'3,
8656                              (imm5'2,
8657                               (imm5'1,
8658                                (imm5'0,
8659                                 (typ'1,
8660                                  (typ'0,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
8661              let
8662                val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
8663                val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
8664                val R = BitsN.fromBitstring([R'0],1)
8665                val GOOD_MATCH =
8666                  (BitsN.fromBitstring
8667                     ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
8668                  (BitsN.B(0xF,4))
8669              in
8670                if Do(BitsN.B(0xE,4),
8671                      ((R = (BitsN.B(0x1,1))) andalso
8672                       ((Nat.>=(ArchVersion (),7)) andalso
8673                        (Set.mem(Extension_Multiprocessing,(!Extensions))))) orelse
8674                      ((R = (BitsN.B(0x0,1))) andalso (HaveDSPSupport ())))
8675                  then let
8676                         val is_pldw = R = (BitsN.B(0x0,1))
8677                       in
8678                         ( if (Rm = (BitsN.B(0xF,4))) orelse
8679                              (((Rn = (BitsN.B(0xF,4))) andalso is_pldw) orelse
8680                               (not GOOD_MATCH))
8681                             then DECODE_UNPREDICTABLE
8682                                    (mc,"PreloadData (register)")
8683                           else ()
8684                         ; let
8685                             val add =
8686                               (BitsN.fromBitstring([U'0],1)) =
8687                               (BitsN.B(0x1,1))
8688                             val (shift_t,shift_n) =
8689                               DecodeImmShift
8690                                 (BitsN.fromBitstring([typ'1,typ'0],2),
8691                                  BitsN.fromBitstring
8692                                    ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],
8693                                     5))
8694                             val m = register_form1(Rm,(shift_t,shift_n))
8695                           in
8696                             Hint(PreloadData(add,(is_pldw,(Rn,m))))
8697                           end
8698                         )
8699                       end
8700                else Skip ()
8701              end
8702            | (true,
8703             (false,
8704              (false,
8705               (P'0,
8706                (U'0,
8707                 (true,
8708                  (W'0,
8709                   (false,
8710                    (sb'0'1101'3,
8711                     (sb'0'1101'2,
8712                      (sb'0'1101'1,
8713                       (sb'0'1101'0,
8714                        (sb'1'0000'3,
8715                         (sb'1'0000'2,
8716                          (sb'1'0000'1,
8717                           (sb'1'0000'0,
8718                            (sb'2'0101'3,
8719                             (sb'2'0101'2,
8720                              (sb'2'0101'1,
8721                               (sb'2'0101'0,
8722                                (sb'3'000'2,
8723                                 (sb'3'000'1,
8724                                  (sb'3'000'0,
8725                                   (mode'4,
8726                                    (mode'3,(mode'2,(mode'1,mode'0))))))))))))))))))))))))))) =>
8727              let
8728                val U = BitsN.fromBitstring([U'0],1)
8729                val GOOD_MATCH =
8730                  ((BitsN.fromBitstring
8731                      ([sb'0'1101'3,sb'0'1101'2,sb'0'1101'1,sb'0'1101'0],4)) =
8732                   (BitsN.B(0xD,4))) andalso
8733                  (((BitsN.fromBitstring
8734                       ([sb'1'0000'3,sb'1'0000'2,sb'1'0000'1,sb'1'0000'0],
8735                        4)) = (BitsN.B(0x0,4))) andalso
8736                   (((BitsN.fromBitstring
8737                        ([sb'2'0101'3,sb'2'0101'2,sb'2'0101'1,sb'2'0101'0],
8738                         4)) = (BitsN.B(0x5,4))) andalso
8739                    ((BitsN.fromBitstring
8740                        ([sb'3'000'2,sb'3'000'1,sb'3'000'0],3)) =
8741                     (BitsN.B(0x0,3)))))
8742              in
8743                if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),6))
8744                  then ( if not GOOD_MATCH
8745                           then DECODE_UNPREDICTABLE(mc,"SRS")
8746                         else ()
8747                       ; let
8748                           val wback =
8749                             (BitsN.fromBitstring([W'0],1)) =
8750                             (BitsN.B(0x1,1))
8751                           val increment = U = (BitsN.B(0x1,1))
8752                           val wordhigher =
8753                             (BitsN.fromBitstring([P'0],1)) = U
8754                         in
8755                           System
8756                             (StoreReturnState
8757                                (increment,
8758                                 (wordhigher,
8759                                  (wback,
8760                                   BitsN.fromBitstring
8761                                     ([mode'4,mode'3,mode'2,mode'1,mode'0],
8762                                      5)))))
8763                         end
8764                       )
8765                else Skip ()
8766              end
8767            | (true,
8768             (false,
8769              (false,
8770               (P'0,
8771                (U'0,
8772                 (false,
8773                  (W'0,
8774                   (true,
8775                    (Rn'3,
8776                     (Rn'2,
8777                      (Rn'1,
8778                       (Rn'0,
8779                        (sb'0'0000'3,
8780                         (sb'0'0000'2,
8781                          (sb'0'0000'1,
8782                           (sb'0'0000'0,
8783                            (sb'1'1010'3,
8784                             (sb'1'1010'2,
8785                              (sb'1'1010'1,
8786                               (sb'1'1010'0,
8787                                (sb'2'00000000'7,
8788                                 (sb'2'00000000'6,
8789                                  (sb'2'00000000'5,
8790                                   (sb'2'00000000'4,
8791                                    (sb'2'00000000'3,
8792                                     (sb'2'00000000'2,
8793                                      (sb'2'00000000'1,sb'2'00000000'0))))))))))))))))))))))))))) =>
8794              let
8795                val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
8796                val U = BitsN.fromBitstring([U'0],1)
8797                val GOOD_MATCH =
8798                  ((BitsN.fromBitstring
8799                      ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
8800                   (BitsN.B(0x0,4))) andalso
8801                  (((BitsN.fromBitstring
8802                       ([sb'1'1010'3,sb'1'1010'2,sb'1'1010'1,sb'1'1010'0],
8803                        4)) = (BitsN.B(0xA,4))) andalso
8804                   ((BitsN.fromBitstring
8805                       ([sb'2'00000000'7,sb'2'00000000'6,sb'2'00000000'5,
8806                         sb'2'00000000'4,sb'2'00000000'3,sb'2'00000000'2,
8807                         sb'2'00000000'1,sb'2'00000000'0],8)) =
8808                    (BitsN.B(0x0,8))))
8809              in
8810                if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),6))
8811                  then ( if (Rn = (BitsN.B(0xF,4))) orelse
8812                            (not GOOD_MATCH)
8813                           then DECODE_UNPREDICTABLE
8814                                  (mc,"ReturnFromException")
8815                         else ()
8816                       ; let
8817                           val wback =
8818                             (BitsN.fromBitstring([W'0],1)) =
8819                             (BitsN.B(0x1,1))
8820                           val increment = U = (BitsN.B(0x1,1))
8821                           val wordhigher =
8822                             (BitsN.fromBitstring([P'0],1)) = U
8823                         in
8824                           System
8825                             (ReturnFromException
8826                                (increment,(wordhigher,(wback,Rn))))
8827                         end
8828                       )
8829                else Skip ()
8830              end
8831            | (true,
8832             (false,
8833              (true,
8834               (H'0,
8835                (imm24'23,
8836                 (imm24'22,
8837                  (imm24'21,
8838                   (imm24'20,
8839                    (imm24'19,
8840                     (imm24'18,
8841                      (imm24'17,
8842                       (imm24'16,
8843                        (imm24'15,
8844                         (imm24'14,
8845                          (imm24'13,
8846                           (imm24'12,
8847                            (imm24'11,
8848                             (imm24'10,
8849                              (imm24'9,
8850                               (imm24'8,
8851                                (imm24'7,
8852                                 (imm24'6,
8853                                  (imm24'5,
8854                                   (imm24'4,
8855                                    (imm24'3,(imm24'2,(imm24'1,imm24'0))))))))))))))))))))))))))) =>
8856              (if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),5))
8857                 then let
8858                        val imm32 =
8859                          BitsN.signExtend 32
8860                            (BitsN.concat
8861                               [BitsN.fromBitstring
8862                                  ([imm24'23,imm24'22,imm24'21,imm24'20,
8863                                    imm24'19,imm24'18,imm24'17,imm24'16,
8864                                    imm24'15,imm24'14,imm24'13,imm24'12,
8865                                    imm24'11,imm24'10,imm24'9,imm24'8,
8866                                    imm24'7,imm24'6,imm24'5,imm24'4,
8867                                    imm24'3,imm24'2,imm24'1,imm24'0],24),
8868                                BitsN.fromBitstring([H'0],1),
8869                                BitsN.B(0x0,1)])
8870                        val targetInstrSet = InstrSet_Thumb
8871                      in
8872                        Branch
8873                          (BranchLinkExchangeImmediate
8874                             (targetInstrSet,imm32))
8875                      end
8876               else Skip ())
8877            | _ =>
8878              (if Nat.>=(ArchVersion (),5)
8879                 then Undefined(BitsN.B(0x0,32))
8880               else ( DECODE_UNPREDICTABLE(mc,"")
8881                    ; Branch(BranchExchange(BitsN.B(0x0,4)))
8882                    ))
8883    else case boolify'28(BitsN.bits(27,0) w) of
8884            (false,
8885             (true,
8886              (true,
8887               (true,
8888                (true,
8889                 (true,
8890                  (true,
8891                   (true,
8892                    (imm12'11,
8893                     (imm12'10,
8894                      (imm12'9,
8895                       (imm12'8,
8896                        (imm12'7,
8897                         (imm12'6,
8898                          (imm12'5,
8899                           (imm12'4,
8900                            (imm12'3,
8901                             (imm12'2,
8902                              (imm12'1,
8903                               (imm12'0,
8904                                (true,
8905                                 (true,
8906                                  (true,
8907                                   (true,(imm4'3,(imm4'2,(imm4'1,imm4'0))))))))))))))))))))))))))) =>
8908              let
8909                val imm32 =
8910                  BitsN.zeroExtend 32
8911                    (BitsN.@@
8912                       (BitsN.fromBitstring
8913                          ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
8914                            imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
8915                            imm12'1,imm12'0],12),
8916                        BitsN.fromBitstring
8917                          ([imm4'3,imm4'2,imm4'1,imm4'0],4)))
8918              in
8919                ( CurrentCondition := cond
8920                ; if ConditionPassed ()
8921                    then Undefined imm32
8922                  else NoOperation
8923                )
8924              end
8925          | (false,
8926           (false,
8927            (false,
8928             (true,
8929              (false,
8930               (R'0,
8931                (false,
8932                 (false,
8933                  (m1'3,
8934                   (m1'2,
8935                    (m1'1,
8936                     (m1'0,
8937                      (Rd'3,
8938                       (Rd'2,
8939                        (Rd'1,
8940                         (Rd'0,
8941                          (sb'0'00'1,
8942                           (sb'0'00'0,
8943                            (true,
8944                             (m'0,
8945                              (false,
8946                               (false,
8947                                (false,
8948                                 (false,
8949                                  (sb'1'0000'3,
8950                                   (sb'1'0000'2,(sb'1'0000'1,sb'1'0000'0))))))))))))))))))))))))))) =>
8951            let
8952              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
8953              val GOOD_MATCH =
8954                ((BitsN.fromBitstring([sb'0'00'1,sb'0'00'0],2)) =
8955                 (BitsN.B(0x0,2))) andalso
8956                ((BitsN.fromBitstring
8957                    ([sb'1'0000'3,sb'1'0000'2,sb'1'0000'1,sb'1'0000'0],4)) =
8958                 (BitsN.B(0x0,4)))
8959            in
8960              if Do(cond,HaveVirtExt ())
8961                then ( if (Rd = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH)
8962                         then DECODE_UNPREDICTABLE
8963                                (mc,"MoveToRegisterFromBankedOrSpecial")
8964                       else ()
8965                     ; let
8966                         val read_spsr =
8967                           (BitsN.fromBitstring([R'0],1)) =
8968                           (BitsN.B(0x1,1))
8969                         val SYSm =
8970                           BitsN.@@
8971                             (BitsN.fromBitstring([m'0],1),
8972                              BitsN.fromBitstring([m1'3,m1'2,m1'1,m1'0],4))
8973                       in
8974                         System
8975                           (MoveToRegisterFromBankedOrSpecial
8976                              (read_spsr,(SYSm,Rd)))
8977                       end
8978                     )
8979              else Skip ()
8980            end
8981          | (false,
8982           (false,
8983            (false,
8984             (true,
8985              (false,
8986               (R'0,
8987                (false,
8988                 (false,
8989                  (sb'0'1111'3,
8990                   (sb'0'1111'2,
8991                    (sb'0'1111'1,
8992                     (sb'0'1111'0,
8993                      (Rd'3,
8994                       (Rd'2,
8995                        (Rd'1,
8996                         (Rd'0,
8997                          (sb'1'00'1,
8998                           (sb'1'00'0,
8999                            (false,
9000                             (sb'2'0'0,
9001                              (false,
9002                               (false,
9003                                (false,
9004                                 (false,
9005                                  (sb'3'0000'3,
9006                                   (sb'3'0000'2,(sb'3'0000'1,sb'3'0000'0))))))))))))))))))))))))))) =>
9007            let
9008              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9009              val GOOD_MATCH =
9010                ((BitsN.fromBitstring
9011                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
9012                 (BitsN.B(0xF,4))) andalso
9013                (((BitsN.fromBitstring([sb'1'00'1,sb'1'00'0],2)) =
9014                  (BitsN.B(0x0,2))) andalso
9015                 (((BitsN.fromBitstring([sb'2'0'0],1)) = (BitsN.B(0x0,1))) andalso
9016                  ((BitsN.fromBitstring
9017                      ([sb'3'0000'3,sb'3'0000'2,sb'3'0000'1,sb'3'0000'0],4)) =
9018                   (BitsN.B(0x0,4)))))
9019            in
9020              if Do(cond,true)
9021                then ( if (Rd = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH)
9022                         then DECODE_UNPREDICTABLE
9023                                (mc,"MoveToRegisterFromSpecial")
9024                       else ()
9025                     ; let
9026                         val read_spsr =
9027                           (BitsN.fromBitstring([R'0],1)) =
9028                           (BitsN.B(0x1,1))
9029                       in
9030                         System(MoveToRegisterFromSpecial(read_spsr,Rd))
9031                       end
9032                     )
9033              else Skip ()
9034            end
9035          | (false,
9036           (false,
9037            (false,
9038             (true,
9039              (false,
9040               (R'0,
9041                (true,
9042                 (false,
9043                  (m1'3,
9044                   (m1'2,
9045                    (m1'1,
9046                     (m1'0,
9047                      (sb'0'1111'3,
9048                       (sb'0'1111'2,
9049                        (sb'0'1111'1,
9050                         (sb'0'1111'0,
9051                          (sb'1'00'1,
9052                           (sb'1'00'0,
9053                            (true,
9054                             (m'0,
9055                              (false,
9056                               (false,
9057                                (false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9058            let
9059              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9060              val GOOD_MATCH =
9061                ((BitsN.fromBitstring
9062                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
9063                 (BitsN.B(0xF,4))) andalso
9064                ((BitsN.fromBitstring([sb'1'00'1,sb'1'00'0],2)) =
9065                 (BitsN.B(0x0,2)))
9066            in
9067              if Do(cond,HaveVirtExt ())
9068                then ( if (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
9069                          (not GOOD_MATCH)
9070                         then DECODE_UNPREDICTABLE
9071                                (mc,"MoveToBankedOrSpecialRegister")
9072                       else ()
9073                     ; let
9074                         val write_spsr =
9075                           (BitsN.fromBitstring([R'0],1)) =
9076                           (BitsN.B(0x1,1))
9077                         val SYSm =
9078                           BitsN.@@
9079                             (BitsN.fromBitstring([m'0],1),
9080                              BitsN.fromBitstring([m1'3,m1'2,m1'1,m1'0],4))
9081                       in
9082                         System
9083                           (MoveToBankedOrSpecialRegister
9084                              (write_spsr,(SYSm,Rn)))
9085                       end
9086                     )
9087              else Skip ()
9088            end
9089          | (false,
9090           (false,
9091            (false,
9092             (true,
9093              (false,
9094               (R'0,
9095                (true,
9096                 (false,
9097                  (mask'3,
9098                   (mask'2,
9099                    (mask'1,
9100                     (mask'0,
9101                      (sb'0'1111'3,
9102                       (sb'0'1111'2,
9103                        (sb'0'1111'1,
9104                         (sb'0'1111'0,
9105                          (sb'1'00'1,
9106                           (sb'1'00'0,
9107                            (false,
9108                             (sb'2'0'0,
9109                              (false,
9110                               (false,
9111                                (false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9112            let
9113              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9114              val mask =
9115                BitsN.fromBitstring([mask'3,mask'2,mask'1,mask'0],4)
9116              val GOOD_MATCH =
9117                ((BitsN.fromBitstring
9118                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
9119                 (BitsN.B(0xF,4))) andalso
9120                (((BitsN.fromBitstring([sb'1'00'1,sb'1'00'0],2)) =
9121                  (BitsN.B(0x0,2))) andalso
9122                 ((BitsN.fromBitstring([sb'2'0'0],1)) = (BitsN.B(0x0,1))))
9123            in
9124              if Do(cond,true)
9125                then ( if (Rn = (BitsN.B(0xF,4))) orelse
9126                          ((mask = (BitsN.B(0x0,4))) orelse
9127                           (not GOOD_MATCH))
9128                         then DECODE_UNPREDICTABLE
9129                                (mc,"MoveToSpecialFromRegister")
9130                       else ()
9131                     ; let
9132                         val write_spsr =
9133                           (BitsN.fromBitstring([R'0],1)) =
9134                           (BitsN.B(0x1,1))
9135                       in
9136                         System
9137                           (MoveToSpecialFromRegister
9138                              (write_spsr,(Rn,mask)))
9139                       end
9140                     )
9141              else Skip ()
9142            end
9143          | (false,
9144           (false,
9145            (false,
9146             (true,
9147              (false,
9148               (false,
9149                (true,
9150                 (false,
9151                  (sb'0'1111'3,
9152                   (sb'0'1111'2,
9153                    (sb'0'1111'1,
9154                     (sb'0'1111'0,
9155                      (sb'1'1111'3,
9156                       (sb'1'1111'2,
9157                        (sb'1'1111'1,
9158                         (sb'1'1111'0,
9159                          (sb'2'1111'3,
9160                           (sb'2'1111'2,
9161                            (sb'2'1111'1,
9162                             (sb'2'1111'0,
9163                              (false,
9164                               (false,
9165                                (false,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
9166            let
9167              val GOOD_MATCH =
9168                ((BitsN.fromBitstring
9169                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
9170                 (BitsN.B(0xF,4))) andalso
9171                (((BitsN.fromBitstring
9172                     ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
9173                  (BitsN.B(0xF,4))) andalso
9174                 ((BitsN.fromBitstring
9175                     ([sb'2'1111'3,sb'2'1111'2,sb'2'1111'1,sb'2'1111'0],4)) =
9176                  (BitsN.B(0xF,4))))
9177            in
9178              if Do(cond,not((!Architecture) = ARMv4))
9179                then ( if not GOOD_MATCH
9180                         then DECODE_UNPREDICTABLE(mc,"BX")
9181                       else ()
9182                     ; Branch
9183                         (BranchExchange
9184                            (BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)))
9185                     )
9186              else Skip ()
9187            end
9188          | (false,
9189           (false,
9190            (false,
9191             (true,
9192              (false,
9193               (true,
9194                (true,
9195                 (false,
9196                  (sb'0'1111'3,
9197                   (sb'0'1111'2,
9198                    (sb'0'1111'1,
9199                     (sb'0'1111'0,
9200                      (Rd'3,
9201                       (Rd'2,
9202                        (Rd'1,
9203                         (Rd'0,
9204                          (sb'1'1111'3,
9205                           (sb'1'1111'2,
9206                            (sb'1'1111'1,
9207                             (sb'1'1111'0,
9208                              (false,
9209                               (false,
9210                                (false,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
9211            let
9212              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9213              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9214              val GOOD_MATCH =
9215                ((BitsN.fromBitstring
9216                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
9217                 (BitsN.B(0xF,4))) andalso
9218                ((BitsN.fromBitstring
9219                    ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
9220                 (BitsN.B(0xF,4)))
9221            in
9222              if Do(cond,Nat.>=(ArchVersion (),5))
9223                then ( if (Rd = (BitsN.B(0xF,4))) orelse
9224                          ((Rm = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
9225                         then DECODE_UNPREDICTABLE
9226                                (mc,"CountLeadingZeroes")
9227                       else ()
9228                     ; Data(CountLeadingZeroes(Rd,Rm))
9229                     )
9230              else Skip ()
9231            end
9232          | (false,
9233           (false,
9234            (false,
9235             (true,
9236              (false,
9237               (false,
9238                (true,
9239                 (false,
9240                  (sb'0'1111'3,
9241                   (sb'0'1111'2,
9242                    (sb'0'1111'1,
9243                     (sb'0'1111'0,
9244                      (sb'1'1111'3,
9245                       (sb'1'1111'2,
9246                        (sb'1'1111'1,
9247                         (sb'1'1111'0,
9248                          (sb'2'1111'3,
9249                           (sb'2'1111'2,
9250                            (sb'2'1111'1,
9251                             (sb'2'1111'0,
9252                              (false,
9253                               (false,
9254                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
9255            let
9256              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9257              val GOOD_MATCH =
9258                ((BitsN.fromBitstring
9259                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
9260                 (BitsN.B(0xF,4))) andalso
9261                (((BitsN.fromBitstring
9262                     ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
9263                  (BitsN.B(0xF,4))) andalso
9264                 ((BitsN.fromBitstring
9265                     ([sb'2'1111'3,sb'2'1111'2,sb'2'1111'1,sb'2'1111'0],4)) =
9266                  (BitsN.B(0xF,4))))
9267            in
9268              if Do(cond,Nat.>=(ArchVersion (),5))
9269                then ( if (Rm = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH)
9270                         then DECODE_UNPREDICTABLE
9271                                (mc,"BranchLinkExchangeRegister")
9272                       else ()
9273                     ; Branch(BranchLinkExchangeRegister Rm)
9274                     )
9275              else Skip ()
9276            end
9277          | (false,
9278           (false,
9279            (false,
9280             (true,
9281              (false,
9282               (opc'1,
9283                (opc'0,
9284                 (false,
9285                  (Rn'3,
9286                   (Rn'2,
9287                    (Rn'1,
9288                     (Rn'0,
9289                      (Rd'3,
9290                       (Rd'2,
9291                        (Rd'1,
9292                         (Rd'0,
9293                          (sb'0'0000'3,
9294                           (sb'0'0000'2,
9295                            (sb'0'0000'1,
9296                             (sb'0'0000'0,
9297                              (false,
9298                               (true,
9299                                (false,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
9300            let
9301              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9302              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9303              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9304              val GOOD_MATCH =
9305                (BitsN.fromBitstring
9306                   ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
9307                (BitsN.B(0x0,4))
9308            in
9309              if Do(cond,HaveDSPSupport ())
9310                then ( if (Rd = (BitsN.B(0xF,4))) orelse
9311                          ((Rn = (BitsN.B(0xF,4))) orelse
9312                           ((Rm = (BitsN.B(0xF,4))) orelse
9313                            (not GOOD_MATCH)))
9314                         then DECODE_UNPREDICTABLE
9315                                (mc,"SaturatingAddSubtract")
9316                       else ()
9317                     ; Media
9318                         (SaturatingAddSubtract
9319                            (BitsN.fromBitstring([opc'1,opc'0],2),
9320                             (Rd,(Rm,Rn))))
9321                     )
9322              else Skip ()
9323            end
9324          | (false,
9325           (false,
9326            (false,
9327             (true,
9328              (false,
9329               (false,
9330                (true,
9331                 (false,
9332                  (imm12'11,
9333                   (imm12'10,
9334                    (imm12'9,
9335                     (imm12'8,
9336                      (imm12'7,
9337                       (imm12'6,
9338                        (imm12'5,
9339                         (imm12'4,
9340                          (imm12'3,
9341                           (imm12'2,
9342                            (imm12'1,
9343                             (imm12'0,
9344                              (false,
9345                               (true,
9346                                (true,
9347                                 (true,(imm4'3,(imm4'2,(imm4'1,imm4'0))))))))))))))))))))))))))) =>
9348            (if Nat.>=(ArchVersion (),5)
9349               then ( if not(cond = (BitsN.B(0xE,4)))
9350                        then DECODE_UNPREDICTABLE(mc,"Breakpoint")
9351                      else ()
9352                    ; CurrentCondition := cond
9353                    ; let
9354                        val imm32 =
9355                          BitsN.zeroExtend 32
9356                            (BitsN.@@
9357                               (BitsN.fromBitstring
9358                                  ([imm12'11,imm12'10,imm12'9,imm12'8,
9359                                    imm12'7,imm12'6,imm12'5,imm12'4,
9360                                    imm12'3,imm12'2,imm12'1,imm12'0],12),
9361                                BitsN.fromBitstring
9362                                  ([imm4'3,imm4'2,imm4'1,imm4'0],4)))
9363                      in
9364                        Hint(Breakpoint imm32)
9365                      end
9366                    )
9367             else if Do(cond,false)
9368               then Undefined(BitsN.B(0x0,32))
9369             else NoOperation)
9370          | (false,
9371           (false,
9372            (false,
9373             (true,
9374              (false,
9375               (true,
9376                (false,
9377                 (false,
9378                  (imm12'11,
9379                   (imm12'10,
9380                    (imm12'9,
9381                     (imm12'8,
9382                      (imm12'7,
9383                       (imm12'6,
9384                        (imm12'5,
9385                         (imm12'4,
9386                          (imm12'3,
9387                           (imm12'2,
9388                            (imm12'1,
9389                             (imm12'0,
9390                              (false,
9391                               (true,
9392                                (true,
9393                                 (true,(imm4'3,(imm4'2,(imm4'1,imm4'0))))))))))))))))))))))))))) =>
9394            (if Do(cond,HaveVirtExt ())
9395               then ( if not(cond = (BitsN.B(0xE,4)))
9396                        then DECODE_UNPREDICTABLE(mc,"HypervisorCall")
9397                      else ()
9398                    ; let
9399                        val imm16 =
9400                          BitsN.@@
9401                            (BitsN.fromBitstring
9402                               ([imm12'11,imm12'10,imm12'9,imm12'8,
9403                                 imm12'7,imm12'6,imm12'5,imm12'4,imm12'3,
9404                                 imm12'2,imm12'1,imm12'0],12),
9405                             BitsN.fromBitstring
9406                               ([imm4'3,imm4'2,imm4'1,imm4'0],4))
9407                      in
9408                        System(HypervisorCall imm16)
9409                      end
9410                    )
9411             else Skip ())
9412          | (false,
9413           (false,
9414            (false,
9415             (true,
9416              (false,
9417               (true,
9418                (true,
9419                 (false,
9420                  (sb'0'000000000000'11,
9421                   (sb'0'000000000000'10,
9422                    (sb'0'000000000000'9,
9423                     (sb'0'000000000000'8,
9424                      (sb'0'000000000000'7,
9425                       (sb'0'000000000000'6,
9426                        (sb'0'000000000000'5,
9427                         (sb'0'000000000000'4,
9428                          (sb'0'000000000000'3,
9429                           (sb'0'000000000000'2,
9430                            (sb'0'000000000000'1,
9431                             (sb'0'000000000000'0,
9432                              (false,
9433                               (true,
9434                                (true,
9435                                 (true,(imm4'3,(imm4'2,(imm4'1,imm4'0))))))))))))))))))))))))))) =>
9436            let
9437              val GOOD_MATCH =
9438                (BitsN.fromBitstring
9439                   ([sb'0'000000000000'11,sb'0'000000000000'10,
9440                     sb'0'000000000000'9,sb'0'000000000000'8,
9441                     sb'0'000000000000'7,sb'0'000000000000'6,
9442                     sb'0'000000000000'5,sb'0'000000000000'4,
9443                     sb'0'000000000000'3,sb'0'000000000000'2,
9444                     sb'0'000000000000'1,sb'0'000000000000'0],12)) =
9445                (BitsN.B(0x0,12))
9446            in
9447              if Do(cond,HaveSecurityExt ())
9448                then ( if not GOOD_MATCH
9449                         then DECODE_UNPREDICTABLE(mc,"SMC")
9450                       else ()
9451                     ; System
9452                         (SecureMonitorCall
9453                            (BitsN.fromBitstring
9454                               ([imm4'3,imm4'2,imm4'1,imm4'0],4)))
9455                     )
9456              else Skip ()
9457            end
9458          | (false,
9459           (false,
9460            (false,
9461             (true,
9462              (false,
9463               (false,
9464                (false,
9465                 (false,
9466                  (Rd'3,
9467                   (Rd'2,
9468                    (Rd'1,
9469                     (Rd'0,
9470                      (Ra'3,
9471                       (Ra'2,
9472                        (Ra'1,
9473                         (Ra'0,
9474                          (Rm'3,
9475                           (Rm'2,
9476                            (Rm'1,
9477                             (Rm'0,
9478                              (true,
9479                               (M'0,
9480                                (N'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9481            let
9482              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9483              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9484              val Ra = BitsN.fromBitstring([Ra'3,Ra'2,Ra'1,Ra'0],4)
9485              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9486            in
9487              if Do(cond,HaveDSPSupport ())
9488                then ( if (Rd = (BitsN.B(0xF,4))) orelse
9489                          ((Rn = (BitsN.B(0xF,4))) orelse
9490                           ((Rm = (BitsN.B(0xF,4))) orelse
9491                            (Ra = (BitsN.B(0xF,4)))))
9492                         then DECODE_UNPREDICTABLE
9493                                (mc,"Signed16Multiply32Accumulate")
9494                       else ()
9495                     ; let
9496                         val n_high =
9497                           (BitsN.fromBitstring([N'0],1)) =
9498                           (BitsN.B(0x1,1))
9499                         val m_high =
9500                           (BitsN.fromBitstring([M'0],1)) =
9501                           (BitsN.B(0x1,1))
9502                       in
9503                         Multiply
9504                           (Signed16Multiply32Accumulate
9505                              (m_high,(n_high,(Rd,(Rn,(Rm,Ra))))))
9506                       end
9507                     )
9508              else Skip ()
9509            end
9510          | (false,
9511           (false,
9512            (false,
9513             (true,
9514              (false,
9515               (false,
9516                (true,
9517                 (false,
9518                  (Rd'3,
9519                   (Rd'2,
9520                    (Rd'1,
9521                     (Rd'0,
9522                      (Ra'3,
9523                       (Ra'2,
9524                        (Ra'1,
9525                         (Ra'0,
9526                          (Rm'3,
9527                           (Rm'2,
9528                            (Rm'1,
9529                             (Rm'0,
9530                              (true,
9531                               (M'0,
9532                                (false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9533            let
9534              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9535              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9536              val Ra = BitsN.fromBitstring([Ra'3,Ra'2,Ra'1,Ra'0],4)
9537              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9538            in
9539              if Do(cond,HaveDSPSupport ())
9540                then ( if (Rd = (BitsN.B(0xF,4))) orelse
9541                          ((Rn = (BitsN.B(0xF,4))) orelse
9542                           ((Rm = (BitsN.B(0xF,4))) orelse
9543                            (Ra = (BitsN.B(0xF,4)))))
9544                         then DECODE_UNPREDICTABLE
9545                                (mc,"Signed16x32Multiply32Accumulate")
9546                       else ()
9547                     ; let
9548                         val m_high =
9549                           (BitsN.fromBitstring([M'0],1)) =
9550                           (BitsN.B(0x1,1))
9551                       in
9552                         Multiply
9553                           (Signed16x32Multiply32Accumulate
9554                              (m_high,(Rd,(Rn,(Rm,Ra)))))
9555                       end
9556                     )
9557              else Skip ()
9558            end
9559          | (false,
9560           (false,
9561            (false,
9562             (true,
9563              (false,
9564               (false,
9565                (true,
9566                 (false,
9567                  (Rd'3,
9568                   (Rd'2,
9569                    (Rd'1,
9570                     (Rd'0,
9571                      (sb'0'0000'3,
9572                       (sb'0'0000'2,
9573                        (sb'0'0000'1,
9574                         (sb'0'0000'0,
9575                          (Rm'3,
9576                           (Rm'2,
9577                            (Rm'1,
9578                             (Rm'0,
9579                              (true,
9580                               (M'0,
9581                                (true,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9582            let
9583              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9584              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9585              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9586              val GOOD_MATCH =
9587                (BitsN.fromBitstring
9588                   ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
9589                (BitsN.B(0x0,4))
9590            in
9591              if Do(cond,HaveDSPSupport ())
9592                then ( if (Rd = (BitsN.B(0xF,4))) orelse
9593                          ((Rn = (BitsN.B(0xF,4))) orelse
9594                           ((Rm = (BitsN.B(0xF,4))) orelse
9595                            (not GOOD_MATCH)))
9596                         then DECODE_UNPREDICTABLE
9597                                (mc,"Signed16x32Multiply32Result")
9598                       else ()
9599                     ; let
9600                         val m_high =
9601                           (BitsN.fromBitstring([M'0],1)) =
9602                           (BitsN.B(0x1,1))
9603                       in
9604                         Multiply
9605                           (Signed16x32Multiply32Result
9606                              (m_high,(Rd,(Rn,Rm))))
9607                       end
9608                     )
9609              else Skip ()
9610            end
9611          | (false,
9612           (false,
9613            (false,
9614             (true,
9615              (false,
9616               (true,
9617                (false,
9618                 (false,
9619                  (RdHi'3,
9620                   (RdHi'2,
9621                    (RdHi'1,
9622                     (RdHi'0,
9623                      (RdLo'3,
9624                       (RdLo'2,
9625                        (RdLo'1,
9626                         (RdLo'0,
9627                          (Rm'3,
9628                           (Rm'2,
9629                            (Rm'1,
9630                             (Rm'0,
9631                              (true,
9632                               (M'0,
9633                                (N'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9634            let
9635              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9636              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9637              val RdLo =
9638                BitsN.fromBitstring([RdLo'3,RdLo'2,RdLo'1,RdLo'0],4)
9639              val RdHi =
9640                BitsN.fromBitstring([RdHi'3,RdHi'2,RdHi'1,RdHi'0],4)
9641            in
9642              if Do(cond,HaveDSPSupport ())
9643                then ( if (RdLo = (BitsN.B(0xF,4))) orelse
9644                          ((RdHi = (BitsN.B(0xF,4))) orelse
9645                           ((Rn = (BitsN.B(0xF,4))) orelse
9646                            (Rm = (BitsN.B(0xF,4)))))
9647                         then DECODE_UNPREDICTABLE
9648                                (mc,"Signed16Multiply64Accumulate")
9649                       else ()
9650                     ; let
9651                         val n_high =
9652                           (BitsN.fromBitstring([N'0],1)) =
9653                           (BitsN.B(0x1,1))
9654                         val m_high =
9655                           (BitsN.fromBitstring([M'0],1)) =
9656                           (BitsN.B(0x1,1))
9657                       in
9658                         Multiply
9659                           (Signed16Multiply64Accumulate
9660                              (m_high,(n_high,(RdHi,(RdLo,(Rn,Rm))))))
9661                       end
9662                     )
9663              else Skip ()
9664            end
9665          | (false,
9666           (false,
9667            (false,
9668             (true,
9669              (false,
9670               (true,
9671                (true,
9672                 (false,
9673                  (Rd'3,
9674                   (Rd'2,
9675                    (Rd'1,
9676                     (Rd'0,
9677                      (sb'0'0000'3,
9678                       (sb'0'0000'2,
9679                        (sb'0'0000'1,
9680                         (sb'0'0000'0,
9681                          (Rm'3,
9682                           (Rm'2,
9683                            (Rm'1,
9684                             (Rm'0,
9685                              (true,
9686                               (M'0,
9687                                (N'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9688            let
9689              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9690              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9691              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9692              val GOOD_MATCH =
9693                (BitsN.fromBitstring
9694                   ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
9695                (BitsN.B(0x0,4))
9696            in
9697              if Do(cond,HaveDSPSupport ())
9698                then ( if (Rd = (BitsN.B(0xF,4))) orelse
9699                          ((Rn = (BitsN.B(0xF,4))) orelse
9700                           ((Rm = (BitsN.B(0xF,4))) orelse
9701                            (not GOOD_MATCH)))
9702                         then DECODE_UNPREDICTABLE
9703                                (mc,"Signed16Multiply32Result")
9704                       else ()
9705                     ; let
9706                         val n_high =
9707                           (BitsN.fromBitstring([N'0],1)) =
9708                           (BitsN.B(0x1,1))
9709                         val m_high =
9710                           (BitsN.fromBitstring([M'0],1)) =
9711                           (BitsN.B(0x1,1))
9712                       in
9713                         Multiply
9714                           (Signed16Multiply32Result
9715                              (m_high,(n_high,(Rd,(Rn,Rm)))))
9716                       end
9717                     )
9718              else Skip ()
9719            end
9720          | (false,
9721           (false,
9722            (false,
9723             (true,
9724              (false,
9725               (true,
9726                (true,
9727                 (false,
9728                  (false,
9729                   (false,
9730                    (false,
9731                     (false,
9732                      (false,
9733                       (false,
9734                        (false,
9735                         (false,
9736                          (false,
9737                           (false,
9738                            (false,
9739                             (false,
9740                              (false,
9741                               (true,
9742                                (true,(false,(true,(true,(true,false))))))))))))))))))))))))))) =>
9743            if Do(cond,HaveVirtExt ())
9744              then System ExceptionReturn
9745            else Skip ()
9746          | (false,
9747           (false,
9748            (false,
9749             (true,
9750              (false,
9751               (_,
9752                (_,
9753                 (false,
9754                  (_,(_,(_,(_,(_,(_,(_,(_,(_,(_,(_,(_,(false,_))))))))))))))))))))) =>
9755            Undefined(BitsN.B(0x0,32))
9756          | (false,
9757           (false,
9758            (false,
9759             (opc'3,
9760              (opc'2,
9761               (opc'1,
9762                (opc'0,
9763                 (S'0,
9764                  (Rn'3,
9765                   (Rn'2,
9766                    (Rn'1,
9767                     (Rn'0,
9768                      (Rd'3,
9769                       (Rd'2,
9770                        (Rd'1,
9771                         (Rd'0,
9772                          (imm5'4,
9773                           (imm5'3,
9774                            (imm5'2,
9775                             (imm5'1,
9776                              (imm5'0,
9777                               (typ'1,
9778                                (typ'0,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
9779            let
9780              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9781              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9782              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9783              val opc = BitsN.fromBitstring([opc'3,opc'2,opc'1,opc'0],4)
9784            in
9785              if Do(cond,true)
9786                then let
9787                       val setflags =
9788                         (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
9789                       val (shift_t,shift_n) =
9790                         DecodeImmShift
9791                           (BitsN.fromBitstring([typ'1,typ'0],2),
9792                            BitsN.fromBitstring
9793                              ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
9794                     in
9795                       if (BitsN.bits(3,2) opc) = (BitsN.B(0x2,2))
9796                         then Data
9797                                (TestCompareRegister
9798                                   (BitsN.bits(1,0) opc,
9799                                    (Rn,(Rm,(shift_t,shift_n)))))
9800                       else if Set.mem
9801                            (opc,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
9802                         then Data
9803                                (ShiftImmediate
9804                                   (BitsN.bit(opc,1),
9805                                    (setflags,(Rd,(Rm,(shift_t,shift_n))))))
9806                       else Data
9807                              (Register
9808                                 (opc,
9809                                  (setflags,
9810                                   (Rd,(Rn,(Rm,(shift_t,shift_n)))))))
9811                     end
9812              else Skip ()
9813            end
9814          | (false,
9815           (false,
9816            (false,
9817             (opc'3,
9818              (opc'2,
9819               (opc'1,
9820                (opc'0,
9821                 (S'0,
9822                  (Rn'3,
9823                   (Rn'2,
9824                    (Rn'1,
9825                     (Rn'0,
9826                      (Rd'3,
9827                       (Rd'2,
9828                        (Rd'1,
9829                         (Rd'0,
9830                          (Rs'3,
9831                           (Rs'2,
9832                            (Rs'1,
9833                             (Rs'0,
9834                              (false,
9835                               (typ'1,
9836                                (typ'0,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
9837            let
9838              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9839              val Rs = BitsN.fromBitstring([Rs'3,Rs'2,Rs'1,Rs'0],4)
9840              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9841              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9842              val opc = BitsN.fromBitstring([opc'3,opc'2,opc'1,opc'0],4)
9843            in
9844              if Do(cond,true)
9845                then ( if ((Rd = (BitsN.B(0xF,4))) andalso
9846                           (not((BitsN.bits(3,2) opc) = (BitsN.B(0x2,2))))) orelse
9847                          ((Rn = (BitsN.B(0xF,4))) orelse
9848                           ((Rm = (BitsN.B(0xF,4))) orelse
9849                            (Rs = (BitsN.B(0xF,4)))))
9850                         then DECODE_UNPREDICTABLE
9851                                (mc,"RegisterShiftedRegister")
9852                       else ()
9853                     ; let
9854                         val setflags =
9855                           (BitsN.fromBitstring([S'0],1)) =
9856                           (BitsN.B(0x1,1))
9857                         val shift_t =
9858                           DecodeRegShift
9859                             (BitsN.fromBitstring([typ'1,typ'0],2))
9860                       in
9861                         if (opc = (BitsN.B(0xD,4))) orelse
9862                            (opc = (BitsN.B(0xF,4)))
9863                           then Data
9864                                  (ShiftRegister
9865                                     (BitsN.bit(opc,1),
9866                                      (setflags,(Rd,(Rm,(shift_t,Rs))))))
9867                         else Data
9868                                (RegisterShiftedRegister
9869                                   (opc,
9870                                    (setflags,(Rd,(Rn,(Rm,(shift_t,Rs)))))))
9871                       end
9872                     )
9873              else Skip ()
9874            end
9875          | (false,
9876           (false,
9877            (false,
9878             (false,
9879              (false,
9880               (false,
9881                (A'0,
9882                 (S'0,
9883                  (Rd'3,
9884                   (Rd'2,
9885                    (Rd'1,
9886                     (Rd'0,
9887                      (Ra'3,
9888                       (Ra'2,
9889                        (Ra'1,
9890                         (Ra'0,
9891                          (Rm'3,
9892                           (Rm'2,
9893                            (Rm'1,
9894                             (Rm'0,
9895                              (true,
9896                               (false,
9897                                (false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9898            let
9899              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9900              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9901              val Ra = BitsN.fromBitstring([Ra'3,Ra'2,Ra'1,Ra'0],4)
9902              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
9903              val A = BitsN.fromBitstring([A'0],1)
9904            in
9905              if Do(cond,true)
9906                then ( if (Rd = (BitsN.B(0xF,4))) orelse
9907                          ((Rn = (BitsN.B(0xF,4))) orelse
9908                           ((Rm = (BitsN.B(0xF,4))) orelse
9909                            (((A = (BitsN.B(0x1,1))) andalso
9910                              (Ra = (BitsN.B(0xF,4)))) orelse
9911                             ((Nat.<(ArchVersion (),6)) andalso (Rd = Rn)))))
9912                         then DECODE_UNPREDICTABLE(mc,"Multiply")
9913                       else ()
9914                     ; let
9915                         val setflags =
9916                           (BitsN.fromBitstring([S'0],1)) =
9917                           (BitsN.B(0x1,1))
9918                       in
9919                         if A = (BitsN.B(0x1,1))
9920                           then Multiply
9921                                  (MultiplyAccumulate
9922                                     (setflags,(Rd,(Rn,(Rm,Ra)))))
9923                         else Multiply(Multiply32(setflags,(Rd,(Rn,Rm))))
9924                       end
9925                     )
9926              else Skip ()
9927            end
9928          | (false,
9929           (false,
9930            (false,
9931             (false,
9932              (false,
9933               (true,
9934                (false,
9935                 (false,
9936                  (RdHi'3,
9937                   (RdHi'2,
9938                    (RdHi'1,
9939                     (RdHi'0,
9940                      (RdLo'3,
9941                       (RdLo'2,
9942                        (RdLo'1,
9943                         (RdLo'0,
9944                          (Rm'3,
9945                           (Rm'2,
9946                            (Rm'1,
9947                             (Rm'0,
9948                              (true,
9949                               (false,
9950                                (false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9951            let
9952              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9953              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9954              val RdLo =
9955                BitsN.fromBitstring([RdLo'3,RdLo'2,RdLo'1,RdLo'0],4)
9956              val RdHi =
9957                BitsN.fromBitstring([RdHi'3,RdHi'2,RdHi'1,RdHi'0],4)
9958            in
9959              if Do(cond,Nat.>=(ArchVersion (),6))
9960                then ( if (RdHi = (BitsN.B(0xF,4))) orelse
9961                          ((RdLo = (BitsN.B(0xF,4))) orelse
9962                           ((Rn = (BitsN.B(0xF,4))) orelse
9963                            ((Rm = (BitsN.B(0xF,4))) orelse (RdHi = RdLo))))
9964                         then DECODE_UNPREDICTABLE
9965                                (mc,"MultiplyAccumulateAccumulate")
9966                       else ()
9967                     ; Multiply
9968                         (MultiplyAccumulateAccumulate
9969                            (RdHi,(RdLo,(Rn,Rm))))
9970                     )
9971              else Skip ()
9972            end
9973          | (false,
9974           (false,
9975            (false,
9976             (false,
9977              (false,
9978               (true,
9979                (true,
9980                 (false,
9981                  (Rd'3,
9982                   (Rd'2,
9983                    (Rd'1,
9984                     (Rd'0,
9985                      (Ra'3,
9986                       (Ra'2,
9987                        (Ra'1,
9988                         (Ra'0,
9989                          (Rm'3,
9990                           (Rm'2,
9991                            (Rm'1,
9992                             (Rm'0,
9993                              (true,
9994                               (false,
9995                                (false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
9996            let
9997              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
9998              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
9999              val Ra = BitsN.fromBitstring([Ra'3,Ra'2,Ra'1,Ra'0],4)
10000              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
10001            in
10002              if Do(cond,HaveThumb2 ())
10003                then ( if (Rd = (BitsN.B(0xF,4))) orelse
10004                          ((Rn = (BitsN.B(0xF,4))) orelse
10005                           ((Rm = (BitsN.B(0xF,4))) orelse
10006                            (Ra = (BitsN.B(0xF,4)))))
10007                         then DECODE_UNPREDICTABLE(mc,"MultiplySubtract")
10008                       else ()
10009                     ; Multiply(MultiplySubtract(Rd,(Rn,(Rm,Ra))))
10010                     )
10011              else Skip ()
10012            end
10013          | (false,
10014           (false,
10015            (false,
10016             (false,
10017              (true,
10018               (I'0,
10019                (A'0,
10020                 (S'0,
10021                  (RdHi'3,
10022                   (RdHi'2,
10023                    (RdHi'1,
10024                     (RdHi'0,
10025                      (RdLo'3,
10026                       (RdLo'2,
10027                        (RdLo'1,
10028                         (RdLo'0,
10029                          (Rm'3,
10030                           (Rm'2,
10031                            (Rm'1,
10032                             (Rm'0,
10033                              (true,
10034                               (false,
10035                                (false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
10036            let
10037              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10038              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
10039              val RdLo =
10040                BitsN.fromBitstring([RdLo'3,RdLo'2,RdLo'1,RdLo'0],4)
10041              val RdHi =
10042                BitsN.fromBitstring([RdHi'3,RdHi'2,RdHi'1,RdHi'0],4)
10043            in
10044              if Do(cond,true)
10045                then ( if (RdLo = (BitsN.B(0xF,4))) orelse
10046                          ((RdHi = (BitsN.B(0xF,4))) orelse
10047                           ((Rn = (BitsN.B(0xF,4))) orelse
10048                            ((Rm = (BitsN.B(0xF,4))) orelse
10049                             ((RdHi = RdLo) orelse
10050                              ((Nat.<(ArchVersion (),6)) andalso
10051                               ((RdHi = Rn) orelse (RdLo = Rn)))))))
10052                         then DECODE_UNPREDICTABLE(mc,"MultiplyLong")
10053                       else ()
10054                     ; let
10055                         val accumulate =
10056                           (BitsN.fromBitstring([A'0],1)) =
10057                           (BitsN.B(0x1,1))
10058                         val signed =
10059                           (BitsN.fromBitstring([I'0],1)) =
10060                           (BitsN.B(0x1,1))
10061                         val setflags =
10062                           (BitsN.fromBitstring([S'0],1)) =
10063                           (BitsN.B(0x1,1))
10064                       in
10065                         Multiply
10066                           (MultiplyLong
10067                              (accumulate,
10068                               (signed,(setflags,(RdHi,(RdLo,(Rn,Rm)))))))
10069                       end
10070                     )
10071              else Skip ()
10072            end
10073          | (false,
10074           (false,
10075            (false,
10076             (true,
10077              (false,
10078               (B'0,
10079                (false,
10080                 (false,
10081                  (Rn'3,
10082                   (Rn'2,
10083                    (Rn'1,
10084                     (Rn'0,
10085                      (Rt'3,
10086                       (Rt'2,
10087                        (Rt'1,
10088                         (Rt'0,
10089                          (sb'0'0000'3,
10090                           (sb'0'0000'2,
10091                            (sb'0'0000'1,
10092                             (sb'0'0000'0,
10093                              (true,
10094                               (false,
10095                                (false,
10096                                 (true,(Rt2'3,(Rt2'2,(Rt2'1,Rt2'0))))))))))))))))))))))))))) =>
10097            let
10098              val Rt2 = BitsN.fromBitstring([Rt2'3,Rt2'2,Rt2'1,Rt2'0],4)
10099              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10100              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10101              val GOOD_MATCH =
10102                (BitsN.fromBitstring
10103                   ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
10104                (BitsN.B(0x0,4))
10105            in
10106              if Do(cond,true)
10107                then ( if (Rt = (BitsN.B(0xF,4))) orelse
10108                          ((Rt2 = (BitsN.B(0xF,4))) orelse
10109                           ((Rn = (BitsN.B(0xF,4))) orelse
10110                            ((Rn = Rt) orelse
10111                             ((Rn = Rt2) orelse (not GOOD_MATCH)))))
10112                         then DECODE_UNPREDICTABLE(mc,"Swap")
10113                       else ()
10114                     ; let
10115                         val b =
10116                           (BitsN.fromBitstring([B'0],1)) =
10117                           (BitsN.B(0x1,1))
10118                       in
10119                         Swap(b,(Rt,(Rt2,Rn)))
10120                       end
10121                     )
10122              else Skip ()
10123            end
10124          | (false,
10125           (false,
10126            (false,
10127             (true,
10128              (true,
10129               (false,
10130                (false,
10131                 (false,
10132                  (Rn'3,
10133                   (Rn'2,
10134                    (Rn'1,
10135                     (Rn'0,
10136                      (Rd'3,
10137                       (Rd'2,
10138                        (Rd'1,
10139                         (Rd'0,
10140                          (sb'0'1111'3,
10141                           (sb'0'1111'2,
10142                            (sb'0'1111'1,
10143                             (sb'0'1111'0,
10144                              (true,
10145                               (false,
10146                                (false,(true,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))) =>
10147            let
10148              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10149              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
10150              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10151              val GOOD_MATCH =
10152                (BitsN.fromBitstring
10153                   ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
10154                (BitsN.B(0xF,4))
10155            in
10156              if Do(cond,Nat.>=(ArchVersion (),6))
10157                then ( if (Rd = (BitsN.B(0xF,4))) orelse
10158                          ((Rt = (BitsN.B(0xF,4))) orelse
10159                           ((Rn = (BitsN.B(0xF,4))) orelse
10160                            ((Rd = Rn) orelse
10161                             ((Rd = Rt) orelse (not GOOD_MATCH)))))
10162                         then DECODE_UNPREDICTABLE(mc,"StoreExclusive")
10163                       else ()
10164                     ; Store(StoreExclusive(Rd,(Rt,(Rn,BitsN.B(0x0,32)))))
10165                     )
10166              else Skip ()
10167            end
10168          | (false,
10169           (false,
10170            (false,
10171             (true,
10172              (true,
10173               (false,
10174                (false,
10175                 (true,
10176                  (Rn'3,
10177                   (Rn'2,
10178                    (Rn'1,
10179                     (Rn'0,
10180                      (Rt'3,
10181                       (Rt'2,
10182                        (Rt'1,
10183                         (Rt'0,
10184                          (sb'0'1111'3,
10185                           (sb'0'1111'2,
10186                            (sb'0'1111'1,
10187                             (sb'0'1111'0,
10188                              (true,
10189                               (false,
10190                                (false,
10191                                 (true,
10192                                  (sb'1'1111'3,
10193                                   (sb'1'1111'2,(sb'1'1111'1,sb'1'1111'0))))))))))))))))))))))))))) =>
10194            let
10195              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10196              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10197              val GOOD_MATCH =
10198                ((BitsN.fromBitstring
10199                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
10200                 (BitsN.B(0xF,4))) andalso
10201                ((BitsN.fromBitstring
10202                    ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
10203                 (BitsN.B(0xF,4)))
10204            in
10205              if Do(cond,Nat.>=(ArchVersion (),6))
10206                then ( if (Rt = (BitsN.B(0xF,4))) orelse
10207                          ((Rn = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
10208                         then DECODE_UNPREDICTABLE(mc,"LoadExclusive")
10209                       else ()
10210                     ; Load(LoadExclusive(Rt,(Rn,BitsN.B(0x0,32))))
10211                     )
10212              else Skip ()
10213            end
10214          | (false,
10215           (false,
10216            (false,
10217             (true,
10218              (true,
10219               (false,
10220                (true,
10221                 (false,
10222                  (Rn'3,
10223                   (Rn'2,
10224                    (Rn'1,
10225                     (Rn'0,
10226                      (Rd'3,
10227                       (Rd'2,
10228                        (Rd'1,
10229                         (Rd'0,
10230                          (sb'0'1111'3,
10231                           (sb'0'1111'2,
10232                            (sb'0'1111'1,
10233                             (sb'0'1111'0,
10234                              (true,
10235                               (false,
10236                                (false,(true,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))) =>
10237            let
10238              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10239              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
10240              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10241              val GOOD_MATCH =
10242                (BitsN.fromBitstring
10243                   ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
10244                (BitsN.B(0xF,4))
10245            in
10246              if Do(cond,Set.mem((!Architecture),[ARMv6K,ARMv7_A,ARMv7_R]))
10247                then let
10248                       val Rt2 = BitsN.+(Rt,BitsN.B(0x1,4))
10249                     in
10250                       ( if (Rd = (BitsN.B(0xF,4))) orelse
10251                            ((BitsN.bit(Rt,0)) orelse
10252                             ((Rt = (BitsN.B(0xE,4))) orelse
10253                              ((Rn = (BitsN.B(0xF,4))) orelse
10254                               ((Rd = Rn) orelse
10255                                ((Rd = Rt) orelse
10256                                 ((Rd = Rt2) orelse (not GOOD_MATCH)))))))
10257                           then DECODE_UNPREDICTABLE
10258                                  (mc,"StoreExclusiveDoubleword")
10259                         else ()
10260                       ; Store(StoreExclusiveDoubleword(Rd,(Rt,(Rt2,Rn))))
10261                       )
10262                     end
10263              else Skip ()
10264            end
10265          | (false,
10266           (false,
10267            (false,
10268             (true,
10269              (true,
10270               (false,
10271                (true,
10272                 (true,
10273                  (Rn'3,
10274                   (Rn'2,
10275                    (Rn'1,
10276                     (Rn'0,
10277                      (Rt'3,
10278                       (Rt'2,
10279                        (Rt'1,
10280                         (Rt'0,
10281                          (sb'0'1111'3,
10282                           (sb'0'1111'2,
10283                            (sb'0'1111'1,
10284                             (sb'0'1111'0,
10285                              (true,
10286                               (false,
10287                                (false,
10288                                 (true,
10289                                  (sb'1'1111'3,
10290                                   (sb'1'1111'2,(sb'1'1111'1,sb'1'1111'0))))))))))))))))))))))))))) =>
10291            let
10292              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10293              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10294              val GOOD_MATCH =
10295                ((BitsN.fromBitstring
10296                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
10297                 (BitsN.B(0xF,4))) andalso
10298                ((BitsN.fromBitstring
10299                    ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
10300                 (BitsN.B(0xF,4)))
10301            in
10302              if Do(cond,Set.mem((!Architecture),[ARMv6K,ARMv7_A,ARMv7_R]))
10303                then let
10304                       val Rt2 = BitsN.+(Rt,BitsN.B(0x1,4))
10305                     in
10306                       ( if (BitsN.bit(Rt,0)) orelse
10307                            ((Rt = (BitsN.B(0xE,4))) orelse
10308                             ((Rn = (BitsN.B(0xF,4))) orelse
10309                              (not GOOD_MATCH)))
10310                           then DECODE_UNPREDICTABLE
10311                                  (mc,"LoadExclusiveDoubleword")
10312                         else ()
10313                       ; Load(LoadExclusiveDoubleword(Rt,(Rt2,Rn)))
10314                       )
10315                     end
10316              else Skip ()
10317            end
10318          | (false,
10319           (false,
10320            (false,
10321             (true,
10322              (true,
10323               (true,
10324                (false,
10325                 (false,
10326                  (Rn'3,
10327                   (Rn'2,
10328                    (Rn'1,
10329                     (Rn'0,
10330                      (Rd'3,
10331                       (Rd'2,
10332                        (Rd'1,
10333                         (Rd'0,
10334                          (sb'0'1111'3,
10335                           (sb'0'1111'2,
10336                            (sb'0'1111'1,
10337                             (sb'0'1111'0,
10338                              (true,
10339                               (false,
10340                                (false,(true,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))) =>
10341            let
10342              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10343              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
10344              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10345              val GOOD_MATCH =
10346                (BitsN.fromBitstring
10347                   ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
10348                (BitsN.B(0xF,4))
10349            in
10350              if Do(cond,Set.mem((!Architecture),[ARMv6K,ARMv7_A,ARMv7_R]))
10351                then ( if (Rd = (BitsN.B(0xF,4))) orelse
10352                          ((Rt = (BitsN.B(0xF,4))) orelse
10353                           ((Rn = (BitsN.B(0xF,4))) orelse
10354                            ((Rd = Rn) orelse
10355                             ((Rd = Rt) orelse (not GOOD_MATCH)))))
10356                         then DECODE_UNPREDICTABLE
10357                                (mc,"StoreExclusiveByte")
10358                       else ()
10359                     ; Store(StoreExclusiveByte(Rd,(Rt,Rn)))
10360                     )
10361              else Skip ()
10362            end
10363          | (false,
10364           (false,
10365            (false,
10366             (true,
10367              (true,
10368               (true,
10369                (false,
10370                 (true,
10371                  (Rn'3,
10372                   (Rn'2,
10373                    (Rn'1,
10374                     (Rn'0,
10375                      (Rt'3,
10376                       (Rt'2,
10377                        (Rt'1,
10378                         (Rt'0,
10379                          (sb'0'1111'3,
10380                           (sb'0'1111'2,
10381                            (sb'0'1111'1,
10382                             (sb'0'1111'0,
10383                              (true,
10384                               (false,
10385                                (false,
10386                                 (true,
10387                                  (sb'1'1111'3,
10388                                   (sb'1'1111'2,(sb'1'1111'1,sb'1'1111'0))))))))))))))))))))))))))) =>
10389            let
10390              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10391              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10392              val GOOD_MATCH =
10393                ((BitsN.fromBitstring
10394                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
10395                 (BitsN.B(0xF,4))) andalso
10396                ((BitsN.fromBitstring
10397                    ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
10398                 (BitsN.B(0xF,4)))
10399            in
10400              if Do(cond,Set.mem((!Architecture),[ARMv6K,ARMv7_A,ARMv7_R]))
10401                then ( if (Rt = (BitsN.B(0xF,4))) orelse
10402                          ((Rn = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
10403                         then DECODE_UNPREDICTABLE(mc,"LoadExclusiveByte")
10404                       else ()
10405                     ; Load(LoadExclusiveByte(Rt,Rn))
10406                     )
10407              else Skip ()
10408            end
10409          | (false,
10410           (false,
10411            (false,
10412             (true,
10413              (true,
10414               (true,
10415                (true,
10416                 (false,
10417                  (Rn'3,
10418                   (Rn'2,
10419                    (Rn'1,
10420                     (Rn'0,
10421                      (Rd'3,
10422                       (Rd'2,
10423                        (Rd'1,
10424                         (Rd'0,
10425                          (sb'0'1111'3,
10426                           (sb'0'1111'2,
10427                            (sb'0'1111'1,
10428                             (sb'0'1111'0,
10429                              (true,
10430                               (false,
10431                                (false,(true,(Rt'3,(Rt'2,(Rt'1,Rt'0))))))))))))))))))))))))))) =>
10432            let
10433              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10434              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
10435              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10436              val GOOD_MATCH =
10437                (BitsN.fromBitstring
10438                   ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
10439                (BitsN.B(0xF,4))
10440            in
10441              if Do(cond,Set.mem((!Architecture),[ARMv6K,ARMv7_A,ARMv7_R]))
10442                then ( if (Rd = (BitsN.B(0xF,4))) orelse
10443                          ((Rt = (BitsN.B(0xF,4))) orelse
10444                           ((Rn = (BitsN.B(0xF,4))) orelse
10445                            ((Rd = Rn) orelse
10446                             ((Rd = Rt) orelse (not GOOD_MATCH)))))
10447                         then DECODE_UNPREDICTABLE
10448                                (mc,"StoreExclusiveHalf")
10449                       else ()
10450                     ; Store(StoreExclusiveHalf(Rd,(Rt,Rn)))
10451                     )
10452              else Skip ()
10453            end
10454          | (false,
10455           (false,
10456            (false,
10457             (true,
10458              (true,
10459               (true,
10460                (true,
10461                 (true,
10462                  (Rn'3,
10463                   (Rn'2,
10464                    (Rn'1,
10465                     (Rn'0,
10466                      (Rt'3,
10467                       (Rt'2,
10468                        (Rt'1,
10469                         (Rt'0,
10470                          (sb'0'1111'3,
10471                           (sb'0'1111'2,
10472                            (sb'0'1111'1,
10473                             (sb'0'1111'0,
10474                              (true,
10475                               (false,
10476                                (false,
10477                                 (true,
10478                                  (sb'1'1111'3,
10479                                   (sb'1'1111'2,(sb'1'1111'1,sb'1'1111'0))))))))))))))))))))))))))) =>
10480            let
10481              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10482              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10483              val GOOD_MATCH =
10484                ((BitsN.fromBitstring
10485                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
10486                 (BitsN.B(0xF,4))) andalso
10487                ((BitsN.fromBitstring
10488                    ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
10489                 (BitsN.B(0xF,4)))
10490            in
10491              if Do(cond,Set.mem((!Architecture),[ARMv6K,ARMv7_A,ARMv7_R]))
10492                then ( if (Rt = (BitsN.B(0xF,4))) orelse
10493                          ((Rn = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
10494                         then DECODE_UNPREDICTABLE(mc,"LoadExclusiveHalf")
10495                       else ()
10496                     ; Load(LoadExclusiveHalf(Rt,Rn))
10497                     )
10498              else Skip ()
10499            end
10500          | (false,
10501           (false,
10502            (false,
10503             (false,
10504              (U'0,
10505               (false,
10506                (true,
10507                 (false,
10508                  (Rn'3,
10509                   (Rn'2,
10510                    (Rn'1,
10511                     (Rn'0,
10512                      (Rt'3,
10513                       (Rt'2,
10514                        (Rt'1,
10515                         (Rt'0,
10516                          (sb'0'0000'3,
10517                           (sb'0'0000'2,
10518                            (sb'0'0000'1,
10519                             (sb'0'0000'0,
10520                              (true,
10521                               (false,
10522                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
10523            let
10524              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
10525              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10526              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10527              val GOOD_MATCH =
10528                (BitsN.fromBitstring
10529                   ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
10530                (BitsN.B(0x0,4))
10531            in
10532              if Do(cond,HaveThumb2 ())
10533                then ( if (Rt = (BitsN.B(0xF,4))) orelse
10534                          ((Rn = (BitsN.B(0xF,4))) orelse
10535                           ((Rn = Rt) orelse
10536                            ((Rm = (BitsN.B(0xF,4))) orelse
10537                             (not GOOD_MATCH))))
10538                         then DECODE_UNPREDICTABLE
10539                                (mc,"StoreHalfUnprivileged")
10540                       else ()
10541                     ; let
10542                         val add =
10543                           (BitsN.fromBitstring([U'0],1)) =
10544                           (BitsN.B(0x1,1))
10545                         val postindex = true
10546                         val m = register_form2 Rm
10547                       in
10548                         Store
10549                           (StoreHalfUnprivileged
10550                              (add,(postindex,(Rt,(Rn,m)))))
10551                       end
10552                     )
10553              else Skip ()
10554            end
10555          | (false,
10556           (false,
10557            (false,
10558             (P'0,
10559              (U'0,
10560               (false,
10561                (W'0,
10562                 (false,
10563                  (Rn'3,
10564                   (Rn'2,
10565                    (Rn'1,
10566                     (Rn'0,
10567                      (Rt'3,
10568                       (Rt'2,
10569                        (Rt'1,
10570                         (Rt'0,
10571                          (sb'0'0000'3,
10572                           (sb'0'0000'2,
10573                            (sb'0'0000'1,
10574                             (sb'0'0000'0,
10575                              (true,
10576                               (false,
10577                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
10578            let
10579              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
10580              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10581              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10582              val P = BitsN.fromBitstring([P'0],1)
10583              val GOOD_MATCH =
10584                (BitsN.fromBitstring
10585                   ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
10586                (BitsN.B(0x0,4))
10587            in
10588              if Do(cond,true)
10589                then let
10590                       val wback =
10591                         (P = (BitsN.B(0x0,1))) orelse
10592                         ((BitsN.fromBitstring([W'0],1)) =
10593                          (BitsN.B(0x1,1)))
10594                     in
10595                       ( if (Rt = (BitsN.B(0xF,4))) orelse
10596                            ((Rm = (BitsN.B(0xF,4))) orelse
10597                             ((wback andalso
10598                               ((Rn = (BitsN.B(0xF,4))) orelse (Rn = Rt))) orelse
10599                              (((Nat.<(ArchVersion (),6)) andalso
10600                                (wback andalso (Rm = Rn))) orelse
10601                               (not GOOD_MATCH))))
10602                           then DECODE_UNPREDICTABLE(mc,"StoreHalf")
10603                         else ()
10604                       ; let
10605                           val index = P = (BitsN.B(0x1,1))
10606                           val add =
10607                             (BitsN.fromBitstring([U'0],1)) =
10608                             (BitsN.B(0x1,1))
10609                           val (shift_t,shift_n) = (SRType_LSL,0)
10610                           val m = register_form1(Rm,(shift_t,shift_n))
10611                         in
10612                           Store
10613                             (StoreHalf(add,(index,(wback,(Rt,(Rn,m))))))
10614                         end
10615                       )
10616                     end
10617              else Skip ()
10618            end
10619          | (false,
10620           (false,
10621            (false,
10622             (false,
10623              (U'0,
10624               (false,
10625                (true,
10626                 (true,
10627                  (Rn'3,
10628                   (Rn'2,
10629                    (Rn'1,
10630                     (Rn'0,
10631                      (Rt'3,
10632                       (Rt'2,
10633                        (Rt'1,
10634                         (Rt'0,
10635                          (sb'0'0000'3,
10636                           (sb'0'0000'2,
10637                            (sb'0'0000'1,
10638                             (sb'0'0000'0,
10639                              (true,
10640                               (S'0,(H'0,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
10641            let
10642              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
10643              val H = BitsN.fromBitstring([H'0],1)
10644              val S = BitsN.fromBitstring([S'0],1)
10645              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10646              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10647              val GOOD_MATCH =
10648                (BitsN.fromBitstring
10649                   ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
10650                (BitsN.B(0x0,4))
10651            in
10652              if Do(cond,
10653                    ((not(H = (BitsN.B(0x0,1)))) orelse
10654                     (S = (BitsN.B(0x1,1)))) andalso (HaveThumb2 ()))
10655                then ( if (Rt = (BitsN.B(0xF,4))) orelse
10656                          ((Rn = (BitsN.B(0xF,4))) orelse
10657                           ((Rn = Rt) orelse
10658                            ((Rm = (BitsN.B(0xF,4))) orelse
10659                             (not GOOD_MATCH))))
10660                         then DECODE_UNPREDICTABLE
10661                                (mc,"LoadHalf/Byte (unprivileged)")
10662                       else ()
10663                     ; let
10664                         val add =
10665                           (BitsN.fromBitstring([U'0],1)) =
10666                           (BitsN.B(0x1,1))
10667                         val postindex = true
10668                         val unsigned = S = (BitsN.B(0x0,1))
10669                         val m = register_form2 Rm
10670                       in
10671                         if H = (BitsN.B(0x1,1))
10672                           then Load
10673                                  (LoadHalfUnprivileged
10674                                     (unsigned,
10675                                      (add,(postindex,(Rt,(Rn,m))))))
10676                         else Load
10677                                (LoadSignedByteUnprivileged
10678                                   (add,(postindex,(Rt,(Rn,m)))))
10679                       end
10680                     )
10681              else Skip ()
10682            end
10683          | (false,
10684           (false,
10685            (false,
10686             (P'0,
10687              (U'0,
10688               (false,
10689                (W'0,
10690                 (true,
10691                  (Rn'3,
10692                   (Rn'2,
10693                    (Rn'1,
10694                     (Rn'0,
10695                      (Rt'3,
10696                       (Rt'2,
10697                        (Rt'1,
10698                         (Rt'0,
10699                          (sb'0'0000'3,
10700                           (sb'0'0000'2,
10701                            (sb'0'0000'1,
10702                             (sb'0'0000'0,
10703                              (true,
10704                               (S'0,(H'0,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
10705            let
10706              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
10707              val H = BitsN.fromBitstring([H'0],1)
10708              val S = BitsN.fromBitstring([S'0],1)
10709              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10710              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10711              val P = BitsN.fromBitstring([P'0],1)
10712              val GOOD_MATCH =
10713                (BitsN.fromBitstring
10714                   ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
10715                (BitsN.B(0x0,4))
10716            in
10717              if Do(cond,
10718                    (not(H = (BitsN.B(0x0,1)))) orelse
10719                    (S = (BitsN.B(0x1,1))))
10720                then let
10721                       val wback =
10722                         (P = (BitsN.B(0x0,1))) orelse
10723                         ((BitsN.fromBitstring([W'0],1)) =
10724                          (BitsN.B(0x1,1)))
10725                     in
10726                       ( if (Rt = (BitsN.B(0xF,4))) orelse
10727                            ((Rm = (BitsN.B(0xF,4))) orelse
10728                             (((Nat.<(ArchVersion (),6)) andalso
10729                               (wback andalso (Rm = Rn))) orelse
10730                              (not GOOD_MATCH)))
10731                           then DECODE_UNPREDICTABLE(mc,"LoadHalf/Byte")
10732                         else ()
10733                       ; let
10734                           val index = P = (BitsN.B(0x1,1))
10735                           val add =
10736                             (BitsN.fromBitstring([U'0],1)) =
10737                             (BitsN.B(0x1,1))
10738                           val (shift_t,shift_n) = (SRType_LSL,0)
10739                           val unsigned = S = (BitsN.B(0x0,1))
10740                           val m = register_form1(Rm,(shift_t,shift_n))
10741                         in
10742                           if H = (BitsN.B(0x1,1))
10743                             then Load
10744                                    (LoadHalf
10745                                       (unsigned,
10746                                        (add,(index,(wback,(Rt,(Rn,m)))))))
10747                           else Load
10748                                  (LoadByte
10749                                     (unsigned,
10750                                      (add,(index,(wback,(Rt,(Rn,m)))))))
10751                         end
10752                       )
10753                     end
10754              else Skip ()
10755            end
10756          | (false,
10757           (false,
10758            (false,
10759             (P'0,
10760              (U'0,
10761               (false,
10762                (W'0,
10763                 (false,
10764                  (Rn'3,
10765                   (Rn'2,
10766                    (Rn'1,
10767                     (Rn'0,
10768                      (Rt'3,
10769                       (Rt'2,
10770                        (Rt'1,
10771                         (Rt'0,
10772                          (sb'0'0000'3,
10773                           (sb'0'0000'2,
10774                            (sb'0'0000'1,
10775                             (sb'0'0000'0,
10776                              (true,
10777                               (true,
10778                                (S'0,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
10779            let
10780              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
10781              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10782              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10783              val W = BitsN.fromBitstring([W'0],1)
10784              val P = BitsN.fromBitstring([P'0],1)
10785              val GOOD_MATCH =
10786                (BitsN.fromBitstring
10787                   ([sb'0'0000'3,sb'0'0000'2,sb'0'0000'1,sb'0'0000'0],4)) =
10788                (BitsN.B(0x0,4))
10789            in
10790              if Do(cond,HaveDSPSupport ())
10791                then let
10792                       val Rt2 = BitsN.+(Rt,BitsN.B(0x1,4))
10793                       val wback =
10794                         (P = (BitsN.B(0x0,1))) orelse
10795                         (W = (BitsN.B(0x1,1)))
10796                       val store =
10797                         (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
10798                     in
10799                       ( if (BitsN.bit(Rt,0)) orelse
10800                            (((P = (BitsN.B(0x0,1))) andalso
10801                              (W = (BitsN.B(0x1,1)))) orelse
10802                             ((Rt2 = (BitsN.B(0xF,4))) orelse
10803                              ((Rm = (BitsN.B(0xF,4))) orelse
10804                               (((not store) andalso
10805                                 ((Rm = Rt) orelse (Rm = Rt2))) orelse
10806                                ((wback andalso
10807                                  ((Rn = (BitsN.B(0xF,4))) orelse
10808                                   ((Rn = Rt) orelse (Rn = Rt2)))) orelse
10809                                 (((Nat.<(ArchVersion (),6)) andalso
10810                                   (wback andalso (Rm = Rn))) orelse
10811                                  (not GOOD_MATCH)))))))
10812                           then DECODE_UNPREDICTABLE
10813                                  (mc,"Load/StoreDual (register)")
10814                         else ()
10815                       ; let
10816                           val index = P = (BitsN.B(0x1,1))
10817                           val add =
10818                             (BitsN.fromBitstring([U'0],1)) =
10819                             (BitsN.B(0x1,1))
10820                           val m = register_form2 Rm
10821                         in
10822                           if store
10823                             then Store
10824                                    (StoreDual
10825                                       (add,
10826                                        (index,(wback,(Rt,(Rt2,(Rn,m)))))))
10827                           else Load
10828                                  (LoadDual
10829                                     (add,
10830                                      (index,(wback,(Rt,(Rt2,(Rn,m)))))))
10831                         end
10832                       )
10833                     end
10834              else Skip ()
10835            end
10836          | (false,
10837           (false,
10838            (false,
10839             (sb'0'1'0,
10840              (U'0,
10841               (true,
10842                (sb'1'0'0,
10843                 (false,
10844                  (true,
10845                   (true,
10846                    (true,
10847                     (true,
10848                      (Rt'3,
10849                       (Rt'2,
10850                        (Rt'1,
10851                         (Rt'0,
10852                          (imm4H'3,
10853                           (imm4H'2,
10854                            (imm4H'1,
10855                             (imm4H'0,
10856                              (true,
10857                               (true,
10858                                (false,
10859                                 (true,
10860                                  (imm4L'3,(imm4L'2,(imm4L'1,imm4L'0))))))))))))))))))))))))))) =>
10861            let
10862              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10863              val GOOD_MATCH =
10864                ((BitsN.fromBitstring([sb'0'1'0],1)) = (BitsN.B(0x1,1))) andalso
10865                ((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1)))
10866            in
10867              if Do(cond,HaveDSPSupport ())
10868                then let
10869                       val Rt2 = BitsN.+(Rt,BitsN.B(0x1,4))
10870                     in
10871                       ( if (BitsN.bit(Rt,0)) orelse
10872                            ((Rt2 = (BitsN.B(0xF,4))) orelse
10873                             (not GOOD_MATCH))
10874                           then DECODE_UNPREDICTABLE
10875                                  (mc,"LoadDual (literal)")
10876                         else ()
10877                       ; let
10878                           val add =
10879                             (BitsN.fromBitstring([U'0],1)) =
10880                             (BitsN.B(0x1,1))
10881                           val imm32 =
10882                             BitsN.zeroExtend 32
10883                               (BitsN.@@
10884                                  (BitsN.fromBitstring
10885                                     ([imm4H'3,imm4H'2,imm4H'1,imm4H'0],4),
10886                                   BitsN.fromBitstring
10887                                     ([imm4L'3,imm4L'2,imm4L'1,imm4L'0],4)))
10888                         in
10889                           Load(LoadDualLiteral(add,(Rt,(Rt2,imm32))))
10890                         end
10891                       )
10892                     end
10893              else Skip ()
10894            end
10895          | (false,
10896           (false,
10897            (false,
10898             (P'0,
10899              (U'0,
10900               (true,
10901                (W'0,
10902                 (false,
10903                  (Rn'3,
10904                   (Rn'2,
10905                    (Rn'1,
10906                     (Rn'0,
10907                      (Rt'3,
10908                       (Rt'2,
10909                        (Rt'1,
10910                         (Rt'0,
10911                          (imm4H'3,
10912                           (imm4H'2,
10913                            (imm4H'1,
10914                             (imm4H'0,
10915                              (true,
10916                               (true,
10917                                (S'0,
10918                                 (true,
10919                                  (imm4L'3,(imm4L'2,(imm4L'1,imm4L'0))))))))))))))))))))))))))) =>
10920            let
10921              val S = BitsN.fromBitstring([S'0],1)
10922              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
10923              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
10924              val W = BitsN.fromBitstring([W'0],1)
10925              val P = BitsN.fromBitstring([P'0],1)
10926            in
10927              if Do(cond,HaveDSPSupport ())
10928                then let
10929                       val Rt2 = BitsN.+(Rt,BitsN.B(0x1,4))
10930                       val wback =
10931                         (P = (BitsN.B(0x0,1))) orelse
10932                         (W = (BitsN.B(0x1,1)))
10933                     in
10934                       ( if (BitsN.bit(Rt,0)) orelse
10935                            (((P = (BitsN.B(0x0,1))) andalso
10936                              (W = (BitsN.B(0x1,1)))) orelse
10937                             ((wback andalso
10938                               (((S = (BitsN.B(0x1,1))) andalso
10939                                 (Rn = (BitsN.B(0xF,4)))) orelse
10940                                ((Rn = Rt) orelse (Rn = Rt2)))) orelse
10941                              (Rt2 = (BitsN.B(0xF,4)))))
10942                           then DECODE_UNPREDICTABLE
10943                                  (mc,"Load/StoreDual (immediate)")
10944                         else ()
10945                       ; let
10946                           val index = P = (BitsN.B(0x1,1))
10947                           val add =
10948                             (BitsN.fromBitstring([U'0],1)) =
10949                             (BitsN.B(0x1,1))
10950                           val imm32 =
10951                             BitsN.zeroExtend 32
10952                               (BitsN.@@
10953                                  (BitsN.fromBitstring
10954                                     ([imm4H'3,imm4H'2,imm4H'1,imm4H'0],4),
10955                                   BitsN.fromBitstring
10956                                     ([imm4L'3,imm4L'2,imm4L'1,imm4L'0],4)))
10957                           val m = immediate_form2 imm32
10958                         in
10959                           if S = (BitsN.B(0x1,1))
10960                             then Store
10961                                    (StoreDual
10962                                       (add,
10963                                        (index,(wback,(Rt,(Rt2,(Rn,m)))))))
10964                           else Load
10965                                  (LoadDual
10966                                     (add,
10967                                      (index,(wback,(Rt,(Rt2,(Rn,m)))))))
10968                         end
10969                       )
10970                     end
10971              else Skip ()
10972            end
10973          | (false,
10974           (false,
10975            (false,
10976             (false,
10977              (U'0,
10978               (true,
10979                (true,
10980                 (true,
10981                  (Rn'3,
10982                   (Rn'2,
10983                    (Rn'1,
10984                     (Rn'0,
10985                      (Rt'3,
10986                       (Rt'2,
10987                        (Rt'1,
10988                         (Rt'0,
10989                          (imm4H'3,
10990                           (imm4H'2,
10991                            (imm4H'1,
10992                             (imm4H'0,
10993                              (true,
10994                               (S'0,
10995                                (H'0,
10996                                 (true,
10997                                  (imm4L'3,(imm4L'2,(imm4L'1,imm4L'0))))))))))))))))))))))))))) =>
10998            let
10999              val H = BitsN.fromBitstring([H'0],1)
11000              val S = BitsN.fromBitstring([S'0],1)
11001              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11002              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11003            in
11004              if Do(cond,
11005                    ((not(H = (BitsN.B(0x0,1)))) orelse
11006                     (S = (BitsN.B(0x1,1)))) andalso (HaveThumb2 ()))
11007                then ( if (Rt = (BitsN.B(0xF,4))) orelse
11008                          ((Rn = (BitsN.B(0xF,4))) orelse (Rn = Rt))
11009                         then DECODE_UNPREDICTABLE
11010                                (mc,"LoadHalf/Byte (unprivileged)")
11011                       else ()
11012                     ; let
11013                         val postindex = true
11014                         val add =
11015                           (BitsN.fromBitstring([U'0],1)) =
11016                           (BitsN.B(0x1,1))
11017                         val unsigned = S = (BitsN.B(0x0,1))
11018                         val imm32 =
11019                           BitsN.zeroExtend 32
11020                             (BitsN.@@
11021                                (BitsN.fromBitstring
11022                                   ([imm4H'3,imm4H'2,imm4H'1,imm4H'0],4),
11023                                 BitsN.fromBitstring
11024                                   ([imm4L'3,imm4L'2,imm4L'1,imm4L'0],4)))
11025                         val m = immediate_form2 imm32
11026                       in
11027                         if H = (BitsN.B(0x1,1))
11028                           then Load
11029                                  (LoadHalfUnprivileged
11030                                     (unsigned,
11031                                      (add,(postindex,(Rt,(Rn,m))))))
11032                         else Load
11033                                (LoadSignedByteUnprivileged
11034                                   (add,(postindex,(Rt,(Rn,m)))))
11035                       end
11036                     )
11037              else Skip ()
11038            end
11039          | (false,
11040           (false,
11041            (false,
11042             (sb'0'1'0,
11043              (U'0,
11044               (true,
11045                (sb'1'0'0,
11046                 (true,
11047                  (true,
11048                   (true,
11049                    (true,
11050                     (true,
11051                      (Rt'3,
11052                       (Rt'2,
11053                        (Rt'1,
11054                         (Rt'0,
11055                          (imm4H'3,
11056                           (imm4H'2,
11057                            (imm4H'1,
11058                             (imm4H'0,
11059                              (true,
11060                               (S'0,
11061                                (H'0,
11062                                 (true,
11063                                  (imm4L'3,(imm4L'2,(imm4L'1,imm4L'0))))))))))))))))))))))))))) =>
11064            let
11065              val H = BitsN.fromBitstring([H'0],1)
11066              val S = BitsN.fromBitstring([S'0],1)
11067              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11068              val GOOD_MATCH =
11069                ((BitsN.fromBitstring([sb'0'1'0],1)) = (BitsN.B(0x1,1))) andalso
11070                ((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1)))
11071            in
11072              if Do(cond,
11073                    (not(H = (BitsN.B(0x0,1)))) orelse
11074                    (S = (BitsN.B(0x1,1))))
11075                then ( if (Rt = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH)
11076                         then DECODE_UNPREDICTABLE
11077                                (mc,"LoadHalf/Byte (literal)")
11078                       else ()
11079                     ; let
11080                         val add =
11081                           (BitsN.fromBitstring([U'0],1)) =
11082                           (BitsN.B(0x1,1))
11083                         val unsigned = S = (BitsN.B(0x0,1))
11084                         val imm32 =
11085                           BitsN.zeroExtend 32
11086                             (BitsN.@@
11087                                (BitsN.fromBitstring
11088                                   ([imm4H'3,imm4H'2,imm4H'1,imm4H'0],4),
11089                                 BitsN.fromBitstring
11090                                   ([imm4L'3,imm4L'2,imm4L'1,imm4L'0],4)))
11091                       in
11092                         if H = (BitsN.B(0x1,1))
11093                           then Load
11094                                  (LoadHalfLiteral
11095                                     (unsigned,(add,(Rt,imm32))))
11096                         else Load
11097                                (LoadByteLiteral
11098                                   (unsigned,(add,(Rt,imm32))))
11099                       end
11100                     )
11101              else Skip ()
11102            end
11103          | (false,
11104           (false,
11105            (false,
11106             (P'0,
11107              (U'0,
11108               (true,
11109                (W'0,
11110                 (true,
11111                  (Rn'3,
11112                   (Rn'2,
11113                    (Rn'1,
11114                     (Rn'0,
11115                      (Rt'3,
11116                       (Rt'2,
11117                        (Rt'1,
11118                         (Rt'0,
11119                          (imm4H'3,
11120                           (imm4H'2,
11121                            (imm4H'1,
11122                             (imm4H'0,
11123                              (true,
11124                               (S'0,
11125                                (H'0,
11126                                 (true,
11127                                  (imm4L'3,(imm4L'2,(imm4L'1,imm4L'0))))))))))))))))))))))))))) =>
11128            let
11129              val H = BitsN.fromBitstring([H'0],1)
11130              val S = BitsN.fromBitstring([S'0],1)
11131              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11132              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11133              val P = BitsN.fromBitstring([P'0],1)
11134            in
11135              if Do(cond,
11136                    (not(H = (BitsN.B(0x0,1)))) orelse
11137                    (S = (BitsN.B(0x1,1))))
11138                then let
11139                       val wback =
11140                         (P = (BitsN.B(0x0,1))) orelse
11141                         ((BitsN.fromBitstring([W'0],1)) =
11142                          (BitsN.B(0x1,1)))
11143                     in
11144                       ( if (Rt = (BitsN.B(0xF,4))) orelse
11145                            (wback andalso (Rn = Rt))
11146                           then DECODE_UNPREDICTABLE
11147                                  (mc,"LoadHalf/Byte (immediate)")
11148                         else ()
11149                       ; let
11150                           val index = P = (BitsN.B(0x1,1))
11151                           val add =
11152                             (BitsN.fromBitstring([U'0],1)) =
11153                             (BitsN.B(0x1,1))
11154                           val unsigned = S = (BitsN.B(0x0,1))
11155                           val imm32 =
11156                             BitsN.zeroExtend 32
11157                               (BitsN.@@
11158                                  (BitsN.fromBitstring
11159                                     ([imm4H'3,imm4H'2,imm4H'1,imm4H'0],4),
11160                                   BitsN.fromBitstring
11161                                     ([imm4L'3,imm4L'2,imm4L'1,imm4L'0],4)))
11162                           val m = immediate_form1 imm32
11163                         in
11164                           if H = (BitsN.B(0x1,1))
11165                             then Load
11166                                    (LoadHalf
11167                                       (unsigned,
11168                                        (add,(index,(wback,(Rt,(Rn,m)))))))
11169                           else Load
11170                                  (LoadByte
11171                                     (unsigned,
11172                                      (add,(index,(wback,(Rt,(Rn,m)))))))
11173                         end
11174                       )
11175                     end
11176              else Skip ()
11177            end
11178          | (false,
11179           (false,
11180            (false,
11181             (false,
11182              (U'0,
11183               (true,
11184                (true,
11185                 (false,
11186                  (Rn'3,
11187                   (Rn'2,
11188                    (Rn'1,
11189                     (Rn'0,
11190                      (Rt'3,
11191                       (Rt'2,
11192                        (Rt'1,
11193                         (Rt'0,
11194                          (imm4H'3,
11195                           (imm4H'2,
11196                            (imm4H'1,
11197                             (imm4H'0,
11198                              (true,
11199                               (false,
11200                                (true,
11201                                 (true,
11202                                  (imm4L'3,(imm4L'2,(imm4L'1,imm4L'0))))))))))))))))))))))))))) =>
11203            let
11204              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11205              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11206            in
11207              if Do(cond,HaveThumb2 ())
11208                then ( if (Rt = (BitsN.B(0xF,4))) orelse
11209                          ((Rn = (BitsN.B(0xF,4))) orelse (Rn = Rt))
11210                         then DECODE_UNPREDICTABLE
11211                                (mc,"StoreHalf (immediate)")
11212                       else ()
11213                     ; let
11214                         val add =
11215                           (BitsN.fromBitstring([U'0],1)) =
11216                           (BitsN.B(0x1,1))
11217                         val postindex = true
11218                         val imm32 =
11219                           BitsN.zeroExtend 32
11220                             (BitsN.@@
11221                                (BitsN.fromBitstring
11222                                   ([imm4H'3,imm4H'2,imm4H'1,imm4H'0],4),
11223                                 BitsN.fromBitstring
11224                                   ([imm4L'3,imm4L'2,imm4L'1,imm4L'0],4)))
11225                         val m = immediate_form2 imm32
11226                       in
11227                         Store
11228                           (StoreHalfUnprivileged
11229                              (add,(postindex,(Rt,(Rn,m)))))
11230                       end
11231                     )
11232              else Skip ()
11233            end
11234          | (false,
11235           (false,
11236            (false,
11237             (P'0,
11238              (U'0,
11239               (true,
11240                (W'0,
11241                 (false,
11242                  (Rn'3,
11243                   (Rn'2,
11244                    (Rn'1,
11245                     (Rn'0,
11246                      (Rt'3,
11247                       (Rt'2,
11248                        (Rt'1,
11249                         (Rt'0,
11250                          (imm4H'3,
11251                           (imm4H'2,
11252                            (imm4H'1,
11253                             (imm4H'0,
11254                              (true,
11255                               (false,
11256                                (true,
11257                                 (true,
11258                                  (imm4L'3,(imm4L'2,(imm4L'1,imm4L'0))))))))))))))))))))))))))) =>
11259            let
11260              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11261              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11262              val P = BitsN.fromBitstring([P'0],1)
11263            in
11264              if Do(cond,true)
11265                then let
11266                       val wback =
11267                         (P = (BitsN.B(0x0,1))) orelse
11268                         ((BitsN.fromBitstring([W'0],1)) =
11269                          (BitsN.B(0x1,1)))
11270                     in
11271                       ( if (Rt = (BitsN.B(0xF,4))) orelse
11272                            (wback andalso
11273                             ((Rn = (BitsN.B(0xF,4))) orelse (Rn = Rt)))
11274                           then DECODE_UNPREDICTABLE
11275                                  (mc,"StoreHalf (immediate)")
11276                         else ()
11277                       ; let
11278                           val index = P = (BitsN.B(0x1,1))
11279                           val add =
11280                             (BitsN.fromBitstring([U'0],1)) =
11281                             (BitsN.B(0x1,1))
11282                           val imm32 =
11283                             BitsN.zeroExtend 32
11284                               (BitsN.@@
11285                                  (BitsN.fromBitstring
11286                                     ([imm4H'3,imm4H'2,imm4H'1,imm4H'0],4),
11287                                   BitsN.fromBitstring
11288                                     ([imm4L'3,imm4L'2,imm4L'1,imm4L'0],4)))
11289                           val m = immediate_form1 imm32
11290                         in
11291                           Store
11292                             (StoreHalf(add,(index,(wback,(Rt,(Rn,m))))))
11293                         end
11294                       )
11295                     end
11296              else Skip ()
11297            end
11298          | (false,
11299           (false,
11300            (true,
11301             (true,
11302              (false,
11303               (H'0,
11304                (false,
11305                 (false,
11306                  (imm4'3,
11307                   (imm4'2,
11308                    (imm4'1,
11309                     (imm4'0,
11310                      (Rd'3,
11311                       (Rd'2,
11312                        (Rd'1,
11313                         (Rd'0,
11314                          (imm12'11,
11315                           (imm12'10,
11316                            (imm12'9,
11317                             (imm12'8,
11318                              (imm12'7,
11319                               (imm12'6,
11320                                (imm12'5,
11321                                 (imm12'4,
11322                                  (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
11323            let
11324              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
11325            in
11326              if Do(cond,HaveThumb2 ())
11327                then ( if Rd = (BitsN.B(0xF,4))
11328                         then DECODE_UNPREDICTABLE(mc,"MoveTopHalfword")
11329                       else ()
11330                     ; let
11331                         val imm16 =
11332                           BitsN.@@
11333                             (BitsN.fromBitstring
11334                                ([imm4'3,imm4'2,imm4'1,imm4'0],4),
11335                              BitsN.fromBitstring
11336                                ([imm12'11,imm12'10,imm12'9,imm12'8,
11337                                  imm12'7,imm12'6,imm12'5,imm12'4,imm12'3,
11338                                  imm12'2,imm12'1,imm12'0],12))
11339                         val high =
11340                           (BitsN.fromBitstring([H'0],1)) =
11341                           (BitsN.B(0x1,1))
11342                       in
11343                         Data(MoveHalfword(high,(Rd,imm16)))
11344                       end
11345                     )
11346              else Skip ()
11347            end
11348          | (false,
11349           (false,
11350            (true,
11351             (true,
11352              (false,
11353               (false,
11354                (true,
11355                 (false,
11356                  (false,
11357                   (false,
11358                    (false,
11359                     (false,
11360                      (sb'0'1111'3,
11361                       (sb'0'1111'2,
11362                        (sb'0'1111'1,
11363                         (sb'0'1111'0,
11364                          (sb'1'0000'3,
11365                           (sb'1'0000'2,
11366                            (sb'1'0000'1,
11367                             (sb'1'0000'0,
11368                              (op'7,
11369                               (op'6,
11370                                (op'5,(op'4,(op'3,(op'2,(op'1,op'0))))))))))))))))))))))))))) =>
11371            let
11372              val GOOD_MATCH =
11373                ((BitsN.fromBitstring
11374                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
11375                 (BitsN.B(0xF,4))) andalso
11376                ((BitsN.fromBitstring
11377                    ([sb'1'0000'3,sb'1'0000'2,sb'1'0000'1,sb'1'0000'0],4)) =
11378                 (BitsN.B(0x0,4)))
11379            in
11380              ( if not GOOD_MATCH
11381                  then DECODE_UNPREDICTABLE(mc,"Hint")
11382                else ()
11383              ; DecodeHint
11384                  (cond,
11385                   BitsN.fromBitstring
11386                     ([op'7,op'6,op'5,op'4,op'3,op'2,op'1,op'0],8))
11387              )
11388            end
11389          | (false,
11390           (false,
11391            (true,
11392             (true,
11393              (false,
11394               (R'0,
11395                (true,
11396                 (false,
11397                  (mask'3,
11398                   (mask'2,
11399                    (mask'1,
11400                     (mask'0,
11401                      (sb'0'1111'3,
11402                       (sb'0'1111'2,
11403                        (sb'0'1111'1,
11404                         (sb'0'1111'0,
11405                          (imm12'11,
11406                           (imm12'10,
11407                            (imm12'9,
11408                             (imm12'8,
11409                              (imm12'7,
11410                               (imm12'6,
11411                                (imm12'5,
11412                                 (imm12'4,
11413                                  (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
11414            let
11415              val mask =
11416                BitsN.fromBitstring([mask'3,mask'2,mask'1,mask'0],4)
11417              val GOOD_MATCH =
11418                (BitsN.fromBitstring
11419                   ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
11420                (BitsN.B(0xF,4))
11421            in
11422              if Do(cond,true)
11423                then ( if (mask = (BitsN.B(0x0,4))) orelse
11424                          (not GOOD_MATCH)
11425                         then DECODE_UNPREDICTABLE
11426                                (mc,"MoveToSpecialFromImmediate")
11427                       else ()
11428                     ; let
11429                         val write_spsr =
11430                           (BitsN.fromBitstring([R'0],1)) =
11431                           (BitsN.B(0x1,1))
11432                         val imm32 =
11433                           ARMExpandImm
11434                             (BitsN.fromBitstring
11435                                ([imm12'11,imm12'10,imm12'9,imm12'8,
11436                                  imm12'7,imm12'6,imm12'5,imm12'4,imm12'3,
11437                                  imm12'2,imm12'1,imm12'0],12))
11438                       in
11439                         System
11440                           (MoveToSpecialFromImmediate
11441                              (write_spsr,(imm32,mask)))
11442                       end
11443                     )
11444              else Skip ()
11445            end
11446          | (false,
11447           (false,
11448            (true,
11449             (opc'3,
11450              (opc'2,
11451               (opc'1,
11452                (opc'0,
11453                 (S'0,
11454                  (Rn'3,
11455                   (Rn'2,
11456                    (Rn'1,
11457                     (Rn'0,
11458                      (Rd'3,
11459                       (Rd'2,
11460                        (Rd'1,
11461                         (Rd'0,
11462                          (imm12'11,
11463                           (imm12'10,
11464                            (imm12'9,
11465                             (imm12'8,
11466                              (imm12'7,
11467                               (imm12'6,
11468                                (imm12'5,
11469                                 (imm12'4,
11470                                  (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
11471            let
11472              val imm12 =
11473                BitsN.fromBitstring
11474                  ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,imm12'6,
11475                    imm12'5,imm12'4,imm12'3,imm12'2,imm12'1,imm12'0],12)
11476              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
11477              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11478              val opc = BitsN.fromBitstring([opc'3,opc'2,opc'1,opc'0],4)
11479            in
11480              if Do(cond,true)
11481                then let
11482                       val setflags =
11483                         (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
11484                     in
11485                       case boolify'4 opc of
11486                          (true,(true,(N'0,true))) =>
11487                            Data
11488                              (Move
11489                                 (setflags,
11490                                  ((not o L3.equal (BitsN.zero (1)))
11491                                     (BitsN.fromBitstring([N'0],1)),
11492                                   (Rd,imm12))))
11493                        | (true,(false,(op'1,op'0))) =>
11494                          Data
11495                            (TestCompareImmediate
11496                               (BitsN.fromBitstring([op'1,op'0],2),
11497                                (Rn,imm12)))
11498                        | _ =>
11499                          Data
11500                            (ArithLogicImmediate
11501                               (opc,(setflags,(Rd,(Rn,imm12)))))
11502                     end
11503              else Skip ()
11504            end
11505          | (false,
11506           (true,
11507            (false,
11508             (false,
11509              (U'0,
11510               (B'0,
11511                (true,
11512                 (false,
11513                  (Rn'3,
11514                   (Rn'2,
11515                    (Rn'1,
11516                     (Rn'0,
11517                      (Rt'3,
11518                       (Rt'2,
11519                        (Rt'1,
11520                         (Rt'0,
11521                          (imm12'11,
11522                           (imm12'10,
11523                            (imm12'9,
11524                             (imm12'8,
11525                              (imm12'7,
11526                               (imm12'6,
11527                                (imm12'5,
11528                                 (imm12'4,
11529                                  (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
11530            let
11531              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11532              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11533              val B = BitsN.fromBitstring([B'0],1)
11534            in
11535              if Do(cond,true)
11536                then ( if ((B = (BitsN.B(0x1,1))) andalso
11537                           (Rt = (BitsN.B(0xF,4)))) orelse
11538                          ((Rn = (BitsN.B(0xF,4))) orelse (Rn = Rt))
11539                         then DECODE_UNPREDICTABLE
11540                                (mc,"StoreUnprivileged (immediate)")
11541                       else ()
11542                     ; let
11543                         val add =
11544                           (BitsN.fromBitstring([U'0],1)) =
11545                           (BitsN.B(0x1,1))
11546                         val postindex = true
11547                         val imm32 =
11548                           BitsN.zeroExtend 32
11549                             (BitsN.fromBitstring
11550                                ([imm12'11,imm12'10,imm12'9,imm12'8,
11551                                  imm12'7,imm12'6,imm12'5,imm12'4,imm12'3,
11552                                  imm12'2,imm12'1,imm12'0],12))
11553                         val m = immediate_form1 imm32
11554                       in
11555                         if B = (BitsN.B(0x1,1))
11556                           then Store
11557                                  (StoreByteUnprivileged
11558                                     (add,(postindex,(Rt,(Rn,m)))))
11559                         else Store
11560                                (StoreUnprivileged
11561                                   (add,(postindex,(Rt,(Rn,m)))))
11562                       end
11563                     )
11564              else Skip ()
11565            end
11566          | (false,
11567           (true,
11568            (false,
11569             (P'0,
11570              (U'0,
11571               (B'0,
11572                (W'0,
11573                 (false,
11574                  (Rn'3,
11575                   (Rn'2,
11576                    (Rn'1,
11577                     (Rn'0,
11578                      (Rt'3,
11579                       (Rt'2,
11580                        (Rt'1,
11581                         (Rt'0,
11582                          (imm12'11,
11583                           (imm12'10,
11584                            (imm12'9,
11585                             (imm12'8,
11586                              (imm12'7,
11587                               (imm12'6,
11588                                (imm12'5,
11589                                 (imm12'4,
11590                                  (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
11591            let
11592              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11593              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11594              val B = BitsN.fromBitstring([B'0],1)
11595              val P = BitsN.fromBitstring([P'0],1)
11596            in
11597              if Do(cond,true)
11598                then let
11599                       val wback =
11600                         (P = (BitsN.B(0x0,1))) orelse
11601                         ((BitsN.fromBitstring([W'0],1)) =
11602                          (BitsN.B(0x1,1)))
11603                     in
11604                       ( if ((B = (BitsN.B(0x1,1))) andalso
11605                             (Rt = (BitsN.B(0xF,4)))) orelse
11606                            (wback andalso
11607                             ((Rn = (BitsN.B(0xF,4))) orelse (Rn = Rt)))
11608                           then DECODE_UNPREDICTABLE
11609                                  (mc,"Store (immediate)")
11610                         else ()
11611                       ; let
11612                           val add =
11613                             (BitsN.fromBitstring([U'0],1)) =
11614                             (BitsN.B(0x1,1))
11615                           val index = P = (BitsN.B(0x1,1))
11616                           val imm32 =
11617                             BitsN.zeroExtend 32
11618                               (BitsN.fromBitstring
11619                                  ([imm12'11,imm12'10,imm12'9,imm12'8,
11620                                    imm12'7,imm12'6,imm12'5,imm12'4,
11621                                    imm12'3,imm12'2,imm12'1,imm12'0],12))
11622                           val m = immediate_form1 imm32
11623                         in
11624                           if B = (BitsN.B(0x1,1))
11625                             then Store
11626                                    (StoreByte
11627                                       (add,(index,(wback,(Rt,(Rn,m))))))
11628                           else Store
11629                                  (StoreWord
11630                                     (add,(index,(wback,(Rt,(Rn,m))))))
11631                         end
11632                       )
11633                     end
11634              else Skip ()
11635            end
11636          | (false,
11637           (true,
11638            (false,
11639             (false,
11640              (U'0,
11641               (B'0,
11642                (true,
11643                 (true,
11644                  (Rn'3,
11645                   (Rn'2,
11646                    (Rn'1,
11647                     (Rn'0,
11648                      (Rt'3,
11649                       (Rt'2,
11650                        (Rt'1,
11651                         (Rt'0,
11652                          (imm12'11,
11653                           (imm12'10,
11654                            (imm12'9,
11655                             (imm12'8,
11656                              (imm12'7,
11657                               (imm12'6,
11658                                (imm12'5,
11659                                 (imm12'4,
11660                                  (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
11661            let
11662              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11663              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11664            in
11665              if Do(cond,true)
11666                then ( if (Rt = (BitsN.B(0xF,4))) orelse
11667                          ((Rn = (BitsN.B(0xF,4))) orelse (Rn = Rt))
11668                         then DECODE_UNPREDICTABLE
11669                                (mc,"LoadUnprivileged (immediate)")
11670                       else ()
11671                     ; let
11672                         val add =
11673                           (BitsN.fromBitstring([U'0],1)) =
11674                           (BitsN.B(0x1,1))
11675                         val postindex = true
11676                         val imm32 =
11677                           BitsN.zeroExtend 32
11678                             (BitsN.fromBitstring
11679                                ([imm12'11,imm12'10,imm12'9,imm12'8,
11680                                  imm12'7,imm12'6,imm12'5,imm12'4,imm12'3,
11681                                  imm12'2,imm12'1,imm12'0],12))
11682                         val m = immediate_form1 imm32
11683                       in
11684                         if (BitsN.fromBitstring([B'0],1)) =
11685                            (BitsN.B(0x1,1))
11686                           then Load
11687                                  (LoadByteUnprivileged
11688                                     (add,(postindex,(Rt,(Rn,m)))))
11689                         else Load
11690                                (LoadUnprivileged
11691                                   (add,(postindex,(Rt,(Rn,m)))))
11692                       end
11693                     )
11694              else Skip ()
11695            end
11696          | (false,
11697           (true,
11698            (false,
11699             (sb'0'1'0,
11700              (U'0,
11701               (B'0,
11702                (sb'1'0'0,
11703                 (true,
11704                  (true,
11705                   (true,
11706                    (true,
11707                     (true,
11708                      (Rt'3,
11709                       (Rt'2,
11710                        (Rt'1,
11711                         (Rt'0,
11712                          (imm12'11,
11713                           (imm12'10,
11714                            (imm12'9,
11715                             (imm12'8,
11716                              (imm12'7,
11717                               (imm12'6,
11718                                (imm12'5,
11719                                 (imm12'4,
11720                                  (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
11721            let
11722              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11723              val B = BitsN.fromBitstring([B'0],1)
11724              val GOOD_MATCH =
11725                ((BitsN.fromBitstring([sb'0'1'0],1)) = (BitsN.B(0x1,1))) andalso
11726                ((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1)))
11727            in
11728              if Do(cond,true)
11729                then ( if ((B = (BitsN.B(0x1,1))) andalso
11730                           (Rt = (BitsN.B(0xF,4)))) orelse
11731                          (not GOOD_MATCH)
11732                         then DECODE_UNPREDICTABLE
11733                                (mc,"LoadByte (literal)")
11734                       else ()
11735                     ; let
11736                         val add =
11737                           (BitsN.fromBitstring([U'0],1)) =
11738                           (BitsN.B(0x1,1))
11739                         val imm32 =
11740                           BitsN.zeroExtend 32
11741                             (BitsN.fromBitstring
11742                                ([imm12'11,imm12'10,imm12'9,imm12'8,
11743                                  imm12'7,imm12'6,imm12'5,imm12'4,imm12'3,
11744                                  imm12'2,imm12'1,imm12'0],12))
11745                       in
11746                         if B = (BitsN.B(0x1,1))
11747                           then Load
11748                                  (LoadByteLiteral(true,(add,(Rt,imm32))))
11749                         else Load(LoadLiteral(add,(Rt,imm32)))
11750                       end
11751                     )
11752              else Skip ()
11753            end
11754          | (false,
11755           (true,
11756            (false,
11757             (P'0,
11758              (U'0,
11759               (B'0,
11760                (W'0,
11761                 (true,
11762                  (Rn'3,
11763                   (Rn'2,
11764                    (Rn'1,
11765                     (Rn'0,
11766                      (Rt'3,
11767                       (Rt'2,
11768                        (Rt'1,
11769                         (Rt'0,
11770                          (imm12'11,
11771                           (imm12'10,
11772                            (imm12'9,
11773                             (imm12'8,
11774                              (imm12'7,
11775                               (imm12'6,
11776                                (imm12'5,
11777                                 (imm12'4,
11778                                  (imm12'3,(imm12'2,(imm12'1,imm12'0))))))))))))))))))))))))))) =>
11779            let
11780              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11781              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11782              val B = BitsN.fromBitstring([B'0],1)
11783              val P = BitsN.fromBitstring([P'0],1)
11784            in
11785              if Do(cond,true)
11786                then let
11787                       val wback =
11788                         (P = (BitsN.B(0x0,1))) orelse
11789                         ((BitsN.fromBitstring([W'0],1)) =
11790                          (BitsN.B(0x1,1)))
11791                     in
11792                       ( if ((B = (BitsN.B(0x1,1))) andalso
11793                             (Rt = (BitsN.B(0xF,4)))) orelse
11794                            (wback andalso (Rn = Rt))
11795                           then DECODE_UNPREDICTABLE
11796                                  (mc,"LoadWord/Byte (immediate)")
11797                         else ()
11798                       ; let
11799                           val add =
11800                             (BitsN.fromBitstring([U'0],1)) =
11801                             (BitsN.B(0x1,1))
11802                           val index = P = (BitsN.B(0x1,1))
11803                           val imm32 =
11804                             BitsN.zeroExtend 32
11805                               (BitsN.fromBitstring
11806                                  ([imm12'11,imm12'10,imm12'9,imm12'8,
11807                                    imm12'7,imm12'6,imm12'5,imm12'4,
11808                                    imm12'3,imm12'2,imm12'1,imm12'0],12))
11809                           val m = immediate_form1 imm32
11810                         in
11811                           if B = (BitsN.B(0x1,1))
11812                             then Load
11813                                    (LoadByte
11814                                       (true,
11815                                        (add,(index,(wback,(Rt,(Rn,m)))))))
11816                           else Load
11817                                  (LoadWord
11818                                     (add,(index,(wback,(Rt,(Rn,m))))))
11819                         end
11820                       )
11821                     end
11822              else Skip ()
11823            end
11824          | (false,
11825           (true,
11826            (true,
11827             (false,
11828              (U'0,
11829               (B'0,
11830                (true,
11831                 (false,
11832                  (Rn'3,
11833                   (Rn'2,
11834                    (Rn'1,
11835                     (Rn'0,
11836                      (Rt'3,
11837                       (Rt'2,
11838                        (Rt'1,
11839                         (Rt'0,
11840                          (imm5'4,
11841                           (imm5'3,
11842                            (imm5'2,
11843                             (imm5'1,
11844                              (imm5'0,
11845                               (typ'1,
11846                                (typ'0,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
11847            let
11848              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
11849              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11850              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11851              val B = BitsN.fromBitstring([B'0],1)
11852            in
11853              if Do(cond,true)
11854                then ( if ((B = (BitsN.B(0x1,1))) andalso
11855                           (Rt = (BitsN.B(0xF,4)))) orelse
11856                          ((Rn = (BitsN.B(0xF,4))) orelse
11857                           ((Rn = Rt) orelse
11858                            ((Rm = (BitsN.B(0xF,4))) orelse
11859                             ((Nat.<(ArchVersion (),6)) andalso (Rm = Rn)))))
11860                         then DECODE_UNPREDICTABLE
11861                                (mc,"StoreUnprivileged (regiser)")
11862                       else ()
11863                     ; let
11864                         val add =
11865                           (BitsN.fromBitstring([U'0],1)) =
11866                           (BitsN.B(0x1,1))
11867                         val postindex = true
11868                         val (shift_t,shift_n) =
11869                           DecodeImmShift
11870                             (BitsN.fromBitstring([typ'1,typ'0],2),
11871                              BitsN.fromBitstring
11872                                ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
11873                         val m = register_form1(Rm,(shift_t,shift_n))
11874                       in
11875                         if B = (BitsN.B(0x1,1))
11876                           then Store
11877                                  (StoreByteUnprivileged
11878                                     (add,(postindex,(Rt,(Rn,m)))))
11879                         else Store
11880                                (StoreUnprivileged
11881                                   (add,(postindex,(Rt,(Rn,m)))))
11882                       end
11883                     )
11884              else Skip ()
11885            end
11886          | (false,
11887           (true,
11888            (true,
11889             (P'0,
11890              (U'0,
11891               (B'0,
11892                (W'0,
11893                 (false,
11894                  (Rn'3,
11895                   (Rn'2,
11896                    (Rn'1,
11897                     (Rn'0,
11898                      (Rt'3,
11899                       (Rt'2,
11900                        (Rt'1,
11901                         (Rt'0,
11902                          (imm5'4,
11903                           (imm5'3,
11904                            (imm5'2,
11905                             (imm5'1,
11906                              (imm5'0,
11907                               (typ'1,
11908                                (typ'0,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
11909            let
11910              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
11911              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11912              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11913              val B = BitsN.fromBitstring([B'0],1)
11914              val P = BitsN.fromBitstring([P'0],1)
11915            in
11916              if Do(cond,true)
11917                then let
11918                       val wback =
11919                         (P = (BitsN.B(0x0,1))) orelse
11920                         ((BitsN.fromBitstring([W'0],1)) =
11921                          (BitsN.B(0x1,1)))
11922                     in
11923                       ( if ((B = (BitsN.B(0x1,1))) andalso
11924                             (Rt = (BitsN.B(0xF,4)))) orelse
11925                            ((Rm = (BitsN.B(0xF,4))) orelse
11926                             ((wback andalso
11927                               ((Rn = (BitsN.B(0xF,4))) orelse (Rn = Rt))) orelse
11928                              ((Nat.<(ArchVersion (),6)) andalso
11929                               (wback andalso (Rm = Rn)))))
11930                           then DECODE_UNPREDICTABLE(mc,"Store (regiser)")
11931                         else ()
11932                       ; let
11933                           val add =
11934                             (BitsN.fromBitstring([U'0],1)) =
11935                             (BitsN.B(0x1,1))
11936                           val index = P = (BitsN.B(0x1,1))
11937                           val (shift_t,shift_n) =
11938                             DecodeImmShift
11939                               (BitsN.fromBitstring([typ'1,typ'0],2),
11940                                BitsN.fromBitstring
11941                                  ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
11942                           val m = register_form1(Rm,(shift_t,shift_n))
11943                         in
11944                           if B = (BitsN.B(0x1,1))
11945                             then Store
11946                                    (StoreByte
11947                                       (add,(index,(wback,(Rt,(Rn,m))))))
11948                           else Store
11949                                  (StoreWord
11950                                     (add,(index,(wback,(Rt,(Rn,m))))))
11951                         end
11952                       )
11953                     end
11954              else Skip ()
11955            end
11956          | (false,
11957           (true,
11958            (true,
11959             (false,
11960              (U'0,
11961               (B'0,
11962                (true,
11963                 (true,
11964                  (Rn'3,
11965                   (Rn'2,
11966                    (Rn'1,
11967                     (Rn'0,
11968                      (Rt'3,
11969                       (Rt'2,
11970                        (Rt'1,
11971                         (Rt'0,
11972                          (imm5'4,
11973                           (imm5'3,
11974                            (imm5'2,
11975                             (imm5'1,
11976                              (imm5'0,
11977                               (typ'1,
11978                                (typ'0,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
11979            let
11980              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
11981              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
11982              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
11983            in
11984              if Do(cond,true)
11985                then ( if (Rt = (BitsN.B(0xF,4))) orelse
11986                          ((Rn = (BitsN.B(0xF,4))) orelse
11987                           ((Rn = Rt) orelse
11988                            ((Rm = (BitsN.B(0xF,4))) orelse
11989                             ((Nat.<(ArchVersion (),6)) andalso (Rm = Rn)))))
11990                         then DECODE_UNPREDICTABLE
11991                                (mc,"LoadUnprivileged (regiser)")
11992                       else ()
11993                     ; let
11994                         val add =
11995                           (BitsN.fromBitstring([U'0],1)) =
11996                           (BitsN.B(0x1,1))
11997                         val postindex = true
11998                         val (shift_t,shift_n) =
11999                           DecodeImmShift
12000                             (BitsN.fromBitstring([typ'1,typ'0],2),
12001                              BitsN.fromBitstring
12002                                ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
12003                         val m = register_form1(Rm,(shift_t,shift_n))
12004                       in
12005                         if (BitsN.fromBitstring([B'0],1)) =
12006                            (BitsN.B(0x1,1))
12007                           then Load
12008                                  (LoadByteUnprivileged
12009                                     (add,(postindex,(Rt,(Rn,m)))))
12010                         else Load
12011                                (LoadUnprivileged
12012                                   (add,(postindex,(Rt,(Rn,m)))))
12013                       end
12014                     )
12015              else Skip ()
12016            end
12017          | (false,
12018           (true,
12019            (true,
12020             (P'0,
12021              (U'0,
12022               (B'0,
12023                (W'0,
12024                 (true,
12025                  (Rn'3,
12026                   (Rn'2,
12027                    (Rn'1,
12028                     (Rn'0,
12029                      (Rt'3,
12030                       (Rt'2,
12031                        (Rt'1,
12032                         (Rt'0,
12033                          (imm5'4,
12034                           (imm5'3,
12035                            (imm5'2,
12036                             (imm5'1,
12037                              (imm5'0,
12038                               (typ'1,
12039                                (typ'0,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12040            let
12041              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12042              val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
12043              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12044              val B = BitsN.fromBitstring([B'0],1)
12045              val P = BitsN.fromBitstring([P'0],1)
12046            in
12047              if Do(cond,true)
12048                then let
12049                       val wback =
12050                         (P = (BitsN.B(0x0,1))) orelse
12051                         ((BitsN.fromBitstring([W'0],1)) =
12052                          (BitsN.B(0x1,1)))
12053                     in
12054                       ( if ((B = (BitsN.B(0x1,1))) andalso
12055                             (Rt = (BitsN.B(0xF,4)))) orelse
12056                            ((Rm = (BitsN.B(0xF,4))) orelse
12057                             ((wback andalso
12058                               ((Rn = (BitsN.B(0xF,4))) orelse (Rn = Rt))) orelse
12059                              ((Nat.<(ArchVersion (),6)) andalso
12060                               (wback andalso (Rm = Rn)))))
12061                           then DECODE_UNPREDICTABLE
12062                                  (mc,"LoadWord/Byte (regiser)")
12063                         else ()
12064                       ; let
12065                           val add =
12066                             (BitsN.fromBitstring([U'0],1)) =
12067                             (BitsN.B(0x1,1))
12068                           val index = P = (BitsN.B(0x1,1))
12069                           val (shift_t,shift_n) =
12070                             DecodeImmShift
12071                               (BitsN.fromBitstring([typ'1,typ'0],2),
12072                                BitsN.fromBitstring
12073                                  ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
12074                           val m = register_form1(Rm,(shift_t,shift_n))
12075                         in
12076                           if B = (BitsN.B(0x1,1))
12077                             then Load
12078                                    (LoadByte
12079                                       (true,
12080                                        (add,(index,(wback,(Rt,(Rn,m)))))))
12081                           else Load
12082                                  (LoadWord
12083                                     (add,(index,(wback,(Rt,(Rn,m))))))
12084                         end
12085                       )
12086                     end
12087              else Skip ()
12088            end
12089          | (false,
12090           (true,
12091            (true,
12092             (false,
12093              (false,
12094               (U'0,
12095                (op1'1,
12096                 (op1'0,
12097                  (Rn'3,
12098                   (Rn'2,
12099                    (Rn'1,
12100                     (Rn'0,
12101                      (Rd'3,
12102                       (Rd'2,
12103                        (Rd'1,
12104                         (Rd'0,
12105                          (sb'0'1111'3,
12106                           (sb'0'1111'2,
12107                            (sb'0'1111'1,
12108                             (sb'0'1111'0,
12109                              (op2'2,
12110                               (op2'1,
12111                                (op2'0,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12112            let
12113              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12114              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12115              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12116              val GOOD_MATCH =
12117                (BitsN.fromBitstring
12118                   ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
12119                (BitsN.B(0xF,4))
12120            in
12121              if Do(cond,Nat.>=(ArchVersion (),6))
12122                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12123                          ((Rn = (BitsN.B(0xF,4))) orelse
12124                           ((Rm = (BitsN.B(0xF,4))) orelse
12125                            (not GOOD_MATCH)))
12126                         then DECODE_UNPREDICTABLE
12127                                (mc,"Parallel addition and subtraction")
12128                       else ()
12129                     ; DecodeParallelAdditionSubtraction
12130                         (BitsN.fromBitstring([op1'1,op1'0],2),
12131                          (BitsN.fromBitstring([op2'2,op2'1,op2'0],3),
12132                           (BitsN.fromBitstring([U'0],1),(Rd,(Rn,Rm)))))
12133                     )
12134              else Skip ()
12135            end
12136          | (false,
12137           (true,
12138            (true,
12139             (false,
12140              (true,
12141               (false,
12142                (false,
12143                 (false,
12144                  (Rn'3,
12145                   (Rn'2,
12146                    (Rn'1,
12147                     (Rn'0,
12148                      (Rd'3,
12149                       (Rd'2,
12150                        (Rd'1,
12151                         (Rd'0,
12152                          (imm5'4,
12153                           (imm5'3,
12154                            (imm5'2,
12155                             (imm5'1,
12156                              (imm5'0,
12157                               (tb'0,
12158                                (false,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12159            let
12160              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12161              val tb = BitsN.fromBitstring([tb'0],1)
12162              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12163              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12164            in
12165              if Do(cond,Nat.>=(ArchVersion (),6))
12166                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12167                          ((Rn = (BitsN.B(0xF,4))) orelse
12168                           (Rm = (BitsN.B(0xF,4))))
12169                         then DECODE_UNPREDICTABLE(mc,"PackHalfword")
12170                       else ()
12171                     ; let
12172                         val tbform = tb = (BitsN.B(0x1,1))
12173                         val (shift_t,shift_n) =
12174                           DecodeImmShift
12175                             (BitsN.@@(tb,BitsN.B(0x0,1)),
12176                              BitsN.fromBitstring
12177                                ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
12178                       in
12179                         Media
12180                           (PackHalfword
12181                              (shift_t,(shift_n,(tbform,(Rd,(Rn,Rm))))))
12182                       end
12183                     )
12184              else Skip ()
12185            end
12186          | (false,
12187           (true,
12188            (true,
12189             (false,
12190              (true,
12191               (false,
12192                (false,
12193                 (false,
12194                  (Rn'3,
12195                   (Rn'2,
12196                    (Rn'1,
12197                     (Rn'0,
12198                      (Rd'3,
12199                       (Rd'2,
12200                        (Rd'1,
12201                         (Rd'0,
12202                          (sb'0'1111'3,
12203                           (sb'0'1111'2,
12204                            (sb'0'1111'1,
12205                             (sb'0'1111'0,
12206                              (true,
12207                               (false,
12208                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12209            let
12210              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12211              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12212              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12213              val GOOD_MATCH =
12214                (BitsN.fromBitstring
12215                   ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
12216                (BitsN.B(0xF,4))
12217            in
12218              if Do(cond,Nat.>=(ArchVersion (),6))
12219                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12220                          ((Rn = (BitsN.B(0xF,4))) orelse
12221                           ((Rm = (BitsN.B(0xF,4))) orelse
12222                            (not GOOD_MATCH)))
12223                         then DECODE_UNPREDICTABLE(mc,"SelectBytes")
12224                       else ()
12225                     ; Media(SelectBytes(Rd,(Rn,Rm)))
12226                     )
12227              else Skip ()
12228            end
12229          | (false,
12230           (true,
12231            (true,
12232             (false,
12233              (true,
12234               (U'0,
12235                (true,
12236                 (sat_imm'4,
12237                  (sat_imm'3,
12238                   (sat_imm'2,
12239                    (sat_imm'1,
12240                     (sat_imm'0,
12241                      (Rd'3,
12242                       (Rd'2,
12243                        (Rd'1,
12244                         (Rd'0,
12245                          (imm5'4,
12246                           (imm5'3,
12247                            (imm5'2,
12248                             (imm5'1,
12249                              (imm5'0,
12250                               (sh'0,
12251                                (false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
12252            let
12253              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12254              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12255              val sat_imm =
12256                BitsN.fromBitstring
12257                  ([sat_imm'4,sat_imm'3,sat_imm'2,sat_imm'1,sat_imm'0],5)
12258            in
12259              if Do(cond,Nat.>=(ArchVersion (),6))
12260                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12261                          (Rn = (BitsN.B(0xF,4)))
12262                         then DECODE_UNPREDICTABLE(mc,"Saturate")
12263                       else ()
12264                     ; let
12265                         val unsigned =
12266                           (BitsN.fromBitstring([U'0],1)) =
12267                           (BitsN.B(0x1,1))
12268                         val saturate_to =
12269                           if unsigned
12270                             then BitsN.toNat sat_imm
12271                           else Nat.+(BitsN.toNat sat_imm,1)
12272                         val (shift_t,shift_n) =
12273                           DecodeImmShift
12274                             (BitsN.@@
12275                                (BitsN.fromBitstring([sh'0],1),
12276                                 BitsN.B(0x0,1)),
12277                              BitsN.fromBitstring
12278                                ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
12279                       in
12280                         Media
12281                           (Saturate
12282                              (shift_t,
12283                               (shift_n,(saturate_to,(unsigned,(Rd,Rn))))))
12284                       end
12285                     )
12286              else Skip ()
12287            end
12288          | (false,
12289           (true,
12290            (true,
12291             (false,
12292              (true,
12293               (U'0,
12294                (true,
12295                 (false,
12296                  (sat_imm'3,
12297                   (sat_imm'2,
12298                    (sat_imm'1,
12299                     (sat_imm'0,
12300                      (Rd'3,
12301                       (Rd'2,
12302                        (Rd'1,
12303                         (Rd'0,
12304                          (sb'0'1111'3,
12305                           (sb'0'1111'2,
12306                            (sb'0'1111'1,
12307                             (sb'0'1111'0,
12308                              (false,
12309                               (false,
12310                                (true,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
12311            let
12312              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12313              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12314              val sat_imm =
12315                BitsN.fromBitstring
12316                  ([sat_imm'3,sat_imm'2,sat_imm'1,sat_imm'0],4)
12317              val GOOD_MATCH =
12318                (BitsN.fromBitstring
12319                   ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
12320                (BitsN.B(0xF,4))
12321            in
12322              if Do(cond,Nat.>=(ArchVersion (),6))
12323                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12324                          ((Rn = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
12325                         then DECODE_UNPREDICTABLE(mc,"Saturate16")
12326                       else ()
12327                     ; let
12328                         val unsigned =
12329                           (BitsN.fromBitstring([U'0],1)) =
12330                           (BitsN.B(0x1,1))
12331                         val saturate_to =
12332                           if unsigned
12333                             then BitsN.toNat sat_imm
12334                           else Nat.+(BitsN.toNat sat_imm,1)
12335                       in
12336                         Media(Saturate16(saturate_to,(unsigned,(Rd,Rn))))
12337                       end
12338                     )
12339              else Skip ()
12340            end
12341          | (false,
12342           (true,
12343            (true,
12344             (false,
12345              (true,
12346               (U'0,
12347                (false,
12348                 (false,
12349                  (Rn'3,
12350                   (Rn'2,
12351                    (Rn'1,
12352                     (Rn'0,
12353                      (Rd'3,
12354                       (Rd'2,
12355                        (Rd'1,
12356                         (Rd'0,
12357                          (rotate'1,
12358                           (rotate'0,
12359                            (sb'0'00'1,
12360                             (sb'0'00'0,
12361                              (false,
12362                               (true,
12363                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12364            let
12365              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12366              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12367              val GOOD_MATCH =
12368                (BitsN.fromBitstring([sb'0'00'1,sb'0'00'0],2)) =
12369                (BitsN.B(0x0,2))
12370            in
12371              if Do(cond,Nat.>=(ArchVersion (),6))
12372                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12373                          ((Rm = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
12374                         then DECODE_UNPREDICTABLE(mc,"ExtendByte16")
12375                       else ()
12376                     ; let
12377                         val unsigned =
12378                           (BitsN.fromBitstring([U'0],1)) =
12379                           (BitsN.B(0x1,1))
12380                         val rotation =
12381                           BitsN.toNat
12382                             (BitsN.@@
12383                                (BitsN.fromBitstring
12384                                   ([rotate'1,rotate'0],2),BitsN.B(0x0,3)))
12385                       in
12386                         Media
12387                           (ExtendByte16
12388                              (unsigned,
12389                               (Rd,
12390                                (BitsN.fromBitstring
12391                                   ([Rn'3,Rn'2,Rn'1,Rn'0],4),(Rm,rotation)))))
12392                       end
12393                     )
12394              else Skip ()
12395            end
12396          | (false,
12397           (true,
12398            (true,
12399             (false,
12400              (true,
12401               (U'0,
12402                (true,
12403                 (false,
12404                  (Rn'3,
12405                   (Rn'2,
12406                    (Rn'1,
12407                     (Rn'0,
12408                      (Rd'3,
12409                       (Rd'2,
12410                        (Rd'1,
12411                         (Rd'0,
12412                          (rotate'1,
12413                           (rotate'0,
12414                            (sb'0'00'1,
12415                             (sb'0'00'0,
12416                              (false,
12417                               (true,
12418                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12419            let
12420              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12421              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12422              val GOOD_MATCH =
12423                (BitsN.fromBitstring([sb'0'00'1,sb'0'00'0],2)) =
12424                (BitsN.B(0x0,2))
12425            in
12426              if Do(cond,Nat.>=(ArchVersion (),6))
12427                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12428                          ((Rm = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
12429                         then DECODE_UNPREDICTABLE(mc,"ExtendByte")
12430                       else ()
12431                     ; let
12432                         val unsigned =
12433                           (BitsN.fromBitstring([U'0],1)) =
12434                           (BitsN.B(0x1,1))
12435                         val rotation =
12436                           BitsN.toNat
12437                             (BitsN.@@
12438                                (BitsN.fromBitstring
12439                                   ([rotate'1,rotate'0],2),BitsN.B(0x0,3)))
12440                       in
12441                         Media
12442                           (ExtendByte
12443                              (unsigned,
12444                               (Rd,
12445                                (BitsN.fromBitstring
12446                                   ([Rn'3,Rn'2,Rn'1,Rn'0],4),(Rm,rotation)))))
12447                       end
12448                     )
12449              else Skip ()
12450            end
12451          | (false,
12452           (true,
12453            (true,
12454             (false,
12455              (true,
12456               (U'0,
12457                (true,
12458                 (true,
12459                  (Rn'3,
12460                   (Rn'2,
12461                    (Rn'1,
12462                     (Rn'0,
12463                      (Rd'3,
12464                       (Rd'2,
12465                        (Rd'1,
12466                         (Rd'0,
12467                          (rotate'1,
12468                           (rotate'0,
12469                            (sb'0'00'1,
12470                             (sb'0'00'0,
12471                              (false,
12472                               (true,
12473                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12474            let
12475              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12476              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12477              val GOOD_MATCH =
12478                (BitsN.fromBitstring([sb'0'00'1,sb'0'00'0],2)) =
12479                (BitsN.B(0x0,2))
12480            in
12481              if Do(cond,Nat.>=(ArchVersion (),6))
12482                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12483                          ((Rm = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
12484                         then DECODE_UNPREDICTABLE(mc,"ExtendHalfword")
12485                       else ()
12486                     ; let
12487                         val unsigned =
12488                           (BitsN.fromBitstring([U'0],1)) =
12489                           (BitsN.B(0x1,1))
12490                         val rotation =
12491                           BitsN.toNat
12492                             (BitsN.@@
12493                                (BitsN.fromBitstring
12494                                   ([rotate'1,rotate'0],2),BitsN.B(0x0,3)))
12495                       in
12496                         Media
12497                           (ExtendHalfword
12498                              (unsigned,
12499                               (Rd,
12500                                (BitsN.fromBitstring
12501                                   ([Rn'3,Rn'2,Rn'1,Rn'0],4),(Rm,rotation)))))
12502                       end
12503                     )
12504              else Skip ()
12505            end
12506          | (false,
12507           (true,
12508            (true,
12509             (false,
12510              (true,
12511               (false,
12512                (true,
12513                 (true,
12514                  (sb'0'1111'3,
12515                   (sb'0'1111'2,
12516                    (sb'0'1111'1,
12517                     (sb'0'1111'0,
12518                      (Rd'3,
12519                       (Rd'2,
12520                        (Rd'1,
12521                         (Rd'0,
12522                          (sb'1'1111'3,
12523                           (sb'1'1111'2,
12524                            (sb'1'1111'1,
12525                             (sb'1'1111'0,
12526                              (false,
12527                               (false,
12528                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12529            let
12530              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12531              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12532              val GOOD_MATCH =
12533                ((BitsN.fromBitstring
12534                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
12535                 (BitsN.B(0xF,4))) andalso
12536                ((BitsN.fromBitstring
12537                    ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
12538                 (BitsN.B(0xF,4)))
12539            in
12540              if Do(cond,Nat.>=(ArchVersion (),6))
12541                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12542                          ((Rm = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
12543                         then DECODE_UNPREDICTABLE(mc,"ByteReverse")
12544                       else ()
12545                     ; Media(ByteReverse(Rd,Rm))
12546                     )
12547              else Skip ()
12548            end
12549          | (false,
12550           (true,
12551            (true,
12552             (false,
12553              (true,
12554               (false,
12555                (true,
12556                 (true,
12557                  (sb'0'1111'3,
12558                   (sb'0'1111'2,
12559                    (sb'0'1111'1,
12560                     (sb'0'1111'0,
12561                      (Rd'3,
12562                       (Rd'2,
12563                        (Rd'1,
12564                         (Rd'0,
12565                          (sb'1'1111'3,
12566                           (sb'1'1111'2,
12567                            (sb'1'1111'1,
12568                             (sb'1'1111'0,
12569                              (true,
12570                               (false,
12571                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12572            let
12573              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12574              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12575              val GOOD_MATCH =
12576                ((BitsN.fromBitstring
12577                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
12578                 (BitsN.B(0xF,4))) andalso
12579                ((BitsN.fromBitstring
12580                    ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
12581                 (BitsN.B(0xF,4)))
12582            in
12583              if Do(cond,Nat.>=(ArchVersion (),6))
12584                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12585                          ((Rm = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
12586                         then DECODE_UNPREDICTABLE
12587                                (mc,"ByteReversePackedHalfword")
12588                       else ()
12589                     ; Media(ByteReversePackedHalfword(Rd,Rm))
12590                     )
12591              else Skip ()
12592            end
12593          | (false,
12594           (true,
12595            (true,
12596             (false,
12597              (true,
12598               (true,
12599                (true,
12600                 (true,
12601                  (sb'0'1111'3,
12602                   (sb'0'1111'2,
12603                    (sb'0'1111'1,
12604                     (sb'0'1111'0,
12605                      (Rd'3,
12606                       (Rd'2,
12607                        (Rd'1,
12608                         (Rd'0,
12609                          (sb'1'1111'3,
12610                           (sb'1'1111'2,
12611                            (sb'1'1111'1,
12612                             (sb'1'1111'0,
12613                              (true,
12614                               (false,
12615                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12616            let
12617              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12618              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12619              val GOOD_MATCH =
12620                ((BitsN.fromBitstring
12621                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
12622                 (BitsN.B(0xF,4))) andalso
12623                ((BitsN.fromBitstring
12624                    ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
12625                 (BitsN.B(0xF,4)))
12626            in
12627              if Do(cond,Nat.>=(ArchVersion (),6))
12628                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12629                          ((Rm = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
12630                         then DECODE_UNPREDICTABLE
12631                                (mc,"ByteReverseSignedHalfword")
12632                       else ()
12633                     ; Media(ByteReverseSignedHalfword(Rd,Rm))
12634                     )
12635              else Skip ()
12636            end
12637          | (false,
12638           (true,
12639            (true,
12640             (false,
12641              (true,
12642               (true,
12643                (true,
12644                 (true,
12645                  (sb'0'1111'3,
12646                   (sb'0'1111'2,
12647                    (sb'0'1111'1,
12648                     (sb'0'1111'0,
12649                      (Rd'3,
12650                       (Rd'2,
12651                        (Rd'1,
12652                         (Rd'0,
12653                          (sb'1'1111'3,
12654                           (sb'1'1111'2,
12655                            (sb'1'1111'1,
12656                             (sb'1'1111'0,
12657                              (false,
12658                               (false,
12659                                (true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0))))))))))))))))))))))))))) =>
12660            let
12661              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12662              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12663              val GOOD_MATCH =
12664                ((BitsN.fromBitstring
12665                    ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
12666                 (BitsN.B(0xF,4))) andalso
12667                ((BitsN.fromBitstring
12668                    ([sb'1'1111'3,sb'1'1111'2,sb'1'1111'1,sb'1'1111'0],4)) =
12669                 (BitsN.B(0xF,4)))
12670            in
12671              if Do(cond,Nat.>=(ArchVersion (),6))
12672                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12673                          ((Rm = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
12674                         then DECODE_UNPREDICTABLE(mc,"ReverseBits")
12675                       else ()
12676                     ; Media(ReverseBits(Rd,Rm))
12677                     )
12678              else Skip ()
12679            end
12680          | (false,
12681           (true,
12682            (true,
12683             (true,
12684              (false,
12685               (false,
12686                (false,
12687                 (false,
12688                  (Rd'3,
12689                   (Rd'2,
12690                    (Rd'1,
12691                     (Rd'0,
12692                      (Ra'3,
12693                       (Ra'2,
12694                        (Ra'1,
12695                         (Ra'0,
12696                          (Rm'3,
12697                           (Rm'2,
12698                            (Rm'1,
12699                             (Rm'0,
12700                              (false,
12701                               (S'0,(M'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
12702            let
12703              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12704              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12705              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12706            in
12707              if Do(cond,Nat.>=(ArchVersion (),6))
12708                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12709                          ((Rn = (BitsN.B(0xF,4))) orelse
12710                           (Rm = (BitsN.B(0xF,4))))
12711                         then DECODE_UNPREDICTABLE
12712                                (mc,"SignedMultiplyDual")
12713                       else ()
12714                     ; let
12715                         val sub =
12716                           (BitsN.fromBitstring([S'0],1)) =
12717                           (BitsN.B(0x1,1))
12718                         val m_swap =
12719                           (BitsN.fromBitstring([M'0],1)) =
12720                           (BitsN.B(0x1,1))
12721                       in
12722                         Multiply
12723                           (SignedMultiplyDual
12724                              (sub,
12725                               (m_swap,
12726                                (Rd,
12727                                 (Rn,
12728                                  (Rm,
12729                                   BitsN.fromBitstring
12730                                     ([Ra'3,Ra'2,Ra'1,Ra'0],4)))))))
12731                       end
12732                     )
12733              else Skip ()
12734            end
12735          | (false,
12736           (true,
12737            (true,
12738             (true,
12739              (false,
12740               (true,
12741                (false,
12742                 (false,
12743                  (RdHi'3,
12744                   (RdHi'2,
12745                    (RdHi'1,
12746                     (RdHi'0,
12747                      (RdLo'3,
12748                       (RdLo'2,
12749                        (RdLo'1,
12750                         (RdLo'0,
12751                          (Rm'3,
12752                           (Rm'2,
12753                            (Rm'1,
12754                             (Rm'0,
12755                              (false,
12756                               (S'0,(M'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
12757            let
12758              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12759              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12760              val RdLo =
12761                BitsN.fromBitstring([RdLo'3,RdLo'2,RdLo'1,RdLo'0],4)
12762              val RdHi =
12763                BitsN.fromBitstring([RdHi'3,RdHi'2,RdHi'1,RdHi'0],4)
12764            in
12765              if Do(cond,Nat.>=(ArchVersion (),6))
12766                then ( if (RdLo = (BitsN.B(0xF,4))) orelse
12767                          ((RdHi = (BitsN.B(0xF,4))) orelse
12768                           ((Rn = (BitsN.B(0xF,4))) orelse
12769                            (Rm = (BitsN.B(0xF,4)))))
12770                         then DECODE_UNPREDICTABLE
12771                                (mc,"SignedMultiplyLongDual")
12772                       else ()
12773                     ; let
12774                         val sub =
12775                           (BitsN.fromBitstring([S'0],1)) =
12776                           (BitsN.B(0x1,1))
12777                         val m_swap =
12778                           (BitsN.fromBitstring([M'0],1)) =
12779                           (BitsN.B(0x1,1))
12780                       in
12781                         Multiply
12782                           (SignedMultiplyLongDual
12783                              (sub,(m_swap,(RdHi,(RdLo,(Rn,Rm))))))
12784                       end
12785                     )
12786              else Skip ()
12787            end
12788          | (false,
12789           (true,
12790            (true,
12791             (true,
12792              (false,
12793               (true,
12794                (false,
12795                 (true,
12796                  (Rd'3,
12797                   (Rd'2,
12798                    (Rd'1,
12799                     (Rd'0,
12800                      (Ra'3,
12801                       (Ra'2,
12802                        (Ra'1,
12803                         (Ra'0,
12804                          (Rm'3,
12805                           (Rm'2,
12806                            (Rm'1,
12807                             (Rm'0,
12808                              (false,
12809                               (false,
12810                                (R'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
12811            let
12812              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12813              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12814              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12815            in
12816              if Do(cond,Nat.>=(ArchVersion (),6))
12817                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12818                          ((Rn = (BitsN.B(0xF,4))) orelse
12819                           (Rm = (BitsN.B(0xF,4))))
12820                         then DECODE_UNPREDICTABLE
12821                                (mc,"SignedMostSignificantMultiply")
12822                       else ()
12823                     ; let
12824                         val round =
12825                           (BitsN.fromBitstring([R'0],1)) =
12826                           (BitsN.B(0x1,1))
12827                       in
12828                         Multiply
12829                           (SignedMostSignificantMultiply
12830                              (round,
12831                               (Rd,
12832                                (Rn,
12833                                 (Rm,
12834                                  BitsN.fromBitstring
12835                                    ([Ra'3,Ra'2,Ra'1,Ra'0],4))))))
12836                       end
12837                     )
12838              else Skip ()
12839            end
12840          | (false,
12841           (true,
12842            (true,
12843             (true,
12844              (false,
12845               (true,
12846                (false,
12847                 (true,
12848                  (Rd'3,
12849                   (Rd'2,
12850                    (Rd'1,
12851                     (Rd'0,
12852                      (Ra'3,
12853                       (Ra'2,
12854                        (Ra'1,
12855                         (Ra'0,
12856                          (Rm'3,
12857                           (Rm'2,
12858                            (Rm'1,
12859                             (Rm'0,
12860                              (true,
12861                               (true,
12862                                (R'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
12863            let
12864              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12865              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12866              val Ra = BitsN.fromBitstring([Ra'3,Ra'2,Ra'1,Ra'0],4)
12867              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12868            in
12869              if Do(cond,Nat.>=(ArchVersion (),6))
12870                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12871                          ((Rn = (BitsN.B(0xF,4))) orelse
12872                           ((Rm = (BitsN.B(0xF,4))) orelse
12873                            (Ra = (BitsN.B(0xF,4)))))
12874                         then DECODE_UNPREDICTABLE
12875                                (mc,
12876                                 "SignedMostSignificantMultiplySubtract")
12877                       else ()
12878                     ; let
12879                         val round =
12880                           (BitsN.fromBitstring([R'0],1)) =
12881                           (BitsN.B(0x1,1))
12882                       in
12883                         Multiply
12884                           (SignedMostSignificantMultiplySubtract
12885                              (round,(Rd,(Rn,(Rm,Ra)))))
12886                       end
12887                     )
12888              else Skip ()
12889            end
12890          | (false,
12891           (true,
12892            (true,
12893             (true,
12894              (true,
12895               (false,
12896                (false,
12897                 (false,
12898                  (Rd'3,
12899                   (Rd'2,
12900                    (Rd'1,
12901                     (Rd'0,
12902                      (Ra'3,
12903                       (Ra'2,
12904                        (Ra'1,
12905                         (Ra'0,
12906                          (Rm'3,
12907                           (Rm'2,
12908                            (Rm'1,
12909                             (Rm'0,
12910                              (false,
12911                               (false,
12912                                (false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
12913            let
12914              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12915              val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
12916              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12917            in
12918              if Do(cond,Nat.>=(ArchVersion (),6))
12919                then ( if (Rd = (BitsN.B(0xF,4))) orelse
12920                          ((Rn = (BitsN.B(0xF,4))) orelse
12921                           (Rm = (BitsN.B(0xF,4))))
12922                         then DECODE_UNPREDICTABLE
12923                                (mc,"UnsignedSumAbsoluteDifferences")
12924                       else ()
12925                     ; SIMD
12926                         (UnsignedSumAbsoluteDifferences
12927                            (Rd,
12928                             (Rn,
12929                              (Rm,
12930                               BitsN.fromBitstring
12931                                 ([Ra'3,Ra'2,Ra'1,Ra'0],4)))))
12932                     )
12933              else Skip ()
12934            end
12935          | (false,
12936           (true,
12937            (true,
12938             (true,
12939              (true,
12940               (U'0,
12941                (true,
12942                 (widthm1'4,
12943                  (widthm1'3,
12944                   (widthm1'2,
12945                    (widthm1'1,
12946                     (widthm1'0,
12947                      (Rd'3,
12948                       (Rd'2,
12949                        (Rd'1,
12950                         (Rd'0,
12951                          (lsb'4,
12952                           (lsb'3,
12953                            (lsb'2,
12954                             (lsb'1,
12955                              (lsb'0,
12956                               (true,
12957                                (false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
12958            let
12959              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
12960              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
12961            in
12962              if Do(cond,Nat.>=(ArchVersion (),6))
12963                then let
12964                       val lsbit =
12965                         BitsN.toNat
12966                           (BitsN.fromBitstring
12967                              ([lsb'4,lsb'3,lsb'2,lsb'1,lsb'0],5))
12968                       val widthminus1 =
12969                         BitsN.toNat
12970                           (BitsN.fromBitstring
12971                              ([widthm1'4,widthm1'3,widthm1'2,widthm1'1,
12972                                widthm1'0],5))
12973                     in
12974                       ( if (Rd = (BitsN.B(0xF,4))) orelse
12975                            ((Rn = (BitsN.B(0xF,4))) orelse
12976                             (Nat.<(31,Nat.+(lsbit,widthminus1))))
12977                           then DECODE_UNPREDICTABLE(mc,"BitFieldExtract")
12978                         else ()
12979                       ; let
12980                           val unsigned =
12981                             (BitsN.fromBitstring([U'0],1)) =
12982                             (BitsN.B(0x1,1))
12983                         in
12984                           Media
12985                             (BitFieldExtract
12986                                (unsigned,(Rd,(Rn,(lsbit,widthminus1)))))
12987                         end
12988                       )
12989                     end
12990              else Skip ()
12991            end
12992          | (false,
12993           (true,
12994            (true,
12995             (true,
12996              (true,
12997               (true,
12998                (false,
12999                 (msb'4,
13000                  (msb'3,
13001                   (msb'2,
13002                    (msb'1,
13003                     (msb'0,
13004                      (Rd'3,
13005                       (Rd'2,
13006                        (Rd'1,
13007                         (Rd'0,
13008                          (lsb'4,
13009                           (lsb'3,
13010                            (lsb'2,
13011                             (lsb'1,
13012                              (lsb'0,
13013                               (false,
13014                                (false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))))))))))))))) =>
13015            let
13016              val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
13017            in
13018              if Do(cond,Nat.>=(ArchVersion (),6))
13019                then let
13020                       val lsbit =
13021                         BitsN.toNat
13022                           (BitsN.fromBitstring
13023                              ([lsb'4,lsb'3,lsb'2,lsb'1,lsb'0],5))
13024                       val msbit =
13025                         BitsN.toNat
13026                           (BitsN.fromBitstring
13027                              ([msb'4,msb'3,msb'2,msb'1,msb'0],5))
13028                     in
13029                       ( if (Rd = (BitsN.B(0xF,4))) orelse
13030                            (Nat.<(msbit,lsbit))
13031                           then DECODE_UNPREDICTABLE
13032                                  (mc,"BitFieldClearOrInsert")
13033                         else ()
13034                       ; Media
13035                           (BitFieldClearOrInsert
13036                              (Rd,
13037                               (BitsN.fromBitstring
13038                                  ([Rn'3,Rn'2,Rn'1,Rn'0],4),(lsbit,msbit))))
13039                       )
13040                     end
13041              else Skip ()
13042            end
13043          | (true,
13044           (false,
13045            (false,
13046             (P'0,
13047              (U'0,
13048               (true,
13049                (sb'0'0'0,
13050                 (false,
13051                  (Rn'3,
13052                   (Rn'2,
13053                    (Rn'1,
13054                     (Rn'0,
13055                      (registers'15,
13056                       (registers'14,
13057                        (registers'13,
13058                         (registers'12,
13059                          (registers'11,
13060                           (registers'10,
13061                            (registers'9,
13062                             (registers'8,
13063                              (registers'7,
13064                               (registers'6,
13065                                (registers'5,
13066                                 (registers'4,
13067                                  (registers'3,
13068                                   (registers'2,(registers'1,registers'0))))))))))))))))))))))))))) =>
13069            let
13070              val registers =
13071                BitsN.fromBitstring
13072                  ([registers'15,registers'14,registers'13,registers'12,
13073                    registers'11,registers'10,registers'9,registers'8,
13074                    registers'7,registers'6,registers'5,registers'4,
13075                    registers'3,registers'2,registers'1,registers'0],16)
13076              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
13077              val U = BitsN.fromBitstring([U'0],1)
13078              val GOOD_MATCH =
13079                (BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))
13080            in
13081              if Do(cond,true)
13082                then ( if (Rn = (BitsN.B(0xF,4))) orelse
13083                          ((Nat.<(BitCount 16 registers,1)) orelse
13084                           (not GOOD_MATCH))
13085                         then DECODE_UNPREDICTABLE
13086                                (mc,"StoreMultipleUserRegisters")
13087                       else ()
13088                     ; let
13089                         val increment = U = (BitsN.B(0x1,1))
13090                         val wordhigher =
13091                           (BitsN.fromBitstring([P'0],1)) = U
13092                       in
13093                         Store
13094                           (StoreMultipleUserRegisters
13095                              (increment,(wordhigher,(Rn,registers))))
13096                       end
13097                     )
13098              else Skip ()
13099            end
13100          | (true,
13101           (false,
13102            (false,
13103             (P'0,
13104              (U'0,
13105               (false,
13106                (W'0,
13107                 (false,
13108                  (Rn'3,
13109                   (Rn'2,
13110                    (Rn'1,
13111                     (Rn'0,
13112                      (registers'15,
13113                       (registers'14,
13114                        (registers'13,
13115                         (registers'12,
13116                          (registers'11,
13117                           (registers'10,
13118                            (registers'9,
13119                             (registers'8,
13120                              (registers'7,
13121                               (registers'6,
13122                                (registers'5,
13123                                 (registers'4,
13124                                  (registers'3,
13125                                   (registers'2,(registers'1,registers'0))))))))))))))))))))))))))) =>
13126            let
13127              val registers =
13128                BitsN.fromBitstring
13129                  ([registers'15,registers'14,registers'13,registers'12,
13130                    registers'11,registers'10,registers'9,registers'8,
13131                    registers'7,registers'6,registers'5,registers'4,
13132                    registers'3,registers'2,registers'1,registers'0],16)
13133              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
13134            in
13135              if Do(cond,true)
13136                then ( if (Rn = (BitsN.B(0xF,4))) orelse
13137                          (Nat.<(BitCount 16 registers,1))
13138                         then DECODE_UNPREDICTABLE(mc,"StoreMultiple")
13139                       else ()
13140                     ; let
13141                         val index =
13142                           (BitsN.fromBitstring([P'0],1)) =
13143                           (BitsN.B(0x1,1))
13144                         val increment =
13145                           (BitsN.fromBitstring([U'0],1)) =
13146                           (BitsN.B(0x1,1))
13147                         val wback =
13148                           (BitsN.fromBitstring([W'0],1)) =
13149                           (BitsN.B(0x1,1))
13150                       in
13151                         Store
13152                           (StoreMultiple
13153                              (increment,(index,(wback,(Rn,registers)))))
13154                       end
13155                     )
13156              else Skip ()
13157            end
13158          | (true,
13159           (false,
13160            (false,
13161             (P'0,
13162              (U'0,
13163               (true,
13164                (sb'0'0'0,
13165                 (true,
13166                  (Rn'3,
13167                   (Rn'2,
13168                    (Rn'1,
13169                     (Rn'0,
13170                      (false,
13171                       (registers'14,
13172                        (registers'13,
13173                         (registers'12,
13174                          (registers'11,
13175                           (registers'10,
13176                            (registers'9,
13177                             (registers'8,
13178                              (registers'7,
13179                               (registers'6,
13180                                (registers'5,
13181                                 (registers'4,
13182                                  (registers'3,
13183                                   (registers'2,(registers'1,registers'0))))))))))))))))))))))))))) =>
13184            let
13185              val registers =
13186                BitsN.fromBitstring
13187                  ([registers'14,registers'13,registers'12,registers'11,
13188                    registers'10,registers'9,registers'8,registers'7,
13189                    registers'6,registers'5,registers'4,registers'3,
13190                    registers'2,registers'1,registers'0],15)
13191              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
13192              val U = BitsN.fromBitstring([U'0],1)
13193              val GOOD_MATCH =
13194                (BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))
13195            in
13196              if Do(cond,true)
13197                then ( if (Rn = (BitsN.B(0xF,4))) orelse
13198                          ((Nat.<(BitCount 15 registers,1)) orelse
13199                           (not GOOD_MATCH))
13200                         then DECODE_UNPREDICTABLE
13201                                (mc,"LoadMultipleUserRegisters")
13202                       else ()
13203                     ; let
13204                         val increment = U = (BitsN.B(0x1,1))
13205                         val wordhigher =
13206                           (BitsN.fromBitstring([P'0],1)) = U
13207                       in
13208                         Load
13209                           (LoadMultipleUserRegisters
13210                              (increment,(wordhigher,(Rn,registers))))
13211                       end
13212                     )
13213              else Skip ()
13214            end
13215          | (true,
13216           (false,
13217            (false,
13218             (P'0,
13219              (U'0,
13220               (true,
13221                (W'0,
13222                 (true,
13223                  (Rn'3,
13224                   (Rn'2,
13225                    (Rn'1,
13226                     (Rn'0,
13227                      (true,
13228                       (registers'14,
13229                        (registers'13,
13230                         (registers'12,
13231                          (registers'11,
13232                           (registers'10,
13233                            (registers'9,
13234                             (registers'8,
13235                              (registers'7,
13236                               (registers'6,
13237                                (registers'5,
13238                                 (registers'4,
13239                                  (registers'3,
13240                                   (registers'2,(registers'1,registers'0))))))))))))))))))))))))))) =>
13241            let
13242              val registers =
13243                BitsN.fromBitstring
13244                  ([registers'14,registers'13,registers'12,registers'11,
13245                    registers'10,registers'9,registers'8,registers'7,
13246                    registers'6,registers'5,registers'4,registers'3,
13247                    registers'2,registers'1,registers'0],15)
13248              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
13249              val U = BitsN.fromBitstring([U'0],1)
13250            in
13251              if Do(cond,true)
13252                then let
13253                       val wback =
13254                         (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
13255                     in
13256                       ( if (Rn = (BitsN.B(0xF,4))) orelse
13257                            (wback andalso
13258                             ((BitsN.bit(registers,BitsN.toNat Rn)) andalso
13259                              (Nat.>=(ArchVersion (),7))))
13260                           then DECODE_UNPREDICTABLE
13261                                  (mc,"LoadMultipleExceptionReturn")
13262                         else ()
13263                       ; let
13264                           val increment = U = (BitsN.B(0x1,1))
13265                           val wordhigher =
13266                             (BitsN.fromBitstring([P'0],1)) = U
13267                         in
13268                           Load
13269                             (LoadMultipleExceptionReturn
13270                                (increment,
13271                                 (wordhigher,(wback,(Rn,registers)))))
13272                         end
13273                       )
13274                     end
13275              else Skip ()
13276            end
13277          | (true,
13278           (false,
13279            (false,
13280             (P'0,
13281              (U'0,
13282               (false,
13283                (W'0,
13284                 (true,
13285                  (Rn'3,
13286                   (Rn'2,
13287                    (Rn'1,
13288                     (Rn'0,
13289                      (registers'15,
13290                       (registers'14,
13291                        (registers'13,
13292                         (registers'12,
13293                          (registers'11,
13294                           (registers'10,
13295                            (registers'9,
13296                             (registers'8,
13297                              (registers'7,
13298                               (registers'6,
13299                                (registers'5,
13300                                 (registers'4,
13301                                  (registers'3,
13302                                   (registers'2,(registers'1,registers'0))))))))))))))))))))))))))) =>
13303            let
13304              val registers =
13305                BitsN.fromBitstring
13306                  ([registers'15,registers'14,registers'13,registers'12,
13307                    registers'11,registers'10,registers'9,registers'8,
13308                    registers'7,registers'6,registers'5,registers'4,
13309                    registers'3,registers'2,registers'1,registers'0],16)
13310              val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
13311            in
13312              if Do(cond,true)
13313                then let
13314                       val wback =
13315                         (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
13316                     in
13317                       ( if (Rn = (BitsN.B(0xF,4))) orelse
13318                            ((Nat.<(BitCount 16 registers,1)) orelse
13319                             (wback andalso
13320                              ((BitsN.bit(registers,BitsN.toNat Rn)) andalso
13321                               (Nat.>=(ArchVersion (),7)))))
13322                           then DECODE_UNPREDICTABLE(mc,"LoadMultiple")
13323                         else ()
13324                       ; let
13325                           val index =
13326                             (BitsN.fromBitstring([P'0],1)) =
13327                             (BitsN.B(0x1,1))
13328                           val increment =
13329                             (BitsN.fromBitstring([U'0],1)) =
13330                             (BitsN.B(0x1,1))
13331                         in
13332                           Load
13333                             (LoadMultiple
13334                                (increment,(index,(wback,(Rn,registers)))))
13335                         end
13336                       )
13337                     end
13338              else Skip ()
13339            end
13340          | (true,
13341           (false,
13342            (true,
13343             (false,
13344              (imm24'23,
13345               (imm24'22,
13346                (imm24'21,
13347                 (imm24'20,
13348                  (imm24'19,
13349                   (imm24'18,
13350                    (imm24'17,
13351                     (imm24'16,
13352                      (imm24'15,
13353                       (imm24'14,
13354                        (imm24'13,
13355                         (imm24'12,
13356                          (imm24'11,
13357                           (imm24'10,
13358                            (imm24'9,
13359                             (imm24'8,
13360                              (imm24'7,
13361                               (imm24'6,
13362                                (imm24'5,
13363                                 (imm24'4,
13364                                  (imm24'3,(imm24'2,(imm24'1,imm24'0))))))))))))))))))))))))))) =>
13365            (if Do(cond,true)
13366               then let
13367                      val imm32 =
13368                        BitsN.signExtend 32
13369                          (BitsN.@@
13370                             (BitsN.fromBitstring
13371                                ([imm24'23,imm24'22,imm24'21,imm24'20,
13372                                  imm24'19,imm24'18,imm24'17,imm24'16,
13373                                  imm24'15,imm24'14,imm24'13,imm24'12,
13374                                  imm24'11,imm24'10,imm24'9,imm24'8,
13375                                  imm24'7,imm24'6,imm24'5,imm24'4,imm24'3,
13376                                  imm24'2,imm24'1,imm24'0],24),
13377                              BitsN.B(0x0,2)))
13378                    in
13379                      Branch(BranchTarget imm32)
13380                    end
13381             else Skip ())
13382          | (true,
13383           (false,
13384            (true,
13385             (true,
13386              (imm24'23,
13387               (imm24'22,
13388                (imm24'21,
13389                 (imm24'20,
13390                  (imm24'19,
13391                   (imm24'18,
13392                    (imm24'17,
13393                     (imm24'16,
13394                      (imm24'15,
13395                       (imm24'14,
13396                        (imm24'13,
13397                         (imm24'12,
13398                          (imm24'11,
13399                           (imm24'10,
13400                            (imm24'9,
13401                             (imm24'8,
13402                              (imm24'7,
13403                               (imm24'6,
13404                                (imm24'5,
13405                                 (imm24'4,
13406                                  (imm24'3,(imm24'2,(imm24'1,imm24'0))))))))))))))))))))))))))) =>
13407            (if Do(cond,true)
13408               then let
13409                      val imm32 =
13410                        BitsN.signExtend 32
13411                          (BitsN.@@
13412                             (BitsN.fromBitstring
13413                                ([imm24'23,imm24'22,imm24'21,imm24'20,
13414                                  imm24'19,imm24'18,imm24'17,imm24'16,
13415                                  imm24'15,imm24'14,imm24'13,imm24'12,
13416                                  imm24'11,imm24'10,imm24'9,imm24'8,
13417                                  imm24'7,imm24'6,imm24'5,imm24'4,imm24'3,
13418                                  imm24'2,imm24'1,imm24'0],24),
13419                              BitsN.B(0x0,2)))
13420                      val targetInstrSet = InstrSet_ARM
13421                    in
13422                      Branch
13423                        (BranchLinkExchangeImmediate(targetInstrSet,imm32))
13424                    end
13425             else Skip ())
13426          | (true,
13427           (true,
13428            (true,
13429             (true,
13430              (imm24'23,
13431               (imm24'22,
13432                (imm24'21,
13433                 (imm24'20,
13434                  (imm24'19,
13435                   (imm24'18,
13436                    (imm24'17,
13437                     (imm24'16,
13438                      (imm24'15,
13439                       (imm24'14,
13440                        (imm24'13,
13441                         (imm24'12,
13442                          (imm24'11,
13443                           (imm24'10,
13444                            (imm24'9,
13445                             (imm24'8,
13446                              (imm24'7,
13447                               (imm24'6,
13448                                (imm24'5,
13449                                 (imm24'4,
13450                                  (imm24'3,(imm24'2,(imm24'1,imm24'0))))))))))))))))))))))))))) =>
13451            (if Do(cond,true)
13452               then let
13453                      val imm32 =
13454                        BitsN.signExtend 32
13455                          (BitsN.fromBitstring
13456                             ([imm24'23,imm24'22,imm24'21,imm24'20,
13457                               imm24'19,imm24'18,imm24'17,imm24'16,
13458                               imm24'15,imm24'14,imm24'13,imm24'12,
13459                               imm24'11,imm24'10,imm24'9,imm24'8,imm24'7,
13460                               imm24'6,imm24'5,imm24'4,imm24'3,imm24'2,
13461                               imm24'1,imm24'0],24))
13462                    in
13463                      System(SupervisorCall imm32)
13464                    end
13465             else Skip ())
13466          | (true,
13467           (true,
13468            (_,
13469             (_,
13470              (_,
13471               (_,
13472                (_,
13473                 (_,
13474                  (_,(_,(_,(_,(_,(_,(_,(_,(true,(false,(true,_))))))))))))))))))) =>
13475            let
13476              val (defined,(unpred,i)) = DecodeVFP w
13477            in
13478              if Do(cond,defined)
13479                then ( if not(unpred = "")
13480                         then DECODE_UNPREDICTABLE
13481                                (mc,"DecodeVFP: " ^ unpred)
13482                       else ()
13483                     ; i
13484                     )
13485              else Skip ()
13486            end
13487          | _ => UndefinedARM cond
13488  end;
13489
13490fun DecodeThumb h =
13491  let
13492    val mc = Thumb h
13493  in
13494    case boolify'16 h of
13495       (false,
13496        (false,
13497         (false,
13498          (true,
13499           (true,
13500            (false,
13501             (S'0,
13502              (Rm'2,(Rm'1,(Rm'0,(Rn'2,(Rn'1,(Rn'0,(Rd'2,(Rd'1,Rd'0))))))))))))))) =>
13503         (if Do(ThumbCondition (),true)
13504            then let
13505                   val d =
13506                     BitsN.fromNat
13507                       (BitsN.toNat
13508                          (BitsN.fromBitstring([Rd'2,Rd'1,Rd'0],3)),4)
13509                   val n =
13510                     BitsN.fromNat
13511                       (BitsN.toNat
13512                          (BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)),4)
13513                   val m =
13514                     BitsN.fromNat
13515                       (BitsN.toNat
13516                          (BitsN.fromBitstring([Rm'2,Rm'1,Rm'0],3)),4)
13517                   val setflags = not(InITBlock ())
13518                   val (shift_t,shift_n) = (SRType_LSL,0)
13519                   val opc =
13520                     if (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
13521                       then BitsN.B(0x2,4)
13522                     else BitsN.B(0x4,4)
13523                 in
13524                   Data
13525                     (Register
13526                        (opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))))
13527                 end
13528          else Skip ())
13529     | (false,
13530      (false,
13531       (false,
13532        (true,
13533         (true,
13534          (true,
13535           (S'0,
13536            (imm3'2,
13537             (imm3'1,(imm3'0,(Rn'2,(Rn'1,(Rn'0,(Rd'2,(Rd'1,Rd'0))))))))))))))) =>
13538       (if Do(ThumbCondition (),true)
13539          then let
13540                 val d =
13541                   BitsN.fromNat
13542                     (BitsN.toNat(BitsN.fromBitstring([Rd'2,Rd'1,Rd'0],3)),
13543                      4)
13544                 val n =
13545                   BitsN.fromNat
13546                     (BitsN.toNat(BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)),
13547                      4)
13548                 val setflags = not(InITBlock ())
13549                 val imm12 =
13550                   BitsN.zeroExtend 12
13551                     (BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3))
13552                 val opc =
13553                   if (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
13554                     then BitsN.B(0x2,4)
13555                   else BitsN.B(0x4,4)
13556               in
13557                 Data(ArithLogicImmediate(opc,(setflags,(d,(n,imm12)))))
13558               end
13559        else Skip ())
13560     | (false,
13561      (false,
13562       (false,
13563        (opc'1,
13564         (opc'0,
13565          (imm5'4,
13566           (imm5'3,
13567            (imm5'2,
13568             (imm5'1,(imm5'0,(Rm'2,(Rm'1,(Rm'0,(Rd'2,(Rd'1,Rd'0))))))))))))))) =>
13569       (if Do(ThumbCondition (),true)
13570          then let
13571                 val d =
13572                   BitsN.fromNat
13573                     (BitsN.toNat(BitsN.fromBitstring([Rd'2,Rd'1,Rd'0],3)),
13574                      4)
13575                 val m =
13576                   BitsN.fromNat
13577                     (BitsN.toNat(BitsN.fromBitstring([Rm'2,Rm'1,Rm'0],3)),
13578                      4)
13579                 val setflags = not(InITBlock ())
13580                 val (shift_t,shift_n) =
13581                   DecodeImmShift
13582                     (BitsN.fromBitstring([opc'1,opc'0],2),
13583                      BitsN.fromBitstring
13584                        ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
13585               in
13586                 Data
13587                   (ShiftImmediate
13588                      (false,(setflags,(d,(m,(shift_t,shift_n))))))
13589               end
13590        else Skip ())
13591     | (false,
13592      (false,
13593       (true,
13594        (false,
13595         (false,
13596          (Rd'2,
13597           (Rd'1,
13598            (Rd'0,
13599             (imm8'7,
13600              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
13601       (if Do(ThumbCondition (),true)
13602          then let
13603                 val d =
13604                   BitsN.fromNat
13605                     (BitsN.toNat(BitsN.fromBitstring([Rd'2,Rd'1,Rd'0],3)),
13606                      4)
13607                 val imm12 =
13608                   BitsN.zeroExtend 12
13609                     (BitsN.fromBitstring
13610                        ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
13611                          imm8'1,imm8'0],8))
13612                 val setflags = not(InITBlock ())
13613                 val negate = false
13614               in
13615                 Data(Move(setflags,(negate,(d,imm12))))
13616               end
13617        else Skip ())
13618     | (false,
13619      (false,
13620       (true,
13621        (false,
13622         (true,
13623          (Rn'2,
13624           (Rn'1,
13625            (Rn'0,
13626             (imm8'7,
13627              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
13628       (if Do(ThumbCondition (),true)
13629          then let
13630                 val n =
13631                   BitsN.fromNat
13632                     (BitsN.toNat(BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)),
13633                      4)
13634                 val imm12 =
13635                   BitsN.zeroExtend 12
13636                     (BitsN.fromBitstring
13637                        ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
13638                          imm8'1,imm8'0],8))
13639               in
13640                 Data(TestCompareImmediate(BitsN.B(0x2,2),(n,imm12)))
13641               end
13642        else Skip ())
13643     | (false,
13644      (false,
13645       (true,
13646        (true,
13647         (S'0,
13648          (Rdn'2,
13649           (Rdn'1,
13650            (Rdn'0,
13651             (imm8'7,
13652              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
13653       (if Do(ThumbCondition (),true)
13654          then let
13655                 val d =
13656                   BitsN.fromNat
13657                     (BitsN.toNat
13658                        (BitsN.fromBitstring([Rdn'2,Rdn'1,Rdn'0],3)),4)
13659                 val n = d
13660                 val setflags = not(InITBlock ())
13661                 val imm12 =
13662                   BitsN.zeroExtend 12
13663                     (BitsN.fromBitstring
13664                        ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
13665                          imm8'1,imm8'0],8))
13666                 val opc =
13667                   if (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
13668                     then BitsN.B(0x2,4)
13669                   else BitsN.B(0x4,4)
13670               in
13671                 Data(ArithLogicImmediate(opc,(setflags,(d,(n,imm12)))))
13672               end
13673        else Skip ())
13674     | (false,
13675      (true,
13676       (false,
13677        (false,
13678         (false,
13679          (false,
13680           (opc'3,
13681            (opc'2,(opc'1,(opc'0,(Rx'2,(Rx'1,(Rx'0,(Ry'2,(Ry'1,Ry'0))))))))))))))) =>
13682       let
13683         val Ry = BitsN.fromBitstring([Ry'2,Ry'1,Ry'0],3)
13684         val Rx = BitsN.fromBitstring([Rx'2,Rx'1,Rx'0],3)
13685         val opc = BitsN.fromBitstring([opc'3,opc'2,opc'1,opc'0],4)
13686       in
13687         if Do(ThumbCondition (),true)
13688           then case opc of
13689                   BitsN.B(0x0,_) =>
13690                     let
13691                       val d = BitsN.fromNat(BitsN.toNat Ry,4)
13692                       val n = d
13693                       val m = BitsN.fromNat(BitsN.toNat Rx,4)
13694                       val setflags = not(InITBlock ())
13695                       val (shift_t,shift_n) = (SRType_LSL,0)
13696                     in
13697                       Data
13698                         (Register
13699                            (opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))))
13700                     end
13701                 | BitsN.B(0x1,_) =>
13702                   let
13703                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13704                     val n = d
13705                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13706                     val setflags = not(InITBlock ())
13707                     val (shift_t,shift_n) = (SRType_LSL,0)
13708                   in
13709                     Data
13710                       (Register
13711                          (opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))))
13712                   end
13713                 | BitsN.B(0x5,_) =>
13714                   let
13715                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13716                     val n = d
13717                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13718                     val setflags = not(InITBlock ())
13719                     val (shift_t,shift_n) = (SRType_LSL,0)
13720                   in
13721                     Data
13722                       (Register
13723                          (opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))))
13724                   end
13725                 | BitsN.B(0x6,_) =>
13726                   let
13727                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13728                     val n = d
13729                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13730                     val setflags = not(InITBlock ())
13731                     val (shift_t,shift_n) = (SRType_LSL,0)
13732                   in
13733                     Data
13734                       (Register
13735                          (opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))))
13736                   end
13737                 | BitsN.B(0xC,_) =>
13738                   let
13739                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13740                     val n = d
13741                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13742                     val setflags = not(InITBlock ())
13743                     val (shift_t,shift_n) = (SRType_LSL,0)
13744                   in
13745                     Data
13746                       (Register
13747                          (opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))))
13748                   end
13749                 | BitsN.B(0xE,_) =>
13750                   let
13751                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13752                     val n = d
13753                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13754                     val setflags = not(InITBlock ())
13755                     val (shift_t,shift_n) = (SRType_LSL,0)
13756                   in
13757                     Data
13758                       (Register
13759                          (opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))))
13760                   end
13761                 | BitsN.B(0x2,_) =>
13762                   let
13763                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13764                     val n = d
13765                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13766                     val setflags = not(InITBlock ())
13767                     val shift_t =
13768                       DecodeRegShift
13769                         (BitsN.fromNat
13770                            (BitsN.toNat(BitsN.-(opc,BitsN.B(0x2,4))),2))
13771                   in
13772                     Data
13773                       (ShiftRegister
13774                          (false,(setflags,(d,(n,(shift_t,m))))))
13775                   end
13776                 | BitsN.B(0x3,_) =>
13777                   let
13778                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13779                     val n = d
13780                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13781                     val setflags = not(InITBlock ())
13782                     val shift_t =
13783                       DecodeRegShift
13784                         (BitsN.fromNat
13785                            (BitsN.toNat(BitsN.-(opc,BitsN.B(0x2,4))),2))
13786                   in
13787                     Data
13788                       (ShiftRegister
13789                          (false,(setflags,(d,(n,(shift_t,m))))))
13790                   end
13791                 | BitsN.B(0x4,_) =>
13792                   let
13793                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13794                     val n = d
13795                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13796                     val setflags = not(InITBlock ())
13797                     val shift_t =
13798                       DecodeRegShift
13799                         (BitsN.fromNat
13800                            (BitsN.toNat(BitsN.-(opc,BitsN.B(0x2,4))),2))
13801                   in
13802                     Data
13803                       (ShiftRegister
13804                          (false,(setflags,(d,(n,(shift_t,m))))))
13805                   end
13806                 | BitsN.B(0x7,_) =>
13807                   let
13808                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13809                     val n = d
13810                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13811                     val setflags = not(InITBlock ())
13812                   in
13813                     Data
13814                       (ShiftRegister
13815                          (false,(setflags,(d,(n,(SRType_ROR,m))))))
13816                   end
13817                 | BitsN.B(0x8,_) =>
13818                   let
13819                     val n = BitsN.fromNat(BitsN.toNat Ry,4)
13820                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13821                     val (shift_t,shift_n) = (SRType_LSL,0)
13822                   in
13823                     Data
13824                       (TestCompareRegister
13825                          (BitsN.bits(1,0) opc,(n,(m,(shift_t,shift_n)))))
13826                   end
13827                 | BitsN.B(0xA,_) =>
13828                   let
13829                     val n = BitsN.fromNat(BitsN.toNat Ry,4)
13830                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13831                     val (shift_t,shift_n) = (SRType_LSL,0)
13832                   in
13833                     Data
13834                       (TestCompareRegister
13835                          (BitsN.bits(1,0) opc,(n,(m,(shift_t,shift_n)))))
13836                   end
13837                 | BitsN.B(0xB,_) =>
13838                   let
13839                     val n = BitsN.fromNat(BitsN.toNat Ry,4)
13840                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13841                     val (shift_t,shift_n) = (SRType_LSL,0)
13842                   in
13843                     Data
13844                       (TestCompareRegister
13845                          (BitsN.bits(1,0) opc,(n,(m,(shift_t,shift_n)))))
13846                   end
13847                 | BitsN.B(0x9,_) =>
13848                   let
13849                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13850                     val n = BitsN.fromNat(BitsN.toNat Rx,4)
13851                     val setflags = not(InITBlock ())
13852                   in
13853                     Data
13854                       (ArithLogicImmediate
13855                          (BitsN.B(0x3,4),
13856                           (setflags,(d,(n,BitsN.B(0x0,12))))))
13857                   end
13858                 | BitsN.B(0xD,_) =>
13859                   let
13860                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13861                     val n = BitsN.fromNat(BitsN.toNat Rx,4)
13862                   in
13863                     ( if (Nat.<(ArchVersion (),6)) andalso (d = n)
13864                         then DECODE_UNPREDICTABLE(mc,"Multiply")
13865                       else ()
13866                     ; let
13867                         val m = d
13868                         val setflags = not(InITBlock ())
13869                       in
13870                         Multiply(Multiply32(setflags,(d,(n,m))))
13871                       end
13872                     )
13873                   end
13874                 | BitsN.B(0xF,_) =>
13875                   let
13876                     val d = BitsN.fromNat(BitsN.toNat Ry,4)
13877                     val m = BitsN.fromNat(BitsN.toNat Rx,4)
13878                     val setflags = not(InITBlock ())
13879                     val (shift_t,shift_n) = (SRType_LSL,0)
13880                   in
13881                     Data
13882                       (ShiftImmediate
13883                          (true,(setflags,(d,(m,(shift_t,shift_n))))))
13884                   end
13885                 | _ => raise General.Bind
13886         else Skip ()
13887       end
13888     | (false,
13889      (true,
13890       (false,
13891        (false,
13892         (false,
13893          (true,
13894           (false,
13895            (false,
13896             (DN'0,(Rm'3,(Rm'2,(Rm'1,(Rm'0,(Rdn'2,(Rdn'1,Rdn'0))))))))))))))) =>
13897       let
13898         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
13899         val DN = BitsN.fromBitstring([DN'0],1)
13900       in
13901         if Do(ThumbCondition (),
13902               (BitsN.msb Rm) orelse
13903               ((DN = (BitsN.B(0x1,1))) orelse (HaveThumb2 ())))
13904           then let
13905                  val d =
13906                    BitsN.@@
13907                      (DN,BitsN.fromBitstring([Rdn'2,Rdn'1,Rdn'0],3))
13908                  val n = d
13909                in
13910                  ( if ((n = (BitsN.B(0xF,4))) andalso
13911                        (Rm = (BitsN.B(0xF,4)))) orelse
13912                       ((d = (BitsN.B(0xF,4))) andalso
13913                        ((InITBlock ()) andalso (not(LastInITBlock ()))))
13914                      then DECODE_UNPREDICTABLE(mc,"ADD")
13915                    else ()
13916                  ; let
13917                      val setflags = false
13918                      val (shift_t,shift_n) = (SRType_LSL,0)
13919                    in
13920                      Data
13921                        (Register
13922                           (BitsN.B(0x4,4),
13923                            (setflags,(d,(n,(Rm,(shift_t,shift_n)))))))
13924                    end
13925                  )
13926                end
13927         else Skip ()
13928       end
13929     | (false,
13930      (true,
13931       (false,(false,(false,(true,(false,(true,(false,(false,_)))))))))) =>
13932       raise UNPREDICTABLE "Thumb: 010001 0100 _"
13933     | (false,
13934      (true,
13935       (false,
13936        (false,
13937         (false,
13938          (true,
13939           (false,
13940            (true,(N'0,(Rm'3,(Rm'2,(Rm'1,(Rm'0,(Rn'2,(Rn'1,Rn'0))))))))))))))) =>
13941       let
13942         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
13943       in
13944         if Do(ThumbCondition (),true)
13945           then let
13946                  val n =
13947                    BitsN.@@
13948                      (BitsN.fromBitstring([N'0],1),
13949                       BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3))
13950                in
13951                  ( if ((BitsN.<+(n,BitsN.B(0x8,4))) andalso
13952                        (BitsN.<+(Rm,BitsN.B(0x8,4)))) orelse
13953                       ((n = (BitsN.B(0xF,4))) orelse
13954                        (Rm = (BitsN.B(0xF,4))))
13955                      then DECODE_UNPREDICTABLE(mc,"CMP")
13956                    else ()
13957                  ; Data
13958                      (TestCompareRegister
13959                         (BitsN.B(0x2,2),(n,(Rm,(SRType_LSL,0)))))
13960                  )
13961                end
13962         else Skip ()
13963       end
13964     | (false,
13965      (true,
13966       (false,
13967        (false,
13968         (false,
13969          (true,
13970           (true,
13971            (false,(D'0,(Rm'3,(Rm'2,(Rm'1,(Rm'0,(Rd'2,(Rd'1,Rd'0))))))))))))))) =>
13972       let
13973         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
13974         val D = BitsN.fromBitstring([D'0],1)
13975       in
13976         if Do(ThumbCondition (),
13977               (BitsN.msb Rm) orelse
13978               ((D = (BitsN.B(0x1,1))) orelse (Nat.>=(ArchVersion (),6))))
13979           then let
13980                  val d =
13981                    BitsN.@@(D,BitsN.fromBitstring([Rd'2,Rd'1,Rd'0],3))
13982                in
13983                  ( if (d = (BitsN.B(0xF,4))) andalso
13984                       ((InITBlock ()) andalso (not(LastInITBlock ())))
13985                      then DECODE_UNPREDICTABLE(mc,"MOV")
13986                    else ()
13987                  ; let
13988                      val setflags = false
13989                      val (shift_t,shift_n) = (SRType_LSL,0)
13990                    in
13991                      Data
13992                        (ShiftImmediate
13993                           (false,(setflags,(d,(Rm,(shift_t,shift_n))))))
13994                    end
13995                  )
13996                end
13997         else Skip ()
13998       end
13999     | (false,
14000      (true,
14001       (false,
14002        (false,
14003         (false,
14004          (true,
14005           (true,
14006            (true,
14007             (false,
14008              (Rm'3,
14009               (Rm'2,(Rm'1,(Rm'0,(sb'0'000'2,(sb'0'000'1,sb'0'000'0))))))))))))))) =>
14010       let
14011         val GOOD_MATCH =
14012           (BitsN.fromBitstring([sb'0'000'2,sb'0'000'1,sb'0'000'0],3)) =
14013           (BitsN.B(0x0,3))
14014       in
14015         if Do(ThumbCondition (),true)
14016           then ( if ((InITBlock ()) andalso (not(LastInITBlock ()))) orelse
14017                     (not GOOD_MATCH)
14018                    then DECODE_UNPREDICTABLE(mc,"BranchExchange")
14019                  else ()
14020                ; Branch
14021                    (BranchExchange
14022                       (BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)))
14023                )
14024         else Skip ()
14025       end
14026     | (false,
14027      (true,
14028       (false,
14029        (false,
14030         (false,
14031          (true,
14032           (true,
14033            (true,
14034             (true,
14035              (Rm'3,
14036               (Rm'2,(Rm'1,(Rm'0,(sb'0'000'2,(sb'0'000'1,sb'0'000'0))))))))))))))) =>
14037       let
14038         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
14039         val GOOD_MATCH =
14040           (BitsN.fromBitstring([sb'0'000'2,sb'0'000'1,sb'0'000'0],3)) =
14041           (BitsN.B(0x0,3))
14042       in
14043         if Do(ThumbCondition (),Nat.>=(ArchVersion (),5))
14044           then ( if (Rm = (BitsN.B(0xF,4))) orelse
14045                     (((InITBlock ()) andalso (not(LastInITBlock ()))) orelse
14046                      (not GOOD_MATCH))
14047                    then DECODE_UNPREDICTABLE
14048                           (mc,"BranchLinkExchangeRegister")
14049                  else ()
14050                ; Branch(BranchLinkExchangeRegister Rm)
14051                )
14052         else Skip ()
14053       end
14054     | (false,
14055      (true,
14056       (false,
14057        (false,
14058         (true,
14059          (Rt'2,
14060           (Rt'1,
14061            (Rt'0,
14062             (imm8'7,
14063              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
14064       (if Do(ThumbCondition (),true)
14065          then let
14066                 val add = true
14067                 val imm32 =
14068                   BitsN.zeroExtend 32
14069                     (BitsN.@@
14070                        (BitsN.fromBitstring
14071                           ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
14072                             imm8'1,imm8'0],8),BitsN.B(0x0,2)))
14073               in
14074                 Load
14075                   (LoadLiteral
14076                      (add,
14077                       (BitsN.fromNat
14078                          (BitsN.toNat
14079                             (BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)),4),
14080                        imm32)))
14081               end
14082        else Skip ())
14083     | (false,
14084      (true,
14085       (false,
14086        (true,
14087         (opc'2,
14088          (opc'1,
14089           (opc'0,
14090            (Rm'2,(Rm'1,(Rm'0,(Rn'2,(Rn'1,(Rn'0,(Rt'2,(Rt'1,Rt'0))))))))))))))) =>
14091       let
14092         val Rt = BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)
14093         val Rn = BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)
14094       in
14095         if Do(ThumbCondition (),true)
14096           then let
14097                  val index = true
14098                  val add = true
14099                  val wback = false
14100                  val (shift_t,shift_n) = (SRType_LSL,0)
14101                  val m =
14102                    register_form1
14103                      (BitsN.fromNat
14104                         (BitsN.toNat
14105                            (BitsN.fromBitstring([Rm'2,Rm'1,Rm'0],3)),4),
14106                       (shift_t,shift_n))
14107                in
14108                  case BitsN.fromBitstring([opc'2,opc'1,opc'0],3) of
14109                     BitsN.B(0x0,_) =>
14110                       Store
14111                         (StoreWord
14112                            (add,
14113                             (index,
14114                              (wback,
14115                               (BitsN.fromNat(BitsN.toNat Rt,4),
14116                                (BitsN.fromNat(BitsN.toNat Rn,4),m))))))
14117                   | BitsN.B(0x1,_) =>
14118                     Store
14119                       (StoreHalf
14120                          (add,
14121                           (index,
14122                            (wback,
14123                             (BitsN.fromNat(BitsN.toNat Rt,4),
14124                              (BitsN.fromNat(BitsN.toNat Rn,4),m))))))
14125                   | BitsN.B(0x2,_) =>
14126                     Store
14127                       (StoreByte
14128                          (add,
14129                           (index,
14130                            (wback,
14131                             (BitsN.fromNat(BitsN.toNat Rt,4),
14132                              (BitsN.fromNat(BitsN.toNat Rn,4),m))))))
14133                   | BitsN.B(0x3,_) =>
14134                     Load
14135                       (LoadByte
14136                          (false,
14137                           (add,
14138                            (index,
14139                             (wback,
14140                              (BitsN.fromNat(BitsN.toNat Rt,4),
14141                               (BitsN.fromNat(BitsN.toNat Rn,4),m)))))))
14142                   | BitsN.B(0x4,_) =>
14143                     Load
14144                       (LoadWord
14145                          (add,
14146                           (index,
14147                            (wback,
14148                             (BitsN.fromNat(BitsN.toNat Rt,4),
14149                              (BitsN.fromNat(BitsN.toNat Rn,4),m))))))
14150                   | BitsN.B(0x5,_) =>
14151                     Load
14152                       (LoadHalf
14153                          (true,
14154                           (add,
14155                            (index,
14156                             (wback,
14157                              (BitsN.fromNat(BitsN.toNat Rt,4),
14158                               (BitsN.fromNat(BitsN.toNat Rn,4),m)))))))
14159                   | BitsN.B(0x6,_) =>
14160                     Load
14161                       (LoadByte
14162                          (true,
14163                           (add,
14164                            (index,
14165                             (wback,
14166                              (BitsN.fromNat(BitsN.toNat Rt,4),
14167                               (BitsN.fromNat(BitsN.toNat Rn,4),m)))))))
14168                   | BitsN.B(0x7,_) =>
14169                     Load
14170                       (LoadHalf
14171                          (false,
14172                           (add,
14173                            (index,
14174                             (wback,
14175                              (BitsN.fromNat(BitsN.toNat Rt,4),
14176                               (BitsN.fromNat(BitsN.toNat Rn,4),m)))))))
14177                   | _ => raise General.Bind
14178                end
14179         else Skip ()
14180       end
14181     | (false,
14182      (true,
14183       (true,
14184        (false,
14185         (L'0,
14186          (imm5'4,
14187           (imm5'3,
14188            (imm5'2,
14189             (imm5'1,(imm5'0,(Rn'2,(Rn'1,(Rn'0,(Rt'2,(Rt'1,Rt'0))))))))))))))) =>
14190       let
14191         val Rt = BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)
14192         val Rn = BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)
14193       in
14194         if Do(ThumbCondition (),true)
14195           then let
14196                  val index = true
14197                  val add = true
14198                  val wback = false
14199                  val imm32 =
14200                    BitsN.zeroExtend 32
14201                      (BitsN.@@
14202                         (BitsN.fromBitstring
14203                            ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5),
14204                          BitsN.B(0x0,2)))
14205                  val m = immediate_form1 imm32
14206                in
14207                  if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
14208                    then Load
14209                           (LoadWord
14210                              (add,
14211                               (index,
14212                                (wback,
14213                                 (BitsN.fromNat(BitsN.toNat Rt,4),
14214                                  (BitsN.fromNat(BitsN.toNat Rn,4),m))))))
14215                  else Store
14216                         (StoreWord
14217                            (add,
14218                             (index,
14219                              (wback,
14220                               (BitsN.fromNat(BitsN.toNat Rt,4),
14221                                (BitsN.fromNat(BitsN.toNat Rn,4),m))))))
14222                end
14223         else Skip ()
14224       end
14225     | (false,
14226      (true,
14227       (true,
14228        (true,
14229         (L'0,
14230          (imm5'4,
14231           (imm5'3,
14232            (imm5'2,
14233             (imm5'1,(imm5'0,(Rn'2,(Rn'1,(Rn'0,(Rt'2,(Rt'1,Rt'0))))))))))))))) =>
14234       let
14235         val Rt = BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)
14236         val Rn = BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)
14237       in
14238         if Do(ThumbCondition (),true)
14239           then let
14240                  val index = true
14241                  val add = true
14242                  val wback = false
14243                  val imm32 =
14244                    BitsN.zeroExtend 32
14245                      (BitsN.fromBitstring
14246                         ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
14247                  val m = immediate_form1 imm32
14248                in
14249                  if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
14250                    then Load
14251                           (LoadByte
14252                              (true,
14253                               (add,
14254                                (index,
14255                                 (wback,
14256                                  (BitsN.fromNat(BitsN.toNat Rt,4),
14257                                   (BitsN.fromNat(BitsN.toNat Rn,4),m)))))))
14258                  else Store
14259                         (StoreByte
14260                            (add,
14261                             (index,
14262                              (wback,
14263                               (BitsN.fromNat(BitsN.toNat Rt,4),
14264                                (BitsN.fromNat(BitsN.toNat Rn,4),m))))))
14265                end
14266         else Skip ()
14267       end
14268     | (true,
14269      (false,
14270       (false,
14271        (false,
14272         (L'0,
14273          (imm5'4,
14274           (imm5'3,
14275            (imm5'2,
14276             (imm5'1,(imm5'0,(Rn'2,(Rn'1,(Rn'0,(Rt'2,(Rt'1,Rt'0))))))))))))))) =>
14277       let
14278         val Rt = BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)
14279         val Rn = BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)
14280       in
14281         if Do(ThumbCondition (),true)
14282           then let
14283                  val index = true
14284                  val add = true
14285                  val wback = false
14286                  val imm32 =
14287                    BitsN.zeroExtend 32
14288                      (BitsN.@@
14289                         (BitsN.fromBitstring
14290                            ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5),
14291                          BitsN.B(0x0,1)))
14292                  val m = immediate_form1 imm32
14293                in
14294                  if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
14295                    then Load
14296                           (LoadHalf
14297                              (true,
14298                               (add,
14299                                (index,
14300                                 (wback,
14301                                  (BitsN.fromNat(BitsN.toNat Rt,4),
14302                                   (BitsN.fromNat(BitsN.toNat Rn,4),m)))))))
14303                  else Store
14304                         (StoreHalf
14305                            (add,
14306                             (index,
14307                              (wback,
14308                               (BitsN.fromNat(BitsN.toNat Rt,4),
14309                                (BitsN.fromNat(BitsN.toNat Rn,4),m))))))
14310                end
14311         else Skip ()
14312       end
14313     | (true,
14314      (false,
14315       (false,
14316        (true,
14317         (L'0,
14318          (Rt'2,
14319           (Rt'1,
14320            (Rt'0,
14321             (imm8'7,
14322              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
14323       let
14324         val Rt = BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)
14325       in
14326         if Do(ThumbCondition (),true)
14327           then let
14328                  val index = true
14329                  val add = true
14330                  val wback = false
14331                  val imm32 =
14332                    BitsN.zeroExtend 32
14333                      (BitsN.@@
14334                         (BitsN.fromBitstring
14335                            ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
14336                              imm8'1,imm8'0],8),BitsN.B(0x0,2)))
14337                  val m = immediate_form1 imm32
14338                in
14339                  if (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
14340                    then Load
14341                           (LoadWord
14342                              (add,
14343                               (index,
14344                                (wback,
14345                                 (BitsN.fromNat(BitsN.toNat Rt,4),
14346                                  (BitsN.B(0xD,4),m))))))
14347                  else Store
14348                         (StoreWord
14349                            (add,
14350                             (index,
14351                              (wback,
14352                               (BitsN.fromNat(BitsN.toNat Rt,4),
14353                                (BitsN.B(0xD,4),m))))))
14354                end
14355         else Skip ()
14356       end
14357     | (true,
14358      (false,
14359       (true,
14360        (false,
14361         (S'0,
14362          (Rd'2,
14363           (Rd'1,
14364            (Rd'0,
14365             (imm8'7,
14366              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
14367       (if Do(ThumbCondition (),true)
14368          then let
14369                 val imm12 =
14370                   BitsN.@@
14371                     (BitsN.B(0xF,4),
14372                      BitsN.fromBitstring
14373                        ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
14374                          imm8'1,imm8'0],8))
14375                 val Rn =
14376                   if (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
14377                     then BitsN.B(0xD,4)
14378                   else BitsN.B(0xF,4)
14379               in
14380                 Data
14381                   (ArithLogicImmediate
14382                      (BitsN.B(0x4,4),
14383                       (false,
14384                        (BitsN.fromNat
14385                           (BitsN.toNat
14386                              (BitsN.fromBitstring([Rd'2,Rd'1,Rd'0],3)),4),
14387                         (Rn,imm12)))))
14388               end
14389        else Skip ())
14390     | (true,
14391      (false,
14392       (true,
14393        (true,
14394         (false,
14395          (false,
14396           (false,
14397            (false,
14398             (S'0,
14399              (imm7'6,(imm7'5,(imm7'4,(imm7'3,(imm7'2,(imm7'1,imm7'0))))))))))))))) =>
14400       (if Do(ThumbCondition (),true)
14401          then let
14402                 val imm12 =
14403                   BitsN.@@
14404                     (BitsN.B(0x1E,5),
14405                      BitsN.fromBitstring
14406                        ([imm7'6,imm7'5,imm7'4,imm7'3,imm7'2,imm7'1,imm7'0],
14407                         7))
14408                 val opc =
14409                   if (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
14410                     then BitsN.B(0x2,4)
14411                   else BitsN.B(0x4,4)
14412               in
14413                 Data
14414                   (ArithLogicImmediate
14415                      (opc,(false,(BitsN.B(0xD,4),(BitsN.B(0xD,4),imm12)))))
14416               end
14417        else Skip ())
14418     | (true,
14419      (false,
14420       (true,
14421        (true,
14422         (op'0,
14423          (false,
14424           (i'0,
14425            (true,
14426             (imm5'4,
14427              (imm5'3,(imm5'2,(imm5'1,(imm5'0,(Rn'2,(Rn'1,Rn'0))))))))))))))) =>
14428       (if Do(BitsN.B(0xE,4),HaveThumb2 ())
14429          then ( if InITBlock ()
14430                   then DECODE_UNPREDICTABLE(mc,"CompareBranch")
14431                 else ()
14432               ; let
14433                   val imm32 =
14434                     BitsN.zeroExtend 32
14435                       (BitsN.concat
14436                          [BitsN.fromBitstring([i'0],1),
14437                           BitsN.fromBitstring
14438                             ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5),
14439                           BitsN.B(0x0,1)])
14440                   val nonzero =
14441                     (BitsN.fromBitstring([op'0],1)) = (BitsN.B(0x1,1))
14442                 in
14443                   Branch
14444                     (CompareBranch
14445                        (nonzero,
14446                         (BitsN.fromNat
14447                            (BitsN.toNat
14448                               (BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)),4),
14449                          imm32)))
14450                 end
14451               )
14452        else Skip ())
14453     | (true,
14454      (false,
14455       (true,
14456        (true,
14457         (false,
14458          (false,
14459           (true,
14460            (false,(U'0,(false,(Rm'2,(Rm'1,(Rm'0,(Rd'2,(Rd'1,Rd'0))))))))))))))) =>
14461       (if Do(ThumbCondition (),Nat.>=(ArchVersion (),6))
14462          then let
14463                 val unsigned =
14464                   (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
14465               in
14466                 Media
14467                   (ExtendHalfword
14468                      (unsigned,
14469                       (BitsN.fromNat
14470                          (BitsN.toNat
14471                             (BitsN.fromBitstring([Rd'2,Rd'1,Rd'0],3)),4),
14472                        (BitsN.B(0xF,4),
14473                         (BitsN.fromNat
14474                            (BitsN.toNat
14475                               (BitsN.fromBitstring([Rm'2,Rm'1,Rm'0],3)),4),
14476                          0)))))
14477               end
14478        else Skip ())
14479     | (true,
14480      (false,
14481       (true,
14482        (true,
14483         (false,
14484          (false,
14485           (true,
14486            (false,(U'0,(true,(Rm'2,(Rm'1,(Rm'0,(Rd'2,(Rd'1,Rd'0))))))))))))))) =>
14487       (if Do(ThumbCondition (),Nat.>=(ArchVersion (),6))
14488          then let
14489                 val unsigned =
14490                   (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
14491               in
14492                 Media
14493                   (ExtendByte
14494                      (unsigned,
14495                       (BitsN.fromNat
14496                          (BitsN.toNat
14497                             (BitsN.fromBitstring([Rd'2,Rd'1,Rd'0],3)),4),
14498                        (BitsN.B(0xF,4),
14499                         (BitsN.fromNat
14500                            (BitsN.toNat
14501                               (BitsN.fromBitstring([Rm'2,Rm'1,Rm'0],3)),4),
14502                          0)))))
14503               end
14504        else Skip ())
14505     | (true,
14506      (false,
14507       (true,
14508        (true,
14509         (false,
14510          (true,
14511           (false,
14512            (M'0,
14513             (register_list'7,
14514              (register_list'6,
14515               (register_list'5,
14516                (register_list'4,
14517                 (register_list'3,
14518                  (register_list'2,(register_list'1,register_list'0))))))))))))))) =>
14519       (if Do(ThumbCondition (),true)
14520          then let
14521                 val registers =
14522                   BitsN.concat
14523                     [BitsN.B(0x0,1),BitsN.fromBitstring([M'0],1),
14524                      BitsN.B(0x0,6),
14525                      BitsN.fromBitstring
14526                        ([register_list'7,register_list'6,register_list'5,
14527                          register_list'4,register_list'3,register_list'2,
14528                          register_list'1,register_list'0],8)]
14529               in
14530                 ( if Nat.<(BitCount 16 registers,1)
14531                     then DECODE_UNPREDICTABLE(mc,"StoreMultiple")
14532                   else ()
14533                 ; let
14534                     val increment = false
14535                     val index = true
14536                     val wback = true
14537                   in
14538                     Store
14539                       (StoreMultiple
14540                          (increment,
14541                           (index,(wback,(BitsN.B(0xD,4),registers)))))
14542                   end
14543                 )
14544               end
14545        else Skip ())
14546     | (true,
14547      (false,
14548       (true,
14549        (true,
14550         (false,
14551          (true,
14552           (true,
14553            (false,
14554             (false,
14555              (true,
14556               (false,
14557                (sb'0'1'0,(E'0,(sb'1'000'2,(sb'1'000'1,sb'1'000'0))))))))))))))) =>
14558       let
14559         val GOOD_MATCH =
14560           ((BitsN.fromBitstring([sb'0'1'0],1)) = (BitsN.B(0x1,1))) andalso
14561           ((BitsN.fromBitstring([sb'1'000'2,sb'1'000'1,sb'1'000'0],3)) =
14562            (BitsN.B(0x0,3)))
14563       in
14564         if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),6))
14565           then ( if (InITBlock ()) orelse (not GOOD_MATCH)
14566                    then DECODE_UNPREDICTABLE(mc,"Setend")
14567                  else ()
14568                ; let
14569                    val set_bigend =
14570                      (BitsN.fromBitstring([E'0],1)) = (BitsN.B(0x1,1))
14571                  in
14572                    System(Setend set_bigend)
14573                  end
14574                )
14575         else Skip ()
14576       end
14577     | (true,
14578      (false,
14579       (true,
14580        (true,
14581         (false,
14582          (true,
14583           (true,
14584            (false,(false,(true,(true,(im'0,(sb'0'0'0,(A'0,(I'0,F'0))))))))))))))) =>
14585       let
14586         val F = BitsN.fromBitstring([F'0],1)
14587         val I = BitsN.fromBitstring([I'0],1)
14588         val A = BitsN.fromBitstring([A'0],1)
14589         val GOOD_MATCH =
14590           (BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))
14591       in
14592         if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),6))
14593           then ( if ((BitsN.concat[A,I,F]) = (BitsN.B(0x0,3))) orelse
14594                     ((InITBlock ()) orelse (not GOOD_MATCH))
14595                    then DECODE_UNPREDICTABLE(mc,"ChangeProcessorState")
14596                  else ()
14597                ; let
14598                    val enable =
14599                      (BitsN.fromBitstring([im'0],1)) = (BitsN.B(0x0,1))
14600                    val affectA = A = (BitsN.B(0x1,1))
14601                    val affectI = I = (BitsN.B(0x1,1))
14602                    val affectF = F = (BitsN.B(0x1,1))
14603                  in
14604                    System
14605                      (ChangeProcessorState
14606                         (enable,
14607                          (not enable,(affectA,(affectI,(affectF,NONE))))))
14608                  end
14609                )
14610         else Skip ()
14611       end
14612     | (true,
14613      (false,
14614       (true,
14615        (true,
14616         (true,
14617          (false,
14618           (true,
14619            (false,(opc'1,(opc'0,(Rm'2,(Rm'1,(Rm'0,(Rd'2,(Rd'1,Rd'0))))))))))))))) =>
14620       let
14621         val Rd = BitsN.fromBitstring([Rd'2,Rd'1,Rd'0],3)
14622         val Rm = BitsN.fromBitstring([Rm'2,Rm'1,Rm'0],3)
14623       in
14624         if Do(ThumbCondition (),Nat.>=(ArchVersion (),6))
14625           then case BitsN.fromBitstring([opc'1,opc'0],2) of
14626                   BitsN.B(0x0,_) =>
14627                     Media
14628                       (ByteReverse
14629                          (BitsN.fromNat(BitsN.toNat Rd,4),
14630                           BitsN.fromNat(BitsN.toNat Rm,4)))
14631                 | BitsN.B(0x1,_) =>
14632                   Media
14633                     (ByteReversePackedHalfword
14634                        (BitsN.fromNat(BitsN.toNat Rd,4),
14635                         BitsN.fromNat(BitsN.toNat Rm,4)))
14636                 | BitsN.B(0x3,_) =>
14637                   Media
14638                     (ByteReverseSignedHalfword
14639                        (BitsN.fromNat(BitsN.toNat Rd,4),
14640                         BitsN.fromNat(BitsN.toNat Rm,4)))
14641                 | _ => Undefined(BitsN.B(0x0,32))
14642         else Skip ()
14643       end
14644     | (true,
14645      (false,
14646       (true,
14647        (true,
14648         (true,
14649          (true,
14650           (false,
14651            (P'0,
14652             (register_list'7,
14653              (register_list'6,
14654               (register_list'5,
14655                (register_list'4,
14656                 (register_list'3,
14657                  (register_list'2,(register_list'1,register_list'0))))))))))))))) =>
14658       (if Do(ThumbCondition (),true)
14659          then let
14660                 val registers =
14661                   BitsN.concat
14662                     [BitsN.fromBitstring([P'0],1),BitsN.B(0x0,7),
14663                      BitsN.fromBitstring
14664                        ([register_list'7,register_list'6,register_list'5,
14665                          register_list'4,register_list'3,register_list'2,
14666                          register_list'1,register_list'0],8)]
14667               in
14668                 ( if (Nat.<(BitCount 16 registers,1)) orelse
14669                      ((BitsN.bit(registers,15)) andalso
14670                       ((InITBlock ()) andalso (not(LastInITBlock ()))))
14671                     then DECODE_UNPREDICTABLE(mc,"LoadMultiple")
14672                   else ()
14673                 ; let
14674                     val increment = true
14675                     val index = false
14676                     val wback = true
14677                   in
14678                     Load
14679                       (LoadMultiple
14680                          (increment,
14681                           (index,(wback,(BitsN.B(0xD,4),registers)))))
14682                   end
14683                 )
14684               end
14685        else Skip ())
14686     | (true,
14687      (false,
14688       (true,
14689        (true,
14690         (true,
14691          (true,
14692           (true,
14693            (false,
14694             (imm8'7,
14695              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
14696       (if Do(BitsN.B(0xE,4),Nat.>=(ArchVersion (),5))
14697          then let
14698                 val imm32 =
14699                   BitsN.zeroExtend 32
14700                     (BitsN.fromBitstring
14701                        ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
14702                          imm8'1,imm8'0],8))
14703               in
14704                 Hint(Breakpoint imm32)
14705               end
14706        else Skip ())
14707     | (true,
14708      (false,
14709       (true,
14710        (true,
14711         (true,
14712          (true,
14713           (true,
14714            (true,
14715             (op'3,(op'2,(op'1,(op'0,(false,(false,(false,false))))))))))))))) =>
14716       DecodeHint
14717         (ThumbCondition (),
14718          BitsN.zeroExtend 8
14719            (BitsN.fromBitstring([op'3,op'2,op'1,op'0],4)))
14720     | (true,
14721      (false,
14722       (true,
14723        (true,
14724         (true,
14725          (true,
14726           (true,
14727            (true,
14728             (firstcond'3,
14729              (firstcond'2,
14730               (firstcond'1,
14731                (firstcond'0,(mask'3,(mask'2,(mask'1,mask'0))))))))))))))) =>
14732       let
14733         val mask = BitsN.fromBitstring([mask'3,mask'2,mask'1,mask'0],4)
14734         val firstcond =
14735           BitsN.fromBitstring
14736             ([firstcond'3,firstcond'2,firstcond'1,firstcond'0],4)
14737       in
14738         if Do(BitsN.B(0xE,4),HaveThumb2 ())
14739           then ( if (firstcond = (BitsN.B(0xF,4))) orelse
14740                     (((firstcond = (BitsN.B(0xE,4))) andalso
14741                       (not((BitCount 4 mask) = 1))) orelse (InITBlock ()))
14742                    then DECODE_UNPREDICTABLE(mc,"IfThen")
14743                  else ()
14744                ; IfThen(firstcond,mask)
14745                )
14746         else Skip ()
14747       end
14748     | (true,
14749      (true,
14750       (false,
14751        (false,
14752         (false,
14753          (Rn'2,
14754           (Rn'1,
14755            (Rn'0,
14756             (register_list'7,
14757              (register_list'6,
14758               (register_list'5,
14759                (register_list'4,
14760                 (register_list'3,
14761                  (register_list'2,(register_list'1,register_list'0))))))))))))))) =>
14762       (if Do(ThumbCondition (),true)
14763          then let
14764                 val registers =
14765                   BitsN.fromNat
14766                     (BitsN.toNat
14767                        (BitsN.fromBitstring
14768                           ([register_list'7,register_list'6,
14769                             register_list'5,register_list'4,
14770                             register_list'3,register_list'2,
14771                             register_list'1,register_list'0],8)),16)
14772               in
14773                 ( if Nat.<(BitCount 16 registers,1)
14774                     then DECODE_UNPREDICTABLE(mc,"StoreMultiple")
14775                   else ()
14776                 ; let
14777                     val increment = true
14778                     val index = false
14779                     val wback = true
14780                   in
14781                     Store
14782                       (StoreMultiple
14783                          (increment,
14784                           (index,
14785                            (wback,
14786                             (BitsN.fromNat
14787                                (BitsN.toNat
14788                                   (BitsN.fromBitstring
14789                                      ([Rn'2,Rn'1,Rn'0],3)),4),registers)))))
14790                   end
14791                 )
14792               end
14793        else Skip ())
14794     | (true,
14795      (true,
14796       (false,
14797        (false,
14798         (true,
14799          (Rn'2,
14800           (Rn'1,
14801            (Rn'0,
14802             (register_list'7,
14803              (register_list'6,
14804               (register_list'5,
14805                (register_list'4,
14806                 (register_list'3,
14807                  (register_list'2,(register_list'1,register_list'0))))))))))))))) =>
14808       let
14809         val Rn = BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)
14810       in
14811         if Do(ThumbCondition (),true)
14812           then let
14813                  val registers =
14814                    BitsN.fromNat
14815                      (BitsN.toNat
14816                         (BitsN.fromBitstring
14817                            ([register_list'7,register_list'6,
14818                              register_list'5,register_list'4,
14819                              register_list'3,register_list'2,
14820                              register_list'1,register_list'0],8)),16)
14821                in
14822                  ( if Nat.<(BitCount 16 registers,1)
14823                      then DECODE_UNPREDICTABLE(mc,"LoadMultiple")
14824                    else ()
14825                  ; let
14826                      val increment = true
14827                      val index = false
14828                      val wback = not(BitsN.bit(registers,BitsN.toNat Rn))
14829                    in
14830                      Load
14831                        (LoadMultiple
14832                           (increment,
14833                            (index,
14834                             (wback,
14835                              (BitsN.fromNat(BitsN.toNat Rn,4),registers)))))
14836                    end
14837                  )
14838                end
14839         else Skip ()
14840       end
14841     | (true,
14842      (true,
14843       (false,
14844        (true,
14845         (true,
14846          (true,
14847           (true,
14848            (false,
14849             (imm8'7,
14850              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
14851       (if Do(ThumbCondition (),true)
14852          then let
14853                 val imm32 =
14854                   BitsN.zeroExtend 32
14855                     (BitsN.fromBitstring
14856                        ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
14857                          imm8'1,imm8'0],8))
14858               in
14859                 Undefined imm32
14860               end
14861        else Skip ())
14862     | (true,
14863      (true,
14864       (false,
14865        (true,
14866         (true,
14867          (true,
14868           (true,
14869            (true,
14870             (imm8'7,
14871              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
14872       (if Do(ThumbCondition (),true)
14873          then System
14874                 (SupervisorCall
14875                    (BitsN.zeroExtend 32
14876                       (BitsN.fromBitstring
14877                          ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
14878                            imm8'1,imm8'0],8))))
14879        else Skip ())
14880     | (true,
14881      (true,
14882       (false,
14883        (true,
14884         (cond'3,
14885          (cond'2,
14886           (cond'1,
14887            (cond'0,
14888             (imm8'7,
14889              (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0))))))))))))))) =>
14890       (if Do(BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4),true)
14891          then ( if InITBlock ()
14892                   then DECODE_UNPREDICTABLE(mc,"BranchTarget")
14893                 else ()
14894               ; let
14895                   val imm32 =
14896                     BitsN.signExtend 32
14897                       (BitsN.@@
14898                          (BitsN.fromBitstring
14899                             ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
14900                               imm8'1,imm8'0],8),BitsN.B(0x0,1)))
14901                 in
14902                   Branch(BranchTarget imm32)
14903                 end
14904               )
14905        else Skip ())
14906     | (true,
14907      (true,
14908       (true,
14909        (false,
14910         (false,
14911          (imm11'10,
14912           (imm11'9,
14913            (imm11'8,
14914             (imm11'7,
14915              (imm11'6,
14916               (imm11'5,(imm11'4,(imm11'3,(imm11'2,(imm11'1,imm11'0))))))))))))))) =>
14917       (if Do(ThumbCondition (),true)
14918          then ( if (InITBlock ()) andalso (not(LastInITBlock ()))
14919                   then DECODE_UNPREDICTABLE(mc,"BranchTarget")
14920                 else ()
14921               ; let
14922                   val imm32 =
14923                     BitsN.signExtend 32
14924                       (BitsN.@@
14925                          (BitsN.fromBitstring
14926                             ([imm11'10,imm11'9,imm11'8,imm11'7,imm11'6,
14927                               imm11'5,imm11'4,imm11'3,imm11'2,imm11'1,
14928                               imm11'0],11),BitsN.B(0x0,1)))
14929                 in
14930                   Branch(BranchTarget imm32)
14931                 end
14932               )
14933        else Skip ())
14934     | _ => UndefinedThumb ()
14935  end;
14936
14937fun DecodeThumbEE h =
14938  let
14939    val mc = Thumb h
14940  in
14941    case boolify'16 h of
14942       (false,
14943        (true,
14944         (false,
14945          (true,
14946           (opc'2,
14947            (opc'1,
14948             (opc'0,
14949              (Rm'2,(Rm'1,(Rm'0,(Rn'2,(Rn'1,(Rn'0,(Rt'2,(Rt'1,Rt'0))))))))))))))) =>
14950         let
14951           val Rt = BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)
14952           val Rn = BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)
14953         in
14954           if Do(ThumbCondition (),true)
14955             then let
14956                    val index = true
14957                    val add = true
14958                    val wback = false
14959                    val m =
14960                      BitsN.fromNat
14961                        (BitsN.toNat
14962                           (BitsN.fromBitstring([Rm'2,Rm'1,Rm'0],3)),4)
14963                    val m1 = register_form1(m,(SRType_LSL,1))
14964                    val m2 = register_form1(m,(SRType_LSL,2))
14965                  in
14966                    case BitsN.fromBitstring([opc'2,opc'1,opc'0],3) of
14967                       BitsN.B(0x0,_) =>
14968                         Store
14969                           (StoreWord
14970                              (add,
14971                               (index,
14972                                (wback,
14973                                 (BitsN.fromNat(BitsN.toNat Rt,4),
14974                                  (BitsN.fromNat(BitsN.toNat Rn,4),m2))))))
14975                     | BitsN.B(0x1,_) =>
14976                       Store
14977                         (StoreHalf
14978                            (add,
14979                             (index,
14980                              (wback,
14981                               (BitsN.fromNat(BitsN.toNat Rt,4),
14982                                (BitsN.fromNat(BitsN.toNat Rn,4),m1))))))
14983                     | BitsN.B(0x4,_) =>
14984                       Load
14985                         (LoadWord
14986                            (add,
14987                             (index,
14988                              (wback,
14989                               (BitsN.fromNat(BitsN.toNat Rt,4),
14990                                (BitsN.fromNat(BitsN.toNat Rn,4),m2))))))
14991                     | BitsN.B(0x5,_) =>
14992                       Load
14993                         (LoadHalf
14994                            (true,
14995                             (add,
14996                              (index,
14997                               (wback,
14998                                (BitsN.fromNat(BitsN.toNat Rt,4),
14999                                 (BitsN.fromNat(BitsN.toNat Rn,4),m1)))))))
15000                     | BitsN.B(0x7,_) =>
15001                       Load
15002                         (LoadHalf
15003                            (false,
15004                             (add,
15005                              (index,
15006                               (wback,
15007                                (BitsN.fromNat(BitsN.toNat Rt,4),
15008                                 (BitsN.fromNat(BitsN.toNat Rn,4),m1)))))))
15009                     | _ => DecodeThumb h
15010                  end
15011           else Skip ()
15012         end
15013     | (true,
15014      (true,
15015       (false,
15016        (false,
15017         (false,
15018          (false,
15019           (false,
15020            (false,
15021             (imm3'2,
15022              (imm3'1,
15023               (imm3'0,
15024                (handler'4,(handler'3,(handler'2,(handler'1,handler'0))))))))))))))) =>
15025       (if Do(ThumbCondition (),true)
15026          then ( if (InITBlock ()) andalso (not(LastInITBlock ()))
15027                   then DECODE_UNPREDICTABLE(mc,"HandlerBranchParameter")
15028                 else ()
15029               ; let
15030                   val imm32 =
15031                     BitsN.zeroExtend 32
15032                       (BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3))
15033                   val handler_offset =
15034                     BitsN.zeroExtend 32
15035                       (BitsN.@@
15036                          (BitsN.fromBitstring
15037                             ([handler'4,handler'3,handler'2,handler'1,
15038                               handler'0],5),BitsN.B(0x0,5)))
15039                 in
15040                   Branch(HandlerBranchParameter(imm32,handler_offset))
15041                 end
15042               )
15043        else Skip ())
15044     | (true,(true,(false,(false,(false,(false,(false,(true,_)))))))) =>
15045       Undefined(BitsN.B(0x0,32))
15046     | (true,
15047      (true,
15048       (false,
15049        (false,
15050         (false,
15051          (false,
15052           (true,
15053            (L'0,
15054             (handler'7,
15055              (handler'6,
15056               (handler'5,
15057                (handler'4,(handler'3,(handler'2,(handler'1,handler'0))))))))))))))) =>
15058       (if Do(ThumbCondition (),true)
15059          then ( if (InITBlock ()) andalso (not(LastInITBlock ()))
15060                   then DECODE_UNPREDICTABLE(mc,"HandlerBranchLink")
15061                 else ()
15062               ; let
15063                   val generate_link =
15064                     (BitsN.fromBitstring([L'0],1)) = (BitsN.B(0x1,1))
15065                   val handler_offset =
15066                     BitsN.zeroExtend 32
15067                       (BitsN.@@
15068                          (BitsN.fromBitstring
15069                             ([handler'7,handler'6,handler'5,handler'4,
15070                               handler'3,handler'2,handler'1,handler'0],8),
15071                           BitsN.B(0x0,5)))
15072                 in
15073                   Branch(HandlerBranchLink(generate_link,handler_offset))
15074                 end
15075               )
15076        else Skip ())
15077     | (true,
15078      (true,
15079       (false,
15080        (false,
15081         (false,
15082          (true,
15083           (imm5'4,
15084            (imm5'3,
15085             (imm5'2,
15086              (imm5'1,
15087               (imm5'0,
15088                (handler'4,(handler'3,(handler'2,(handler'1,handler'0))))))))))))))) =>
15089       (if Do(ThumbCondition (),true)
15090          then ( if (InITBlock ()) andalso (not(LastInITBlock ()))
15091                   then DECODE_UNPREDICTABLE
15092                          (mc,"HandlerBranchLinkParameter")
15093                 else ()
15094               ; let
15095                   val imm32 =
15096                     BitsN.zeroExtend 32
15097                       (BitsN.fromBitstring
15098                          ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5))
15099                   val handler_offset =
15100                     BitsN.zeroExtend 32
15101                       (BitsN.@@
15102                          (BitsN.fromBitstring
15103                             ([handler'4,handler'3,handler'2,handler'1,
15104                               handler'0],5),BitsN.B(0x0,5)))
15105                 in
15106                   Branch
15107                     (HandlerBranchLinkParameter(imm32,handler_offset))
15108                 end
15109               )
15110        else Skip ())
15111     | (true,
15112      (true,
15113       (false,
15114        (false,
15115         (true,
15116          (false,
15117           (false,
15118            (imm3'2,
15119             (imm3'1,(imm3'0,(Rn'2,(Rn'1,(Rn'0,(Rt'2,(Rt'1,Rt'0))))))))))))))) =>
15120       (if Do(ThumbCondition (),true)
15121          then let
15122                 val index = true
15123                 val add = false
15124                 val wback = false
15125                 val imm32 =
15126                   BitsN.zeroExtend 32
15127                     (BitsN.@@
15128                        (BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3),
15129                         BitsN.B(0x0,2)))
15130                 val m = immediate_form1 imm32
15131               in
15132                 Load
15133                   (LoadWord
15134                      (add,
15135                       (index,
15136                        (wback,
15137                         (BitsN.fromNat
15138                            (BitsN.toNat
15139                               (BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)),4),
15140                          (BitsN.fromNat
15141                             (BitsN.toNat
15142                                (BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3)),
15143                              4),m))))))
15144               end
15145        else Skip ())
15146     | (true,
15147      (true,
15148       (false,
15149        (false,
15150         (true,
15151          (false,
15152           (true,
15153            (false,(N'0,(Rm'3,(Rm'2,(Rm'1,(Rm'0,(Rn'2,(Rn'1,Rn'0))))))))))))))) =>
15154       let
15155         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
15156       in
15157         if Do(ThumbCondition (),true)
15158           then let
15159                  val n =
15160                    BitsN.@@
15161                      (BitsN.fromBitstring([N'0],1),
15162                       BitsN.fromBitstring([Rn'2,Rn'1,Rn'0],3))
15163                in
15164                  ( if (n = (BitsN.B(0xF,4))) orelse
15165                       (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))
15166                      then DECODE_UNPREDICTABLE(mc,"CheckArray")
15167                    else ()
15168                  ; Branch(CheckArray(Rm,n))
15169                  )
15170                end
15171         else Skip ()
15172       end
15173     | (true,
15174      (true,
15175       (false,
15176        (false,
15177         (true,
15178          (false,
15179           (true,
15180            (true,
15181             (imm5'4,
15182              (imm5'3,(imm5'2,(imm5'1,(imm5'0,(Rt'2,(Rt'1,Rt'0))))))))))))))) =>
15183       (if Do(ThumbCondition (),true)
15184          then let
15185                 val index = true
15186                 val add = true
15187                 val wback = false
15188                 val imm32 =
15189                   BitsN.zeroExtend 32
15190                     (BitsN.@@
15191                        (BitsN.fromBitstring
15192                           ([imm5'4,imm5'3,imm5'2,imm5'1,imm5'0],5),
15193                         BitsN.B(0x0,2)))
15194                 val m = immediate_form1 imm32
15195               in
15196                 Load
15197                   (LoadWord
15198                      (add,
15199                       (index,
15200                        (wback,
15201                         (BitsN.fromNat
15202                            (BitsN.toNat
15203                               (BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)),4),
15204                          (BitsN.B(0xA,4),m))))))
15205               end
15206        else Skip ())
15207     | (true,
15208      (true,
15209       (false,
15210        (false,
15211         (true,
15212          (true,
15213           (S'0,
15214            (imm6'5,
15215             (imm6'4,
15216              (imm6'3,(imm6'2,(imm6'1,(imm6'0,(Rt'2,(Rt'1,Rt'0))))))))))))))) =>
15217       let
15218         val Rt = BitsN.fromBitstring([Rt'2,Rt'1,Rt'0],3)
15219       in
15220         if Do(ThumbCondition (),true)
15221           then let
15222                  val index = true
15223                  val add = true
15224                  val wback = false
15225                  val imm32 =
15226                    BitsN.zeroExtend 32
15227                      (BitsN.@@
15228                         (BitsN.fromBitstring
15229                            ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],6),
15230                          BitsN.B(0x0,2)))
15231                  val m = immediate_form1 imm32
15232                in
15233                  if (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
15234                    then Store
15235                           (StoreWord
15236                              (add,
15237                               (index,
15238                                (wback,
15239                                 (BitsN.fromNat(BitsN.toNat Rt,4),
15240                                  (BitsN.B(0x9,4),m))))))
15241                  else Load
15242                         (LoadWord
15243                            (add,
15244                             (index,
15245                              (wback,
15246                               (BitsN.fromNat(BitsN.toNat Rt,4),
15247                                (BitsN.B(0x9,4),m))))))
15248                end
15249         else Skip ()
15250       end
15251     | (ireg'15,
15252      (ireg'14,
15253       (ireg'13,
15254        (ireg'12,
15255         (ireg'11,
15256          (ireg'10,
15257           (ireg'9,
15258            (ireg'8,
15259             (ireg'7,
15260              (ireg'6,(ireg'5,(ireg'4,(ireg'3,(ireg'2,(ireg'1,ireg'0))))))))))))))) =>
15261       DecodeThumb
15262         (BitsN.fromBitstring
15263            ([ireg'15,ireg'14,ireg'13,ireg'12,ireg'11,ireg'10,ireg'9,
15264              ireg'8,ireg'7,ireg'6,ireg'5,ireg'4,ireg'3,ireg'2,ireg'1,
15265              ireg'0],16))
15266  end;
15267
15268fun DecodeThumb2 h =
15269  let
15270    val mc = Thumb2 h
15271  in
15272    case (boolify'16(L3.fst h),boolify'16(L3.snd h)) of
15273       ((true,
15274         (true,
15275          (true,
15276           (false,
15277            (true,
15278             (false,
15279              (false,
15280               (false,
15281                (true,(false,(W'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15282        (sb'0'0'0,
15283         (M'0,
15284          (sb'1'0'0,
15285           (register_list'12,
15286            (register_list'11,
15287             (register_list'10,
15288              (register_list'9,
15289               (register_list'8,
15290                (register_list'7,
15291                 (register_list'6,
15292                  (register_list'5,
15293                   (register_list'4,
15294                    (register_list'3,
15295                     (register_list'2,(register_list'1,register_list'0)))))))))))))))) =>
15296         let
15297           val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15298           val GOOD_MATCH =
15299             ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
15300             ((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1)))
15301         in
15302           if Do(ThumbCondition (),HaveThumb2 ())
15303             then let
15304                    val registers =
15305                      BitsN.concat
15306                        [BitsN.B(0x0,1),BitsN.fromBitstring([M'0],1),
15307                         BitsN.B(0x0,1),
15308                         BitsN.fromBitstring
15309                           ([register_list'12,register_list'11,
15310                             register_list'10,register_list'9,
15311                             register_list'8,register_list'7,
15312                             register_list'6,register_list'5,
15313                             register_list'4,register_list'3,
15314                             register_list'2,register_list'1,
15315                             register_list'0],13)]
15316                    val wback =
15317                      (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
15318                  in
15319                    ( if (Rn = (BitsN.B(0xF,4))) orelse
15320                         ((Nat.<(BitCount 16 registers,2)) orelse
15321                          ((wback andalso
15322                            (BitsN.bit(registers,BitsN.toNat Rn))) orelse
15323                           (not GOOD_MATCH)))
15324                        then DECODE_UNPREDICTABLE(mc,"StoreMultiple")
15325                      else ()
15326                    ; let
15327                        val index = false
15328                        val increment = true
15329                      in
15330                        Store
15331                          (StoreMultiple
15332                             (increment,(index,(wback,(Rn,registers)))))
15333                      end
15334                    )
15335                  end
15336           else Skip ()
15337         end
15338     | ((true,
15339       (true,
15340        (true,
15341         (false,
15342          (true,
15343           (false,
15344            (false,
15345             (true,(false,(false,(W'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15346      (sb'0'0'0,
15347       (M'0,
15348        (sb'1'0'0,
15349         (register_list'12,
15350          (register_list'11,
15351           (register_list'10,
15352            (register_list'9,
15353             (register_list'8,
15354              (register_list'7,
15355               (register_list'6,
15356                (register_list'5,
15357                 (register_list'4,
15358                  (register_list'3,
15359                   (register_list'2,(register_list'1,register_list'0)))))))))))))))) =>
15360       let
15361         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15362         val GOOD_MATCH =
15363           ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
15364           ((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1)))
15365       in
15366         if Do(ThumbCondition (),HaveThumb2 ())
15367           then let
15368                  val registers =
15369                    BitsN.concat
15370                      [BitsN.B(0x0,1),BitsN.fromBitstring([M'0],1),
15371                       BitsN.B(0x0,1),
15372                       BitsN.fromBitstring
15373                         ([register_list'12,register_list'11,
15374                           register_list'10,register_list'9,
15375                           register_list'8,register_list'7,
15376                           register_list'6,register_list'5,
15377                           register_list'4,register_list'3,
15378                           register_list'2,register_list'1,register_list'0],
15379                          13)]
15380                  val wback =
15381                    (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
15382                in
15383                  ( if (Rn = (BitsN.B(0xF,4))) orelse
15384                       ((Nat.<(BitCount 16 registers,2)) orelse
15385                        ((wback andalso
15386                          (BitsN.bit(registers,BitsN.toNat Rn))) orelse
15387                         (not GOOD_MATCH)))
15388                      then DECODE_UNPREDICTABLE(mc,"StoreMultiple")
15389                    else ()
15390                  ; let
15391                      val index = true
15392                      val increment = false
15393                    in
15394                      Store
15395                        (StoreMultiple
15396                           (increment,(index,(wback,(Rn,registers)))))
15397                    end
15398                  )
15399                end
15400         else Skip ()
15401       end
15402     | ((true,
15403       (true,
15404        (true,
15405         (false,
15406          (true,
15407           (false,
15408            (false,
15409             (false,(true,(false,(W'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15410      (P'0,
15411       (M'0,
15412        (sb'0'0'0,
15413         (register_list'12,
15414          (register_list'11,
15415           (register_list'10,
15416            (register_list'9,
15417             (register_list'8,
15418              (register_list'7,
15419               (register_list'6,
15420                (register_list'5,
15421                 (register_list'4,
15422                  (register_list'3,
15423                   (register_list'2,(register_list'1,register_list'0)))))))))))))))) =>
15424       let
15425         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15426         val M = BitsN.fromBitstring([M'0],1)
15427         val P = BitsN.fromBitstring([P'0],1)
15428         val GOOD_MATCH =
15429           (BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))
15430       in
15431         if Do(ThumbCondition (),HaveThumb2 ())
15432           then let
15433                  val registers =
15434                    BitsN.concat
15435                      [P,M,BitsN.B(0x0,1),
15436                       BitsN.fromBitstring
15437                         ([register_list'12,register_list'11,
15438                           register_list'10,register_list'9,
15439                           register_list'8,register_list'7,
15440                           register_list'6,register_list'5,
15441                           register_list'4,register_list'3,
15442                           register_list'2,register_list'1,register_list'0],
15443                          13)]
15444                  val wback =
15445                    (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
15446                in
15447                  ( if (Rn = (BitsN.B(0xF,4))) orelse
15448                       ((Nat.<(BitCount 16 registers,2)) orelse
15449                        (((P = (BitsN.B(0x1,1))) andalso
15450                          (M = (BitsN.B(0x1,1)))) orelse
15451                         (((BitsN.bit(registers,15)) andalso
15452                           ((InITBlock ()) andalso (not(LastInITBlock ())))) orelse
15453                          ((wback andalso
15454                            (BitsN.bit(registers,BitsN.toNat Rn))) orelse
15455                           (not GOOD_MATCH)))))
15456                      then DECODE_UNPREDICTABLE(mc,"LoadMultiple")
15457                    else ()
15458                  ; let
15459                      val index = false
15460                      val increment = true
15461                    in
15462                      Load
15463                        (LoadMultiple
15464                           (increment,(index,(wback,(Rn,registers)))))
15465                    end
15466                  )
15467                end
15468         else Skip ()
15469       end
15470     | ((true,
15471       (true,
15472        (true,
15473         (false,
15474          (true,
15475           (false,
15476            (false,
15477             (true,(false,(false,(W'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15478      (P'0,
15479       (M'0,
15480        (sb'0'0'0,
15481         (register_list'12,
15482          (register_list'11,
15483           (register_list'10,
15484            (register_list'9,
15485             (register_list'8,
15486              (register_list'7,
15487               (register_list'6,
15488                (register_list'5,
15489                 (register_list'4,
15490                  (register_list'3,
15491                   (register_list'2,(register_list'1,register_list'0)))))))))))))))) =>
15492       let
15493         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15494         val M = BitsN.fromBitstring([M'0],1)
15495         val P = BitsN.fromBitstring([P'0],1)
15496         val GOOD_MATCH =
15497           (BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))
15498       in
15499         if Do(ThumbCondition (),HaveThumb2 ())
15500           then let
15501                  val registers =
15502                    BitsN.concat
15503                      [P,M,BitsN.B(0x0,1),
15504                       BitsN.fromBitstring
15505                         ([register_list'12,register_list'11,
15506                           register_list'10,register_list'9,
15507                           register_list'8,register_list'7,
15508                           register_list'6,register_list'5,
15509                           register_list'4,register_list'3,
15510                           register_list'2,register_list'1,register_list'0],
15511                          13)]
15512                  val wback =
15513                    (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
15514                in
15515                  ( if (Rn = (BitsN.B(0xF,4))) orelse
15516                       ((Nat.<(BitCount 16 registers,2)) orelse
15517                        (((P = (BitsN.B(0x1,1))) andalso
15518                          (M = (BitsN.B(0x1,1)))) orelse
15519                         (((BitsN.bit(registers,15)) andalso
15520                           ((InITBlock ()) andalso (not(LastInITBlock ())))) orelse
15521                          ((wback andalso
15522                            (BitsN.bit(registers,BitsN.toNat Rn))) orelse
15523                           (not GOOD_MATCH)))))
15524                      then DECODE_UNPREDICTABLE(mc,"LoadMultiple")
15525                    else ()
15526                  ; let
15527                      val index = true
15528                      val increment = false
15529                    in
15530                      Load
15531                        (LoadMultiple
15532                           (increment,(index,(wback,(Rn,registers)))))
15533                    end
15534                  )
15535                end
15536         else Skip ()
15537       end
15538     | ((true,
15539       (true,
15540        (true,
15541         (false,
15542          (true,
15543           (false,
15544            (false,
15545             (op'1,
15546              (op'0,
15547               (false,
15548                (W'0,
15549                 (false,
15550                  (sb'0'1101'3,(sb'0'1101'2,(sb'0'1101'1,sb'0'1101'0))))))))))))))),
15551      (sb'1'11000000000'10,
15552       (sb'1'11000000000'9,
15553        (sb'1'11000000000'8,
15554         (sb'1'11000000000'7,
15555          (sb'1'11000000000'6,
15556           (sb'1'11000000000'5,
15557            (sb'1'11000000000'4,
15558             (sb'1'11000000000'3,
15559              (sb'1'11000000000'2,
15560               (sb'1'11000000000'1,
15561                (sb'1'11000000000'0,
15562                 (mode'4,(mode'3,(mode'2,(mode'1,mode'0)))))))))))))))) =>
15563       let
15564         val op' = BitsN.fromBitstring([op'1,op'0],2)
15565         val GOOD_MATCH =
15566           ((BitsN.fromBitstring
15567               ([sb'0'1101'3,sb'0'1101'2,sb'0'1101'1,sb'0'1101'0],4)) =
15568            (BitsN.B(0xD,4))) andalso
15569           ((BitsN.fromBitstring
15570               ([sb'1'11000000000'10,sb'1'11000000000'9,
15571                 sb'1'11000000000'8,sb'1'11000000000'7,sb'1'11000000000'6,
15572                 sb'1'11000000000'5,sb'1'11000000000'4,sb'1'11000000000'3,
15573                 sb'1'11000000000'2,sb'1'11000000000'1,sb'1'11000000000'0],
15574                11)) = (BitsN.B(0x600,11)))
15575       in
15576         if Do(ThumbCondition (),
15577               (Set.mem(op',[BitsN.B(0x0,2),BitsN.B(0x3,2)])) andalso
15578               (HaveThumb2 ()))
15579           then ( if ((CurrentInstrSet ()) = InstrSet_ThumbEE) orelse
15580                     (not GOOD_MATCH)
15581                    then DECODE_UNPREDICTABLE(mc,"StoreReturnState")
15582                  else ()
15583                ; let
15584                    val wback =
15585                      (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
15586                    val increment = op' = (BitsN.B(0x3,2))
15587                    val wordhigher = false
15588                  in
15589                    System
15590                      (StoreReturnState
15591                         (increment,
15592                          (wordhigher,
15593                           (wback,
15594                            BitsN.fromBitstring
15595                              ([mode'4,mode'3,mode'2,mode'1,mode'0],5)))))
15596                  end
15597                )
15598         else Skip ()
15599       end
15600     | ((true,
15601       (true,
15602        (true,
15603         (false,
15604          (true,
15605           (false,
15606            (false,
15607             (op'1,(op'0,(false,(W'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15608      (sb'0'1100000000000000'15,
15609       (sb'0'1100000000000000'14,
15610        (sb'0'1100000000000000'13,
15611         (sb'0'1100000000000000'12,
15612          (sb'0'1100000000000000'11,
15613           (sb'0'1100000000000000'10,
15614            (sb'0'1100000000000000'9,
15615             (sb'0'1100000000000000'8,
15616              (sb'0'1100000000000000'7,
15617               (sb'0'1100000000000000'6,
15618                (sb'0'1100000000000000'5,
15619                 (sb'0'1100000000000000'4,
15620                  (sb'0'1100000000000000'3,
15621                   (sb'0'1100000000000000'2,
15622                    (sb'0'1100000000000000'1,sb'0'1100000000000000'0)))))))))))))))) =>
15623       let
15624         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15625         val op' = BitsN.fromBitstring([op'1,op'0],2)
15626         val GOOD_MATCH =
15627           (BitsN.fromBitstring
15628              ([sb'0'1100000000000000'15,sb'0'1100000000000000'14,
15629                sb'0'1100000000000000'13,sb'0'1100000000000000'12,
15630                sb'0'1100000000000000'11,sb'0'1100000000000000'10,
15631                sb'0'1100000000000000'9,sb'0'1100000000000000'8,
15632                sb'0'1100000000000000'7,sb'0'1100000000000000'6,
15633                sb'0'1100000000000000'5,sb'0'1100000000000000'4,
15634                sb'0'1100000000000000'3,sb'0'1100000000000000'2,
15635                sb'0'1100000000000000'1,sb'0'1100000000000000'0],16)) =
15636           (BitsN.B(0xC000,16))
15637       in
15638         if Do(ThumbCondition (),
15639               (Set.mem(op',[BitsN.B(0x0,2),BitsN.B(0x3,2)])) andalso
15640               (HaveThumb2 ()))
15641           then ( if ((CurrentInstrSet ()) = InstrSet_ThumbEE) orelse
15642                     ((Rn = (BitsN.B(0xF,4))) orelse
15643                      (((InITBlock ()) andalso (not(LastInITBlock ()))) orelse
15644                       (not GOOD_MATCH)))
15645                    then DECODE_UNPREDICTABLE(mc,"ReturnFromException")
15646                  else ()
15647                ; let
15648                    val wback =
15649                      (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
15650                    val increment = op' = (BitsN.B(0x3,2))
15651                    val wordhigher = false
15652                  in
15653                    System
15654                      (ReturnFromException
15655                         (increment,(wordhigher,(wback,Rn))))
15656                  end
15657                )
15658         else Skip ()
15659       end
15660     | ((true,
15661       (true,
15662        (true,
15663         (false,
15664          (true,
15665           (false,
15666            (false,
15667             (false,
15668              (false,(true,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15669      (Rt'3,
15670       (Rt'2,
15671        (Rt'1,
15672         (Rt'0,
15673          (Rd'3,
15674           (Rd'2,
15675            (Rd'1,
15676             (Rd'0,
15677              (imm8'7,
15678               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
15679       let
15680         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15681         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
15682         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
15683       in
15684         if Do(ThumbCondition (),HaveThumb2 ())
15685           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15686                     ((Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15687                      ((Rn = (BitsN.B(0xF,4))) orelse
15688                       ((Rd = Rn) orelse (Rd = Rt))))
15689                    then DECODE_UNPREDICTABLE(mc,"StoreExclusive")
15690                  else ()
15691                ; let
15692                    val imm32 =
15693                      BitsN.zeroExtend 32
15694                        (BitsN.@@
15695                           (BitsN.fromBitstring
15696                              ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
15697                                imm8'1,imm8'0],8),BitsN.B(0x0,2)))
15698                  in
15699                    Store(StoreExclusive(Rd,(Rt,(Rn,imm32))))
15700                  end
15701                )
15702         else Skip ()
15703       end
15704     | ((true,
15705       (true,
15706        (true,
15707         (false,
15708          (true,
15709           (false,
15710            (false,
15711             (false,
15712              (false,(true,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15713      (Rt'3,
15714       (Rt'2,
15715        (Rt'1,
15716         (Rt'0,
15717          (Rd'3,
15718           (Rd'2,
15719            (Rd'1,
15720             (Rd'0,
15721              (imm8'7,
15722               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
15723       let
15724         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15725         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
15726       in
15727         if Do(ThumbCondition (),HaveThumb2 ())
15728           then ( if (Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15729                     (Rn = (BitsN.B(0xF,4)))
15730                    then DECODE_UNPREDICTABLE(mc,"StoreExclusive")
15731                  else ()
15732                ; let
15733                    val imm32 =
15734                      BitsN.zeroExtend 32
15735                        (BitsN.@@
15736                           (BitsN.fromBitstring
15737                              ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
15738                                imm8'1,imm8'0],8),BitsN.B(0x0,2)))
15739                  in
15740                    Load(LoadExclusive(Rt,(Rn,imm32)))
15741                  end
15742                )
15743         else Skip ()
15744       end
15745     | ((true,
15746       (true,
15747        (true,
15748         (false,
15749          (true,
15750           (false,
15751            (false,
15752             (false,
15753              (true,(true,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15754      (Rt'3,
15755       (Rt'2,
15756        (Rt'1,
15757         (Rt'0,
15758          (sb'0'1111'3,
15759           (sb'0'1111'2,
15760            (sb'0'1111'1,
15761             (sb'0'1111'0,
15762              (false,(true,(false,(H'0,(Rd'3,(Rd'2,(Rd'1,Rd'0)))))))))))))))) =>
15763       let
15764         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15765         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
15766         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
15767         val GOOD_MATCH =
15768           (BitsN.fromBitstring
15769              ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
15770           (BitsN.B(0xF,4))
15771       in
15772         if Do(ThumbCondition (),Nat.>=(ArchVersion (),7))
15773           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15774                     ((Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15775                      ((Rn = (BitsN.B(0xF,4))) orelse
15776                       ((Rd = Rn) orelse
15777                        ((Rd = Rt) orelse (not GOOD_MATCH)))))
15778                    then DECODE_UNPREDICTABLE
15779                           (mc,"StoreExclusive: Byte or Halfword")
15780                  else ()
15781                ; if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
15782                    then Store(StoreExclusiveHalf(Rd,(Rt,Rn)))
15783                  else Store(StoreExclusiveByte(Rd,(Rt,Rn)))
15784                )
15785         else Skip ()
15786       end
15787     | ((true,
15788       (true,
15789        (true,
15790         (false,
15791          (true,
15792           (false,
15793            (false,
15794             (false,
15795              (true,(true,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15796      (Rt'3,
15797       (Rt'2,
15798        (Rt'1,
15799         (Rt'0,
15800          (Rt2'3,
15801           (Rt2'2,
15802            (Rt2'1,
15803             (Rt2'0,(false,(true,(true,(true,(Rd'3,(Rd'2,(Rd'1,Rd'0)))))))))))))))) =>
15804       let
15805         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15806         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
15807         val Rt2 = BitsN.fromBitstring([Rt2'3,Rt2'2,Rt2'1,Rt2'0],4)
15808         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
15809       in
15810         if Do(ThumbCondition (),Nat.>=(ArchVersion (),7))
15811           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15812                     ((Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15813                      ((Set.mem(Rt2,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15814                       ((Rn = (BitsN.B(0xF,4))) orelse
15815                        ((Rd = Rn) orelse (Rd = Rt)))))
15816                    then DECODE_UNPREDICTABLE
15817                           (mc,"StoreExclusivDoubleword")
15818                  else ()
15819                ; Store(StoreExclusiveDoubleword(Rd,(Rt,(Rt2,Rn))))
15820                )
15821         else Skip ()
15822       end
15823     | ((true,
15824       (true,
15825        (true,
15826         (false,
15827          (true,
15828           (false,
15829            (false,
15830             (false,(true,(true,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15831      (sb'0'1111'3,
15832       (sb'0'1111'2,
15833        (sb'0'1111'1,
15834         (sb'0'1111'0,
15835          (sb'1'0000'3,
15836           (sb'1'0000'2,
15837            (sb'1'0000'1,
15838             (sb'1'0000'0,
15839              (false,(false,(false,(H'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
15840       let
15841         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15842         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
15843         val GOOD_MATCH =
15844           ((BitsN.fromBitstring
15845               ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
15846            (BitsN.B(0xF,4))) andalso
15847           ((BitsN.fromBitstring
15848               ([sb'1'0000'3,sb'1'0000'2,sb'1'0000'1,sb'1'0000'0],4)) =
15849            (BitsN.B(0x0,4)))
15850       in
15851         if Do(ThumbCondition (),HaveThumb2 ())
15852           then ( if (Rn = (BitsN.B(0xD,4))) orelse
15853                     ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15854                      (((InITBlock ()) andalso (not(LastInITBlock ()))) orelse
15855                       (not GOOD_MATCH)))
15856                    then DECODE_UNPREDICTABLE(mc,"TableBranchByte")
15857                  else ()
15858                ; let
15859                    val is_tbh =
15860                      (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
15861                  in
15862                    Branch(TableBranchByte(is_tbh,(Rm,Rn)))
15863                  end
15864                )
15865         else Skip ()
15866       end
15867     | ((true,
15868       (true,
15869        (true,
15870         (false,
15871          (true,
15872           (false,
15873            (false,
15874             (false,(true,(true,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15875      (Rt'3,
15876       (Rt'2,
15877        (Rt'1,
15878         (Rt'0,
15879          (sb'0'1111'3,
15880           (sb'0'1111'2,
15881            (sb'0'1111'1,
15882             (sb'0'1111'0,
15883              (false,(true,(false,(H'0,(Rd'3,(Rd'2,(Rd'1,Rd'0)))))))))))))))) =>
15884       let
15885         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15886         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
15887         val GOOD_MATCH =
15888           (BitsN.fromBitstring
15889              ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
15890           (BitsN.B(0xF,4))
15891       in
15892         if Do(ThumbCondition (),Nat.>=(ArchVersion (),7))
15893           then ( if (Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15894                     ((Rn = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))
15895                    then DECODE_UNPREDICTABLE
15896                           (mc,"LoadExclusive: Byte or Halfword")
15897                  else ()
15898                ; if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
15899                    then Load(LoadExclusiveHalf(Rt,Rn))
15900                  else Load(LoadExclusiveByte(Rt,Rn))
15901                )
15902         else Skip ()
15903       end
15904     | ((true,
15905       (true,
15906        (true,
15907         (false,
15908          (true,
15909           (false,
15910            (false,
15911             (false,(true,(true,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15912      (Rt'3,
15913       (Rt'2,
15914        (Rt'1,
15915         (Rt'0,
15916          (Rt2'3,
15917           (Rt2'2,
15918            (Rt2'1,
15919             (Rt2'0,
15920              (false,
15921               (true,
15922                (true,
15923                 (true,
15924                  (sb'0'1111'3,(sb'0'1111'2,(sb'0'1111'1,sb'0'1111'0)))))))))))))))) =>
15925       let
15926         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15927         val Rt2 = BitsN.fromBitstring([Rt2'3,Rt2'2,Rt2'1,Rt2'0],4)
15928         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
15929         val GOOD_MATCH =
15930           (BitsN.fromBitstring
15931              ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
15932           (BitsN.B(0xF,4))
15933       in
15934         if Do(ThumbCondition (),Nat.>=(ArchVersion (),7))
15935           then ( if (Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15936                     ((Set.mem(Rt2,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15937                      ((Rt = Rt2) orelse
15938                       ((Rn = (BitsN.B(0xF,4))) orelse (not GOOD_MATCH))))
15939                    then DECODE_UNPREDICTABLE
15940                           (mc,"LoadExclusiveDoubleword")
15941                  else ()
15942                ; Load(LoadExclusiveDoubleword(Rt,(Rt2,Rn)))
15943                )
15944         else Skip ()
15945       end
15946     | ((true,
15947       (true,
15948        (true,
15949         (false,
15950          (true,
15951           (false,
15952            (false,
15953             (P'0,(U'0,(true,(W'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
15954      (Rt'3,
15955       (Rt'2,
15956        (Rt'1,
15957         (Rt'0,
15958          (Rt2'3,
15959           (Rt2'2,
15960            (Rt2'1,
15961             (Rt2'0,
15962              (imm8'7,
15963               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
15964       let
15965         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
15966         val W = BitsN.fromBitstring([W'0],1)
15967         val P = BitsN.fromBitstring([P'0],1)
15968         val Rt2 = BitsN.fromBitstring([Rt2'3,Rt2'2,Rt2'1,Rt2'0],4)
15969         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
15970       in
15971         if Do(ThumbCondition (),
15972               ((P = (BitsN.B(0x1,1))) orelse (W = (BitsN.B(0x1,1)))) andalso
15973               (HaveThumb2 ()))
15974           then let
15975                  val wback = W = (BitsN.B(0x1,1))
15976                in
15977                  ( if (wback andalso ((Rn = Rt) orelse (Rn = Rt2))) orelse
15978                       ((Rn = (BitsN.B(0xF,4))) orelse
15979                        ((Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
15980                         (Set.mem(Rt2,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))))
15981                      then DECODE_UNPREDICTABLE(mc,"StoreDual")
15982                    else ()
15983                  ; let
15984                      val index = P = (BitsN.B(0x1,1))
15985                      val add =
15986                        (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
15987                      val imm32 =
15988                        BitsN.zeroExtend 32
15989                          (BitsN.@@
15990                             (BitsN.fromBitstring
15991                                ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,
15992                                  imm8'2,imm8'1,imm8'0],8),BitsN.B(0x0,2)))
15993                      val m = immediate_form2 imm32
15994                    in
15995                      Store
15996                        (StoreDual(add,(index,(wback,(Rt,(Rt2,(Rn,m)))))))
15997                    end
15998                  )
15999                end
16000         else Skip ()
16001       end
16002     | ((true,
16003       (true,
16004        (true,
16005         (false,
16006          (true,
16007           (false,
16008            (false,
16009             (P'0,(U'0,(true,(W'0,(true,(true,(true,(true,true))))))))))))))),
16010      (Rt'3,
16011       (Rt'2,
16012        (Rt'1,
16013         (Rt'0,
16014          (Rt2'3,
16015           (Rt2'2,
16016            (Rt2'1,
16017             (Rt2'0,
16018              (imm8'7,
16019               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
16020       let
16021         val W = BitsN.fromBitstring([W'0],1)
16022         val Rt2 = BitsN.fromBitstring([Rt2'3,Rt2'2,Rt2'1,Rt2'0],4)
16023         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
16024       in
16025         if Do(ThumbCondition (),
16026               (((BitsN.fromBitstring([P'0],1)) = (BitsN.B(0x1,1))) orelse
16027                (W = (BitsN.B(0x1,1)))) andalso (HaveThumb2 ()))
16028           then ( if (Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16029                     ((Set.mem(Rt2,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16030                      ((Rt = Rt2) orelse (W = (BitsN.B(0x1,1)))))
16031                    then DECODE_UNPREDICTABLE(mc,"LoadDual: literal")
16032                  else ()
16033                ; let
16034                    val imm32 =
16035                      BitsN.zeroExtend 32
16036                        (BitsN.@@
16037                           (BitsN.fromBitstring
16038                              ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
16039                                imm8'1,imm8'0],8),BitsN.B(0x0,2)))
16040                    val add =
16041                      (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
16042                  in
16043                    Load(LoadDualLiteral(add,(Rt,(Rt2,imm32))))
16044                  end
16045                )
16046         else Skip ()
16047       end
16048     | ((true,
16049       (true,
16050        (true,
16051         (false,
16052          (true,
16053           (false,
16054            (false,
16055             (P'0,(U'0,(true,(W'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16056      (Rt'3,
16057       (Rt'2,
16058        (Rt'1,
16059         (Rt'0,
16060          (Rt2'3,
16061           (Rt2'2,
16062            (Rt2'1,
16063             (Rt2'0,
16064              (imm8'7,
16065               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
16066       let
16067         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
16068         val W = BitsN.fromBitstring([W'0],1)
16069         val P = BitsN.fromBitstring([P'0],1)
16070         val Rt2 = BitsN.fromBitstring([Rt2'3,Rt2'2,Rt2'1,Rt2'0],4)
16071         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
16072       in
16073         if Do(ThumbCondition (),
16074               ((P = (BitsN.B(0x1,1))) orelse (W = (BitsN.B(0x1,1)))) andalso
16075               (HaveThumb2 ()))
16076           then let
16077                  val wback = W = (BitsN.B(0x1,1))
16078                in
16079                  ( if (wback andalso ((Rn = Rt) orelse (Rn = Rt2))) orelse
16080                       ((Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16081                        ((Set.mem(Rt2,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16082                         (Rt = Rt2)))
16083                      then DECODE_UNPREDICTABLE(mc,"LoadDual")
16084                    else ()
16085                  ; let
16086                      val index = P = (BitsN.B(0x1,1))
16087                      val add =
16088                        (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
16089                      val imm32 =
16090                        BitsN.zeroExtend 32
16091                          (BitsN.@@
16092                             (BitsN.fromBitstring
16093                                ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,
16094                                  imm8'2,imm8'1,imm8'0],8),BitsN.B(0x0,2)))
16095                      val m = immediate_form2 imm32
16096                    in
16097                      Load
16098                        (LoadDual(add,(index,(wback,(Rt,(Rt2,(Rn,m)))))))
16099                    end
16100                  )
16101                end
16102         else Skip ()
16103       end
16104     | ((true,
16105       (true,
16106        (true,
16107         (false,
16108          (true,
16109           (false,
16110            (true,
16111             (op'3,(op'2,(op'1,(op'0,(S'0,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16112      (sb'0'0'0,
16113       (imm3'2,
16114        (imm3'1,
16115         (imm3'0,
16116          (Rd'3,
16117           (Rd'2,
16118            (Rd'1,
16119             (Rd'0,
16120              (imm2'1,(imm2'0,(typ'1,(typ'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
16121       let
16122         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
16123         val S = BitsN.fromBitstring([S'0],1)
16124         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
16125         val typ = BitsN.fromBitstring([typ'1,typ'0],2)
16126         val imm2 = BitsN.fromBitstring([imm2'1,imm2'0],2)
16127         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
16128         val imm3 = BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3)
16129         val GOOD_MATCH =
16130           (BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))
16131       in
16132         if Do(ThumbCondition (),HaveThumb2 ())
16133           then let
16134                  val (shift_t,shift_n) =
16135                    DecodeImmShift(typ,BitsN.@@(imm3,imm2))
16136                  val setflags = S = (BitsN.B(0x1,1))
16137                in
16138                  case (BitsN.fromBitstring([op'3,op'2,op'1,op'0],4),
16139                   (Rn,(Rd,S))) of
16140                     (BitsN.B(0x0,_),(_,(BitsN.B(0xF,_),BitsN.B(0x1,_)))) =>
16141                       ( if (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16142                            ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16143                             (not GOOD_MATCH))
16144                           then DECODE_UNPREDICTABLE(mc,"TST (register)")
16145                         else ()
16146                       ; Data
16147                           (TestCompareRegister
16148                              (BitsN.B(0x0,2),(Rn,(Rm,(shift_t,shift_n)))))
16149                       )
16150                   | (BitsN.B(0x0,_),_) =>
16151                     ( if (Rd = (BitsN.B(0xD,4))) orelse
16152                          (((Rd = (BitsN.B(0xF,4))) andalso (not setflags)) orelse
16153                           ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16154                            ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16155                             (not GOOD_MATCH))))
16156                         then DECODE_UNPREDICTABLE(mc,"AND (register)")
16157                       else ()
16158                     ; Data
16159                         (Register
16160                            (BitsN.B(0x0,4),
16161                             (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16162                     )
16163                   | (BitsN.B(0x1,_),_) =>
16164                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16165                          ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16166                           ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16167                            (not GOOD_MATCH)))
16168                         then DECODE_UNPREDICTABLE(mc,"BIC (register)")
16169                       else ()
16170                     ; Data
16171                         (Register
16172                            (BitsN.B(0xE,4),
16173                             (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16174                     )
16175                   | (BitsN.B(0x2,_),(BitsN.B(0xF,_),_)) =>
16176                     ( if (typ = (BitsN.B(0x0,2))) andalso
16177                          ((imm3 = (BitsN.B(0x0,3))) andalso
16178                           (imm2 = (BitsN.B(0x0,2))))
16179                         then if (setflags andalso
16180                                  ((Set.mem
16181                                      (Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16182                                   (Set.mem
16183                                      (Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])))) orelse
16184                                 (((not setflags) andalso
16185                                   ((Rd = (BitsN.B(0xF,4))) orelse
16186                                    ((Rm = (BitsN.B(0xF,4))) orelse
16187                                     ((Rd = (BitsN.B(0xD,4))) andalso
16188                                      (Rm = (BitsN.B(0xD,4))))))) orelse
16189                                  (not GOOD_MATCH))
16190                                then DECODE_UNPREDICTABLE
16191                                       (mc,"MOV (register)")
16192                              else ()
16193                       else if (Set.mem
16194                             (Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16195                          ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16196                           (not GOOD_MATCH))
16197                         then DECODE_UNPREDICTABLE(mc,"SHIFT (register)")
16198                       else ()
16199                     ; Data
16200                         (ShiftImmediate
16201                            (false,(setflags,(Rd,(Rm,(shift_t,shift_n))))))
16202                     )
16203                   | (BitsN.B(0x2,_),_) =>
16204                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16205                          ((Rn = (BitsN.B(0xD,4))) orelse
16206                           ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16207                            (not GOOD_MATCH)))
16208                         then DECODE_UNPREDICTABLE(mc,"ORR (register)")
16209                       else ()
16210                     ; Data
16211                         (Register
16212                            (BitsN.B(0xC,4),
16213                             (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16214                     )
16215                   | (BitsN.B(0x3,_),(BitsN.B(0xF,_),_)) =>
16216                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16217                          ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16218                           (not GOOD_MATCH))
16219                         then DECODE_UNPREDICTABLE(mc,"MVN (register)")
16220                       else ()
16221                     ; Data
16222                         (ShiftImmediate
16223                            (true,(setflags,(Rd,(Rm,(shift_t,shift_n))))))
16224                     )
16225                   | (BitsN.B(0x3,_),_) =>
16226                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16227                          ((Rn = (BitsN.B(0xD,4))) orelse
16228                           ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16229                            (not GOOD_MATCH)))
16230                         then DECODE_UNPREDICTABLE(mc,"ORN (register)")
16231                       else ()
16232                     ; Data
16233                         (Register
16234                            (BitsN.B(0xF,4),
16235                             (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16236                     )
16237                   | (BitsN.B(0x4,_),(_,(BitsN.B(0xF,_),BitsN.B(0x1,_)))) =>
16238                     ( if (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16239                          ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16240                           (not GOOD_MATCH))
16241                         then DECODE_UNPREDICTABLE(mc,"TEQ (register)")
16242                       else ()
16243                     ; Data
16244                         (TestCompareRegister
16245                            (BitsN.B(0x1,2),(Rn,(Rm,(shift_t,shift_n)))))
16246                     )
16247                   | (BitsN.B(0x4,_),_) =>
16248                     ( if (Rd = (BitsN.B(0xD,4))) orelse
16249                          (((Rd = (BitsN.B(0xF,4))) andalso (not setflags)) orelse
16250                           ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16251                            ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16252                             (not GOOD_MATCH))))
16253                         then DECODE_UNPREDICTABLE(mc,"EOR (register)")
16254                       else ()
16255                     ; Data
16256                         (Register
16257                            (BitsN.B(0x1,4),
16258                             (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16259                     )
16260                   | (BitsN.B(0x6,_),(_,(_,BitsN.B(0x0,_)))) =>
16261                     (if BitsN.bit(typ,0)
16262                        then Undefined(BitsN.B(0x0,32))
16263                      else ( if (Set.mem
16264                                   (Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16265                                ((Set.mem
16266                                    (Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16267                                 ((Set.mem
16268                                     (Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16269                                  (not GOOD_MATCH)))
16270                               then DECODE_UNPREDICTABLE
16271                                      (mc,"PackHalfword")
16272                             else ()
16273                           ; let
16274                               val tbform = BitsN.bit(typ,1)
16275                             in
16276                               Media
16277                                 (PackHalfword
16278                                    (shift_t,
16279                                     (shift_n,(tbform,(Rd,(Rn,Rm))))))
16280                             end
16281                           ))
16282                   | (BitsN.B(0x8,_),(_,(BitsN.B(0xF,_),BitsN.B(0x1,_)))) =>
16283                     ( if (Rn = (BitsN.B(0xF,4))) orelse
16284                          ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16285                           (not GOOD_MATCH))
16286                         then DECODE_UNPREDICTABLE(mc,"CMN (register)")
16287                       else ()
16288                     ; Data
16289                         (TestCompareRegister
16290                            (BitsN.B(0x3,2),(Rn,(Rm,(shift_t,shift_n)))))
16291                     )
16292                   | (BitsN.B(0x8,_),_) =>
16293                     ( if (Rd = (BitsN.B(0xD,4))) orelse
16294                          (((Rd = (BitsN.B(0xF,4))) andalso (not setflags)) orelse
16295                           ((Rn = (BitsN.B(0xF,4))) orelse
16296                            ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16297                             (not GOOD_MATCH))))
16298                         then DECODE_UNPREDICTABLE(mc,"ADD (register)")
16299                       else ()
16300                     ; let
16301                         val (shift_t,shift_n) =
16302                           DecodeImmShift(typ,BitsN.@@(imm3,imm2))
16303                       in
16304                         Data
16305                           (Register
16306                              (BitsN.B(0x4,4),
16307                               (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16308                       end
16309                     )
16310                   | (BitsN.B(0xA,_),_) =>
16311                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16312                          ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16313                           ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16314                            (not GOOD_MATCH)))
16315                         then DECODE_UNPREDICTABLE(mc,"ADC (register)")
16316                       else ()
16317                     ; Data
16318                         (Register
16319                            (BitsN.B(0x5,4),
16320                             (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16321                     )
16322                   | (BitsN.B(0xB,_),_) =>
16323                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16324                          ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16325                           ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16326                            (not GOOD_MATCH)))
16327                         then DECODE_UNPREDICTABLE(mc,"SBC (register)")
16328                       else ()
16329                     ; Data
16330                         (Register
16331                            (BitsN.B(0x6,4),
16332                             (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16333                     )
16334                   | (BitsN.B(0xD,_),(_,(BitsN.B(0xF,_),BitsN.B(0x1,_)))) =>
16335                     ( if (Rn = (BitsN.B(0xF,4))) orelse
16336                          ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16337                           (not GOOD_MATCH))
16338                         then DECODE_UNPREDICTABLE(mc,"CMP (register)")
16339                       else ()
16340                     ; Data
16341                         (TestCompareRegister
16342                            (BitsN.B(0x2,2),(Rn,(Rm,(shift_t,shift_n)))))
16343                     )
16344                   | (BitsN.B(0xD,_),_) =>
16345                     ( if (Rd = (BitsN.B(0xD,4))) orelse
16346                          (((Rd = (BitsN.B(0xF,4))) andalso (not setflags)) orelse
16347                           ((Rn = (BitsN.B(0xF,4))) orelse
16348                            ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16349                             (not GOOD_MATCH))))
16350                         then DECODE_UNPREDICTABLE(mc,"SUB (register)")
16351                       else ()
16352                     ; Data
16353                         (Register
16354                            (BitsN.B(0x2,4),
16355                             (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16356                     )
16357                   | (BitsN.B(0xE,_),_) =>
16358                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16359                          ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16360                           ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16361                            (not GOOD_MATCH)))
16362                         then DECODE_UNPREDICTABLE(mc,"RSB (register)")
16363                       else ()
16364                     ; Data
16365                         (Register
16366                            (BitsN.B(0x3,4),
16367                             (setflags,(Rd,(Rn,(Rm,(shift_t,shift_n)))))))
16368                     )
16369                   | _ => Undefined(BitsN.B(0x0,32))
16370                end
16371         else Skip ()
16372       end
16373     | ((true,
16374       (true,
16375        (true,
16376         (true,
16377          (false,
16378           (i'0,
16379            (false,
16380             (op'3,(op'2,(op'1,(op'0,(S'0,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16381      (false,
16382       (imm3'2,
16383        (imm3'1,
16384         (imm3'0,
16385          (Rd'3,
16386           (Rd'2,
16387            (Rd'1,
16388             (Rd'0,
16389              (imm8'7,
16390               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
16391       let
16392         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
16393         val S = BitsN.fromBitstring([S'0],1)
16394         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
16395       in
16396         if Do(ThumbCondition (),HaveThumb2 ())
16397           then let
16398                  val imm12 =
16399                    BitsN.concat
16400                      [BitsN.fromBitstring([i'0],1),
16401                       BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3),
16402                       BitsN.fromBitstring
16403                         ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
16404                           imm8'1,imm8'0],8)]
16405                  val setflags = S = (BitsN.B(0x1,1))
16406                in
16407                  case (BitsN.fromBitstring([op'3,op'2,op'1,op'0],4),
16408                   (Rn,(Rd,S))) of
16409                     (BitsN.B(0x0,_),(_,(BitsN.B(0xF,_),BitsN.B(0x1,_)))) =>
16410                       ( if Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
16411                           then DECODE_UNPREDICTABLE(mc,"TST (immediate)")
16412                         else ()
16413                       ; Data
16414                           (TestCompareImmediate
16415                              (BitsN.B(0x0,2),(Rn,imm12)))
16416                       )
16417                   | (BitsN.B(0x0,_),_) =>
16418                     ( if (Rd = (BitsN.B(0xD,4))) orelse
16419                          (((Rd = (BitsN.B(0xF,4))) andalso (not setflags)) orelse
16420                           (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])))
16421                         then DECODE_UNPREDICTABLE(mc,"AND (immediate)")
16422                       else ()
16423                     ; Data
16424                         (ArithLogicImmediate
16425                            (BitsN.B(0x0,4),(setflags,(Rd,(Rn,imm12)))))
16426                     )
16427                   | (BitsN.B(0x1,_),_) =>
16428                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16429                          (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))
16430                         then DECODE_UNPREDICTABLE(mc,"BIC (immediate)")
16431                       else ()
16432                     ; Data
16433                         (ArithLogicImmediate
16434                            (BitsN.B(0xE,4),(setflags,(Rd,(Rn,imm12)))))
16435                     )
16436                   | (BitsN.B(0x2,_),(BitsN.B(0xF,_),_)) =>
16437                     ( if Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
16438                         then DECODE_UNPREDICTABLE(mc,"MOV (immediate)")
16439                       else ()
16440                     ; Data(Move(setflags,(false,(Rd,imm12))))
16441                     )
16442                   | (BitsN.B(0x2,_),_) =>
16443                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16444                          (Rn = (BitsN.B(0xD,4)))
16445                         then DECODE_UNPREDICTABLE(mc,"ORR (immediate)")
16446                       else ()
16447                     ; Data
16448                         (ArithLogicImmediate
16449                            (BitsN.B(0xC,4),(setflags,(Rd,(Rn,imm12)))))
16450                     )
16451                   | (BitsN.B(0x3,_),(BitsN.B(0xF,_),_)) =>
16452                     ( if Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
16453                         then DECODE_UNPREDICTABLE(mc,"MVN (immediate)")
16454                       else ()
16455                     ; Data(Move(setflags,(true,(Rd,imm12))))
16456                     )
16457                   | (BitsN.B(0x3,_),_) =>
16458                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16459                          (Rn = (BitsN.B(0xD,4)))
16460                         then DECODE_UNPREDICTABLE(mc,"ORN (immediate)")
16461                       else ()
16462                     ; Data
16463                         (ArithLogicImmediate
16464                            (BitsN.B(0xF,4),(setflags,(Rd,(Rn,imm12)))))
16465                     )
16466                   | (BitsN.B(0x4,_),(_,(BitsN.B(0xF,_),BitsN.B(0x1,_)))) =>
16467                     ( if Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
16468                         then DECODE_UNPREDICTABLE(mc,"TEQ (immediate)")
16469                       else ()
16470                     ; Data
16471                         (TestCompareImmediate(BitsN.B(0x1,2),(Rn,imm12)))
16472                     )
16473                   | (BitsN.B(0x4,_),_) =>
16474                     ( if (Rd = (BitsN.B(0xD,4))) orelse
16475                          (((Rd = (BitsN.B(0xF,4))) andalso (not setflags)) orelse
16476                           (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])))
16477                         then DECODE_UNPREDICTABLE(mc,"EOR (immediate)")
16478                       else ()
16479                     ; Data
16480                         (ArithLogicImmediate
16481                            (BitsN.B(0x1,4),(setflags,(Rd,(Rn,imm12)))))
16482                     )
16483                   | (BitsN.B(0x8,_),(_,(BitsN.B(0xF,_),BitsN.B(0x1,_)))) =>
16484                     ( if Rn = (BitsN.B(0xF,4))
16485                         then DECODE_UNPREDICTABLE(mc,"CMN (immediate)")
16486                       else ()
16487                     ; Data
16488                         (TestCompareImmediate(BitsN.B(0x3,2),(Rn,imm12)))
16489                     )
16490                   | (BitsN.B(0x8,_),_) =>
16491                     ( if (Rd = (BitsN.B(0xD,4))) orelse
16492                          (((Rd = (BitsN.B(0xF,4))) andalso (not setflags)) orelse
16493                           (Rn = (BitsN.B(0xF,4))))
16494                         then DECODE_UNPREDICTABLE(mc,"ADD (immediate)")
16495                       else ()
16496                     ; Data
16497                         (ArithLogicImmediate
16498                            (BitsN.B(0x4,4),(setflags,(Rd,(Rn,imm12)))))
16499                     )
16500                   | (BitsN.B(0xA,_),_) =>
16501                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16502                          (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))
16503                         then DECODE_UNPREDICTABLE(mc,"ADC (immediate)")
16504                       else ()
16505                     ; Data
16506                         (ArithLogicImmediate
16507                            (BitsN.B(0x5,4),(setflags,(Rd,(Rn,imm12)))))
16508                     )
16509                   | (BitsN.B(0xB,_),_) =>
16510                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16511                          (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))
16512                         then DECODE_UNPREDICTABLE(mc,"SBC (immediate)")
16513                       else ()
16514                     ; Data
16515                         (ArithLogicImmediate
16516                            (BitsN.B(0x6,4),(setflags,(Rd,(Rn,imm12)))))
16517                     )
16518                   | (BitsN.B(0xD,_),(_,(BitsN.B(0xF,_),BitsN.B(0x1,_)))) =>
16519                     ( if Rn = (BitsN.B(0xF,4))
16520                         then DECODE_UNPREDICTABLE(mc,"CMP (immediate)")
16521                       else ()
16522                     ; Data
16523                         (TestCompareImmediate(BitsN.B(0x2,2),(Rn,imm12)))
16524                     )
16525                   | (BitsN.B(0xD,_),_) =>
16526                     ( if (Rd = (BitsN.B(0xD,4))) orelse
16527                          (((Rd = (BitsN.B(0xF,4))) andalso (not setflags)) orelse
16528                           (Rn = (BitsN.B(0xF,4))))
16529                         then DECODE_UNPREDICTABLE(mc,"SUB (immediate)")
16530                       else ()
16531                     ; Data
16532                         (ArithLogicImmediate
16533                            (BitsN.B(0x2,4),(setflags,(Rd,(Rn,imm12)))))
16534                     )
16535                   | (BitsN.B(0xE,_),_) =>
16536                     ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16537                          (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))
16538                         then DECODE_UNPREDICTABLE(mc,"RSB (immediate)")
16539                       else ()
16540                     ; Data
16541                         (ArithLogicImmediate
16542                            (BitsN.B(0x3,4),(setflags,(Rd,(Rn,imm12)))))
16543                     )
16544                   | _ => Undefined(BitsN.B(0x0,32))
16545                end
16546         else Skip ()
16547       end
16548     | ((true,
16549       (true,
16550        (true,
16551         (true,
16552          (false,
16553           (i'0,
16554            (true,
16555             (false,
16556              (false,(false,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16557      (false,
16558       (imm3'2,
16559        (imm3'1,
16560         (imm3'0,
16561          (Rd'3,
16562           (Rd'2,
16563            (Rd'1,
16564             (Rd'0,
16565              (imm8'7,
16566               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
16567       let
16568         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
16569       in
16570         if Do(ThumbCondition (),HaveThumb2 ())
16571           then ( if Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
16572                    then DECODE_UNPREDICTABLE(mc,"ADDW (immediate)")
16573                  else ()
16574                ; let
16575                    val imm12 =
16576                      BitsN.concat
16577                        [BitsN.fromBitstring([i'0],1),
16578                         BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3),
16579                         BitsN.fromBitstring
16580                           ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
16581                             imm8'1,imm8'0],8)]
16582                  in
16583                    Data
16584                      (AddSub
16585                         (false,
16586                          (Rd,
16587                           (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),
16588                            imm12))))
16589                  end
16590                )
16591         else Skip ()
16592       end
16593     | ((true,
16594       (true,
16595        (true,
16596         (true,
16597          (false,
16598           (i'0,
16599            (true,
16600             (false,
16601              (true,(false,(true,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16602      (false,
16603       (imm3'2,
16604        (imm3'1,
16605         (imm3'0,
16606          (Rd'3,
16607           (Rd'2,
16608            (Rd'1,
16609             (Rd'0,
16610              (imm8'7,
16611               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
16612       let
16613         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
16614       in
16615         if Do(ThumbCondition (),HaveThumb2 ())
16616           then ( if Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
16617                    then DECODE_UNPREDICTABLE(mc,"SUBW (immediate)")
16618                  else ()
16619                ; let
16620                    val imm12 =
16621                      BitsN.concat
16622                        [BitsN.fromBitstring([i'0],1),
16623                         BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3),
16624                         BitsN.fromBitstring
16625                           ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
16626                             imm8'1,imm8'0],8)]
16627                  in
16628                    Data
16629                      (AddSub
16630                         (true,
16631                          (Rd,
16632                           (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),
16633                            imm12))))
16634                  end
16635                )
16636         else Skip ()
16637       end
16638     | ((true,
16639       (true,
16640        (true,
16641         (true,
16642          (false,
16643           (i'0,
16644            (true,
16645             (false,
16646              (H'0,
16647               (true,(false,(false,(imm4'3,(imm4'2,(imm4'1,imm4'0))))))))))))))),
16648      (false,
16649       (imm3'2,
16650        (imm3'1,
16651         (imm3'0,
16652          (Rd'3,
16653           (Rd'2,
16654            (Rd'1,
16655             (Rd'0,
16656              (imm8'7,
16657               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
16658       let
16659         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
16660       in
16661         if Do(ThumbCondition (),HaveThumb2 ())
16662           then ( if Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
16663                    then DECODE_UNPREDICTABLE
16664                           (mc,"MOVT or MOVW (immediate)")
16665                  else ()
16666                ; let
16667                    val imm16 =
16668                      BitsN.concat
16669                        [BitsN.fromBitstring
16670                           ([imm4'3,imm4'2,imm4'1,imm4'0],4),
16671                         BitsN.fromBitstring([i'0],1),
16672                         BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3),
16673                         BitsN.fromBitstring
16674                           ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
16675                             imm8'1,imm8'0],8)]
16676                    val high =
16677                      (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
16678                  in
16679                    Data(MoveHalfword(high,(Rd,imm16)))
16680                  end
16681                )
16682         else Skip ()
16683       end
16684     | ((true,
16685       (true,
16686        (true,
16687         (true,
16688          (false,
16689           (sb'0'0'0,
16690            (true,
16691             (true,(U'0,(false,(true,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16692      (false,
16693       (false,
16694        (false,
16695         (false,
16696          (Rd'3,
16697           (Rd'2,
16698            (Rd'1,
16699             (Rd'0,
16700              (false,
16701               (false,
16702                (sb'1'00'1,
16703                 (sb'1'00'0,(sat_imm'3,(sat_imm'2,(sat_imm'1,sat_imm'0)))))))))))))))) =>
16704       let
16705         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
16706         val sat_imm =
16707           BitsN.fromBitstring
16708             ([sat_imm'3,sat_imm'2,sat_imm'1,sat_imm'0],4)
16709         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
16710         val GOOD_MATCH =
16711           ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
16712           ((BitsN.fromBitstring([sb'1'00'1,sb'1'00'0],2)) =
16713            (BitsN.B(0x0,2)))
16714       in
16715         if Do(ThumbCondition (),HaveThumb2 ())
16716           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16717                     ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16718                      (not GOOD_MATCH))
16719                    then DECODE_UNPREDICTABLE(mc,"Saturate16")
16720                  else ()
16721                ; let
16722                    val unsigned =
16723                      (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
16724                    val sarurate_to =
16725                      if unsigned
16726                        then BitsN.toNat sat_imm
16727                      else Nat.+(BitsN.toNat sat_imm,1)
16728                  in
16729                    Media(Saturate16(sarurate_to,(unsigned,(Rd,Rn))))
16730                  end
16731                )
16732         else Skip ()
16733       end
16734     | ((true,
16735       (true,
16736        (true,
16737         (true,
16738          (false,
16739           (sb'0'0'0,
16740            (true,
16741             (true,(U'0,(false,(sh'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16742      (false,
16743       (imm3'2,
16744        (imm3'1,
16745         (imm3'0,
16746          (Rd'3,
16747           (Rd'2,
16748            (Rd'1,
16749             (Rd'0,
16750              (imm2'1,
16751               (imm2'0,
16752                (sb'1'0'0,
16753                 (sat_imm'4,(sat_imm'3,(sat_imm'2,(sat_imm'1,sat_imm'0)))))))))))))))) =>
16754       let
16755         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
16756         val sat_imm =
16757           BitsN.fromBitstring
16758             ([sat_imm'4,sat_imm'3,sat_imm'2,sat_imm'1,sat_imm'0],5)
16759         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
16760         val GOOD_MATCH =
16761           ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
16762           ((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1)))
16763       in
16764         if Do(ThumbCondition (),HaveThumb2 ())
16765           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16766                     ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16767                      (not GOOD_MATCH))
16768                    then DECODE_UNPREDICTABLE(mc,"Saturate")
16769                  else ()
16770                ; let
16771                    val unsigned =
16772                      (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
16773                    val sarurate_to =
16774                      if unsigned
16775                        then BitsN.toNat sat_imm
16776                      else Nat.+(BitsN.toNat sat_imm,1)
16777                    val (shift_t,shift_n) =
16778                      DecodeImmShift
16779                        (BitsN.@@
16780                           (BitsN.fromBitstring([sh'0],1),BitsN.B(0x0,1)),
16781                         BitsN.@@
16782                           (BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3),
16783                            BitsN.fromBitstring([imm2'1,imm2'0],2)))
16784                  in
16785                    Media
16786                      (Saturate
16787                         (shift_t,
16788                          (shift_n,(sarurate_to,(unsigned,(Rd,Rn))))))
16789                  end
16790                )
16791         else Skip ()
16792       end
16793     | ((true,
16794       (true,
16795        (true,
16796         (true,
16797          (false,
16798           (sb'0'0'0,
16799            (true,
16800             (true,(U'0,(true,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16801      (false,
16802       (imm3'2,
16803        (imm3'1,
16804         (imm3'0,
16805          (Rd'3,
16806           (Rd'2,
16807            (Rd'1,
16808             (Rd'0,
16809              (imm2'1,
16810               (imm2'0,
16811                (sb'1'0'0,
16812                 (widthm1'4,(widthm1'3,(widthm1'2,(widthm1'1,widthm1'0)))))))))))))))) =>
16813       let
16814         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
16815         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
16816         val GOOD_MATCH =
16817           ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
16818           ((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1)))
16819       in
16820         if Do(ThumbCondition (),HaveThumb2 ())
16821           then let
16822                  val widthminus1 =
16823                    BitsN.toNat
16824                      (BitsN.fromBitstring
16825                         ([widthm1'4,widthm1'3,widthm1'2,widthm1'1,
16826                           widthm1'0],5))
16827                  val lsbit =
16828                    BitsN.toNat
16829                      (BitsN.@@
16830                         (BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3),
16831                          BitsN.fromBitstring([imm2'1,imm2'0],2)))
16832                in
16833                  ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16834                       ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16835                        ((Nat.<(31,Nat.+(lsbit,widthminus1))) orelse
16836                         (not GOOD_MATCH)))
16837                      then DECODE_UNPREDICTABLE(mc,"BitFieldExtract")
16838                    else ()
16839                  ; let
16840                      val unsigned =
16841                        (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
16842                    in
16843                      Media
16844                        (BitFieldExtract
16845                           (unsigned,(Rd,(Rn,(lsbit,widthminus1)))))
16846                    end
16847                  )
16848                end
16849         else Skip ()
16850       end
16851     | ((true,
16852       (true,
16853        (true,
16854         (true,
16855          (false,
16856           (sb'0'0'0,
16857            (true,
16858             (true,(false,(true,(true,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16859      (false,
16860       (imm3'2,
16861        (imm3'1,
16862         (imm3'0,
16863          (Rd'3,
16864           (Rd'2,
16865            (Rd'1,
16866             (Rd'0,
16867              (imm2'1,
16868               (imm2'0,(sb'1'0'0,(msb'4,(msb'3,(msb'2,(msb'1,msb'0)))))))))))))))) =>
16869       let
16870         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
16871         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
16872         val GOOD_MATCH =
16873           ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
16874           ((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1)))
16875       in
16876         if Do(ThumbCondition (),HaveThumb2 ())
16877           then let
16878                  val msbit =
16879                    BitsN.toNat
16880                      (BitsN.fromBitstring
16881                         ([msb'4,msb'3,msb'2,msb'1,msb'0],5))
16882                  val lsbit =
16883                    BitsN.toNat
16884                      (BitsN.@@
16885                         (BitsN.fromBitstring([imm3'2,imm3'1,imm3'0],3),
16886                          BitsN.fromBitstring([imm2'1,imm2'0],2)))
16887                in
16888                  ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16889                       ((Rn = (BitsN.B(0xD,4))) orelse
16890                        ((Nat.<(msbit,lsbit)) orelse (not GOOD_MATCH)))
16891                      then DECODE_UNPREDICTABLE
16892                             (mc,"BitFieldClearOrInsert")
16893                    else ()
16894                  ; Media(BitFieldClearOrInsert(Rd,(Rn,(lsbit,msbit))))
16895                  )
16896                end
16897         else Skip ()
16898       end
16899     | ((true,
16900       (true,
16901        (true,
16902         (true,
16903          (false,
16904           (false,
16905            (true,
16906             (true,(true,(false,(false,(R'0,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16907      (true,
16908       (false,
16909        (sb'0'0'0,
16910         (false,
16911          (m1'3,
16912           (m1'2,
16913            (m1'1,
16914             (m1'0,
16915              (sb'1'00'1,
16916               (sb'1'00'0,
16917                (true,
16918                 (m'0,
16919                  (sb'2'0000'3,(sb'2'0000'2,(sb'2'0000'1,sb'2'0000'0)))))))))))))))) =>
16920       let
16921         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
16922         val GOOD_MATCH =
16923           ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
16924           (((BitsN.fromBitstring([sb'1'00'1,sb'1'00'0],2)) =
16925             (BitsN.B(0x0,2))) andalso
16926            ((BitsN.fromBitstring
16927                ([sb'2'0000'3,sb'2'0000'2,sb'2'0000'1,sb'2'0000'0],4)) =
16928             (BitsN.B(0x0,4))))
16929       in
16930         if Do(ThumbCondition (),HaveVirtExt ())
16931           then ( if (Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16932                     (not GOOD_MATCH)
16933                    then DECODE_UNPREDICTABLE
16934                           (mc,"MoveToBankedOrSpecialRegister")
16935                  else ()
16936                ; let
16937                    val write_spsr =
16938                      (BitsN.fromBitstring([R'0],1)) = (BitsN.B(0x1,1))
16939                    val SYSm =
16940                      BitsN.@@
16941                        (BitsN.fromBitstring([m'0],1),
16942                         BitsN.fromBitstring([m1'3,m1'2,m1'1,m1'0],4))
16943                  in
16944                    System
16945                      (MoveToBankedOrSpecialRegister(write_spsr,(SYSm,Rn)))
16946                  end
16947                )
16948         else Skip ()
16949       end
16950     | ((true,
16951       (true,
16952        (true,
16953         (true,
16954          (false,
16955           (false,
16956            (true,
16957             (true,(true,(false,(false,(R'0,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
16958      (true,
16959       (false,
16960        (sb'0'0'0,
16961         (false,
16962          (mask'3,
16963           (mask'2,
16964            (mask'1,
16965             (mask'0,
16966              (sb'1'00'1,
16967               (sb'1'00'0,
16968                (false,
16969                 (sb'2'00000'4,
16970                  (sb'2'00000'3,(sb'2'00000'2,(sb'2'00000'1,sb'2'00000'0)))))))))))))))) =>
16971       let
16972         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
16973         val mask = BitsN.fromBitstring([mask'3,mask'2,mask'1,mask'0],4)
16974         val GOOD_MATCH =
16975           ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
16976           (((BitsN.fromBitstring([sb'1'00'1,sb'1'00'0],2)) =
16977             (BitsN.B(0x0,2))) andalso
16978            ((BitsN.fromBitstring
16979                ([sb'2'00000'4,sb'2'00000'3,sb'2'00000'2,sb'2'00000'1,
16980                  sb'2'00000'0],5)) = (BitsN.B(0x0,5))))
16981       in
16982         if Do(ThumbCondition (),HaveThumb2 ())
16983           then ( if (mask = (BitsN.B(0x0,4))) orelse
16984                     ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
16985                      (not GOOD_MATCH))
16986                    then DECODE_UNPREDICTABLE
16987                           (mc,"MoveToSpecialFromRegister")
16988                  else ()
16989                ; let
16990                    val write_spsr =
16991                      (BitsN.fromBitstring([R'0],1)) = (BitsN.B(0x1,1))
16992                  in
16993                    System
16994                      (MoveToSpecialFromRegister(write_spsr,(Rn,mask)))
16995                  end
16996                )
16997         else Skip ()
16998       end
16999     | ((true,
17000       (true,
17001        (true,
17002         (true,
17003          (false,
17004           (false,
17005            (true,
17006             (true,
17007              (true,
17008               (false,
17009                (true,
17010                 (false,
17011                  (sb'0'1111'3,(sb'0'1111'2,(sb'0'1111'1,sb'0'1111'0))))))))))))))),
17012      (true,
17013       (false,
17014        (sb'1'0'0,
17015         (false,
17016          (sb'2'0'0,
17017           (false,
17018            (false,
17019             (false,(op'7,(op'6,(op'5,(op'4,(op'3,(op'2,(op'1,op'0)))))))))))))))) =>
17020       let
17021         val GOOD_MATCH =
17022           ((BitsN.fromBitstring
17023               ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
17024            (BitsN.B(0xF,4))) andalso
17025           (((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1))) andalso
17026            ((BitsN.fromBitstring([sb'2'0'0],1)) = (BitsN.B(0x0,1))))
17027       in
17028         ( if not GOOD_MATCH then DECODE_UNPREDICTABLE(mc,"Hint") else ()
17029         ; DecodeHint
17030             (ThumbCondition (),
17031              BitsN.fromBitstring
17032                ([op'7,op'6,op'5,op'4,op'3,op'2,op'1,op'0],8))
17033         )
17034       end
17035     | ((true,
17036       (true,
17037        (true,
17038         (true,
17039          (false,
17040           (false,
17041            (true,
17042             (true,
17043              (true,
17044               (false,
17045                (true,
17046                 (false,
17047                  (sb'0'1111'3,(sb'0'1111'2,(sb'0'1111'1,sb'0'1111'0))))))))))))))),
17048      (true,
17049       (false,
17050        (sb'1'0'0,
17051         (false,
17052          (sb'2'0'0,
17053           (imod'1,
17054            (imod'0,
17055             (M'0,
17056              (A'0,(I'0,(F'0,(mode'4,(mode'3,(mode'2,(mode'1,mode'0)))))))))))))))) =>
17057       let
17058         val mode =
17059           BitsN.fromBitstring([mode'4,mode'3,mode'2,mode'1,mode'0],5)
17060         val F = BitsN.fromBitstring([F'0],1)
17061         val I = BitsN.fromBitstring([I'0],1)
17062         val A = BitsN.fromBitstring([A'0],1)
17063         val M = BitsN.fromBitstring([M'0],1)
17064         val imod = BitsN.fromBitstring([imod'1,imod'0],2)
17065         val GOOD_MATCH =
17066           ((BitsN.fromBitstring
17067               ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
17068            (BitsN.B(0xF,4))) andalso
17069           (((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1))) andalso
17070            ((BitsN.fromBitstring([sb'2'0'0],1)) = (BitsN.B(0x0,1))))
17071       in
17072         if Do(ThumbCondition (),HaveThumb2 ())
17073           then ( if ((not(mode = (BitsN.B(0x0,5)))) andalso
17074                      (M = (BitsN.B(0x0,1)))) orelse
17075                     (((BitsN.bit(imod,1)) =
17076                       ((BitsN.concat[A,I,F]) = (BitsN.B(0x0,3)))) orelse
17077                      ((imod = (BitsN.B(0x1,2))) orelse
17078                       ((InITBlock ()) orelse (not GOOD_MATCH))))
17079                    then DECODE_UNPREDICTABLE(mc,"ChangeProcessorState")
17080                  else ()
17081                ; let
17082                    val enable = imod = (BitsN.B(0x2,2))
17083                    val disable = imod = (BitsN.B(0x3,2))
17084                    val changemode =
17085                      if M = (BitsN.B(0x1,1))
17086                        then Option.SOME mode
17087                      else NONE
17088                    val affectA = A = (BitsN.B(0x1,1))
17089                    val affectI = I = (BitsN.B(0x1,1))
17090                    val affectF = F = (BitsN.B(0x1,1))
17091                  in
17092                    System
17093                      (ChangeProcessorState
17094                         (enable,
17095                          (disable,
17096                           (affectA,(affectI,(affectF,changemode))))))
17097                  end
17098                )
17099         else Skip ()
17100       end
17101     | ((true,
17102       (true,
17103        (true,
17104         (true,
17105          (false,
17106           (false,
17107            (true,
17108             (true,
17109              (true,
17110               (false,
17111                (true,
17112                 (true,
17113                  (sb'0'1111'3,(sb'0'1111'2,(sb'0'1111'1,sb'0'1111'0))))))))))))))),
17114      (true,
17115       (false,
17116        (sb'1'0'0,
17117         (false,
17118          (sb'2'1111'3,
17119           (sb'2'1111'2,
17120            (sb'2'1111'1,
17121             (sb'2'1111'0,
17122              (false,
17123               (false,
17124                (false,
17125                 (J'0,
17126                  (sb'3'1111'3,(sb'3'1111'2,(sb'3'1111'1,sb'3'1111'0)))))))))))))))) =>
17127       let
17128         val J = BitsN.fromBitstring([J'0],1)
17129         val GOOD_MATCH =
17130           ((BitsN.fromBitstring
17131               ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
17132            (BitsN.B(0xF,4))) andalso
17133           (((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1))) andalso
17134            (((BitsN.fromBitstring
17135                 ([sb'2'1111'3,sb'2'1111'2,sb'2'1111'1,sb'2'1111'0],4)) =
17136              (BitsN.B(0xF,4))) andalso
17137             ((BitsN.fromBitstring
17138                 ([sb'3'1111'3,sb'3'1111'2,sb'3'1111'1,sb'3'1111'0],4)) =
17139              (BitsN.B(0xF,4)))))
17140       in
17141         if (Do(ThumbCondition (),HaveThumbEE ())) andalso
17142            (not(((CurrentInstrSet ()) = InstrSet_Thumb) andalso
17143                 (J = (BitsN.B(0x0,1)))))
17144           then ( if (InITBlock ()) orelse (not GOOD_MATCH)
17145                    then DECODE_UNPREDICTABLE(mc,"EnterxLeavex")
17146                  else ()
17147                ; let
17148                    val is_enterx = J = (BitsN.B(0x1,1))
17149                  in
17150                    System(EnterxLeavex is_enterx)
17151                  end
17152                )
17153         else Skip ()
17154       end
17155     | ((true,
17156       (true,
17157        (true,
17158         (true,
17159          (false,
17160           (false,
17161            (true,
17162             (true,
17163              (true,
17164               (false,
17165                (true,
17166                 (true,
17167                  (sb'0'1111'3,(sb'0'1111'2,(sb'0'1111'1,sb'0'1111'0))))))))))))))),
17168      (true,
17169       (false,
17170        (sb'1'0'0,
17171         (false,
17172          (sb'2'1111'3,
17173           (sb'2'1111'2,
17174            (sb'2'1111'1,
17175             (sb'2'1111'0,
17176              (op'3,
17177               (op'2,
17178                (op'1,(op'0,(option'3,(option'2,(option'1,option'0)))))))))))))))) =>
17179       let
17180         val option =
17181           BitsN.fromBitstring([option'3,option'2,option'1,option'0],4)
17182         val GOOD_MATCH =
17183           ((BitsN.fromBitstring
17184               ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
17185            (BitsN.B(0xF,4))) andalso
17186           (((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1))) andalso
17187            ((BitsN.fromBitstring
17188                ([sb'2'1111'3,sb'2'1111'2,sb'2'1111'1,sb'2'1111'0],4)) =
17189             (BitsN.B(0xF,4))))
17190       in
17191         if Do(ThumbCondition (),HaveThumb2 ())
17192           then case BitsN.fromBitstring([op'3,op'2,op'1,op'0],4) of
17193                   BitsN.B(0x2,_) =>
17194                     ( if not GOOD_MATCH
17195                         then DECODE_UNPREDICTABLE(mc,"CLREX")
17196                       else ()
17197                     ; ClearExclusive
17198                     )
17199                 | BitsN.B(0x4,_) =>
17200                   ( if not GOOD_MATCH
17201                       then DECODE_UNPREDICTABLE(mc,"DSB")
17202                     else ()
17203                   ; Hint(DataSynchronizationBarrier option)
17204                   )
17205                 | BitsN.B(0x5,_) =>
17206                   ( if not GOOD_MATCH
17207                       then DECODE_UNPREDICTABLE(mc,"DMB")
17208                     else ()
17209                   ; Hint(DataMemoryBarrier option)
17210                   )
17211                 | BitsN.B(0x6,_) =>
17212                   ( if not GOOD_MATCH
17213                       then DECODE_UNPREDICTABLE(mc,"ISB")
17214                     else ()
17215                   ; Hint(InstructionSynchronizationBarrier option)
17216                   )
17217                 | _ =>
17218                   (if Nat.>=(ArchVersion (),7)
17219                      then Undefined(BitsN.B(0x0,32))
17220                    else ( DECODE_UNPREDICTABLE
17221                             (mc,"Miscellaneous control")
17222                         ; Branch(BranchExchange(BitsN.B(0x0,4)))
17223                         ))
17224         else Skip ()
17225       end
17226     | ((true,
17227       (true,
17228        (true,
17229         (true,
17230          (false,
17231           (false,
17232            (true,
17233             (true,
17234              (true,
17235               (true,
17236                (false,
17237                 (true,
17238                  (sb'0'1111'3,(sb'0'1111'2,(sb'0'1111'1,sb'0'1111'0))))))))))))))),
17239      (true,
17240       (false,
17241        (sb'1'0'0,
17242         (false,
17243          (sb'2'1111'3,
17244           (sb'2'1111'2,
17245            (sb'2'1111'1,
17246             (sb'2'1111'0,
17247              (imm8'7,
17248               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
17249       let
17250         val imm8 =
17251           BitsN.fromBitstring
17252             ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,imm8'1,imm8'0],8)
17253         val GOOD_MATCH =
17254           ((BitsN.fromBitstring
17255               ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
17256            (BitsN.B(0xF,4))) andalso
17257           (((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1))) andalso
17258            ((BitsN.fromBitstring
17259                ([sb'2'1111'3,sb'2'1111'2,sb'2'1111'1,sb'2'1111'0],4)) =
17260             (BitsN.B(0xF,4))))
17261       in
17262         if Do(ThumbCondition (),HaveThumb2 ())
17263           then if (HaveVirtExt ()) andalso
17264                   ((imm8 = (BitsN.B(0x0,8))) andalso GOOD_MATCH)
17265                  then System ExceptionReturn
17266                else ( if ((CurrentInstrSet ()) = InstrSet_ThumbEE) orelse
17267                          (((InITBlock ()) andalso (not(LastInITBlock ()))) orelse
17268                           (not GOOD_MATCH))
17269                         then DECODE_UNPREDICTABLE
17270                                (mc,"SUBS<c> PC, LR, #0")
17271                       else ()
17272                     ; let
17273                         val imm12 = BitsN.zeroExtend 12 imm8
17274                       in
17275                         if CurrentModeIsHyp ()
17276                           then Undefined(BitsN.B(0x0,32))
17277                         else Data
17278                                (ArithLogicImmediate
17279                                   (BitsN.B(0x2,4),
17280                                    (true,
17281                                     (BitsN.B(0xF,4),
17282                                      (BitsN.B(0xE,4),imm12)))))
17283                       end
17284                     )
17285         else Skip ()
17286       end
17287     | ((true,
17288       (true,
17289        (true,
17290         (true,
17291          (false,
17292           (false,
17293            (true,
17294             (true,(true,(true,(true,(R'0,(m1'3,(m1'2,(m1'1,m1'0))))))))))))))),
17295      (true,
17296       (false,
17297        (sb'0'0'0,
17298         (false,
17299          (Rd'3,
17300           (Rd'2,
17301            (Rd'1,
17302             (Rd'0,
17303              (sb'1'00'1,
17304               (sb'1'00'0,
17305                (true,
17306                 (m'0,
17307                  (sb'2'0000'3,(sb'2'0000'2,(sb'2'0000'1,sb'2'0000'0)))))))))))))))) =>
17308       let
17309         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
17310         val GOOD_MATCH =
17311           ((BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))) andalso
17312           (((BitsN.fromBitstring([sb'1'00'1,sb'1'00'0],2)) =
17313             (BitsN.B(0x0,2))) andalso
17314            ((BitsN.fromBitstring
17315                ([sb'2'0000'3,sb'2'0000'2,sb'2'0000'1,sb'2'0000'0],4)) =
17316             (BitsN.B(0x0,4))))
17317       in
17318         if Do(ThumbCondition (),HaveVirtExt ())
17319           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
17320                     (not GOOD_MATCH)
17321                    then DECODE_UNPREDICTABLE
17322                           (mc,"MoveToRegisterFromBankedOrSpecial")
17323                  else ()
17324                ; let
17325                    val write_spsr =
17326                      (BitsN.fromBitstring([R'0],1)) = (BitsN.B(0x1,1))
17327                    val SYSm =
17328                      BitsN.@@
17329                        (BitsN.fromBitstring([m'0],1),
17330                         BitsN.fromBitstring([m1'3,m1'2,m1'1,m1'0],4))
17331                  in
17332                    System
17333                      (MoveToRegisterFromBankedOrSpecial
17334                         (write_spsr,(SYSm,Rd)))
17335                  end
17336                )
17337         else Skip ()
17338       end
17339     | ((true,
17340       (true,
17341        (true,
17342         (true,
17343          (false,
17344           (false,
17345            (true,
17346             (true,
17347              (true,
17348               (true,
17349                (true,
17350                 (R'0,
17351                  (sb'0'1111'3,(sb'0'1111'2,(sb'0'1111'1,sb'0'1111'0))))))))))))))),
17352      (true,
17353       (false,
17354        (sb'1'0'0,
17355         (false,
17356          (Rd'3,
17357           (Rd'2,
17358            (Rd'1,
17359             (Rd'0,
17360              (sb'2'00'1,
17361               (sb'2'00'0,
17362                (false,
17363                 (sb'3'00000'4,
17364                  (sb'3'00000'3,(sb'3'00000'2,(sb'3'00000'1,sb'3'00000'0)))))))))))))))) =>
17365       let
17366         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
17367         val GOOD_MATCH =
17368           ((BitsN.fromBitstring
17369               ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
17370            (BitsN.B(0xF,4))) andalso
17371           (((BitsN.fromBitstring([sb'1'0'0],1)) = (BitsN.B(0x0,1))) andalso
17372            (((BitsN.fromBitstring([sb'2'00'1,sb'2'00'0],2)) =
17373              (BitsN.B(0x0,2))) andalso
17374             ((BitsN.fromBitstring
17375                 ([sb'3'00000'4,sb'3'00000'3,sb'3'00000'2,sb'3'00000'1,
17376                   sb'3'00000'0],5)) = (BitsN.B(0x0,5)))))
17377       in
17378         if Do(ThumbCondition (),HaveThumb2 ())
17379           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
17380                     (not GOOD_MATCH)
17381                    then DECODE_UNPREDICTABLE
17382                           (mc,"MoveToRegisterFromSpecial")
17383                  else ()
17384                ; let
17385                    val write_spsr =
17386                      (BitsN.fromBitstring([R'0],1)) = (BitsN.B(0x1,1))
17387                  in
17388                    System(MoveToRegisterFromSpecial(write_spsr,Rd))
17389                  end
17390                )
17391         else Skip ()
17392       end
17393     | ((true,
17394       (true,
17395        (true,
17396         (true,
17397          (false,
17398           (true,
17399            (true,
17400             (true,
17401              (true,
17402               (true,(true,(false,(imm4'3,(imm4'2,(imm4'1,imm4'0))))))))))))))),
17403      (true,
17404       (false,
17405        (false,
17406         (false,
17407          (imm12'11,
17408           (imm12'10,
17409            (imm12'9,
17410             (imm12'8,
17411              (imm12'7,
17412               (imm12'6,
17413                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
17414       (if Do(ThumbCondition (),HaveVirtExt ())
17415          then ( if InITBlock ()
17416                   then DECODE_UNPREDICTABLE(mc,"HypervisorCall")
17417                 else ()
17418               ; let
17419                   val imm16 =
17420                     BitsN.@@
17421                       (BitsN.fromBitstring
17422                          ([imm4'3,imm4'2,imm4'1,imm4'0],4),
17423                        BitsN.fromBitstring
17424                          ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
17425                            imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
17426                            imm12'1,imm12'0],12))
17427                 in
17428                   System(HypervisorCall imm16)
17429                 end
17430               )
17431        else Skip ())
17432     | ((true,
17433       (true,
17434        (true,
17435         (true,
17436          (false,
17437           (true,
17438            (true,
17439             (true,
17440              (true,(true,(true,(true,(imm4'3,(imm4'2,(imm4'1,imm4'0))))))))))))))),
17441      (true,
17442       (false,
17443        (false,
17444         (false,
17445          (sb'0'000000000000'11,
17446           (sb'0'000000000000'10,
17447            (sb'0'000000000000'9,
17448             (sb'0'000000000000'8,
17449              (sb'0'000000000000'7,
17450               (sb'0'000000000000'6,
17451                (sb'0'000000000000'5,
17452                 (sb'0'000000000000'4,
17453                  (sb'0'000000000000'3,
17454                   (sb'0'000000000000'2,
17455                    (sb'0'000000000000'1,sb'0'000000000000'0)))))))))))))))) =>
17456       let
17457         val GOOD_MATCH =
17458           (BitsN.fromBitstring
17459              ([sb'0'000000000000'11,sb'0'000000000000'10,
17460                sb'0'000000000000'9,sb'0'000000000000'8,
17461                sb'0'000000000000'7,sb'0'000000000000'6,
17462                sb'0'000000000000'5,sb'0'000000000000'4,
17463                sb'0'000000000000'3,sb'0'000000000000'2,
17464                sb'0'000000000000'1,sb'0'000000000000'0],12)) =
17465           (BitsN.B(0x0,12))
17466       in
17467         if Do(ThumbCondition (),
17468               (HaveSecurityExt ()) andalso
17469               (not((!Architecture) = ARMv6K)))
17470           then ( if ((InITBlock ()) andalso (not(LastInITBlock ()))) orelse
17471                     (not GOOD_MATCH)
17472                    then DECODE_UNPREDICTABLE(mc,"SecureMonitorCall")
17473                  else ()
17474                ; System
17475                    (SecureMonitorCall
17476                       (BitsN.fromBitstring
17477                          ([imm4'3,imm4'2,imm4'1,imm4'0],4)))
17478                )
17479         else Skip ()
17480       end
17481     | ((true,
17482       (true,
17483        (true,
17484         (true,
17485          (false,
17486           (true,
17487            (true,
17488             (true,
17489              (true,(true,(true,(true,(imm4'3,(imm4'2,(imm4'1,imm4'0))))))))))))))),
17490      (true,
17491       (false,
17492        (true,
17493         (false,
17494          (imm12'11,
17495           (imm12'10,
17496            (imm12'9,
17497             (imm12'8,
17498              (imm12'7,
17499               (imm12'6,
17500                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
17501       (if Do(ThumbCondition (),HaveThumb2 ())
17502          then let
17503                 val imm32 =
17504                   BitsN.zeroExtend 32
17505                     (BitsN.@@
17506                        (BitsN.fromBitstring
17507                           ([imm4'3,imm4'2,imm4'1,imm4'0],4),
17508                         BitsN.fromBitstring
17509                           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
17510                             imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
17511                             imm12'1,imm12'0],12)))
17512               in
17513                 Undefined imm32
17514               end
17515        else Skip ())
17516     | ((true,
17517       (true,
17518        (true,
17519         (true,
17520          (false,
17521           (S'0,
17522            (cond'3,
17523             (cond'2,
17524              (cond'1,
17525               (cond'0,(imm6'5,(imm6'4,(imm6'3,(imm6'2,(imm6'1,imm6'0))))))))))))))),
17526      (true,
17527       (false,
17528        (J1'0,
17529         (false,
17530          (J2'0,
17531           (imm11'10,
17532            (imm11'9,
17533             (imm11'8,
17534              (imm11'7,
17535               (imm11'6,
17536                (imm11'5,(imm11'4,(imm11'3,(imm11'2,(imm11'1,imm11'0)))))))))))))))) =>
17537       (if Do(BitsN.fromBitstring([cond'3,cond'2,cond'1,cond'0],4),
17538              HaveThumb2 ())
17539          then ( if InITBlock ()
17540                   then DECODE_UNPREDICTABLE(mc,"BranchTarget")
17541                 else ()
17542               ; let
17543                   val imm32 =
17544                     BitsN.signExtend 32
17545                       (BitsN.concat
17546                          [BitsN.fromBitstring([S'0],1),
17547                           BitsN.fromBitstring([J2'0],1),
17548                           BitsN.fromBitstring([J1'0],1),
17549                           BitsN.fromBitstring
17550                             ([imm6'5,imm6'4,imm6'3,imm6'2,imm6'1,imm6'0],
17551                              6),
17552                           BitsN.fromBitstring
17553                             ([imm11'10,imm11'9,imm11'8,imm11'7,imm11'6,
17554                               imm11'5,imm11'4,imm11'3,imm11'2,imm11'1,
17555                               imm11'0],11),BitsN.B(0x0,1)])
17556                 in
17557                   Branch(BranchTarget imm32)
17558                 end
17559               )
17560        else Skip ())
17561     | ((true,
17562       (true,
17563        (true,
17564         (true,
17565          (false,
17566           (S'0,
17567            (imm10'9,
17568             (imm10'8,
17569              (imm10'7,
17570               (imm10'6,
17571                (imm10'5,(imm10'4,(imm10'3,(imm10'2,(imm10'1,imm10'0))))))))))))))),
17572      (true,
17573       (L'0,
17574        (J1'0,
17575         (true,
17576          (J2'0,
17577           (imm11'10,
17578            (imm11'9,
17579             (imm11'8,
17580              (imm11'7,
17581               (imm11'6,
17582                (imm11'5,(imm11'4,(imm11'3,(imm11'2,(imm11'1,imm11'0)))))))))))))))) =>
17583       let
17584         val S = BitsN.fromBitstring([S'0],1)
17585         val J2 = BitsN.fromBitstring([J2'0],1)
17586         val J1 = BitsN.fromBitstring([J1'0],1)
17587         val L = BitsN.fromBitstring([L'0],1)
17588       in
17589         if Do(ThumbCondition (),
17590               ((L = (BitsN.B(0x1,1))) andalso
17591                ((J1 = (BitsN.B(0x1,1))) andalso (J1 = J2))) orelse
17592               (HaveThumb2 ()))
17593           then ( if (InITBlock ()) andalso (not(LastInITBlock ()))
17594                    then DECODE_UNPREDICTABLE
17595                           (mc,
17596                            "BranchTarget or BranchLinkExchangeImmediate")
17597                  else ()
17598                ; let
17599                    val I1 = BitsN.~(BitsN.??(J1,S))
17600                    val I2 = BitsN.~(BitsN.??(J2,S))
17601                    val imm32 =
17602                      BitsN.signExtend 32
17603                        (BitsN.concat
17604                           [S,I1,I2,
17605                            BitsN.fromBitstring
17606                              ([imm10'9,imm10'8,imm10'7,imm10'6,imm10'5,
17607                                imm10'4,imm10'3,imm10'2,imm10'1,imm10'0],
17608                               10),
17609                            BitsN.fromBitstring
17610                              ([imm11'10,imm11'9,imm11'8,imm11'7,imm11'6,
17611                                imm11'5,imm11'4,imm11'3,imm11'2,imm11'1,
17612                                imm11'0],11),BitsN.B(0x0,1)])
17613                    val targetInstrSet = InstrSet_Thumb
17614                  in
17615                    if L = (BitsN.B(0x1,1))
17616                      then Branch
17617                             (BranchLinkExchangeImmediate
17618                                (targetInstrSet,imm32))
17619                    else Branch(BranchTarget imm32)
17620                  end
17621                )
17622         else Skip ()
17623       end
17624     | ((true,
17625       (true,
17626        (true,
17627         (true,
17628          (false,
17629           (S'0,
17630            (imm10H'9,
17631             (imm10H'8,
17632              (imm10H'7,
17633               (imm10H'6,
17634                (imm10H'5,
17635                 (imm10H'4,(imm10H'3,(imm10H'2,(imm10H'1,imm10H'0))))))))))))))),
17636      (true,
17637       (true,
17638        (J1'0,
17639         (false,
17640          (J2'0,
17641           (imm10L'9,
17642            (imm10L'8,
17643             (imm10L'7,
17644              (imm10L'6,
17645               (imm10L'5,
17646                (imm10L'4,(imm10L'3,(imm10L'2,(imm10L'1,(imm10L'0,H'0)))))))))))))))) =>
17647       let
17648         val S = BitsN.fromBitstring([S'0],1)
17649         val J2 = BitsN.fromBitstring([J2'0],1)
17650         val J1 = BitsN.fromBitstring([J1'0],1)
17651       in
17652         if Do(ThumbCondition (),
17653               (not(((CurrentInstrSet ()) = InstrSet_ThumbEE) orelse
17654                    ((BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))))) andalso
17655               (if (J1 = (BitsN.B(0x1,1))) andalso (J1 = J2)
17656                  then Nat.>=(ArchVersion (),5)
17657                else HaveThumb2 ()))
17658           then ( if (InITBlock ()) andalso (not(LastInITBlock ()))
17659                    then DECODE_UNPREDICTABLE
17660                           (mc,"BranchLinkExchangeImmediate")
17661                  else ()
17662                ; let
17663                    val I1 = BitsN.~(BitsN.??(J1,S))
17664                    val I2 = BitsN.~(BitsN.??(J2,S))
17665                    val imm32 =
17666                      BitsN.signExtend 32
17667                        (BitsN.concat
17668                           [S,I1,I2,
17669                            BitsN.fromBitstring
17670                              ([imm10H'9,imm10H'8,imm10H'7,imm10H'6,
17671                                imm10H'5,imm10H'4,imm10H'3,imm10H'2,
17672                                imm10H'1,imm10H'0],10),
17673                            BitsN.fromBitstring
17674                              ([imm10L'9,imm10L'8,imm10L'7,imm10L'6,
17675                                imm10L'5,imm10L'4,imm10L'3,imm10L'2,
17676                                imm10L'1,imm10L'0],10),BitsN.B(0x0,2)])
17677                    val targetInstrSet = InstrSet_ARM
17678                  in
17679                    Branch
17680                      (BranchLinkExchangeImmediate(targetInstrSet,imm32))
17681                  end
17682                )
17683         else Skip ()
17684       end
17685     | ((true,
17686       (true,
17687        (true,
17688         (true,
17689          (true,
17690           (false,
17691            (false,
17692             (false,(_,(false,(true,(true,(true,(true,(true,true))))))))))))))),
17693      (true,(true,(true,(true,_))))) =>
17694       ( DECODE_UNPREDICTABLE(mc,"PreloadDataLiteral")
17695       ; Branch(BranchExchange(BitsN.B(0x0,4)))
17696       )
17697     | ((true,
17698       (true,
17699        (true,
17700         (true,
17701          (true,
17702           (false,
17703            (false,
17704             (false,
17705              (U'0,(false,(sb'0'0'0,(true,(true,(true,(true,true))))))))))))))),
17706      (true,
17707       (true,
17708        (true,
17709         (true,
17710          (imm12'11,
17711           (imm12'10,
17712            (imm12'9,
17713             (imm12'8,
17714              (imm12'7,
17715               (imm12'6,
17716                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
17717       let
17718         val GOOD_MATCH =
17719           (BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))
17720       in
17721         if Do(ThumbCondition (),HaveThumb2 ())
17722           then ( if not GOOD_MATCH
17723                    then DECODE_UNPREDICTABLE(mc,"PLD")
17724                  else ()
17725                ; let
17726                    val imm32 =
17727                      BitsN.zeroExtend 32
17728                        (BitsN.fromBitstring
17729                           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
17730                             imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
17731                             imm12'1,imm12'0],12))
17732                    val add =
17733                      (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
17734                  in
17735                    Hint(PreloadDataLiteral(add,imm32))
17736                  end
17737                )
17738         else Skip ()
17739       end
17740     | ((true,
17741       (true,
17742        (true,
17743         (true,
17744          (true,
17745           (false,
17746            (false,
17747             (true,(U'0,(false,(false,(true,(true,(true,(true,true))))))))))))))),
17748      (true,
17749       (true,
17750        (true,
17751         (true,
17752          (imm12'11,
17753           (imm12'10,
17754            (imm12'9,
17755             (imm12'8,
17756              (imm12'7,
17757               (imm12'6,
17758                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
17759       (if Do(ThumbCondition (),Nat.>=(ArchVersion (),7))
17760          then let
17761                 val imm32 =
17762                   BitsN.zeroExtend 32
17763                     (BitsN.fromBitstring
17764                        ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
17765                          imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,imm12'1,
17766                          imm12'0],12))
17767                 val add =
17768                   (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
17769                 val Rn = BitsN.B(0xF,4)
17770               in
17771                 Hint(PreloadInstruction(add,(Rn,immediate_form1 imm32)))
17772               end
17773        else Skip ())
17774     | ((true,
17775       (true,
17776        (true,
17777         (true,
17778          (true,
17779           (false,
17780            (false,
17781             (true,(true,(false,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
17782      (true,
17783       (true,
17784        (true,
17785         (true,
17786          (imm12'11,
17787           (imm12'10,
17788            (imm12'9,
17789             (imm12'8,
17790              (imm12'7,
17791               (imm12'6,
17792                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
17793       (if Do(ThumbCondition (),Nat.>=(ArchVersion (),7))
17794          then let
17795                 val imm32 =
17796                   BitsN.zeroExtend 32
17797                     (BitsN.fromBitstring
17798                        ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
17799                          imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,imm12'1,
17800                          imm12'0],12))
17801                 val add = true
17802               in
17803                 Hint
17804                   (PreloadInstruction
17805                      (add,
17806                       (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),
17807                        immediate_form1 imm32)))
17808               end
17809        else Skip ())
17810     | ((true,
17811       (true,
17812        (true,
17813         (true,
17814          (true,
17815           (false,
17816            (false,
17817             (false,(true,(false,(W'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
17818      (true,
17819       (true,
17820        (true,
17821         (true,
17822          (imm12'11,
17823           (imm12'10,
17824            (imm12'9,
17825             (imm12'8,
17826              (imm12'7,
17827               (imm12'6,
17828                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
17829       let
17830         val W = BitsN.fromBitstring([W'0],1)
17831       in
17832         if Do(ThumbCondition (),
17833               if W = (BitsN.B(0x1,1))
17834                 then HaveMPExt ()
17835               else HaveThumb2 ())
17836           then let
17837                  val imm32 =
17838                    BitsN.zeroExtend 32
17839                      (BitsN.fromBitstring
17840                         ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
17841                           imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
17842                           imm12'1,imm12'0],12))
17843                  val add = true
17844                  val is_pldw = W = (BitsN.B(0x1,1))
17845                in
17846                  Hint
17847                    (PreloadData
17848                       (add,
17849                        (is_pldw,
17850                         (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),
17851                          immediate_form1 imm32))))
17852                end
17853         else Skip ()
17854       end
17855     | ((true,
17856       (true,
17857        (true,
17858         (true,
17859          (true,
17860           (false,
17861            (false,
17862             (true,(_,(false,(true,(true,(true,(true,(true,true))))))))))))))),
17863      (true,(true,(true,(true,_))))) => NoOperation
17864     | ((true,
17865       (true,
17866        (true,
17867         (true,
17868          (true,
17869           (false,
17870            (false,
17871             (S'0,(U'0,(false,(H'0,(true,(true,(true,(true,true))))))))))))))),
17872      (Rt'3,
17873       (Rt'2,
17874        (Rt'1,
17875         (Rt'0,
17876          (imm12'11,
17877           (imm12'10,
17878            (imm12'9,
17879             (imm12'8,
17880              (imm12'7,
17881               (imm12'6,
17882                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
17883       let
17884         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
17885       in
17886         if Do(ThumbCondition (),HaveThumb2 ())
17887           then ( if Rt = (BitsN.B(0xD,4))
17888                    then DECODE_UNPREDICTABLE
17889                           (mc,"LoadByteLiteral/LoadHalfLiteral")
17890                  else ()
17891                ; let
17892                    val imm32 =
17893                      BitsN.zeroExtend 32
17894                        (BitsN.fromBitstring
17895                           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
17896                             imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
17897                             imm12'1,imm12'0],12))
17898                    val add =
17899                      (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
17900                    val unsigned =
17901                      (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x0,1))
17902                  in
17903                    if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
17904                      then Load
17905                             (LoadHalfLiteral(unsigned,(add,(Rt,imm32))))
17906                    else Load(LoadByteLiteral(unsigned,(add,(Rt,imm32))))
17907                  end
17908                )
17909         else Skip ()
17910       end
17911     | ((true,
17912       (true,
17913        (true,
17914         (true,
17915          (true,
17916           (false,
17917            (false,
17918             (false,(U'0,(true,(false,(true,(true,(true,(true,true))))))))))))))),
17919      (Rt'3,
17920       (Rt'2,
17921        (Rt'1,
17922         (Rt'0,
17923          (imm12'11,
17924           (imm12'10,
17925            (imm12'9,
17926             (imm12'8,
17927              (imm12'7,
17928               (imm12'6,
17929                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
17930       let
17931         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
17932       in
17933         if Do(ThumbCondition (),HaveThumb2 ())
17934           then ( if (Rt = (BitsN.B(0xF,4))) andalso
17935                     ((InITBlock ()) andalso (not(LastInITBlock ())))
17936                    then DECODE_UNPREDICTABLE(mc,"LoadLiteral")
17937                  else ()
17938                ; let
17939                    val imm32 =
17940                      BitsN.zeroExtend 32
17941                        (BitsN.fromBitstring
17942                           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
17943                             imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
17944                             imm12'1,imm12'0],12))
17945                    val add =
17946                      (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
17947                  in
17948                    Load(LoadLiteral(add,(Rt,imm32)))
17949                  end
17950                )
17951         else Skip ()
17952       end
17953     | ((true,
17954       (true,
17955        (true,
17956         (true,
17957          (true,
17958           (false,
17959            (false,
17960             (S'0,(true,(false,(H'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
17961      (Rt'3,
17962       (Rt'2,
17963        (Rt'1,
17964         (Rt'0,
17965          (imm12'11,
17966           (imm12'10,
17967            (imm12'9,
17968             (imm12'8,
17969              (imm12'7,
17970               (imm12'6,
17971                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
17972       let
17973         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
17974         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
17975       in
17976         if Do(ThumbCondition (),HaveThumb2 ())
17977           then ( if Rt = (BitsN.B(0xD,4))
17978                    then DECODE_UNPREDICTABLE
17979                           (mc,"LoadByte/LoadHalf (immediate)")
17980                  else ()
17981                ; let
17982                    val add = true
17983                    val index = true
17984                    val wback = false
17985                    val imm32 =
17986                      BitsN.zeroExtend 32
17987                        (BitsN.fromBitstring
17988                           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
17989                             imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
17990                             imm12'1,imm12'0],12))
17991                    val m = immediate_form1 imm32
17992                    val unsigned =
17993                      (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x0,1))
17994                  in
17995                    if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
17996                      then Load
17997                             (LoadHalf
17998                                (unsigned,
17999                                 (add,(index,(wback,(Rt,(Rn,m)))))))
18000                    else Load
18001                           (LoadByte
18002                              (unsigned,(add,(index,(wback,(Rt,(Rn,m)))))))
18003                  end
18004                )
18005         else Skip ()
18006       end
18007     | ((true,
18008       (true,
18009        (true,
18010         (true,
18011          (true,
18012           (false,
18013            (false,
18014             (false,(true,(true,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18015      (Rt'3,
18016       (Rt'2,
18017        (Rt'1,
18018         (Rt'0,
18019          (imm12'11,
18020           (imm12'10,
18021            (imm12'9,
18022             (imm12'8,
18023              (imm12'7,
18024               (imm12'6,
18025                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
18026       let
18027         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18028       in
18029         if Do(ThumbCondition (),HaveThumb2 ())
18030           then ( if (Rt = (BitsN.B(0xF,4))) andalso
18031                     ((InITBlock ()) andalso (not(LastInITBlock ())))
18032                    then DECODE_UNPREDICTABLE(mc,"LoadWord")
18033                  else ()
18034                ; let
18035                    val add = true
18036                    val index = true
18037                    val wback = false
18038                    val imm32 =
18039                      BitsN.zeroExtend 32
18040                        (BitsN.fromBitstring
18041                           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
18042                             imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
18043                             imm12'1,imm12'0],12))
18044                    val m = immediate_form1 imm32
18045                  in
18046                    Load
18047                      (LoadWord
18048                         (add,
18049                          (index,
18050                           (wback,
18051                            (Rt,
18052                             (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),
18053                              m))))))
18054                  end
18055                )
18056         else Skip ()
18057       end
18058     | ((true,
18059       (true,
18060        (true,
18061         (true,
18062          (true,
18063           (false,
18064            (false,
18065             (false,(false,(false,(W'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18066      (true,
18067       (true,
18068        (true,
18069         (true,
18070          (true,
18071           (true,
18072            (false,
18073             (false,
18074              (imm8'7,
18075               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18076       let
18077         val W = BitsN.fromBitstring([W'0],1)
18078       in
18079         if Do(ThumbCondition (),
18080               if W = (BitsN.B(0x1,1))
18081                 then HaveMPExt ()
18082               else HaveThumb2 ())
18083           then let
18084                  val imm32 =
18085                    BitsN.zeroExtend 32
18086                      (BitsN.fromBitstring
18087                         ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18088                           imm8'1,imm8'0],8))
18089                  val add = false
18090                  val is_pldw = W = (BitsN.B(0x1,1))
18091                in
18092                  Hint
18093                    (PreloadData
18094                       (add,
18095                        (is_pldw,
18096                         (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),
18097                          immediate_form1 imm32))))
18098                end
18099         else Skip ()
18100       end
18101     | ((true,
18102       (true,
18103        (true,
18104         (true,
18105          (true,
18106           (false,
18107            (false,
18108             (true,
18109              (false,(false,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18110      (true,
18111       (true,
18112        (true,
18113         (true,
18114          (true,
18115           (true,
18116            (false,
18117             (false,
18118              (imm8'7,
18119               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18120       (if Do(ThumbCondition (),Nat.>=(ArchVersion (),7))
18121          then let
18122                 val imm32 =
18123                   BitsN.zeroExtend 32
18124                     (BitsN.fromBitstring
18125                        ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18126                          imm8'1,imm8'0],8))
18127                 val add = false
18128               in
18129                 Hint
18130                   (PreloadInstruction
18131                      (add,
18132                       (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),
18133                        immediate_form1 imm32)))
18134               end
18135        else Skip ())
18136     | ((true,
18137       (true,
18138        (true,
18139         (true,(true,(false,(false,(_,(false,(false,(_,(true,_)))))))))))),
18140      (_,(_,(_,(_,(true,(false,(_,(false,_))))))))) =>
18141       Undefined(BitsN.B(0x0,32))
18142     | ((true,
18143       (true,
18144        (true,
18145         (true,
18146          (true,
18147           (false,
18148            (false,
18149             (S'0,(false,(false,(H'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18150      (Rt'3,
18151       (Rt'2,
18152        (Rt'1,
18153         (Rt'0,
18154          (true,
18155           (true,
18156            (true,
18157             (false,
18158              (imm8'7,
18159               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18160       let
18161         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18162         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18163       in
18164         if Do(ThumbCondition (),HaveThumb2 ())
18165           then ( if Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
18166                    then DECODE_UNPREDICTABLE(mc,"LoadUnprivileged")
18167                  else ()
18168                ; let
18169                    val add = true
18170                    val postindex = false
18171                    val unsigned =
18172                      (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x0,1))
18173                    val imm32 =
18174                      BitsN.zeroExtend 32
18175                        (BitsN.fromBitstring
18176                           ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18177                             imm8'1,imm8'0],8))
18178                    val m = immediate_form2 imm32
18179                  in
18180                    if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
18181                      then Load
18182                             (LoadHalfUnprivileged
18183                                (unsigned,(add,(postindex,(Rt,(Rn,m))))))
18184                    else if unsigned
18185                      then Load
18186                             (LoadByteUnprivileged
18187                                (add,
18188                                 (postindex,
18189                                  (Rt,(Rn,immediate_form1 imm32)))))
18190                    else Load
18191                           (LoadSignedByteUnprivileged
18192                              (add,(postindex,(Rt,(Rn,m)))))
18193                  end
18194                )
18195         else Skip ()
18196       end
18197     | ((true,
18198       (true,
18199        (true,
18200         (true,
18201          (true,(false,(false,(true,(false,(false,(true,(true,_)))))))))))),
18202      (true,(true,(true,(true,(true,(true,(false,(false,_))))))))) =>
18203       NoOperation
18204     | ((true,
18205       (true,
18206        (true,
18207         (true,
18208          (true,
18209           (false,
18210            (false,
18211             (S'0,(false,(false,(H'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18212      (Rt'3,
18213       (Rt'2,
18214        (Rt'1,
18215         (Rt'0,
18216          (true,
18217           (P'0,
18218            (U'0,
18219             (W'0,
18220              (imm8'7,
18221               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18222       let
18223         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18224         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18225       in
18226         if Do(ThumbCondition (),HaveThumb2 ())
18227           then let
18228                  val wback =
18229                    (BitsN.fromBitstring([W'0],1)) = (BitsN.B(0x1,1))
18230                in
18231                  ( if (Rt = (BitsN.B(0xD,4))) orelse
18232                       (((Rt = (BitsN.B(0xF,4))) andalso wback) orelse
18233                        (wback andalso (Rn = Rt)))
18234                      then DECODE_UNPREDICTABLE(mc,"Load (immediate)")
18235                    else ()
18236                  ; let
18237                      val add =
18238                        (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
18239                      val index =
18240                        (BitsN.fromBitstring([P'0],1)) = (BitsN.B(0x1,1))
18241                      val unsigned =
18242                        (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x0,1))
18243                      val imm32 =
18244                        BitsN.zeroExtend 32
18245                          (BitsN.fromBitstring
18246                             ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18247                               imm8'1,imm8'0],8))
18248                      val m = immediate_form1 imm32
18249                    in
18250                      if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
18251                        then Load
18252                               (LoadHalf
18253                                  (unsigned,
18254                                   (add,(index,(wback,(Rt,(Rn,m)))))))
18255                      else Load
18256                             (LoadByte
18257                                (unsigned,
18258                                 (add,(index,(wback,(Rt,(Rn,m)))))))
18259                    end
18260                  )
18261                end
18262         else Skip ()
18263       end
18264     | ((true,
18265       (true,
18266        (true,
18267         (true,
18268          (true,
18269           (false,
18270            (false,
18271             (false,
18272              (false,(true,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18273      (Rt'3,
18274       (Rt'2,
18275        (Rt'1,
18276         (Rt'0,
18277          (true,
18278           (true,
18279            (true,
18280             (false,
18281              (imm8'7,
18282               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18283       let
18284         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18285       in
18286         if Do(ThumbCondition (),HaveThumb2 ())
18287           then ( if Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
18288                    then DECODE_UNPREDICTABLE(mc,"LoadUnprivileged")
18289                  else ()
18290                ; let
18291                    val add = true
18292                    val postindex = false
18293                    val imm32 =
18294                      BitsN.zeroExtend 32
18295                        (BitsN.fromBitstring
18296                           ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18297                             imm8'1,imm8'0],8))
18298                    val m = immediate_form1 imm32
18299                  in
18300                    Load
18301                      (LoadUnprivileged
18302                         (add,
18303                          (postindex,
18304                           (Rt,
18305                            (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),
18306                             m)))))
18307                  end
18308                )
18309         else Skip ()
18310       end
18311     | ((true,
18312       (true,
18313        (true,
18314         (true,
18315          (true,
18316           (false,
18317            (false,
18318             (false,
18319              (false,(true,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18320      (Rt'3,
18321       (Rt'2,
18322        (Rt'1,
18323         (Rt'0,
18324          (true,
18325           (P'0,
18326            (U'0,
18327             (W'0,
18328              (imm8'7,
18329               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18330       let
18331         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18332         val W = BitsN.fromBitstring([W'0],1)
18333         val P = BitsN.fromBitstring([P'0],1)
18334         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18335       in
18336         if Do(ThumbCondition (),
18337               ((P = (BitsN.B(0x1,1))) orelse (W = (BitsN.B(0x1,1)))) andalso
18338               (HaveThumb2 ()))
18339           then let
18340                  val wback = W = (BitsN.B(0x1,1))
18341                in
18342                  ( if (wback andalso (Rn = Rt)) orelse
18343                       ((Rt = (BitsN.B(0xF,4))) andalso
18344                        ((InITBlock ()) andalso (not(LastInITBlock ()))))
18345                      then DECODE_UNPREDICTABLE(mc,"LoadWord")
18346                    else ()
18347                  ; let
18348                      val add =
18349                        (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
18350                      val index = P = (BitsN.B(0x1,1))
18351                      val imm32 =
18352                        BitsN.zeroExtend 32
18353                          (BitsN.fromBitstring
18354                             ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18355                               imm8'1,imm8'0],8))
18356                      val m = immediate_form1 imm32
18357                    in
18358                      Load(LoadWord(add,(index,(wback,(Rt,(Rn,m))))))
18359                    end
18360                  )
18361                end
18362         else Skip ()
18363       end
18364     | ((true,
18365       (true,
18366        (true,
18367         (true,
18368          (true,
18369           (false,
18370            (false,
18371             (false,(false,(false,(W'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18372      (true,
18373       (true,
18374        (true,
18375         (true,
18376          (false,
18377           (false,
18378            (false,
18379             (false,
18380              (false,(false,(imm2'1,(imm2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
18381       let
18382         val W = BitsN.fromBitstring([W'0],1)
18383         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
18384       in
18385         if Do(ThumbCondition (),
18386               if W = (BitsN.B(0x1,1))
18387                 then HaveMPExt ()
18388               else HaveThumb2 ())
18389           then ( if Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
18390                    then DECODE_UNPREDICTABLE(mc,"PreloadData")
18391                  else ()
18392                ; let
18393                    val add = true
18394                    val is_pldw = W = (BitsN.B(0x1,1))
18395                    val (shift_t,shift_n) =
18396                      (SRType_LSL,
18397                       BitsN.toNat(BitsN.fromBitstring([imm2'1,imm2'0],2)))
18398                    val m = register_form1(Rm,(shift_t,shift_n))
18399                  in
18400                    Hint
18401                      (PreloadData
18402                         (add,
18403                          (is_pldw,
18404                           (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),m))))
18405                  end
18406                )
18407         else Skip ()
18408       end
18409     | ((true,
18410       (true,
18411        (true,
18412         (true,
18413          (true,
18414           (false,
18415            (false,
18416             (true,
18417              (false,(false,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18418      (true,
18419       (true,
18420        (true,
18421         (true,
18422          (false,
18423           (false,
18424            (false,
18425             (false,
18426              (false,(false,(imm2'1,(imm2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
18427       let
18428         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
18429       in
18430         if Do(ThumbCondition (),Nat.>=(ArchVersion (),7))
18431           then ( if Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
18432                    then DECODE_UNPREDICTABLE(mc,"PreloadInstruction")
18433                  else ()
18434                ; let
18435                    val add = true
18436                    val (shift_t,shift_n) =
18437                      (SRType_LSL,
18438                       BitsN.toNat(BitsN.fromBitstring([imm2'1,imm2'0],2)))
18439                    val m = register_form1(Rm,(shift_t,shift_n))
18440                  in
18441                    Hint
18442                      (PreloadInstruction
18443                         (add,
18444                          (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),m)))
18445                  end
18446                )
18447         else Skip ()
18448       end
18449     | ((true,
18450       (true,
18451        (true,
18452         (true,
18453          (true,(false,(false,(true,(false,(false,(true,(true,_)))))))))))),
18454      (true,
18455       (true,
18456        (true,(true,(false,(false,(false,(false,(false,(false,_))))))))))) =>
18457       NoOperation
18458     | ((true,
18459       (true,
18460        (true,
18461         (true,
18462          (true,
18463           (false,
18464            (false,
18465             (S'0,(false,(false,(H'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18466      (Rt'3,
18467       (Rt'2,
18468        (Rt'1,
18469         (Rt'0,
18470          (false,
18471           (false,
18472            (false,
18473             (false,
18474              (false,(false,(imm2'1,(imm2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
18475       let
18476         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18477         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
18478         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18479       in
18480         if Do(ThumbCondition (),HaveThumb2 ())
18481           then ( if (Rt = (BitsN.B(0xD,4))) orelse
18482                     (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))
18483                    then DECODE_UNPREDICTABLE(mc,"Load (register)")
18484                  else ()
18485                ; let
18486                    val add = true
18487                    val index = true
18488                    val wback = false
18489                    val unsigned =
18490                      (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x0,1))
18491                    val (shift_t,shift_n) =
18492                      (SRType_LSL,
18493                       BitsN.toNat(BitsN.fromBitstring([imm2'1,imm2'0],2)))
18494                    val m = register_form1(Rm,(shift_t,shift_n))
18495                  in
18496                    if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
18497                      then Load
18498                             (LoadHalf
18499                                (unsigned,
18500                                 (add,(index,(wback,(Rt,(Rn,m)))))))
18501                    else Load
18502                           (LoadByte
18503                              (unsigned,(add,(index,(wback,(Rt,(Rn,m)))))))
18504                  end
18505                )
18506         else Skip ()
18507       end
18508     | ((true,
18509       (true,
18510        (true,
18511         (true,
18512          (true,
18513           (false,
18514            (false,
18515             (false,
18516              (false,(true,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18517      (Rt'3,
18518       (Rt'2,
18519        (Rt'1,
18520         (Rt'0,
18521          (false,
18522           (false,
18523            (false,
18524             (false,
18525              (false,(false,(imm2'1,(imm2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
18526       let
18527         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
18528         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18529       in
18530         if Do(ThumbCondition (),HaveThumb2 ())
18531           then ( if ((Rt = (BitsN.B(0xF,4))) andalso
18532                      ((InITBlock ()) andalso (not(LastInITBlock ())))) orelse
18533                     (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))
18534                    then DECODE_UNPREDICTABLE(mc,"LoadWord")
18535                  else ()
18536                ; let
18537                    val add = true
18538                    val index = true
18539                    val wback = false
18540                    val (shift_t,shift_n) =
18541                      (SRType_LSL,
18542                       BitsN.toNat(BitsN.fromBitstring([imm2'1,imm2'0],2)))
18543                    val m = register_form1(Rm,(shift_t,shift_n))
18544                  in
18545                    Load
18546                      (LoadWord
18547                         (add,
18548                          (index,
18549                           (wback,
18550                            (Rt,
18551                             (BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4),
18552                              m))))))
18553                  end
18554                )
18555         else Skip ()
18556       end
18557     | ((true,
18558       (true,
18559        (true,
18560         (true,
18561          (true,
18562           (false,
18563            (false,
18564             (false,
18565              (false,(true,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18566      (Rt'3,
18567       (Rt'2,
18568        (Rt'1,
18569         (Rt'0,
18570          (false,
18571           (false,
18572            (false,
18573             (false,
18574              (false,(false,(imm2'1,(imm2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
18575       let
18576         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18577         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
18578         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18579       in
18580         if Do(ThumbCondition (),
18581               (not(Rn = (BitsN.B(0xF,4)))) andalso (HaveThumb2 ()))
18582           then ( if (Rt = (BitsN.B(0xF,4))) orelse
18583                     (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))
18584                    then DECODE_UNPREDICTABLE(mc,"Store (register)")
18585                  else ()
18586                ; let
18587                    val add = true
18588                    val index = true
18589                    val wback = false
18590                    val (shift_t,shift_n) =
18591                      (SRType_LSL,
18592                       BitsN.toNat(BitsN.fromBitstring([imm2'1,imm2'0],2)))
18593                    val m = register_form1(Rm,(shift_t,shift_n))
18594                  in
18595                    Store(StoreWord(add,(index,(wback,(Rt,(Rn,m))))))
18596                  end
18597                )
18598         else Skip ()
18599       end
18600     | ((true,
18601       (true,
18602        (true,
18603         (true,
18604          (true,
18605           (false,
18606            (false,
18607             (false,
18608              (false,(false,(H'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18609      (Rt'3,
18610       (Rt'2,
18611        (Rt'1,
18612         (Rt'0,
18613          (false,
18614           (false,
18615            (false,
18616             (false,
18617              (false,(false,(imm2'1,(imm2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
18618       let
18619         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18620         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
18621         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18622       in
18623         if Do(ThumbCondition (),
18624               (not(Rn = (BitsN.B(0xF,4)))) andalso (HaveThumb2 ()))
18625           then ( if (Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
18626                     (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)]))
18627                    then DECODE_UNPREDICTABLE
18628                           (mc,"StoreByte/Half (register)")
18629                  else ()
18630                ; let
18631                    val add = true
18632                    val index = true
18633                    val wback = false
18634                    val (shift_t,shift_n) =
18635                      (SRType_LSL,
18636                       BitsN.toNat(BitsN.fromBitstring([imm2'1,imm2'0],2)))
18637                    val m = register_form1(Rm,(shift_t,shift_n))
18638                  in
18639                    if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
18640                      then Store
18641                             (StoreHalf(add,(index,(wback,(Rt,(Rn,m))))))
18642                    else Store(StoreByte(add,(index,(wback,(Rt,(Rn,m))))))
18643                  end
18644                )
18645         else Skip ()
18646       end
18647     | ((true,
18648       (true,
18649        (true,
18650         (true,
18651          (true,
18652           (false,
18653            (false,
18654             (false,
18655              (false,(true,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18656      (Rt'3,
18657       (Rt'2,
18658        (Rt'1,
18659         (Rt'0,
18660          (true,
18661           (true,
18662            (true,
18663             (false,
18664              (imm8'7,
18665               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18666       let
18667         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18668         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18669       in
18670         if Do(ThumbCondition (),
18671               (not(Rn = (BitsN.B(0xF,4)))) andalso (HaveThumb2 ()))
18672           then ( if Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
18673                    then DECODE_UNPREDICTABLE(mc,"StoreUnprivileged")
18674                  else ()
18675                ; let
18676                    val add = true
18677                    val postindex = false
18678                    val imm32 =
18679                      BitsN.zeroExtend 32
18680                        (BitsN.fromBitstring
18681                           ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18682                             imm8'1,imm8'0],8))
18683                    val m = immediate_form1 imm32
18684                  in
18685                    Store(StoreUnprivileged(add,(postindex,(Rt,(Rn,m)))))
18686                  end
18687                )
18688         else Skip ()
18689       end
18690     | ((true,
18691       (true,
18692        (true,
18693         (true,
18694          (true,
18695           (false,
18696            (false,
18697             (false,
18698              (false,(false,(H'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18699      (Rt'3,
18700       (Rt'2,
18701        (Rt'1,
18702         (Rt'0,
18703          (true,
18704           (true,
18705            (true,
18706             (false,
18707              (imm8'7,
18708               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18709       let
18710         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18711         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18712       in
18713         if Do(ThumbCondition (),
18714               (not(Rn = (BitsN.B(0xF,4)))) andalso (HaveThumb2 ()))
18715           then ( if Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
18716                    then DECODE_UNPREDICTABLE
18717                           (mc,"StoreByte/HalfUnprivileged")
18718                  else ()
18719                ; let
18720                    val add = true
18721                    val postindex = false
18722                    val imm32 =
18723                      BitsN.zeroExtend 32
18724                        (BitsN.fromBitstring
18725                           ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18726                             imm8'1,imm8'0],8))
18727                    val m1 = immediate_form1 imm32
18728                    val m2 = immediate_form2 imm32
18729                  in
18730                    if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
18731                      then Store
18732                             (StoreHalfUnprivileged
18733                                (add,(postindex,(Rt,(Rn,m2)))))
18734                    else Store
18735                           (StoreByteUnprivileged
18736                              (add,(postindex,(Rt,(Rn,m1)))))
18737                  end
18738                )
18739         else Skip ()
18740       end
18741     | ((true,
18742       (true,
18743        (true,
18744         (true,
18745          (true,
18746           (false,
18747            (false,
18748             (false,
18749              (false,(true,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18750      (Rt'3,
18751       (Rt'2,
18752        (Rt'1,
18753         (Rt'0,
18754          (true,
18755           (P'0,
18756            (U'0,
18757             (W'0,
18758              (imm8'7,
18759               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18760       let
18761         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18762         val W = BitsN.fromBitstring([W'0],1)
18763         val P = BitsN.fromBitstring([P'0],1)
18764         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18765       in
18766         if Do(ThumbCondition (),
18767               (not(Rn = (BitsN.B(0xF,4)))) andalso
18768               (((P = (BitsN.B(0x1,1))) orelse (W = (BitsN.B(0x1,1)))) andalso
18769                (HaveThumb2 ())))
18770           then let
18771                  val wback = W = (BitsN.B(0x1,1))
18772                in
18773                  ( if (Rt = (BitsN.B(0xF,4))) orelse
18774                       (wback andalso (Rn = Rt))
18775                      then DECODE_UNPREDICTABLE(mc,"Store (immediate)")
18776                    else ()
18777                  ; let
18778                      val add =
18779                        (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
18780                      val index = P = (BitsN.B(0x1,1))
18781                      val imm32 =
18782                        BitsN.zeroExtend 32
18783                          (BitsN.fromBitstring
18784                             ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18785                               imm8'1,imm8'0],8))
18786                      val m = immediate_form1 imm32
18787                    in
18788                      Store(StoreWord(add,(index,(wback,(Rt,(Rn,m))))))
18789                    end
18790                  )
18791                end
18792         else Skip ()
18793       end
18794     | ((true,
18795       (true,
18796        (true,
18797         (true,
18798          (true,
18799           (false,
18800            (false,
18801             (false,
18802              (false,(false,(H'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18803      (Rt'3,
18804       (Rt'2,
18805        (Rt'1,
18806         (Rt'0,
18807          (true,
18808           (P'0,
18809            (U'0,
18810             (W'0,
18811              (imm8'7,
18812               (imm8'6,(imm8'5,(imm8'4,(imm8'3,(imm8'2,(imm8'1,imm8'0)))))))))))))))) =>
18813       let
18814         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18815         val W = BitsN.fromBitstring([W'0],1)
18816         val P = BitsN.fromBitstring([P'0],1)
18817         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18818       in
18819         if Do(ThumbCondition (),
18820               (not(Rn = (BitsN.B(0xF,4)))) andalso
18821               (((P = (BitsN.B(0x1,1))) orelse (W = (BitsN.B(0x1,1)))) andalso
18822                (HaveThumb2 ())))
18823           then let
18824                  val wback = W = (BitsN.B(0x1,1))
18825                in
18826                  ( if (Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
18827                       (wback andalso (Rn = Rt))
18828                      then DECODE_UNPREDICTABLE
18829                             (mc,"StoreByte/Half (immediate)")
18830                    else ()
18831                  ; let
18832                      val add =
18833                        (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
18834                      val index = P = (BitsN.B(0x1,1))
18835                      val imm32 =
18836                        BitsN.zeroExtend 32
18837                          (BitsN.fromBitstring
18838                             ([imm8'7,imm8'6,imm8'5,imm8'4,imm8'3,imm8'2,
18839                               imm8'1,imm8'0],8))
18840                      val m = immediate_form1 imm32
18841                    in
18842                      if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
18843                        then Store
18844                               (StoreHalf(add,(index,(wback,(Rt,(Rn,m))))))
18845                      else Store
18846                             (StoreByte(add,(index,(wback,(Rt,(Rn,m))))))
18847                    end
18848                  )
18849                end
18850         else Skip ()
18851       end
18852     | ((true,
18853       (true,
18854        (true,
18855         (true,
18856          (true,
18857           (false,
18858            (false,
18859             (false,
18860              (true,(true,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18861      (Rt'3,
18862       (Rt'2,
18863        (Rt'1,
18864         (Rt'0,
18865          (imm12'11,
18866           (imm12'10,
18867            (imm12'9,
18868             (imm12'8,
18869              (imm12'7,
18870               (imm12'6,
18871                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
18872       let
18873         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18874         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18875       in
18876         if Do(ThumbCondition (),
18877               (not(Rn = (BitsN.B(0xF,4)))) andalso (HaveThumb2 ()))
18878           then ( if Rt = (BitsN.B(0xF,4))
18879                    then DECODE_UNPREDICTABLE(mc,"Store (immediate)")
18880                  else ()
18881                ; let
18882                    val add = true
18883                    val index = true
18884                    val wback = false
18885                    val imm32 =
18886                      BitsN.zeroExtend 32
18887                        (BitsN.fromBitstring
18888                           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
18889                             imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
18890                             imm12'1,imm12'0],12))
18891                    val m = immediate_form1 imm32
18892                  in
18893                    Store(StoreWord(add,(index,(wback,(Rt,(Rn,m))))))
18894                  end
18895                )
18896         else Skip ()
18897       end
18898     | ((true,
18899       (true,
18900        (true,
18901         (true,
18902          (true,
18903           (false,
18904            (false,
18905             (false,(true,(false,(H'0,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18906      (Rt'3,
18907       (Rt'2,
18908        (Rt'1,
18909         (Rt'0,
18910          (imm12'11,
18911           (imm12'10,
18912            (imm12'9,
18913             (imm12'8,
18914              (imm12'7,
18915               (imm12'6,
18916                (imm12'5,(imm12'4,(imm12'3,(imm12'2,(imm12'1,imm12'0)))))))))))))))) =>
18917       let
18918         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18919         val Rt = BitsN.fromBitstring([Rt'3,Rt'2,Rt'1,Rt'0],4)
18920       in
18921         if Do(ThumbCondition (),
18922               (not(Rn = (BitsN.B(0xF,4)))) andalso (HaveThumb2 ()))
18923           then ( if Set.mem(Rt,[BitsN.B(0xD,4),BitsN.B(0xF,4)])
18924                    then DECODE_UNPREDICTABLE
18925                           (mc,"StoreByte/Half (immediate)")
18926                  else ()
18927                ; let
18928                    val add = true
18929                    val index = true
18930                    val wback = false
18931                    val imm32 =
18932                      BitsN.zeroExtend 32
18933                        (BitsN.fromBitstring
18934                           ([imm12'11,imm12'10,imm12'9,imm12'8,imm12'7,
18935                             imm12'6,imm12'5,imm12'4,imm12'3,imm12'2,
18936                             imm12'1,imm12'0],12))
18937                    val m = immediate_form1 imm32
18938                  in
18939                    if (BitsN.fromBitstring([H'0],1)) = (BitsN.B(0x1,1))
18940                      then Store
18941                             (StoreHalf(add,(index,(wback,(Rt,(Rn,m))))))
18942                    else Store(StoreByte(add,(index,(wback,(Rt,(Rn,m))))))
18943                  end
18944                )
18945         else Skip ()
18946       end
18947     | ((true,
18948       (true,
18949        (true,
18950         (true,
18951          (true,
18952           (false,
18953            (true,
18954             (false,(false,(op'1,(op'0,(S'0,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18955      (true,
18956       (true,
18957        (true,
18958         (true,
18959          (Rd'3,
18960           (Rd'2,
18961            (Rd'1,
18962             (Rd'0,
18963              (false,(false,(false,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
18964       let
18965         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
18966         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
18967         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
18968       in
18969         if Do(ThumbCondition (),HaveThumb2 ())
18970           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
18971                     ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
18972                      (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])))
18973                    then DECODE_UNPREDICTABLE(mc,"Shift (register)")
18974                  else ()
18975                ; let
18976                    val setflags =
18977                      (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
18978                    val shift_t =
18979                      DecodeRegShift(BitsN.fromBitstring([op'1,op'0],2))
18980                  in
18981                    Data
18982                      (ShiftRegister
18983                         (false,(setflags,(Rd,(Rn,(shift_t,Rm))))))
18984                  end
18985                )
18986         else Skip ()
18987       end
18988     | ((true,
18989       (true,
18990        (true,
18991         (true,
18992          (true,
18993           (false,
18994            (true,
18995             (false,(false,(op'1,(op'0,(U'0,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
18996      (true,
18997       (true,
18998        (true,
18999         (true,
19000          (Rd'3,
19001           (Rd'2,
19002            (Rd'1,
19003             (Rd'0,
19004              (true,
19005               (sb'0'0'0,(rotate'1,(rotate'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
19006       let
19007         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
19008         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
19009         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
19010         val GOOD_MATCH =
19011           (BitsN.fromBitstring([sb'0'0'0],1)) = (BitsN.B(0x0,1))
19012       in
19013         if Do(ThumbCondition (),HaveThumb2 ())
19014           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19015                     ((Rn = (BitsN.B(0xD,4))) orelse
19016                      ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19017                       (not GOOD_MATCH)))
19018                    then DECODE_UNPREDICTABLE(mc,"Extend (register)")
19019                  else ()
19020                ; let
19021                    val unsigned =
19022                      (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
19023                    val rotation =
19024                      BitsN.toNat
19025                        (BitsN.@@
19026                           (BitsN.fromBitstring([rotate'1,rotate'0],2),
19027                            BitsN.B(0x0,3)))
19028                    val args = (unsigned,(Rd,(Rn,(Rm,rotation))))
19029                  in
19030                    case BitsN.fromBitstring([op'1,op'0],2) of
19031                       BitsN.B(0x0,_) => Media(ExtendHalfword args)
19032                     | BitsN.B(0x1,_) => Media(ExtendByte16 args)
19033                     | BitsN.B(0x2,_) => Media(ExtendByte args)
19034                     | BitsN.B(0x3,_) => Undefined(BitsN.B(0x0,32))
19035                     | _ => raise General.Bind
19036                  end
19037                )
19038         else Skip ()
19039       end
19040     | ((true,
19041       (true,
19042        (true,
19043         (true,
19044          (true,
19045           (false,
19046            (true,
19047             (false,
19048              (true,(op1'2,(op1'1,(op1'0,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
19049      (true,
19050       (true,
19051        (true,
19052         (true,
19053          (Rd'3,
19054           (Rd'2,
19055            (Rd'1,
19056             (Rd'0,(false,(U'0,(op2'1,(op2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
19057       let
19058         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
19059         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
19060         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
19061       in
19062         if Do(ThumbCondition (),HaveThumb2 ())
19063           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19064                     ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19065                      (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])))
19066                    then DECODE_UNPREDICTABLE
19067                           (mc,"Parallel addition and subtraction")
19068                  else ()
19069                ; let
19070                    val opc =
19071                      case BitsN.fromBitstring([op1'2,op1'1,op1'0],3) of
19072                         BitsN.B(0x1,_) => BitsN.B(0x0,3)
19073                       | BitsN.B(0x2,_) => BitsN.B(0x1,3)
19074                       | BitsN.B(0x6,_) => BitsN.B(0x2,3)
19075                       | BitsN.B(0x5,_) => BitsN.B(0x3,3)
19076                       | BitsN.B(0x0,_) => BitsN.B(0x4,3)
19077                       | BitsN.B(0x4,_) => BitsN.B(0x7,3)
19078                       | _ => BitsN.B(0x5,3)
19079                  in
19080                    DecodeParallelAdditionSubtraction
19081                      (BitsN.+
19082                         (BitsN.fromBitstring([op2'1,op2'0],2),
19083                          BitsN.B(0x1,2)),
19084                       (opc,(BitsN.fromBitstring([U'0],1),(Rd,(Rn,Rm)))))
19085                  end
19086                )
19087         else Skip ()
19088       end
19089     | ((true,
19090       (true,
19091        (true,
19092         (true,
19093          (true,
19094           (false,
19095            (true,
19096             (false,
19097              (true,(false,(false,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
19098      (true,
19099       (true,
19100        (true,
19101         (true,
19102          (Rd'3,
19103           (Rd'2,
19104            (Rd'1,
19105             (Rd'0,
19106              (true,(false,(op2'1,(op2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
19107       let
19108         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
19109         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
19110         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
19111       in
19112         if Do(ThumbCondition (),HaveThumb2 ())
19113           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19114                     ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19115                      (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])))
19116                    then DECODE_UNPREDICTABLE(mc,"SaturatingAddSubtract")
19117                  else ()
19118                ; let
19119                    val opc =
19120                      BitsN.reverse(BitsN.fromBitstring([op2'1,op2'0],2))
19121                  in
19122                    Media(SaturatingAddSubtract(opc,(Rd,(Rm,Rn))))
19123                  end
19124                )
19125         else Skip ()
19126       end
19127     | ((true,
19128       (true,
19129        (true,
19130         (true,
19131          (true,
19132           (false,
19133            (true,
19134             (false,
19135              (true,(false,(false,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
19136      (true,
19137       (true,
19138        (true,
19139         (true,
19140          (Rd'3,
19141           (Rd'2,
19142            (Rd'1,
19143             (Rd'0,
19144              (true,(false,(op2'1,(op2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
19145       let
19146         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
19147         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
19148       in
19149         if Do(ThumbCondition (),HaveThumb2 ())
19150           then ( if (not((BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)) =
19151                          Rm)) orelse
19152                     ((Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19153                      (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])))
19154                    then DECODE_UNPREDICTABLE(mc,"Reverses")
19155                  else ()
19156                ; case BitsN.fromBitstring([op2'1,op2'0],2) of
19157                     BitsN.B(0x0,_) => Media(ByteReverse(Rd,Rm))
19158                   | BitsN.B(0x1,_) =>
19159                     Media(ByteReversePackedHalfword(Rd,Rm))
19160                   | BitsN.B(0x2,_) => Media(ReverseBits(Rd,Rm))
19161                   | BitsN.B(0x3,_) =>
19162                     Media(ByteReverseSignedHalfword(Rd,Rm))
19163                   | _ => raise General.Bind
19164                )
19165         else Skip ()
19166       end
19167     | ((true,
19168       (true,
19169        (true,
19170         (true,
19171          (true,
19172           (false,
19173            (true,
19174             (false,
19175              (true,(false,(true,(false,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
19176      (true,
19177       (true,
19178        (true,
19179         (true,
19180          (Rd'3,
19181           (Rd'2,
19182            (Rd'1,
19183             (Rd'0,
19184              (true,(false,(false,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
19185       let
19186         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
19187         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
19188         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
19189       in
19190         if Do(ThumbCondition (),HaveThumb2 ())
19191           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19192                     ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19193                      (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])))
19194                    then DECODE_UNPREDICTABLE(mc,"SelectBytes")
19195                  else ()
19196                ; Media(SelectBytes(Rd,(Rn,Rm)))
19197                )
19198         else Skip ()
19199       end
19200     | ((true,
19201       (true,
19202        (true,
19203         (true,
19204          (true,
19205           (false,
19206            (true,
19207             (false,(true,(false,(true,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
19208      (true,
19209       (true,
19210        (true,
19211         (true,
19212          (Rd'3,
19213           (Rd'2,
19214            (Rd'1,
19215             (Rd'0,
19216              (true,(false,(false,(false,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
19217       let
19218         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
19219         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
19220       in
19221         if Do(ThumbCondition (),HaveThumb2 ())
19222           then ( if (not((BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)) =
19223                          Rm)) orelse
19224                     ((Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19225                      (Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])))
19226                    then DECODE_UNPREDICTABLE(mc,"CountLeadingZeroes")
19227                  else ()
19228                ; Data(CountLeadingZeroes(Rd,Rm))
19229                )
19230         else Skip ()
19231       end
19232     | ((true,
19233       (true,
19234        (true,
19235         (true,
19236          (true,
19237           (false,
19238            (true,
19239             (true,
19240              (false,(opc'2,(opc'1,(opc'0,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
19241      (Ra'3,
19242       (Ra'2,
19243        (Ra'1,
19244         (Ra'0,
19245          (Rd'3,
19246           (Rd'2,
19247            (Rd'1,
19248             (Rd'0,(false,(false,(N'0,(M'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
19249       let
19250         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
19251         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
19252         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
19253         val Ra = BitsN.fromBitstring([Ra'3,Ra'2,Ra'1,Ra'0],4)
19254       in
19255         if Do(ThumbCondition (),HaveThumb2 ())
19256           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19257                     ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19258                      ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19259                       (Ra = (BitsN.B(0xD,4)))))
19260                    then DECODE_UNPREDICTABLE
19261                           (mc,"Multiplies and absolute difference")
19262                  else ()
19263                ; case (BitsN.fromBitstring([opc'2,opc'1,opc'0],3),
19264                   (Ra,
19265                    ((BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x1,1)),
19266                     (BitsN.fromBitstring([M'0],1)) = (BitsN.B(0x1,1))))) of
19267                     (BitsN.B(0x0,_),(BitsN.B(0xF,_),(false,false))) =>
19268                       Multiply(Multiply32(false,(Rd,(Rn,Rm))))
19269                   | (BitsN.B(0x0,_),(_,(false,false))) =>
19270                     Multiply(MultiplyAccumulate(false,(Rd,(Rn,(Rm,Ra)))))
19271                   | (BitsN.B(0x0,_),(BitsN.B(0xF,_),(false,true))) =>
19272                     ( DECODE_UNPREDICTABLE(mc,"MultiplySubtract")
19273                     ; Branch(BranchExchange(BitsN.B(0x0,4)))
19274                     )
19275                   | (BitsN.B(0x0,_),(_,(false,true))) =>
19276                     Multiply(MultiplySubtract(Rd,(Rn,(Rm,Ra))))
19277                   | (BitsN.B(0x1,_),(BitsN.B(0xF,_),(n_high,m_high))) =>
19278                     Multiply
19279                       (Signed16Multiply32Result
19280                          (m_high,(n_high,(Rd,(Rn,Rm)))))
19281                   | (BitsN.B(0x1,_),(_,(n_high,m_high))) =>
19282                     Multiply
19283                       (Signed16Multiply32Accumulate
19284                          (m_high,(n_high,(Rd,(Rn,(Rm,Ra))))))
19285                   | (BitsN.B(0x2,_),(_,(false,m_swap))) =>
19286                     Multiply
19287                       (SignedMultiplyDual
19288                          (false,(m_swap,(Rd,(Rn,(Rm,Ra))))))
19289                   | (BitsN.B(0x3,_),(BitsN.B(0xF,_),(false,m_high))) =>
19290                     Multiply
19291                       (Signed16x32Multiply32Result(m_high,(Rd,(Rn,Rm))))
19292                   | (BitsN.B(0x3,_),(_,(false,m_high))) =>
19293                     Multiply
19294                       (Signed16x32Multiply32Accumulate
19295                          (m_high,(Rd,(Rn,(Rm,Ra)))))
19296                   | (BitsN.B(0x4,_),(_,(false,m_swap))) =>
19297                     Multiply
19298                       (SignedMultiplyDual
19299                          (true,(m_swap,(Rd,(Rn,(Rm,Ra))))))
19300                   | (BitsN.B(0x5,_),(_,(false,round))) =>
19301                     Multiply
19302                       (SignedMostSignificantMultiply
19303                          (round,(Rd,(Rn,(Rm,Ra)))))
19304                   | (BitsN.B(0x6,_),(BitsN.B(0xF,_),(false,_))) =>
19305                     ( DECODE_UNPREDICTABLE
19306                         (mc,"SignedMostSignificantMultiplySubtract")
19307                     ; Branch(BranchExchange(BitsN.B(0x0,4)))
19308                     )
19309                   | (BitsN.B(0x6,_),(_,(false,round))) =>
19310                     Multiply
19311                       (SignedMostSignificantMultiplySubtract
19312                          (round,(Rd,(Rn,(Rm,Ra)))))
19313                   | (BitsN.B(0x7,_),(_,(false,false))) =>
19314                     SIMD(UnsignedSumAbsoluteDifferences(Rd,(Rn,(Rm,Ra))))
19315                   | _ => Undefined(BitsN.B(0x0,32))
19316                )
19317         else Skip ()
19318       end
19319     | ((true,
19320       (true,
19321        (true,
19322         (true,
19323          (true,
19324           (false,
19325            (true,
19326             (true,(true,(false,(U'0,(true,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
19327      (sb'0'1111'3,
19328       (sb'0'1111'2,
19329        (sb'0'1111'1,
19330         (sb'0'1111'0,
19331          (Rd'3,
19332           (Rd'2,
19333            (Rd'1,
19334             (Rd'0,(true,(true,(true,(true,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
19335       let
19336         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
19337         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
19338         val Rd = BitsN.fromBitstring([Rd'3,Rd'2,Rd'1,Rd'0],4)
19339         val GOOD_MATCH =
19340           (BitsN.fromBitstring
19341              ([sb'0'1111'3,sb'0'1111'2,sb'0'1111'1,sb'0'1111'0],4)) =
19342           (BitsN.B(0xF,4))
19343       in
19344         if Do(ThumbCondition (),
19345               (HaveVirtExt ()) orelse ((!Architecture) = ARMv7_R))
19346           then ( if (Set.mem(Rd,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19347                     ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19348                      ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19349                       (not GOOD_MATCH)))
19350                    then DECODE_UNPREDICTABLE(mc,"Divide")
19351                  else ()
19352                ; let
19353                    val unsigned =
19354                      (BitsN.fromBitstring([U'0],1)) = (BitsN.B(0x1,1))
19355                  in
19356                    Divide(unsigned,(Rd,(Rn,Rm)))
19357                  end
19358                )
19359         else Skip ()
19360       end
19361     | ((true,
19362       (true,
19363        (true,
19364         (true,
19365          (true,
19366           (false,
19367            (true,
19368             (true,
19369              (true,(op1'2,(op1'1,(op1'0,(Rn'3,(Rn'2,(Rn'1,Rn'0))))))))))))))),
19370      (RdLo'3,
19371       (RdLo'2,
19372        (RdLo'1,
19373         (RdLo'0,
19374          (RdHi'3,
19375           (RdHi'2,
19376            (RdHi'1,
19377             (RdHi'0,
19378              (op2'3,(op2'2,(op2'1,(op2'0,(Rm'3,(Rm'2,(Rm'1,Rm'0)))))))))))))))) =>
19379       let
19380         val Rn = BitsN.fromBitstring([Rn'3,Rn'2,Rn'1,Rn'0],4)
19381         val Rm = BitsN.fromBitstring([Rm'3,Rm'2,Rm'1,Rm'0],4)
19382         val RdHi = BitsN.fromBitstring([RdHi'3,RdHi'2,RdHi'1,RdHi'0],4)
19383         val RdLo = BitsN.fromBitstring([RdLo'3,RdLo'2,RdLo'1,RdLo'0],4)
19384       in
19385         if Do(ThumbCondition (),HaveThumb2 ())
19386           then ( if (Set.mem(RdLo,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19387                     ((Set.mem(RdHi,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19388                      ((Set.mem(Rn,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19389                       ((Set.mem(Rm,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) orelse
19390                        (RdHi = RdLo))))
19391                    then DECODE_UNPREDICTABLE
19392                           (mc,"Long multiply, long multiply accumulate")
19393                  else ()
19394                ; case (boolify'3
19395                     (BitsN.fromBitstring([op1'2,op1'1,op1'0],3)),
19396                   boolify'4
19397                     (BitsN.fromBitstring([op2'3,op2'2,op2'1,op2'0],4))) of
19398                     ((A'0,(U'0,false)),(false,(false,(false,false)))) =>
19399                       let
19400                         val accumulate =
19401                           (BitsN.fromBitstring([A'0],1)) =
19402                           (BitsN.B(0x1,1))
19403                         val signed =
19404                           (BitsN.fromBitstring([U'0],1)) =
19405                           (BitsN.B(0x0,1))
19406                       in
19407                         Multiply
19408                           (MultiplyLong
19409                              (accumulate,
19410                               (signed,(false,(RdHi,(RdLo,(Rn,Rm)))))))
19411                       end
19412                   | ((true,(false,false)),(true,(false,(N'0,M'0)))) =>
19413                     let
19414                       val n_high =
19415                         (BitsN.fromBitstring([N'0],1)) = (BitsN.B(0x1,1))
19416                       val m_high =
19417                         (BitsN.fromBitstring([M'0],1)) = (BitsN.B(0x1,1))
19418                     in
19419                       Multiply
19420                         (Signed16Multiply64Accumulate
19421                            (m_high,(n_high,(RdHi,(RdLo,(Rn,Rm))))))
19422                     end
19423                   | ((true,(false,S'0)),(true,(true,(false,M'0)))) =>
19424                     let
19425                       val sub =
19426                         (BitsN.fromBitstring([S'0],1)) = (BitsN.B(0x1,1))
19427                       val m_swap =
19428                         (BitsN.fromBitstring([M'0],1)) = (BitsN.B(0x1,1))
19429                     in
19430                       Multiply
19431                         (SignedMultiplyLongDual
19432                            (sub,(m_swap,(RdHi,(RdLo,(Rn,Rm))))))
19433                     end
19434                   | ((true,(true,false)),(false,(true,(true,false)))) =>
19435                     Multiply
19436                       (MultiplyAccumulateAccumulate(RdHi,(RdLo,(Rn,Rm))))
19437                   | _ => Undefined(BitsN.B(0x0,32))
19438                )
19439         else Skip ()
19440       end
19441     | _ => UndefinedThumb ()
19442  end;
19443
19444fun Decode mc =
19445  case mc of
19446     ARM w => DecodeARM w
19447   | Thumb h => DecodeThumb h
19448   | ThumbEE h => DecodeThumbEE h
19449   | Thumb2 hs => DecodeThumb2 hs
19450   | BadCode s => raise UNPREDICTABLE s;
19451
19452fun Next () = ( Run(Decode(Fetch ())); ITAdvance () );
19453
19454fun EncodeThumbImmediate x =
19455  let
19456    val x0 = x
19457    val b3 = BitsN.bits(31,24) x0
19458    val b2 = BitsN.bits(23,16) x0
19459    val b1 = BitsN.bits(15,8) x0
19460    val b0 = BitsN.bits(7,0) x0
19461  in
19462    case (b3 = (BitsN.B(0x0,8)),
19463     (b2 = (BitsN.B(0x0,8)),(b1 = (BitsN.B(0x0,8)),b0 = (BitsN.B(0x0,8))))) of
19464       (true,(true,(true,_))) => Option.SOME(BitsN.@@(BitsN.B(0x0,4),b0))
19465     | (true,(false,(true,false))) =>
19466       if b2 = b0 then Option.SOME(BitsN.@@(BitsN.B(0x1,4),b0)) else NONE
19467     | (false,(true,(false,true))) =>
19468       if b3 = b1 then Option.SOME(BitsN.@@(BitsN.B(0x2,4),b1)) else NONE
19469     | (false,(false,(false,false))) =>
19470       if (b3 = b2) andalso ((b2 = b1) andalso (b1 = b0))
19471         then Option.SOME(BitsN.@@(BitsN.B(0x3,4),b0))
19472       else NONE
19473     | _ =>
19474       let
19475         val m = BitsN.toNat(BitsN.log2 x)
19476         val n = BitsN.#>>(x,Nat.-(Nat.+(m,1),8))
19477       in
19478         if BitsN.<+(n,BitsN.B(0x100,32))
19479           then Option.SOME
19480                  (BitsN.@@
19481                     (BitsN.+
19482                        (BitsN.-(BitsN.B(0x1F,5),BitsN.fromNat(m,5)),
19483                         BitsN.B(0x8,5)),BitsN.bits(6,0) n))
19484         else NONE
19485       end
19486  end;
19487
19488fun EncodeARMImmediate_aux (n,x) =
19489  if (BitsN.bits(31,8) x) = (BitsN.B(0x0,24))
19490    then Option.SOME
19491           (BitsN.@@(BitsN.-(BitsN.B(0xF,4),n),BitsN.bits(7,0) x))
19492  else if n = (BitsN.B(0x0,4))
19493    then NONE
19494  else EncodeARMImmediate_aux(BitsN.-(n,BitsN.B(0x1,4)),BitsN.#<<(x,2));
19495
19496fun EncodeARMImmediate x = EncodeARMImmediate_aux(BitsN.B(0xF,4),x);
19497
19498fun EncodeImmShift (shift_t,shift_n) =
19499  case shift_t of
19500     SRType_LSL => (BitsN.B(0x0,2),BitsN.fromNat(shift_n,5))
19501   | SRType_LSR =>
19502     (BitsN.B(0x1,2),
19503      if shift_n = 32 then BitsN.B(0x0,5) else BitsN.fromNat(shift_n,5))
19504   | SRType_ASR =>
19505     (BitsN.B(0x2,2),
19506      if shift_n = 32 then BitsN.B(0x0,5) else BitsN.fromNat(shift_n,5))
19507   | SRType_ROR => (BitsN.B(0x3,2),BitsN.fromNat(shift_n,5))
19508   | SRType_RRX => (BitsN.B(0x3,2),BitsN.B(0x0,5));
19509
19510fun EncodeRegShift shift_t =
19511  case shift_t of
19512     SRType_LSL => BitsN.B(0x0,2)
19513   | SRType_LSR => BitsN.B(0x1,2)
19514   | SRType_ASR => BitsN.B(0x2,2)
19515   | SRType_ROR => BitsN.B(0x3,2)
19516   | SRType_RRX => BitsN.B(0x0,2);
19517
19518fun EncodeAddSubOpc opc =
19519  case opc of
19520     BitsN.B(0x0,_) => BitsN.B(0x1,3)
19521   | BitsN.B(0x1,_) => BitsN.B(0x2,3)
19522   | BitsN.B(0x2,_) => BitsN.B(0x6,3)
19523   | BitsN.B(0x3,_) => BitsN.B(0x5,3)
19524   | _ => raise General.Bind;
19525
19526fun EncodeVFPImmediate (imm64,single_register) =
19527  if single_register
19528    then if ((BitsN.bits(18,0) imm64) = (BitsN.B(0x0,19))) andalso
19529            ((Set.mem
19530                (BitsN.bits(29,25) imm64,[BitsN.B(0x0,5),BitsN.B(0x1F,5)])) andalso
19531             ((not((BitsN.bit(imm64,25)) = (BitsN.bit(imm64,30)))) andalso
19532              ((BitsN.bits(63,32) imm64) = (BitsN.B(0x0,32)))))
19533           then Option.SOME
19534                  (BitsN.concat
19535                     [BitsN.bits(31,31) imm64,BitsN.bits(25,25) imm64,
19536                      BitsN.bits(24,19) imm64])
19537         else NONE
19538  else if ((BitsN.bits(47,0) imm64) = (BitsN.B(0x0,48))) andalso
19539     ((Set.mem(BitsN.bits(61,54) imm64,[BitsN.B(0x0,8),BitsN.B(0xFF,8)])) andalso
19540      (not((BitsN.bit(imm64,61)) = (BitsN.bit(imm64,62)))))
19541    then Option.SOME
19542           (BitsN.concat
19543              [BitsN.bits(63,63) imm64,BitsN.bits(54,54) imm64,
19544               BitsN.bits(53,48) imm64])
19545  else NONE;
19546
19547fun EncodeVFPReg (d,single_register) =
19548  if single_register
19549    then (BitsN.bits(0,0) d,BitsN.bits(4,1) d)
19550  else (BitsN.bits(4,4) d,BitsN.bits(3,0) d);
19551
19552fun e_branch (c,(ast,e)) =
19553  case ast of
19554     BranchTarget imm32 =>
19555       (if e = Enc_ARM
19556          then if (BitsN.<=(BitsN.neg(BitsN.B(0x2000000,32)),imm32)) andalso
19557                  ((BitsN.<=(imm32,BitsN.B(0x1FFFFFC,32))) andalso
19558                   (Aligned 32 (imm32,4)))
19559                 then let
19560                        val imm24 = BitsN.bits(25,2) imm32
19561                      in
19562                        ARM(BitsN.concat[c,BitsN.B(0xA,4),imm24])
19563                      end
19564               else BadCode "B: bad offset"
19565        else if not(Aligned 32 (imm32,2))
19566          then BadCode "BranchTarget: bad offset"
19567        else if Set.mem(c,[BitsN.B(0xE,4),BitsN.B(0xF,4)])
19568          then if (BitsN.<=(BitsN.neg(BitsN.B(0x800,32)),imm32)) andalso
19569                  ((BitsN.<=(imm32,BitsN.B(0x7FE,32))) andalso
19570                   (not(e = Enc_Wide)))
19571                 then let
19572                        val imm11 = BitsN.bits(11,1) imm32
19573                      in
19574                        Thumb(BitsN.@@(BitsN.B(0x1C,5),imm11))
19575                      end
19576               else if (BitsN.<=(BitsN.neg(BitsN.B(0x1000000,32)),imm32)) andalso
19577                  ((BitsN.<=(imm32,BitsN.B(0xFFFFFE,32))) andalso
19578                   (not(e = Enc_Narrow)))
19579                 then let
19580                        val S = BitsN.bits(24,24) imm32
19581                        val I1 = BitsN.bits(23,23) imm32
19582                        val I2 = BitsN.bits(22,22) imm32
19583                        val J1 = BitsN.fromBit(I1 = S)
19584                        val J2 = BitsN.fromBit(I2 = S)
19585                        val imm10 = BitsN.bits(21,12) imm32
19586                        val imm11 = BitsN.bits(11,1) imm32
19587                      in
19588                        Thumb2
19589                          (BitsN.concat[BitsN.B(0x1E,5),S,imm10],
19590                           BitsN.concat
19591                             [BitsN.B(0x2,2),J1,BitsN.B(0x1,1),J2,imm11])
19592                      end
19593               else BadCode "B: bad offset"
19594        else if (BitsN.<=(BitsN.neg(BitsN.B(0x100,32)),imm32)) andalso
19595           ((BitsN.<=(imm32,BitsN.B(0xFE,32))) andalso (not(e = Enc_Wide)))
19596          then let
19597                 val imm8 = BitsN.bits(8,1) imm32
19598               in
19599                 Thumb(BitsN.concat[BitsN.B(0xD,4),c,imm8])
19600               end
19601        else if (BitsN.<=(BitsN.neg(BitsN.B(0x100000,32)),imm32)) andalso
19602           ((BitsN.<=(imm32,BitsN.B(0xFFFFE,32))) andalso
19603            (not(e = Enc_Narrow)))
19604          then let
19605                 val S = BitsN.bits(20,20) imm32
19606                 val J2 = BitsN.bits(19,19) imm32
19607                 val J1 = BitsN.bits(18,18) imm32
19608                 val imm6 = BitsN.bits(17,12) imm32
19609                 val imm11 = BitsN.bits(11,1) imm32
19610               in
19611                 Thumb2
19612                   (BitsN.concat[BitsN.B(0x1E,5),S,c,imm6],
19613                    BitsN.concat
19614                      [BitsN.B(0x2,2),J1,BitsN.B(0x0,1),J2,imm11])
19615               end
19616        else BadCode "B: bad offset")
19617   | BranchExchange Rm =>
19618     (if e = Enc_ARM
19619        then ARM(BitsN.concat[c,BitsN.B(0x12FFF1,24),Rm])
19620      else if not(e = Enc_Wide)
19621        then Thumb(BitsN.concat[BitsN.B(0x8E,9),Rm,BitsN.B(0x0,3)])
19622      else BadCode "no wide BX (register)")
19623   | BranchLinkExchangeImmediate(targetInstrSet,imm32) =>
19624     (if e = Enc_ARM
19625        then if c = (BitsN.B(0xE,4))
19626               then if targetInstrSet = InstrSet_ARM
19627                      then if (BitsN.<=
19628                                 (BitsN.neg(BitsN.B(0x2000000,32)),imm32)) andalso
19629                              ((BitsN.<=(imm32,BitsN.B(0x1FFFFFC,32))) andalso
19630                               (Aligned 32 (imm32,4)))
19631                             then let
19632                                    val imm24 = BitsN.bits(25,2) imm32
19633                                  in
19634                                    ARM(BitsN.concat
19635                                          [c,BitsN.B(0xB,4),imm24])
19636                                  end
19637                           else BadCode "BL: bad offset"
19638                    else if (BitsN.<=
19639                          (BitsN.neg(BitsN.B(0x2000000,32)),imm32)) andalso
19640                       ((BitsN.<=(imm32,BitsN.B(0x1FFFFFE,32))) andalso
19641                        (Aligned 32 (imm32,2)))
19642                      then let
19643                             val imm24 = BitsN.bits(25,2) imm32
19644                             val H = BitsN.bits(1,1) imm32
19645                           in
19646                             ARM(BitsN.concat[BitsN.B(0x7D,7),H,imm24])
19647                           end
19648                    else BadCode "BLX (immediate): bad offset"
19649             else BadCode "BLX (immediate)"
19650      else if targetInstrSet = InstrSet_ARM
19651        then if (BitsN.<=(BitsN.neg(BitsN.B(0x1000000,32)),imm32)) andalso
19652                ((BitsN.<=(imm32,BitsN.B(0xFFFFFC,32))) andalso
19653                 ((Aligned 32 (imm32,4)) andalso (not(e = Enc_Narrow))))
19654               then let
19655                      val S = BitsN.bits(24,24) imm32
19656                      val I1 = BitsN.bits(23,23) imm32
19657                      val I2 = BitsN.bits(22,22) imm32
19658                      val J1 = BitsN.fromBit(I1 = S)
19659                      val J2 = BitsN.fromBit(I2 = S)
19660                      val imm10H = BitsN.bits(21,12) imm32
19661                      val imm10L = BitsN.bits(11,2) imm32
19662                    in
19663                      Thumb2
19664                        (BitsN.concat[BitsN.B(0x1E,5),S,imm10H],
19665                         BitsN.concat
19666                           [BitsN.B(0x3,2),J1,BitsN.B(0x0,1),J2,imm10L,
19667                            BitsN.B(0x0,1)])
19668                    end
19669             else BadCode "BLX (immediate): bad offset"
19670      else if (BitsN.<=(BitsN.neg(BitsN.B(0x1000000,32)),imm32)) andalso
19671         ((BitsN.<=(imm32,BitsN.B(0xFFFFFE,32))) andalso
19672          ((Aligned 32 (imm32,2)) andalso (not(e = Enc_Narrow))))
19673        then let
19674               val S = BitsN.bits(24,24) imm32
19675               val I1 = BitsN.bits(23,23) imm32
19676               val I2 = BitsN.bits(22,22) imm32
19677               val J1 = BitsN.fromBit(I1 = S)
19678               val J2 = BitsN.fromBit(I2 = S)
19679               val imm10 = BitsN.bits(21,12) imm32
19680               val imm11 = BitsN.bits(11,1) imm32
19681             in
19682               Thumb2
19683                 (BitsN.concat[BitsN.B(0x1E,5),S,imm10],
19684                  BitsN.concat[BitsN.B(0x3,2),J1,BitsN.B(0x1,1),J2,imm11])
19685             end
19686      else BadCode "BL: bad offset")
19687   | BranchLinkExchangeRegister Rm =>
19688     (if e = Enc_ARM
19689        then ARM(BitsN.concat[c,BitsN.B(0x12FFF3,24),Rm])
19690      else if not(e = Enc_Wide)
19691        then Thumb(BitsN.concat[BitsN.B(0x8F,9),Rm,BitsN.B(0x0,3)])
19692      else BadCode "no wide BLX (register)")
19693   | CompareBranch(nonzero,(n,imm32)) =>
19694     (if (BitsN.<=+(imm32,BitsN.B(0x7E,32))) andalso
19695         ((Aligned 32 (imm32,2)) andalso
19696          ((not(BitsN.bit(n,3))) andalso
19697           (Set.mem(e,[Enc_Thumb,Enc_Narrow]))))
19698        then let
19699               val op' = BitsN.fromBit nonzero
19700               val i = BitsN.bits(6,6) imm32
19701               val imm5 = BitsN.bits(5,1) imm32
19702               val Rn = BitsN.bits(2,0) n
19703             in
19704               Thumb
19705                 (BitsN.concat
19706                    [BitsN.B(0xB,4),op',BitsN.B(0x0,1),i,BitsN.B(0x1,1),
19707                     imm5,Rn])
19708             end
19709      else BadCode "CBZ")
19710   | TableBranchByte(is_tbh,(Rm,Rn)) =>
19711     (if Set.mem(e,[Enc_Thumb,Enc_Wide])
19712        then let
19713               val H = BitsN.fromBit is_tbh
19714             in
19715               Thumb2
19716                 (BitsN.@@(BitsN.B(0xE8D,12),Rn),
19717                  BitsN.concat[BitsN.B(0x780,11),H,Rm])
19718             end
19719      else BadCode "CBZ")
19720   | CheckArray(Rm,n) =>
19721     (if Set.mem(e,[Enc_Thumb,Enc_Narrow])
19722        then let
19723               val N = BitsN.bits(3,3) n
19724               val Rn = BitsN.bits(2,0) n
19725             in
19726               ThumbEE(BitsN.concat[BitsN.B(0xCA,8),N,Rm,Rn])
19727             end
19728      else BadCode "CHKA")
19729   | HandlerBranchLink(generate_link,handler_offset) =>
19730     (if (BitsN.<=+(handler_offset,BitsN.B(0x1FE0,32))) andalso
19731         (((BitsN.bits(4,0) handler_offset) = (BitsN.B(0x0,5))) andalso
19732          (Set.mem(e,[Enc_Thumb,Enc_Narrow])))
19733        then let
19734               val L = BitsN.fromBit generate_link
19735               val handler = BitsN.bits(12,5) handler_offset
19736             in
19737               ThumbEE(BitsN.concat[BitsN.B(0x61,7),L,handler])
19738             end
19739      else BadCode "HB{L}")
19740   | HandlerBranchLinkParameter(imm32,handler_offset) =>
19741     (if (BitsN.<+(imm32,BitsN.B(0x20,32))) andalso
19742         ((BitsN.<=+(handler_offset,BitsN.B(0x3E0,32))) andalso
19743          (((BitsN.bits(4,0) handler_offset) = (BitsN.B(0x0,5))) andalso
19744           (Set.mem(e,[Enc_Thumb,Enc_Narrow]))))
19745        then let
19746               val imm5 = BitsN.bits(4,0) imm32
19747               val handler = BitsN.bits(9,5) handler_offset
19748             in
19749               ThumbEE(BitsN.concat[BitsN.B(0x31,6),imm5,handler])
19750             end
19751      else BadCode "HBLP")
19752   | HandlerBranchParameter(imm32,handler_offset) =>
19753     (if (BitsN.<+(imm32,BitsN.B(0x8,32))) andalso
19754         ((BitsN.<=+(handler_offset,BitsN.B(0x3E0,32))) andalso
19755          (((BitsN.bits(4,0) handler_offset) = (BitsN.B(0x0,5))) andalso
19756           (Set.mem(e,[Enc_Thumb,Enc_Narrow]))))
19757        then let
19758               val imm3 = BitsN.bits(2,0) imm32
19759               val handler = BitsN.bits(9,5) handler_offset
19760             in
19761               ThumbEE(BitsN.concat[BitsN.B(0xC0,8),imm3,handler])
19762             end
19763      else BadCode "CBZ");
19764
19765fun e_vfp (c,(ast,e)) =
19766  case ast of
19767     vmrs t =>
19768       (if e = Enc_ARM
19769          then ARM(BitsN.concat[c,BitsN.B(0xEF1,12),t,BitsN.B(0xA10,12)])
19770        else BadCode "VMRS")
19771   | vmsr t =>
19772     (if e = Enc_ARM
19773        then ARM(BitsN.concat[c,BitsN.B(0xEE1,12),t,BitsN.B(0xA10,12)])
19774      else BadCode "VMRS")
19775   | vcmp(dp_operation,(d,Option.SOME m)) =>
19776     (if e = Enc_ARM
19777        then let
19778               val (D,Vd) = EncodeVFPReg(d,not dp_operation)
19779               val (M,Vm) = EncodeVFPReg(m,not dp_operation)
19780             in
19781               ARM(BitsN.concat
19782                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x34,6),Vd,
19783                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,
19784                      BitsN.B(0x3,2),M,BitsN.B(0x0,1),Vm])
19785             end
19786      else BadCode "VCMP (register)")
19787   | vcmp(dp_operation,(d,NONE)) =>
19788     (if e = Enc_ARM
19789        then let
19790               val (D,Vd) = EncodeVFPReg(d,not dp_operation)
19791             in
19792               ARM(BitsN.concat
19793                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x35,6),Vd,
19794                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,
19795                      BitsN.B(0xC0,8)])
19796             end
19797      else BadCode "VCMP (zero)")
19798   | vcvt_float(double_to_single,(d,m)) =>
19799     (if e = Enc_ARM
19800        then let
19801               val (D,Vd) = EncodeVFPReg(d,double_to_single)
19802               val (M,Vm) = EncodeVFPReg(m,not double_to_single)
19803             in
19804               ARM(BitsN.concat
19805                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x37,6),Vd,
19806                      BitsN.B(0x5,3),BitsN.fromBit double_to_single,
19807                      BitsN.B(0x3,2),M,BitsN.B(0x0,1),Vm])
19808             end
19809      else BadCode "VCVT (float)")
19810   | vcvt_from_integer(dp_operation,(unsigned,(d,m))) =>
19811     (if e = Enc_ARM
19812        then let
19813               val (D,Vd) = EncodeVFPReg(d,not dp_operation)
19814               val (M,Vm) = EncodeVFPReg(m,true)
19815             in
19816               ARM(BitsN.concat
19817                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x38,6),Vd,
19818                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,
19819                      BitsN.fromBit(not unsigned),BitsN.B(0x1,1),M,
19820                      BitsN.B(0x0,1),Vm])
19821             end
19822      else BadCode "VCVT (from integer)")
19823   | vcvt_to_integer(dp_operation,(unsigned,(round_zero,(d,m)))) =>
19824     (if e = Enc_ARM
19825        then let
19826               val (D,Vd) = EncodeVFPReg(d,true)
19827               val (M,Vm) = EncodeVFPReg(m,not dp_operation)
19828             in
19829               ARM(BitsN.concat
19830                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x1E,5),
19831                      BitsN.fromBit(not unsigned),Vd,BitsN.B(0x5,3),
19832                      BitsN.fromBit dp_operation,BitsN.fromBit round_zero,
19833                      BitsN.B(0x1,1),M,BitsN.B(0x0,1),Vm])
19834             end
19835      else BadCode "VCVT (to integer)")
19836   | vmov_imm(single_register,(d,imm64)) =>
19837     (if e = Enc_ARM
19838        then case EncodeVFPImmediate(imm64,single_register) of
19839                Option.SOME v'0 =>
19840                  let
19841                    val (D,Vd) = EncodeVFPReg(d,single_register)
19842                  in
19843                    ARM(BitsN.concat
19844                          [c,BitsN.B(0x1D,5),D,BitsN.B(0x3,2),
19845                           BitsN.bits(7,4) v'0,Vd,BitsN.B(0x5,3),
19846                           BitsN.fromBit(not single_register),
19847                           BitsN.B(0x0,4),BitsN.bits(3,0) v'0])
19848                  end
19849              | NONE => BadCode "VMOV (immediate)"
19850      else BadCode "VMOV (immediate)")
19851   | vmov(single_register,(d,m)) =>
19852     (if e = Enc_ARM
19853        then let
19854               val (D,Vd) = EncodeVFPReg(d,single_register)
19855               val (M,Vm) = EncodeVFPReg(m,single_register)
19856             in
19857               ARM(BitsN.concat
19858                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x30,6),Vd,
19859                      BitsN.B(0x5,3),BitsN.fromBit(not single_register),
19860                      BitsN.B(0x1,2),M,BitsN.B(0x0,1),Vm])
19861             end
19862      else BadCode "VMOV")
19863   | vmov_single(to_arm_register,(t,n)) =>
19864     (if e = Enc_ARM
19865        then let
19866               val (N,Vn) = EncodeVFPReg(n,true)
19867             in
19868               ARM(BitsN.concat
19869                     [c,BitsN.B(0x70,7),BitsN.fromBit to_arm_register,Vn,
19870                      t,BitsN.B(0xA,4),N,BitsN.B(0x10,7)])
19871             end
19872      else BadCode "VMOV (single)")
19873   | vmov_two_singles(to_arm_registers,(t,(t2,m))) =>
19874     (if e = Enc_ARM
19875        then let
19876               val (M,Vm) = EncodeVFPReg(m,true)
19877             in
19878               ARM(BitsN.concat
19879                     [c,BitsN.B(0x62,7),BitsN.fromBit to_arm_registers,t2,
19880                      t,BitsN.B(0x28,6),M,BitsN.B(0x1,1),Vm])
19881             end
19882      else BadCode "VMOV (two singles)")
19883   | vmov_double(to_arm_registers,(t,(t2,m))) =>
19884     (if e = Enc_ARM
19885        then let
19886               val (M,Vm) = EncodeVFPReg(m,false)
19887             in
19888               ARM(BitsN.concat
19889                     [c,BitsN.B(0x62,7),BitsN.fromBit to_arm_registers,t2,
19890                      t,BitsN.B(0x2C,6),M,BitsN.B(0x1,1),Vm])
19891             end
19892      else BadCode "VMOV (double)")
19893   | vabs(dp_operation,(d,m)) =>
19894     (if e = Enc_ARM
19895        then let
19896               val (D,Vd) = EncodeVFPReg(d,not dp_operation)
19897               val (M,Vm) = EncodeVFPReg(m,not dp_operation)
19898             in
19899               ARM(BitsN.concat
19900                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x30,6),Vd,
19901                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,
19902                      BitsN.B(0x3,2),M,BitsN.B(0x0,1),Vm])
19903             end
19904      else BadCode "VABS")
19905   | vneg(dp_operation,(d,m)) =>
19906     (if e = Enc_ARM
19907        then let
19908               val (D,Vd) = EncodeVFPReg(d,not dp_operation)
19909               val (M,Vm) = EncodeVFPReg(m,not dp_operation)
19910             in
19911               ARM(BitsN.concat
19912                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x31,6),Vd,
19913                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,
19914                      BitsN.B(0x1,2),M,BitsN.B(0x0,1),Vm])
19915             end
19916      else BadCode "VNEG")
19917   | vsqrt(dp_operation,(d,m)) =>
19918     (if e = Enc_ARM
19919        then let
19920               val (D,Vd) = EncodeVFPReg(d,not dp_operation)
19921               val (M,Vm) = EncodeVFPReg(m,not dp_operation)
19922             in
19923               ARM(BitsN.concat
19924                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x31,6),Vd,
19925                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,
19926                      BitsN.B(0x3,2),M,BitsN.B(0x0,1),Vm])
19927             end
19928      else BadCode "VSQRT")
19929   | vadd(dp_operation,(d,(n,m))) =>
19930     (if e = Enc_ARM
19931        then let
19932               val single_register = not dp_operation
19933               val (D,Vd) = EncodeVFPReg(d,single_register)
19934               val (N,Vn) = EncodeVFPReg(n,single_register)
19935               val (M,Vm) = EncodeVFPReg(m,single_register)
19936             in
19937               ARM(BitsN.concat
19938                     [c,BitsN.B(0x1C,5),D,BitsN.B(0x3,2),Vn,Vd,
19939                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,N,
19940                      BitsN.B(0x0,1),M,BitsN.B(0x0,1),Vm])
19941             end
19942      else BadCode "VADD")
19943   | vsub(dp_operation,(d,(n,m))) =>
19944     (if e = Enc_ARM
19945        then let
19946               val single_register = not dp_operation
19947               val (D,Vd) = EncodeVFPReg(d,single_register)
19948               val (N,Vn) = EncodeVFPReg(n,single_register)
19949               val (M,Vm) = EncodeVFPReg(m,single_register)
19950             in
19951               ARM(BitsN.concat
19952                     [c,BitsN.B(0x1C,5),D,BitsN.B(0x3,2),Vn,Vd,
19953                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,N,
19954                      BitsN.B(0x1,1),M,BitsN.B(0x0,1),Vm])
19955             end
19956      else BadCode "VSUB")
19957   | vmul(dp_operation,(d,(n,m))) =>
19958     (if e = Enc_ARM
19959        then let
19960               val single_register = not dp_operation
19961               val (D,Vd) = EncodeVFPReg(d,single_register)
19962               val (N,Vn) = EncodeVFPReg(n,single_register)
19963               val (M,Vm) = EncodeVFPReg(m,single_register)
19964             in
19965               ARM(BitsN.concat
19966                     [c,BitsN.B(0x1C,5),D,BitsN.B(0x2,2),Vn,Vd,
19967                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,N,
19968                      BitsN.B(0x0,1),M,BitsN.B(0x0,1),Vm])
19969             end
19970      else BadCode "VMUL")
19971   | vdiv(dp_operation,(d,(n,m))) =>
19972     (if e = Enc_ARM
19973        then let
19974               val single_register = not dp_operation
19975               val (D,Vd) = EncodeVFPReg(d,single_register)
19976               val (N,Vn) = EncodeVFPReg(n,single_register)
19977               val (M,Vm) = EncodeVFPReg(m,single_register)
19978             in
19979               ARM(BitsN.concat
19980                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x0,2),Vn,Vd,
19981                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,N,
19982                      BitsN.B(0x0,1),M,BitsN.B(0x0,1),Vm])
19983             end
19984      else BadCode "VDIV")
19985   | vneg_mul(dp_operation,(typ,(d,(n,m)))) =>
19986     (if e = Enc_ARM
19987        then let
19988               val single_register = not dp_operation
19989               val (D,Vd) = EncodeVFPReg(d,single_register)
19990               val (N,Vn) = EncodeVFPReg(n,single_register)
19991               val (M,Vm) = EncodeVFPReg(m,single_register)
19992               val (op1,op2) =
19993                 case typ of
19994                    VFPNegMul_VNMUL => (BitsN.B(0x2,2),BitsN.B(0x1,1))
19995                  | VFPNegMul_VNMLA => (BitsN.B(0x1,2),BitsN.B(0x1,1))
19996                  | VFPNegMul_VNMLS => (BitsN.B(0x1,2),BitsN.B(0x0,1))
19997             in
19998               ARM(BitsN.concat
19999                     [c,BitsN.B(0x1C,5),D,op1,Vn,Vd,BitsN.B(0x5,3),
20000                      BitsN.fromBit dp_operation,N,op2,M,BitsN.B(0x0,1),Vm])
20001             end
20002      else BadCode "VNMUL")
20003   | vmla_vmls(dp_operation,(add,(d,(n,m)))) =>
20004     (if e = Enc_ARM
20005        then let
20006               val single_register = not dp_operation
20007               val (D,Vd) = EncodeVFPReg(d,single_register)
20008               val (N,Vn) = EncodeVFPReg(n,single_register)
20009               val (M,Vm) = EncodeVFPReg(m,single_register)
20010             in
20011               ARM(BitsN.concat
20012                     [c,BitsN.B(0x1C,5),D,BitsN.B(0x0,2),Vn,Vd,
20013                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,N,
20014                      BitsN.fromBit(not add),M,BitsN.B(0x0,1),Vm])
20015             end
20016      else BadCode "VMLA")
20017   | vfma_vfms(dp_operation,(add,(d,(n,m)))) =>
20018     (if e = Enc_ARM
20019        then let
20020               val single_register = not dp_operation
20021               val (D,Vd) = EncodeVFPReg(d,single_register)
20022               val (N,Vn) = EncodeVFPReg(n,single_register)
20023               val (M,Vm) = EncodeVFPReg(m,single_register)
20024             in
20025               ARM(BitsN.concat
20026                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x2,2),Vn,Vd,
20027                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,N,
20028                      BitsN.fromBit(not add),M,BitsN.B(0x0,1),Vm])
20029             end
20030      else BadCode "VFMA")
20031   | vfnma_vfnms(dp_operation,(add,(d,(n,m)))) =>
20032     (if e = Enc_ARM
20033        then let
20034               val single_register = not dp_operation
20035               val (D,Vd) = EncodeVFPReg(d,single_register)
20036               val (N,Vn) = EncodeVFPReg(n,single_register)
20037               val (M,Vm) = EncodeVFPReg(m,single_register)
20038             in
20039               ARM(BitsN.concat
20040                     [c,BitsN.B(0x1D,5),D,BitsN.B(0x1,2),Vn,Vd,
20041                      BitsN.B(0x5,3),BitsN.fromBit dp_operation,N,
20042                      BitsN.fromBit(not add),M,BitsN.B(0x0,1),Vm])
20043             end
20044      else BadCode "VFNMA")
20045   | vldr(single_register,(add,(d,(n,imm32)))) =>
20046     (if e = Enc_ARM
20047        then if (not((BitsN.bits(1,0) imm32) = (BitsN.B(0x0,2)))) orelse
20048                (not((BitsN.bits(31,10) imm32) = (BitsN.B(0x0,22))))
20049               then BadCode "VLDR: bad immediate"
20050             else let
20051                    val imm8 = BitsN.bits(9,2) imm32
20052                    val (D,Vd) = EncodeVFPReg(d,single_register)
20053                  in
20054                    ARM(BitsN.concat
20055                          [c,BitsN.B(0xD,4),BitsN.fromBit add,D,
20056                           BitsN.B(0x1,2),n,Vd,BitsN.B(0x5,3),
20057                           BitsN.fromBit(not single_register),imm8])
20058                  end
20059      else BadCode "VLDR")
20060   | vstr(single_register,(add,(d,(n,imm32)))) =>
20061     (if e = Enc_ARM
20062        then if (not((BitsN.bits(1,0) imm32) = (BitsN.B(0x0,2)))) orelse
20063                (not((BitsN.bits(31,10) imm32) = (BitsN.B(0x0,22))))
20064               then BadCode "VSTR: bad immediate"
20065             else let
20066                    val imm8 = BitsN.bits(9,2) imm32
20067                    val (D,Vd) = EncodeVFPReg(d,single_register)
20068                  in
20069                    ARM(BitsN.concat
20070                          [c,BitsN.B(0xD,4),BitsN.fromBit add,D,
20071                           BitsN.B(0x0,2),n,Vd,BitsN.B(0x5,3),
20072                           BitsN.fromBit(not single_register),imm8])
20073                  end
20074      else BadCode "VSTR")
20075   | vldm(single_regs,(add,(wback,(d,(n,imm8))))) =>
20076     (if e = Enc_ARM
20077        then let
20078               val (D,Vd) = EncodeVFPReg(d,single_regs)
20079             in
20080               ARM(BitsN.concat
20081                     [c,BitsN.B(0x6,3),
20082                      if add then BitsN.B(0x1,2) else BitsN.B(0x2,2),D,
20083                      BitsN.fromBit wback,BitsN.B(0x1,1),n,Vd,
20084                      BitsN.B(0x5,3),BitsN.fromBit(not single_regs),imm8])
20085             end
20086      else BadCode "VLDM")
20087   | vstm(single_regs,(add,(wback,(d,(n,imm8))))) =>
20088     (if e = Enc_ARM
20089        then let
20090               val (D,Vd) = EncodeVFPReg(d,single_regs)
20091             in
20092               ARM(BitsN.concat
20093                     [c,BitsN.B(0x6,3),
20094                      if add then BitsN.B(0x1,2) else BitsN.B(0x2,2),D,
20095                      BitsN.fromBit wback,BitsN.B(0x0,1),n,Vd,
20096                      BitsN.B(0x5,3),BitsN.fromBit(not single_regs),imm8])
20097             end
20098      else BadCode "VSTM");
20099
20100fun e_data (c,(ast,e)) =
20101  case ast of
20102     CountLeadingZeroes(Rd,Rm) =>
20103       (if e = Enc_ARM
20104          then ARM(BitsN.concat[c,BitsN.B(0x16F,12),Rd,BitsN.B(0xF1,8),Rm])
20105        else if not(e = Enc_Narrow)
20106          then Thumb2
20107                 (BitsN.@@(BitsN.B(0xFAB,12),Rm),
20108                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x8,4),Rm])
20109        else BadCode "CLZ")
20110   | MoveHalfword(high,(Rd,imm16)) =>
20111     let
20112       val H = BitsN.fromBit high
20113     in
20114       if e = Enc_ARM
20115         then let
20116                val imm4 = BitsN.bits(15,12) imm16
20117                val imm12 = BitsN.bits(11,0) imm16
20118              in
20119                ARM(BitsN.concat
20120                      [c,BitsN.B(0x6,5),H,BitsN.B(0x0,2),imm4,Rd,imm12])
20121              end
20122       else if not(e = Enc_Narrow)
20123         then let
20124                val imm4 = BitsN.bits(15,12) imm16
20125                val i = BitsN.bits(11,11) imm16
20126                val imm3 = BitsN.bits(10,8) imm16
20127                val imm8 = BitsN.bits(7,0) imm16
20128              in
20129                Thumb2
20130                  (BitsN.concat
20131                     [BitsN.B(0x1E,5),i,BitsN.B(0x2,2),H,BitsN.B(0x4,3),
20132                      imm4],BitsN.concat[BitsN.B(0x0,1),imm3,Rd,imm8])
20133              end
20134       else BadCode "MOVT/MOVW"
20135     end
20136   | Move(setflags,(negate,(d,imm12))) =>
20137     (if e = Enc_ARM
20138        then let
20139               val Rd = d
20140               val S = BitsN.fromBit setflags
20141               val N = BitsN.fromBit negate
20142             in
20143               ARM(BitsN.concat
20144                     [c,BitsN.B(0x7,5),N,BitsN.B(0x1,1),S,BitsN.B(0x0,4),
20145                      Rd,imm12])
20146             end
20147      else if ((BitsN.bits(11,8) imm12) = (BitsN.B(0x0,4))) andalso
20148         (not(negate orelse
20149              ((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
20150               ((BitsN.bit(d,3)) orelse (e = Enc_Wide)))))
20151        then let
20152               val Rd = BitsN.bits(2,0) d
20153               val imm8 = BitsN.bits(7,0) imm12
20154             in
20155               Thumb(BitsN.concat[BitsN.B(0x4,5),Rd,imm8])
20156             end
20157      else if not(e = Enc_Narrow)
20158        then let
20159               val Rd = d
20160               val S = BitsN.fromBit setflags
20161               val i = BitsN.bits(11,11) imm12
20162               val imm3 = BitsN.bits(10,8) imm12
20163               val imm8 = BitsN.bits(7,0) imm12
20164               val N = BitsN.fromBit negate
20165             in
20166               Thumb2
20167                 (BitsN.concat
20168                    [BitsN.B(0x1E,5),i,BitsN.B(0x1,4),N,S,BitsN.B(0xF,4)],
20169                  BitsN.concat[BitsN.B(0x0,1),imm3,Rd,imm8])
20170             end
20171      else BadCode "MOV")
20172   | AddSub(sub,(Rd,(Rn,imm12))) =>
20173     (if Set.mem(e,[Enc_Thumb,Enc_Wide])
20174        then let
20175               val i = BitsN.bits(11,11) imm12
20176               val imm3 = BitsN.bits(10,8) imm12
20177               val imm8 = BitsN.bits(7,0) imm12
20178               val S = BitsN.fromBit sub
20179             in
20180               Thumb2
20181                 (BitsN.concat
20182                    [BitsN.B(0x1E,5),i,BitsN.B(0x1,1),BitsN.B(0x0,1),S,
20183                     BitsN.B(0x0,1),S,BitsN.B(0x0,1),Rn],
20184                  BitsN.concat[BitsN.B(0x0,1),imm3,Rd,imm8])
20185             end
20186      else BadCode "ADDW/SUBW")
20187   | TestCompareImmediate(op',(Rn,imm12)) =>
20188     (if e = Enc_ARM
20189        then ARM(BitsN.concat
20190                   [c,BitsN.B(0x6,5),op',BitsN.B(0x1,1),Rn,BitsN.B(0x0,4),
20191                    imm12])
20192      else if (op' = (BitsN.B(0x2,2))) andalso
20193         (((BitsN.bits(11,8) imm12) = (BitsN.B(0x0,4))) andalso
20194          (not((BitsN.bit(Rn,3)) orelse (e = Enc_Wide))))
20195        then let
20196               val n = BitsN.bits(2,0) Rn
20197               val imm8 = BitsN.bits(7,0) imm12
20198             in
20199               Thumb(BitsN.concat[BitsN.B(0x5,5),n,imm8])
20200             end
20201      else if not(e = Enc_Narrow)
20202        then let
20203               val i = BitsN.bits(11,11) imm12
20204               val imm3 = BitsN.bits(10,8) imm12
20205               val imm8 = BitsN.bits(7,0) imm12
20206               val opc =
20207                 case op' of
20208                    BitsN.B(0x0,_) => BitsN.B(0x0,4)
20209                  | BitsN.B(0x1,_) => BitsN.B(0x4,4)
20210                  | BitsN.B(0x2,_) => BitsN.B(0xD,4)
20211                  | BitsN.B(0x3,_) => BitsN.B(0x8,4)
20212                  | _ => raise General.Bind
20213             in
20214               Thumb2
20215                 (BitsN.concat
20216                    [BitsN.B(0x1E,5),i,BitsN.B(0x0,1),opc,BitsN.B(0x1,1),
20217                     Rn],
20218                  BitsN.concat[BitsN.B(0x0,1),imm3,BitsN.B(0xF,4),imm8])
20219             end
20220      else BadCode "TestCompareImmediate")
20221   | ArithLogicImmediate(opc,(setflags,(d,(n,imm12)))) =>
20222     (if e = Enc_ARM
20223        then let
20224               val Rd = d
20225               val Rn = n
20226               val S = BitsN.fromBit setflags
20227             in
20228               ARM(BitsN.concat[c,BitsN.B(0x1,3),opc,S,Rn,Rd,imm12])
20229             end
20230      else if (Set.mem(opc,[BitsN.B(0x4,4),BitsN.B(0x2,4)])) andalso
20231         (((BitsN.bits(11,3) imm12) = (BitsN.B(0x0,9))) andalso
20232          (not((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
20233               ((BitsN.bit(d,3)) orelse
20234                ((BitsN.bit(n,3)) orelse (e = Enc_Wide))))))
20235        then let
20236               val Rd = BitsN.bits(2,0) d
20237               val Rn = BitsN.bits(2,0) n
20238               val imm3 = BitsN.bits(2,0) imm12
20239               val S = BitsN.bits(1,1) opc
20240             in
20241               Thumb(BitsN.concat[BitsN.B(0x7,6),S,imm3,Rn,Rd])
20242             end
20243      else if (Set.mem(opc,[BitsN.B(0x4,4),BitsN.B(0x2,4)])) andalso
20244         ((d = n) andalso
20245          (((BitsN.bits(11,8) imm12) = (BitsN.B(0x0,4))) andalso
20246           (not((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
20247                ((BitsN.bit(d,3)) orelse (e = Enc_Wide))))))
20248        then let
20249               val Rdn = BitsN.bits(2,0) d
20250               val imm8 = BitsN.bits(7,0) imm12
20251               val S = BitsN.bits(1,1) opc
20252             in
20253               Thumb(BitsN.concat[BitsN.B(0x3,4),S,Rdn,imm8])
20254             end
20255      else if (opc = (BitsN.B(0x3,4))) andalso
20256         ((imm12 = (BitsN.B(0x0,12))) andalso
20257          (not((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
20258               ((BitsN.bit(d,3)) orelse
20259                ((BitsN.bit(n,3)) orelse (e = Enc_Wide))))))
20260        then let
20261               val Rd = BitsN.bits(2,0) d
20262               val Rn = BitsN.bits(2,0) n
20263             in
20264               Thumb(BitsN.concat[BitsN.B(0x109,10),Rn,Rd])
20265             end
20266      else if (opc = (BitsN.B(0x4,4))) andalso
20267         ((not setflags) andalso
20268          ((Set.mem(n,[BitsN.B(0xD,4),BitsN.B(0xF,4)])) andalso
20269           (((BitsN.bits(11,8) imm12) = (BitsN.B(0xF,4))) andalso
20270            (not((BitsN.bit(d,3)) orelse (e = Enc_Wide))))))
20271        then let
20272               val Rd = BitsN.bits(2,0) d
20273               val imm8 = BitsN.bits(7,0) imm12
20274               val S = BitsN.fromBit(n = (BitsN.B(0xD,4)))
20275             in
20276               Thumb(BitsN.concat[BitsN.B(0xA,4),S,Rd,imm8])
20277             end
20278      else if (Set.mem(opc,[BitsN.B(0x4,4),BitsN.B(0x2,4)])) andalso
20279         ((d = (BitsN.B(0xD,4))) andalso
20280          ((n = (BitsN.B(0xD,4))) andalso
20281           (((BitsN.bits(11,7) imm12) = (BitsN.B(0x1E,5))) andalso
20282            (not(setflags orelse (e = Enc_Wide))))))
20283        then let
20284               val imm7 = BitsN.bits(6,0) imm12
20285               val S = BitsN.bits(1,1) opc
20286             in
20287               Thumb(BitsN.concat[BitsN.B(0xB0,8),S,imm7])
20288             end
20289      else if (opc = (BitsN.B(0x2,4))) andalso
20290         (setflags andalso
20291          ((d = (BitsN.B(0xF,4))) andalso
20292           ((n = (BitsN.B(0xE,4))) andalso
20293            (((BitsN.bits(11,8) imm12) = (BitsN.B(0x0,4))) andalso
20294             (not(e = Enc_Narrow))))))
20295        then let
20296               val imm8 = BitsN.bits(7,0) imm12
20297             in
20298               Thumb2(BitsN.B(0xF3DF,16),BitsN.@@(BitsN.B(0x8F,8),imm8))
20299             end
20300      else if not(e = Enc_Narrow)
20301        then let
20302               val Rd = d
20303               val Rn = n
20304               val i = BitsN.bits(11,11) imm12
20305               val imm3 = BitsN.bits(10,8) imm12
20306               val imm8 = BitsN.bits(7,0) imm12
20307               val S = BitsN.fromBit setflags
20308               val op' =
20309                 case opc of
20310                    BitsN.B(0x0,_) => BitsN.B(0x0,4)
20311                  | BitsN.B(0xE,_) => BitsN.B(0x1,4)
20312                  | BitsN.B(0xC,_) => BitsN.B(0x2,4)
20313                  | BitsN.B(0xF,_) => BitsN.B(0x3,4)
20314                  | BitsN.B(0x1,_) => BitsN.B(0x4,4)
20315                  | BitsN.B(0x4,_) => BitsN.B(0x8,4)
20316                  | BitsN.B(0x5,_) => BitsN.B(0xA,4)
20317                  | BitsN.B(0x6,_) => BitsN.B(0xB,4)
20318                  | BitsN.B(0x2,_) => BitsN.B(0xD,4)
20319                  | BitsN.B(0x3,_) => BitsN.B(0xE,4)
20320                  | _ => BitsN.B(0xF,4)
20321             in
20322               if op' = (BitsN.B(0xF,4))
20323                 then BadCode
20324                        ("ArithLogicImmediate: bad opc "
20325                           ^
20326                           (BitsN.toHexString opc))
20327               else Thumb2
20328                      (BitsN.concat
20329                         [BitsN.B(0x1E,5),i,BitsN.B(0x0,1),op',S,Rn],
20330                       BitsN.concat[BitsN.B(0x0,1),imm3,Rd,imm8])
20331             end
20332      else BadCode "ArithLogicImmediate")
20333   | Register(opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))) =>
20334     (if e = Enc_ARM
20335        then let
20336               val S = BitsN.fromBit setflags
20337               val Rd = d
20338               val Rn = n
20339               val Rm = m
20340               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
20341             in
20342               ARM(BitsN.concat
20343                     [c,BitsN.B(0x0,3),opc,S,Rn,Rd,imm5,typ,
20344                      BitsN.B(0x0,1),Rm])
20345             end
20346      else if (Set.mem(opc,[BitsN.B(0x2,4),BitsN.B(0x4,4)])) andalso
20347         ((shift_t = SRType_LSL) andalso
20348          ((shift_n = 0) andalso
20349           (not((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
20350                ((BitsN.bit(d,3)) orelse
20351                 ((BitsN.bit(n,3)) orelse
20352                  ((BitsN.bit(m,3)) orelse (e = Enc_Wide))))))))
20353        then let
20354               val Rn = BitsN.bits(2,0) n
20355               val Rd = BitsN.bits(2,0) d
20356               val Rm = BitsN.bits(2,0) m
20357               val S = BitsN.fromBit(opc = (BitsN.B(0x2,4)))
20358             in
20359               Thumb(BitsN.concat[BitsN.B(0x6,6),S,Rm,Rn,Rd])
20360             end
20361      else if (Set.mem
20362            (opc,
20363             [BitsN.B(0x0,4),BitsN.B(0x1,4),BitsN.B(0x5,4),BitsN.B(0x6,4),
20364              BitsN.B(0xC,4),BitsN.B(0xE,4)])) andalso
20365         ((d = n) andalso
20366          ((shift_t = SRType_LSL) andalso
20367           ((shift_n = 0) andalso
20368            (not((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
20369                 ((BitsN.bit(d,3)) orelse
20370                  ((BitsN.bit(m,3)) orelse (e = Enc_Wide))))))))
20371        then let
20372               val Rdn = BitsN.bits(2,0) d
20373               val Rm = BitsN.bits(2,0) m
20374             in
20375               Thumb(BitsN.concat[BitsN.B(0x10,6),opc,Rm,Rdn])
20376             end
20377      else if (opc = (BitsN.B(0x4,4))) andalso
20378         ((d = n) andalso
20379          ((not(setflags orelse (e = Enc_Wide))) andalso
20380           ((shift_t = SRType_LSL) andalso (shift_n = 0))))
20381        then let
20382               val DN = BitsN.bits(3,3) d
20383               val Rdn = BitsN.bits(2,0) d
20384               val Rm = m
20385             in
20386               Thumb(BitsN.concat[BitsN.B(0x44,8),DN,Rm,Rdn])
20387             end
20388      else if not(e = Enc_Narrow)
20389        then let
20390               val S = BitsN.fromBit setflags
20391               val Rd = d
20392               val Rn = n
20393               val Rm = m
20394               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
20395               val imm3 = BitsN.bits(4,2) imm5
20396               val imm2 = BitsN.bits(1,0) imm5
20397               val op' =
20398                 case opc of
20399                    BitsN.B(0x0,_) => BitsN.B(0x0,4)
20400                  | BitsN.B(0xE,_) => BitsN.B(0x1,4)
20401                  | BitsN.B(0xC,_) => BitsN.B(0x2,4)
20402                  | BitsN.B(0xF,_) => BitsN.B(0x3,4)
20403                  | BitsN.B(0x1,_) => BitsN.B(0x4,4)
20404                  | BitsN.B(0x4,_) => BitsN.B(0x8,4)
20405                  | BitsN.B(0x5,_) => BitsN.B(0xA,4)
20406                  | BitsN.B(0x6,_) => BitsN.B(0xB,4)
20407                  | BitsN.B(0x2,_) => BitsN.B(0xD,4)
20408                  | BitsN.B(0x3,_) => BitsN.B(0xE,4)
20409                  | _ => BitsN.B(0xF,4)
20410             in
20411               if op' = (BitsN.B(0xF,4))
20412                 then BadCode
20413                        ("Register: bad opc " ^ (BitsN.toHexString opc))
20414               else Thumb2
20415                      (BitsN.concat[BitsN.B(0x75,7),op',S,Rn],
20416                       BitsN.concat[BitsN.B(0x0,1),imm3,Rd,imm2,typ,Rm])
20417             end
20418      else BadCode "Register")
20419   | TestCompareRegister(opc,(n,(m,(shift_t,shift_n)))) =>
20420     (if e = Enc_ARM
20421        then let
20422               val Rn = n
20423               val Rm = m
20424               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
20425             in
20426               ARM(BitsN.concat
20427                     [c,BitsN.B(0x2,5),opc,BitsN.B(0x1,1),Rn,
20428                      BitsN.B(0x0,4),imm5,typ,BitsN.B(0x0,1),Rm])
20429             end
20430      else if (shift_t = SRType_LSL) andalso
20431         ((shift_n = 0) andalso
20432          (not((opc = (BitsN.B(0x1,2))) orelse
20433               ((BitsN.bit(n,3)) orelse
20434                ((BitsN.bit(m,3)) orelse (e = Enc_Wide))))))
20435        then let
20436               val Rn = BitsN.bits(2,0) n
20437               val Rm = BitsN.bits(2,0) m
20438             in
20439               Thumb(BitsN.concat[BitsN.B(0x42,8),opc,Rm,Rn])
20440             end
20441      else if (not(e = Enc_Wide)) andalso
20442         ((shift_t = SRType_LSL) andalso
20443          ((shift_n = 0) andalso (opc = (BitsN.B(0x2,2)))))
20444        then let
20445               val N = BitsN.bits(3,3) n
20446               val Rn = BitsN.bits(2,0) n
20447               val Rm = m
20448             in
20449               Thumb(BitsN.concat[BitsN.B(0x45,8),N,Rm,Rn])
20450             end
20451      else if not(e = Enc_Narrow)
20452        then let
20453               val Rn = n
20454               val Rm = m
20455               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
20456               val imm3 = BitsN.bits(4,2) imm5
20457               val imm2 = BitsN.bits(1,0) imm5
20458               val op' =
20459                 case opc of
20460                    BitsN.B(0x0,_) => BitsN.B(0x0,4)
20461                  | BitsN.B(0x1,_) => BitsN.B(0x4,4)
20462                  | BitsN.B(0x2,_) => BitsN.B(0xD,4)
20463                  | BitsN.B(0x3,_) => BitsN.B(0x8,4)
20464                  | _ => raise General.Bind
20465             in
20466               Thumb2
20467                 (BitsN.concat[BitsN.B(0x75,7),op',BitsN.B(0x1,1),Rn],
20468                  BitsN.concat
20469                    [BitsN.B(0x0,1),imm3,BitsN.B(0xF,4),imm2,typ,Rm])
20470             end
20471      else BadCode "TestCompareRegister")
20472   | ShiftImmediate(negate,(setflags,(d,(m,(shift_t,shift_n))))) =>
20473     (if e = Enc_ARM
20474        then let
20475               val S = BitsN.fromBit setflags
20476               val Rd = d
20477               val Rm = m
20478               val N = BitsN.fromBit negate
20479               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
20480             in
20481               ARM(BitsN.concat
20482                     [c,BitsN.B(0x3,5),N,BitsN.B(0x1,1),S,BitsN.B(0x0,4),
20483                      Rd,imm5,typ,BitsN.B(0x0,1),Rm])
20484             end
20485      else if negate andalso
20486         ((shift_t = SRType_LSL) andalso
20487          ((shift_n = 0) andalso
20488           (not((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
20489                ((BitsN.bit(m,3)) orelse
20490                 ((BitsN.bit(d,3)) orelse (e = Enc_Wide)))))))
20491        then let
20492               val Rm = BitsN.bits(2,0) m
20493               val Rd = BitsN.bits(2,0) d
20494             in
20495               Thumb(BitsN.concat[BitsN.B(0x10F,10),Rm,Rd])
20496             end
20497      else if (Set.mem(shift_t,[SRType_LSL,SRType_LSR,SRType_ASR])) andalso
20498         (not(negate orelse
20499              ((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
20500               ((BitsN.bit(m,3)) orelse
20501                ((BitsN.bit(d,3)) orelse (e = Enc_Wide))))))
20502        then let
20503               val Rm = BitsN.bits(2,0) m
20504               val Rd = BitsN.bits(2,0) d
20505               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
20506             in
20507               Thumb(BitsN.concat[BitsN.B(0x0,3),typ,imm5,Rm,Rd])
20508             end
20509      else if (shift_t = SRType_LSL) andalso
20510         ((shift_n = 0) andalso
20511          (not(negate orelse
20512               (setflags orelse
20513                ((e = Enc_Wide) orelse
20514                 ((d = (BitsN.B(0xF,4))) andalso
20515                  (not(c = (BitsN.B(0xE,4))))))))))
20516        then let
20517               val D = BitsN.bits(3,3) d
20518               val Rd = BitsN.bits(2,0) d
20519               val Rm = m
20520             in
20521               Thumb(BitsN.concat[BitsN.B(0x46,8),D,Rm,Rd])
20522             end
20523      else if not(e = Enc_Narrow)
20524        then let
20525               val S = BitsN.fromBit setflags
20526               val Rm = m
20527               val Rd = d
20528               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
20529               val imm3 = BitsN.bits(4,2) imm5
20530               val imm2 = BitsN.bits(1,0) imm5
20531               val N = BitsN.fromBit negate
20532             in
20533               Thumb2
20534                 (BitsN.concat[BitsN.B(0x3A9,10),N,S,BitsN.B(0xF,4)],
20535                  BitsN.concat[BitsN.B(0x0,1),imm3,Rd,imm2,typ,Rm])
20536             end
20537      else BadCode "ShiftImmediate")
20538   | RegisterShiftedRegister(_,(_,(_,(_,(_,(SRType_RRX,_)))))) =>
20539     BadCode "RegisterShiftedRegister: rrx"
20540   | RegisterShiftedRegister(opc,(setflags,(d,(n,(m,(shift_t,s)))))) =>
20541     (if e = Enc_ARM
20542        then let
20543               val S = BitsN.fromBit setflags
20544               val Rn = n
20545               val Rd = d
20546               val Rm = m
20547               val Rs = s
20548               val typ = EncodeRegShift shift_t
20549             in
20550               ARM(BitsN.concat
20551                     [c,BitsN.B(0x0,3),opc,S,Rn,Rd,Rs,BitsN.B(0x0,1),typ,
20552                      BitsN.B(0x1,1),Rm])
20553             end
20554      else BadCode "RegisterShiftedRegister")
20555   | ShiftRegister(_,(_,(_,(_,(SRType_RRX,_))))) =>
20556     BadCode "ShiftRegister: rrx"
20557   | ShiftRegister(negate,(setflags,(d,(n,(shift_t,m))))) =>
20558     (if e = Enc_ARM
20559        then let
20560               val S = BitsN.fromBit setflags
20561               val N = BitsN.fromBit negate
20562               val Rd = d
20563               val Rm = n
20564               val Rs = m
20565               val typ = EncodeRegShift shift_t
20566             in
20567               ARM(BitsN.concat
20568                     [c,BitsN.B(0x3,5),N,BitsN.B(0x1,1),S,BitsN.B(0x0,4),
20569                      Rd,Rs,BitsN.B(0x0,1),typ,BitsN.B(0x1,1),Rm])
20570             end
20571      else if (d = n) andalso
20572         (not(negate orelse
20573              ((BitsN.bit(d,3)) orelse
20574               ((BitsN.bit(m,3)) orelse
20575                ((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
20576                 (e = Enc_Wide))))))
20577        then let
20578               val Rm = BitsN.bits(2,0) m
20579               val Rdn = BitsN.bits(2,0) d
20580               val opc =
20581                 case shift_t of
20582                    SRType_LSL => BitsN.B(0x2,3)
20583                  | SRType_LSR => BitsN.B(0x3,3)
20584                  | SRType_ASR => BitsN.B(0x4,3)
20585                  | SRType_ROR => BitsN.B(0x7,3)
20586                  | _ => BitsN.B(0x0,3)
20587             in
20588               Thumb(BitsN.concat[BitsN.B(0x20,7),opc,Rm,Rdn])
20589             end
20590      else if not(negate orelse (e = Enc_Narrow))
20591        then let
20592               val S = BitsN.fromBit setflags
20593               val Rn = n
20594               val Rd = d
20595               val Rm = m
20596               val typ = EncodeRegShift shift_t
20597             in
20598               Thumb2
20599                 (BitsN.concat[BitsN.B(0x1F4,9),typ,S,Rn],
20600                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x0,4),Rm])
20601             end
20602      else BadCode "ShiftRegister");
20603
20604fun e_media (c,(ast,e)) =
20605  case ast of
20606     SaturatingAddSubtract(opc,(Rd,(Rm,Rn))) =>
20607       (if e = Enc_ARM
20608          then ARM(BitsN.concat
20609                     [c,BitsN.B(0x2,5),opc,BitsN.B(0x0,1),Rn,Rd,
20610                      BitsN.B(0x5,8),Rm])
20611        else if not(e = Enc_Narrow)
20612          then let
20613                 val op2 = BitsN.reverse opc
20614               in
20615                 Thumb2
20616                   (BitsN.@@(BitsN.B(0xFA8,12),Rn),
20617                    BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x2,2),op2,Rm])
20618               end
20619        else BadCode "SaturatingAddSubtract")
20620   | PackHalfword(shift_t,(shift_n,(tbform,(Rd,(Rn,Rm))))) =>
20621     let
20622       val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
20623       val tb = BitsN.bits(1,1) typ
20624     in
20625       if e = Enc_ARM
20626         then ARM(BitsN.concat
20627                    [c,BitsN.B(0x68,8),Rn,Rd,imm5,tb,BitsN.B(0x1,2),Rm])
20628       else if not(e = Enc_Narrow)
20629         then let
20630                val imm3 = BitsN.bits(4,2) imm5
20631                val imm2 = BitsN.bits(1,0) imm5
20632              in
20633                Thumb2
20634                  (BitsN.@@(BitsN.B(0xEAC,12),Rn),
20635                   BitsN.concat
20636                     [BitsN.B(0x0,1),imm3,Rd,imm2,tb,BitsN.B(0x0,1),Rm])
20637              end
20638       else BadCode "PackHalfword"
20639     end
20640   | Saturate(shift_t,(shift_n,(saturate_to,(unsigned,(Rd,Rn))))) =>
20641     let
20642       val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
20643       val sh = BitsN.bits(1,1) typ
20644       val sat_imm =
20645         if unsigned
20646           then BitsN.fromNat(saturate_to,5)
20647         else BitsN.fromNat(Nat.-(saturate_to,1),5)
20648       val U = BitsN.fromBit unsigned
20649     in
20650       if e = Enc_ARM
20651         then ARM(BitsN.concat
20652                    [c,BitsN.B(0xD,5),U,BitsN.B(0x1,1),sat_imm,Rd,imm5,sh,
20653                     BitsN.B(0x1,2),Rn])
20654       else if not(e = Enc_Narrow)
20655         then let
20656                val imm3 = BitsN.bits(4,2) imm5
20657                val imm2 = BitsN.bits(1,0) imm5
20658              in
20659                Thumb2
20660                  (BitsN.concat
20661                     [BitsN.B(0xF3,8),U,BitsN.B(0x0,1),sh,BitsN.B(0x0,1),
20662                      Rn],
20663                   BitsN.concat
20664                     [BitsN.B(0x0,1),imm3,Rd,imm2,BitsN.B(0x0,1),sat_imm])
20665              end
20666       else BadCode "Saturate"
20667     end
20668   | Saturate16(saturate_to,(unsigned,(Rd,Rn))) =>
20669     let
20670       val sat_imm =
20671         if unsigned
20672           then BitsN.fromNat(saturate_to,4)
20673         else BitsN.fromNat(Nat.-(saturate_to,1),4)
20674       val U = BitsN.fromBit unsigned
20675     in
20676       if e = Enc_ARM
20677         then ARM(BitsN.concat
20678                    [c,BitsN.B(0xD,5),U,BitsN.B(0x2,2),sat_imm,Rd,
20679                     BitsN.B(0xF3,8),Rn])
20680       else if not(e = Enc_Narrow)
20681         then Thumb2
20682                (BitsN.concat[BitsN.B(0xF3,8),U,BitsN.B(0x2,3),Rn],
20683                 BitsN.concat[BitsN.B(0x0,4),Rd,BitsN.B(0x0,4),sat_imm])
20684       else BadCode "Saturate16"
20685     end
20686   | ExtendByte(unsigned,(d,(Rn,(m,rotation)))) =>
20687     let
20688       val rot = BitsN.fromNat(rotation,5)
20689       val rotate = BitsN.bits(4,3) rot
20690       val U = BitsN.fromBit unsigned
20691     in
20692       if e = Enc_ARM
20693         then let
20694                val Rd = d
20695                val Rm = m
20696              in
20697                ARM(BitsN.concat
20698                      [c,BitsN.B(0xD,5),U,BitsN.B(0x2,2),Rn,Rd,rotate,
20699                       BitsN.B(0x7,6),Rm])
20700              end
20701       else if (Rn = (BitsN.B(0xF,4))) andalso
20702          ((rotation = 0) andalso
20703           (not((BitsN.bit(d,3)) orelse
20704                ((BitsN.bit(m,3)) orelse (e = Enc_Wide)))))
20705         then let
20706                val Rd = BitsN.bits(2,0) d
20707                val Rm = BitsN.bits(2,0) m
20708              in
20709                Thumb
20710                  (BitsN.concat[BitsN.B(0xB2,8),U,BitsN.B(0x1,1),Rm,Rd])
20711              end
20712       else if not(e = Enc_Narrow)
20713         then let
20714                val Rd = d
20715                val Rm = m
20716              in
20717                Thumb2
20718                  (BitsN.concat[BitsN.B(0x7D2,11),U,Rn],
20719                   BitsN.concat
20720                     [BitsN.B(0xF,4),Rd,BitsN.B(0x2,2),rotate,Rm])
20721              end
20722       else BadCode "ExtendByte"
20723     end
20724   | ExtendHalfword(unsigned,(d,(Rn,(m,rotation)))) =>
20725     let
20726       val rot = BitsN.fromNat(rotation,5)
20727       val rotate = BitsN.bits(4,3) rot
20728       val U = BitsN.fromBit unsigned
20729     in
20730       if e = Enc_ARM
20731         then let
20732                val Rd = d
20733                val Rm = m
20734              in
20735                ARM(BitsN.concat
20736                      [c,BitsN.B(0xD,5),U,BitsN.B(0x3,2),Rn,Rd,rotate,
20737                       BitsN.B(0x7,6),Rm])
20738              end
20739       else if (Rn = (BitsN.B(0xF,4))) andalso
20740          ((rotation = 0) andalso
20741           (not((BitsN.bit(d,3)) orelse
20742                ((BitsN.bit(m,3)) orelse (e = Enc_Wide)))))
20743         then let
20744                val Rd = BitsN.bits(2,0) d
20745                val Rm = BitsN.bits(2,0) m
20746              in
20747                Thumb
20748                  (BitsN.concat[BitsN.B(0xB2,8),U,BitsN.B(0x0,1),Rm,Rd])
20749              end
20750       else if not(e = Enc_Narrow)
20751         then let
20752                val Rd = d
20753                val Rm = m
20754              in
20755                Thumb2
20756                  (BitsN.concat[BitsN.B(0x7D0,11),U,Rn],
20757                   BitsN.concat
20758                     [BitsN.B(0xF,4),Rd,BitsN.B(0x2,2),rotate,Rm])
20759              end
20760       else BadCode "ExtendHalfword"
20761     end
20762   | ExtendByte16(unsigned,(Rd,(Rn,(Rm,rotation)))) =>
20763     let
20764       val rot = BitsN.fromNat(rotation,5)
20765       val rotate = BitsN.bits(4,3) rot
20766       val U = BitsN.fromBit unsigned
20767     in
20768       if e = Enc_ARM
20769         then ARM(BitsN.concat
20770                    [c,BitsN.B(0xD,5),U,BitsN.B(0x0,2),Rn,Rd,rotate,
20771                     BitsN.B(0x7,6),Rm])
20772       else if not(e = Enc_Narrow)
20773         then Thumb2
20774                (BitsN.concat[BitsN.B(0x7D1,11),U,Rn],
20775                 BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x2,2),rotate,Rm])
20776       else BadCode "ExtendByte16"
20777     end
20778   | SelectBytes(Rd,(Rn,Rm)) =>
20779     (if e = Enc_ARM
20780        then ARM(BitsN.concat[c,BitsN.B(0x68,8),Rn,Rd,BitsN.B(0xFB,8),Rm])
20781      else if not(e = Enc_Narrow)
20782        then Thumb2
20783               (BitsN.@@(BitsN.B(0xFAA,12),Rn),
20784                BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x8,4),Rm])
20785      else BadCode "SelectBytes")
20786   | ByteReverse(d,m) =>
20787     (if e = Enc_ARM
20788        then let
20789               val Rd = d
20790               val Rm = m
20791             in
20792               ARM(BitsN.concat[c,BitsN.B(0x6BF,12),Rd,BitsN.B(0xF3,8),Rm])
20793             end
20794      else if not((BitsN.bit(d,3)) orelse
20795             ((BitsN.bit(m,3)) orelse (e = Enc_Wide)))
20796        then let
20797               val Rd = BitsN.bits(2,0) d
20798               val Rm = BitsN.bits(2,0) m
20799             in
20800               Thumb(BitsN.concat[BitsN.B(0x2E8,10),Rm,Rd])
20801             end
20802      else if not(e = Enc_Narrow)
20803        then let
20804               val Rd = d
20805               val Rm = m
20806             in
20807               Thumb2
20808                 (BitsN.@@(BitsN.B(0xFA9,12),Rm),
20809                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x8,4),Rm])
20810             end
20811      else BadCode "ByteReverse")
20812   | ByteReversePackedHalfword(d,m) =>
20813     (if e = Enc_ARM
20814        then let
20815               val Rd = d
20816               val Rm = m
20817             in
20818               ARM(BitsN.concat[c,BitsN.B(0x6BF,12),Rd,BitsN.B(0xFB,8),Rm])
20819             end
20820      else if not((BitsN.bit(d,3)) orelse
20821             ((BitsN.bit(m,3)) orelse (e = Enc_Wide)))
20822        then let
20823               val Rd = BitsN.bits(2,0) d
20824               val Rm = BitsN.bits(2,0) m
20825             in
20826               Thumb(BitsN.concat[BitsN.B(0x2E9,10),Rm,Rd])
20827             end
20828      else if not(e = Enc_Narrow)
20829        then let
20830               val Rd = d
20831               val Rm = m
20832             in
20833               Thumb2
20834                 (BitsN.@@(BitsN.B(0xFA9,12),Rm),
20835                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x9,4),Rm])
20836             end
20837      else BadCode "ByteReversePackedHalfword")
20838   | ByteReverseSignedHalfword(d,m) =>
20839     (if e = Enc_ARM
20840        then let
20841               val Rd = d
20842               val Rm = m
20843             in
20844               ARM(BitsN.concat[c,BitsN.B(0x6FF,12),Rd,BitsN.B(0xFB,8),Rm])
20845             end
20846      else if not((BitsN.bit(d,3)) orelse
20847             ((BitsN.bit(m,3)) orelse (e = Enc_Wide)))
20848        then let
20849               val Rd = BitsN.bits(2,0) d
20850               val Rm = BitsN.bits(2,0) m
20851             in
20852               Thumb(BitsN.concat[BitsN.B(0x2EB,10),Rm,Rd])
20853             end
20854      else if not(e = Enc_Narrow)
20855        then let
20856               val Rd = d
20857               val Rm = m
20858             in
20859               Thumb2
20860                 (BitsN.@@(BitsN.B(0xFA9,12),Rm),
20861                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0xB,4),Rm])
20862             end
20863      else BadCode "ByteReverseSignedHalfword")
20864   | ReverseBits(Rd,Rm) =>
20865     (if e = Enc_ARM
20866        then ARM(BitsN.concat[c,BitsN.B(0x6FF,12),Rd,BitsN.B(0xF3,8),Rm])
20867      else if not(e = Enc_Narrow)
20868        then Thumb2
20869               (BitsN.@@(BitsN.B(0xFA9,12),Rm),
20870                BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0xA,4),Rm])
20871      else BadCode "ReverseBits")
20872   | BitFieldExtract(unsigned,(Rd,(Rn,(lsbit,widthminus1)))) =>
20873     let
20874       val U = BitsN.fromBit unsigned
20875       val lsb = BitsN.fromNat(lsbit,5)
20876       val widthm1 = BitsN.fromNat(widthminus1,5)
20877     in
20878       if e = Enc_ARM
20879         then ARM(BitsN.concat
20880                    [c,BitsN.B(0xF,5),U,BitsN.B(0x1,1),widthm1,Rd,lsb,
20881                     BitsN.B(0x5,3),Rn])
20882       else if not(e = Enc_Narrow)
20883         then let
20884                val imm3 = BitsN.bits(4,2) lsb
20885                val imm2 = BitsN.bits(1,0) lsb
20886              in
20887                Thumb2
20888                  (BitsN.concat[BitsN.B(0xF3,8),U,BitsN.B(0x4,3),Rn],
20889                   BitsN.concat
20890                     [BitsN.B(0x0,1),imm3,Rd,imm2,BitsN.B(0x0,1),widthm1])
20891              end
20892       else BadCode "BitFieldExtract"
20893     end
20894   | BitFieldClearOrInsert(Rd,(Rn,(lsbit,msbit))) =>
20895     let
20896       val lsb = BitsN.fromNat(lsbit,5)
20897       val msb = BitsN.fromNat(msbit,5)
20898     in
20899       if e = Enc_ARM
20900         then ARM(BitsN.concat
20901                    [c,BitsN.B(0x3E,7),msb,Rd,lsb,BitsN.B(0x1,3),Rn])
20902       else if not(e = Enc_Narrow)
20903         then let
20904                val imm3 = BitsN.bits(4,2) lsb
20905                val imm2 = BitsN.bits(1,0) lsb
20906              in
20907                Thumb2
20908                  (BitsN.@@(BitsN.B(0xF36,12),Rn),
20909                   BitsN.concat
20910                     [BitsN.B(0x0,1),imm3,Rd,imm2,BitsN.B(0x0,1),msb])
20911              end
20912       else BadCode "BitFieldClearOrInsert"
20913     end;
20914
20915fun e_hint (c,(ast,e)) =
20916  case ast of
20917     Breakpoint imm32 =>
20918       (if e = Enc_ARM
20919          then let
20920                 val imm12 = BitsN.bits(15,4) imm32
20921                 val imm4 = BitsN.bits(3,0) imm32
20922               in
20923                 ARM(BitsN.concat
20924                       [c,BitsN.B(0x12,8),imm12,BitsN.B(0x7,4),imm4])
20925               end
20926        else if not(e = Enc_Wide)
20927          then let
20928                 val imm8 = BitsN.bits(7,0) imm32
20929               in
20930                 Thumb(BitsN.@@(BitsN.B(0xBE,8),imm8))
20931               end
20932        else BadCode "Breakpoint")
20933   | Debug option =>
20934     (if e = Enc_ARM
20935        then ARM(BitsN.concat[c,BitsN.B(0x320F0F,24),option])
20936      else if not(e = Enc_Narrow)
20937        then Thumb2(BitsN.B(0xF3AF,16),BitsN.@@(BitsN.B(0x80F,12),option))
20938      else BadCode "Debug")
20939   | DataMemoryBarrier option =>
20940     (if e = Enc_ARM
20941        then if c = (BitsN.B(0xE,4))
20942               then ARM(BitsN.@@(BitsN.B(0xF57FF05,28),option))
20943             else BadCode "DataMemoryBarrier"
20944      else if not(e = Enc_Narrow)
20945        then Thumb2(BitsN.B(0xF3BF,16),BitsN.@@(BitsN.B(0x8F5,12),option))
20946      else BadCode "DataMemoryBarrier")
20947   | DataSynchronizationBarrier option =>
20948     (if e = Enc_ARM
20949        then if c = (BitsN.B(0xE,4))
20950               then ARM(BitsN.@@(BitsN.B(0xF57FF04,28),option))
20951             else BadCode "DataSynchronizationBarrier"
20952      else if not(e = Enc_Narrow)
20953        then Thumb2(BitsN.B(0xF3BF,16),BitsN.@@(BitsN.B(0x8F4,12),option))
20954      else BadCode "DataSynchronizationBarrier")
20955   | InstructionSynchronizationBarrier option =>
20956     (if e = Enc_ARM
20957        then if c = (BitsN.B(0xE,4))
20958               then ARM(BitsN.@@(BitsN.B(0xF57FF06,28),option))
20959             else BadCode "InstructionSynchronizationBarrier"
20960      else if not(e = Enc_Narrow)
20961        then Thumb2(BitsN.B(0xF3BF,16),BitsN.@@(BitsN.B(0x8F6,12),option))
20962      else BadCode "InstructionSynchronizationBarrier")
20963   | SendEvent =>
20964     if e = Enc_ARM
20965       then ARM(BitsN.@@(c,BitsN.B(0x320F004,28)))
20966     else if e = Enc_Wide
20967       then Thumb2(BitsN.B(0xF3AF,16),BitsN.B(0x8004,16))
20968     else Thumb(BitsN.B(0xBF40,16))
20969   | WaitForEvent =>
20970     if e = Enc_ARM
20971       then ARM(BitsN.@@(c,BitsN.B(0x320F002,28)))
20972     else if e = Enc_Wide
20973       then Thumb2(BitsN.B(0xF3AF,16),BitsN.B(0x8002,16))
20974     else Thumb(BitsN.B(0xBF20,16))
20975   | WaitForInterrupt =>
20976     if e = Enc_ARM
20977       then ARM(BitsN.@@(c,BitsN.B(0x320F003,28)))
20978     else if e = Enc_Wide
20979       then Thumb2(BitsN.B(0xF3AF,16),BitsN.B(0x8003,16))
20980     else Thumb(BitsN.B(0xBF30,16))
20981   | Yield =>
20982     if e = Enc_ARM
20983       then ARM(BitsN.@@(c,BitsN.B(0x320F001,28)))
20984     else if e = Enc_Wide
20985       then Thumb2(BitsN.B(0xF3AF,16),BitsN.B(0x8001,16))
20986     else Thumb(BitsN.B(0xBF10,16))
20987   | PreloadData(add,(is_pldw,(Rn,immediate_form1 imm32))) =>
20988     (if e = Enc_ARM
20989        then let
20990               val U = BitsN.fromBit add
20991               val R = BitsN.fromBit(not is_pldw)
20992               val imm12 = BitsN.bits(11,0) imm32
20993             in
20994               ARM(BitsN.concat
20995                     [BitsN.B(0xF5,8),U,R,BitsN.B(0x1,2),Rn,
20996                      BitsN.B(0xF,4),imm12])
20997             end
20998      else if not(e = Enc_Narrow)
20999        then let
21000               val W = BitsN.fromBit is_pldw
21001             in
21002               if add
21003                 then let
21004                        val imm12 = BitsN.bits(11,0) imm32
21005                      in
21006                        Thumb2
21007                          (BitsN.concat
21008                             [BitsN.B(0x3E2,10),W,BitsN.B(0x1,1),Rn],
21009                           BitsN.@@(BitsN.B(0xF,4),imm12))
21010                      end
21011               else let
21012                      val imm8 = BitsN.bits(7,0) imm32
21013                    in
21014                      Thumb2
21015                        (BitsN.concat
21016                           [BitsN.B(0x3E0,10),W,BitsN.B(0x1,1),Rn],
21017                         BitsN.@@(BitsN.B(0xFC,8),imm8))
21018                    end
21019             end
21020      else BadCode "PreloadData")
21021   | PreloadData(add,(is_pldw,(Rn,register_form1(Rm,(shift_t,shift_n))))) =>
21022     (if e = Enc_ARM
21023        then if c = (BitsN.B(0xE,4))
21024               then let
21025                      val U = BitsN.fromBit add
21026                      val R = BitsN.fromBit(not is_pldw)
21027                      val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
21028                    in
21029                      ARM(BitsN.concat
21030                            [BitsN.B(0xF7,8),U,R,BitsN.B(0x1,2),Rn,
21031                             BitsN.B(0xF,4),imm5,typ,BitsN.B(0x0,1),Rm])
21032                    end
21033             else BadCode "PreloadData"
21034      else if (not(e = Enc_Narrow)) andalso
21035         (add andalso (shift_t = SRType_LSL))
21036        then let
21037               val W = BitsN.fromBit is_pldw
21038               val imm2 = BitsN.fromNat(shift_n,2)
21039             in
21040               Thumb2
21041                 (BitsN.concat[BitsN.B(0x3E0,10),W,BitsN.B(0x1,1),Rn],
21042                  BitsN.concat[BitsN.B(0x3C0,10),imm2,Rm])
21043             end
21044      else BadCode "PreloadData")
21045   | PreloadDataLiteral(add,imm32) =>
21046     let
21047       val imm12 = BitsN.bits(11,0) imm32
21048       val U = BitsN.fromBit add
21049     in
21050       if e = Enc_ARM
21051         then if c = (BitsN.B(0xE,4))
21052                then ARM(BitsN.concat
21053                           [BitsN.B(0xF5,8),U,BitsN.B(0x5FF,11),imm12])
21054              else BadCode "PreloadDataLiteral"
21055       else if not(e = Enc_Narrow)
21056         then Thumb2
21057                (BitsN.concat[BitsN.B(0xF8,8),U,BitsN.B(0x1F,7)],
21058                 BitsN.@@(BitsN.B(0xF,4),imm12))
21059       else BadCode "PreloadDataLiteral"
21060     end
21061   | PreloadInstruction(add,(Rn,immediate_form1 imm32)) =>
21062     let
21063       val U = BitsN.fromBit add
21064       val imm12 = BitsN.bits(11,0) imm32
21065     in
21066       if e = Enc_ARM
21067         then if c = (BitsN.B(0xE,4))
21068                then ARM(BitsN.concat
21069                           [BitsN.B(0xF4,8),U,BitsN.B(0x5,3),Rn,
21070                            BitsN.B(0xF,4),imm12])
21071              else BadCode "PreloadInstruction"
21072       else if not(e = Enc_Narrow)
21073         then if Rn = (BitsN.B(0xF,4))
21074                then Thumb2
21075                       (BitsN.concat[BitsN.B(0xF9,8),U,BitsN.B(0x1F,7)],
21076                        BitsN.@@(BitsN.B(0xF,4),imm12))
21077              else if add
21078                then Thumb2
21079                       (BitsN.@@(BitsN.B(0xF99,12),Rn),
21080                        BitsN.@@(BitsN.B(0xF,4),imm12))
21081              else let
21082                     val imm8 = BitsN.bits(7,0) imm32
21083                   in
21084                     Thumb2
21085                       (BitsN.@@(BitsN.B(0xF91,12),Rn),
21086                        BitsN.@@(BitsN.B(0xFC,8),imm8))
21087                   end
21088       else BadCode "PreloadInstruction"
21089     end
21090   | PreloadInstruction(add,(Rn,register_form1(Rm,(shift_t,shift_n)))) =>
21091     (if e = Enc_ARM
21092        then let
21093               val U = BitsN.fromBit add
21094               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
21095             in
21096               ARM(BitsN.concat
21097                     [BitsN.B(0xF6,8),U,BitsN.B(0x5,3),Rn,BitsN.B(0xF,4),
21098                      imm5,typ,BitsN.B(0x0,1),Rm])
21099             end
21100      else if (not(e = Enc_Narrow)) andalso
21101         (add andalso (shift_t = SRType_LSL))
21102        then let
21103               val imm2 = BitsN.fromNat(shift_n,2)
21104             in
21105               Thumb2
21106                 (BitsN.@@(BitsN.B(0xF91,12),Rn),
21107                  BitsN.concat[BitsN.B(0x3C0,10),imm2,Rm])
21108             end
21109      else BadCode "PreloadInstruction (register)");
21110
21111fun e_system (c,(ast,e)) =
21112  case ast of
21113     EnterxLeavex is_enterx =>
21114       (if Set.mem(e,[Enc_Thumb,Enc_Wide])
21115          then let
21116                 val J = BitsN.fromBit is_enterx
21117               in
21118                 Thumb2
21119                   (BitsN.B(0xF3BF,16),
21120                    BitsN.concat[BitsN.B(0x478,11),J,BitsN.B(0xF,4)])
21121               end
21122        else BadCode "EnterxLeavex")
21123   | ChangeProcessorState(true,(true,_)) => BadCode "ChangeProcessorState"
21124   | ChangeProcessorState
21125     (enable,(disable,(affectA,(affectI,(affectF,changemode))))) =>
21126     let
21127       val A = BitsN.fromBit affectA
21128       val I = BitsN.fromBit affectI
21129       val F = BitsN.fromBit affectF
21130       val (M,mode) =
21131         case changemode of
21132            Option.SOME mode => (BitsN.B(0x1,1),mode)
21133          | NONE => (BitsN.B(0x0,1),BitsN.B(0x0,5))
21134     in
21135       if e = Enc_ARM
21136         then if c = (BitsN.B(0xE,4))
21137                then let
21138                       val imod =
21139                         BitsN.@@
21140                           (BitsN.fromBit(enable orelse disable),
21141                            BitsN.fromBit disable)
21142                     in
21143                       ARM(BitsN.concat
21144                             [BitsN.B(0xF10,12),imod,M,BitsN.B(0x0,8),A,I,
21145                              F,BitsN.B(0x0,1),mode])
21146                     end
21147              else BadCode "ChangeProcessorState"
21148       else if (not(e = Enc_Wide)) andalso (M = (BitsN.B(0x0,1)))
21149         then let
21150                val im = BitsN.fromBit(not enable)
21151                val A = BitsN.fromBit affectA
21152                val I = BitsN.fromBit affectI
21153                val F = BitsN.fromBit affectF
21154              in
21155                Thumb
21156                  (BitsN.concat[BitsN.B(0x5B3,11),im,BitsN.B(0x0,1),A,I,F])
21157              end
21158       else if not(e = Enc_Narrow)
21159         then let
21160                val imod =
21161                  BitsN.@@
21162                    (BitsN.fromBit(enable orelse disable),
21163                     BitsN.fromBit disable)
21164              in
21165                Thumb2
21166                  (BitsN.B(0xF3AF,16),
21167                   BitsN.concat[BitsN.B(0x10,5),imod,M,A,I,F,mode])
21168              end
21169       else BadCode "ChangeProcessorState"
21170     end
21171   | ExceptionReturn =>
21172     if e = Enc_ARM
21173       then ARM(BitsN.@@(c,BitsN.B(0x160006E,28)))
21174     else if not(e = Enc_Narrow)
21175       then Thumb2(BitsN.B(0xF3DE,16),BitsN.B(0x8F00,16))
21176     else BadCode "ExceptionReturn"
21177   | HypervisorCall imm16 =>
21178     (if e = Enc_ARM
21179        then let
21180               val imm12 = BitsN.bits(15,4) imm16
21181               val imm4 = BitsN.bits(3,0) imm16
21182             in
21183               ARM(BitsN.concat
21184                     [c,BitsN.B(0x14,8),imm12,BitsN.B(0x7,4),imm4])
21185             end
21186      else if not(e = Enc_Narrow)
21187        then let
21188               val imm4 = BitsN.bits(15,12) imm16
21189               val imm12 = BitsN.bits(11,0) imm16
21190             in
21191               Thumb2
21192                 (BitsN.@@(BitsN.B(0xF7E,12),imm4),
21193                  BitsN.@@(BitsN.B(0x8,4),imm12))
21194             end
21195      else BadCode "HypervisorCall")
21196   | MoveToRegisterFromSpecial(read_spsr,Rd) =>
21197     let
21198       val R = BitsN.fromBit read_spsr
21199     in
21200       if e = Enc_ARM
21201         then ARM(BitsN.concat
21202                    [c,BitsN.B(0x2,5),R,BitsN.B(0xF,6),Rd,BitsN.B(0x0,12)])
21203       else if not(e = Enc_Narrow)
21204         then Thumb2
21205                (BitsN.concat[BitsN.B(0x79F,11),R,BitsN.B(0xF,4)],
21206                 BitsN.concat[BitsN.B(0x8,4),Rd,BitsN.B(0x0,8)])
21207       else BadCode "MoveToRegisterFromSpecial"
21208     end
21209   | MoveToRegisterFromBankedOrSpecial(read_spsr,(SYSm,Rd)) =>
21210     let
21211       val R = BitsN.fromBit read_spsr
21212       val m = BitsN.bits(4,4) SYSm
21213       val m1 = BitsN.bits(3,0) SYSm
21214     in
21215       if e = Enc_ARM
21216         then ARM(BitsN.concat
21217                    [c,BitsN.B(0x2,5),R,BitsN.B(0x0,2),m1,Rd,
21218                     BitsN.B(0x1,3),m,BitsN.B(0x0,8)])
21219       else if not(e = Enc_Narrow)
21220         then Thumb2
21221                (BitsN.concat[BitsN.B(0x79F,11),R,m1],
21222                 BitsN.concat
21223                   [BitsN.B(0x8,4),Rd,BitsN.B(0x1,3),m,BitsN.B(0x0,4)])
21224       else BadCode "MoveToRegisterFromBankedOrSpecial"
21225     end
21226   | MoveToSpecialFromImmediate(write_spsr,(imm32,mask)) =>
21227     (if e = Enc_ARM
21228        then let
21229               val R = BitsN.fromBit write_spsr
21230             in
21231               case EncodeARMImmediate imm32 of
21232                  Option.SOME imm12 =>
21233                    ARM(BitsN.concat
21234                          [c,BitsN.B(0x6,5),R,BitsN.B(0x2,2),mask,
21235                           BitsN.B(0xF,4),imm12])
21236                | NONE => BadCode "MoveToSpecialFromImmediate"
21237             end
21238      else BadCode "MoveToSpecialFromImmediate")
21239   | MoveToSpecialFromRegister(write_spsr,(Rn,mask)) =>
21240     let
21241       val R = BitsN.fromBit write_spsr
21242     in
21243       if e = Enc_ARM
21244         then ARM(BitsN.concat
21245                    [c,BitsN.B(0x2,5),R,BitsN.B(0x2,2),mask,
21246                     BitsN.B(0xF00,12),Rn])
21247       else if not(e = Enc_Narrow)
21248         then Thumb2
21249                (BitsN.concat[BitsN.B(0x79C,11),R,Rn],
21250                 BitsN.concat[BitsN.B(0x8,4),mask,BitsN.B(0x0,8)])
21251       else BadCode "MoveToSpecialFromRegister"
21252     end
21253   | MoveToBankedOrSpecialRegister(write_spsr,(SYSm,Rn)) =>
21254     let
21255       val R = BitsN.fromBit write_spsr
21256       val m = BitsN.bits(4,4) SYSm
21257       val m1 = BitsN.bits(3,0) SYSm
21258     in
21259       if e = Enc_ARM
21260         then ARM(BitsN.concat
21261                    [c,BitsN.B(0x2,5),R,BitsN.B(0x2,2),m1,BitsN.B(0x79,7),
21262                     m,BitsN.B(0x0,4),Rn])
21263       else if not(e = Enc_Narrow)
21264         then Thumb2
21265                (BitsN.concat[BitsN.B(0x79C,11),R,Rn],
21266                 BitsN.concat
21267                   [BitsN.B(0x8,4),m1,BitsN.B(0x1,3),m,BitsN.B(0x0,4)])
21268       else BadCode "MoveToBankedOrSpecialRegister"
21269     end
21270   | ReturnFromException(increment,(wordhigher,(wback,Rn))) =>
21271     let
21272       val W = BitsN.fromBit wback
21273       val U = BitsN.fromBit increment
21274     in
21275       if e = Enc_ARM
21276         then if c = (BitsN.B(0xE,4))
21277                then let
21278                       val P = if wordhigher then U else BitsN.~ U
21279                     in
21280                       ARM(BitsN.concat
21281                             [BitsN.B(0x7C,7),P,U,BitsN.B(0x0,1),W,
21282                              BitsN.B(0x1,1),Rn,BitsN.B(0xA00,16)])
21283                     end
21284              else BadCode "ReturnFromException"
21285       else if not(wordhigher orelse (e = Enc_Narrow))
21286         then Thumb2
21287                (BitsN.concat
21288                   [BitsN.B(0x74,7),U,U,BitsN.B(0x0,1),W,BitsN.B(0x1,1),Rn],
21289                 BitsN.B(0xC000,16))
21290       else BadCode "ReturnFromException"
21291     end
21292   | SecureMonitorCall imm4 =>
21293     (if e = Enc_ARM
21294        then ARM(BitsN.concat[c,BitsN.B(0x160007,24),imm4])
21295      else if not(e = Enc_Narrow)
21296        then Thumb2(BitsN.@@(BitsN.B(0xF7F,12),imm4),BitsN.B(0x8000,16))
21297      else BadCode "SecureMonitorCall")
21298   | StoreReturnState(increment,(wordhigher,(wback,mode))) =>
21299     let
21300       val W = BitsN.fromBit wback
21301       val U = BitsN.fromBit increment
21302     in
21303       if e = Enc_ARM
21304         then if c = (BitsN.B(0xE,4))
21305                then let
21306                       val P = if wordhigher then U else BitsN.~ U
21307                     in
21308                       ARM(BitsN.concat
21309                             [BitsN.B(0x7C,7),P,U,BitsN.B(0x1,1),W,
21310                              BitsN.B(0x6828,16),mode])
21311                     end
21312              else BadCode "StoreReturnState"
21313       else if not(wordhigher orelse (e = Enc_Narrow))
21314         then Thumb2
21315                (BitsN.concat
21316                   [BitsN.B(0x74,7),U,U,BitsN.B(0x0,1),W,BitsN.B(0xD,5)],
21317                 BitsN.@@(BitsN.B(0x600,11),mode))
21318       else BadCode "StoreReturnState"
21319     end
21320   | SupervisorCall imm32 =>
21321     (if e = Enc_ARM
21322        then let
21323               val imm24 = BitsN.bits(23,0) imm32
21324             in
21325               ARM(BitsN.concat[c,BitsN.B(0xF,4),imm24])
21326             end
21327      else if not(e = Enc_Wide)
21328        then let
21329               val imm8 = BitsN.bits(7,0) imm32
21330             in
21331               Thumb(BitsN.@@(BitsN.B(0xDF,8),imm8))
21332             end
21333      else BadCode "SupervisorCall")
21334   | Setend E =>
21335     (if e = Enc_ARM
21336        then if c = (BitsN.B(0xE,4))
21337               then ARM(BitsN.concat
21338                          [BitsN.B(0x3C4040,22),BitsN.fromBit E,
21339                           BitsN.B(0x0,9)])
21340             else BadCode "Setend"
21341      else if not(e = Enc_Wide)
21342        then Thumb
21343               (BitsN.concat
21344                  [BitsN.B(0xB65,12),BitsN.fromBit E,BitsN.B(0x0,3)])
21345      else BadCode "Setend");
21346
21347fun e_multiply (c,(ast,e)) =
21348  case ast of
21349     MultiplyAccumulate(setflags,(Rd,(Rn,(Rm,Ra)))) =>
21350       (if e = Enc_ARM
21351          then let
21352                 val S = BitsN.fromBit setflags
21353               in
21354                 ARM(BitsN.concat
21355                       [c,BitsN.B(0x1,7),S,Rd,Ra,Rm,BitsN.B(0x9,4),Rn])
21356               end
21357        else if (not setflags) andalso (not(e = Enc_Narrow))
21358          then Thumb2
21359                 (BitsN.@@(BitsN.B(0xFB0,12),Rn),
21360                  BitsN.concat[Ra,Rd,BitsN.B(0x0,4),Rm])
21361        else BadCode "MultiplyAccumulate")
21362   | Multiply32(setflags,(d,(n,Rm))) =>
21363     (if e = Enc_ARM
21364        then let
21365               val S = BitsN.fromBit setflags
21366               val Rd = d
21367               val Rn = n
21368             in
21369               ARM(BitsN.concat
21370                     [c,BitsN.B(0x0,7),S,Rd,BitsN.B(0x0,4),Rm,
21371                      BitsN.B(0x9,4),Rn])
21372             end
21373      else if (d = Rm) andalso
21374         (not((setflags = (not(c = (BitsN.B(0xE,4))))) orelse
21375              ((BitsN.bit(d,3)) orelse (e = Enc_Wide))))
21376        then let
21377               val Rn = BitsN.bits(2,0) n
21378               val Rdm = BitsN.bits(2,0) d
21379             in
21380               Thumb(BitsN.concat[BitsN.B(0x10D,10),Rn,Rdm])
21381             end
21382      else if not(setflags orelse (e = Enc_Narrow))
21383        then let
21384               val Rd = d
21385               val Rn = n
21386             in
21387               Thumb2
21388                 (BitsN.@@(BitsN.B(0xFB0,12),Rn),
21389                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x0,4),Rm])
21390             end
21391      else BadCode "Multiply32")
21392   | MultiplyLong(accumulate,(signed,(setflags,(Rdhi,(Rdlo,(Rn,Rm)))))) =>
21393     (if e = Enc_ARM
21394        then let
21395               val A = BitsN.fromBit accumulate
21396               val I = BitsN.fromBit signed
21397               val S = BitsN.fromBit setflags
21398             in
21399               ARM(BitsN.concat
21400                     [c,BitsN.B(0x1,5),I,A,S,Rdhi,Rdlo,Rm,BitsN.B(0x9,4),
21401                      Rn])
21402             end
21403      else if not(setflags orelse (e = Enc_Narrow))
21404        then let
21405               val A = BitsN.fromBit accumulate
21406               val U = BitsN.fromBit(not signed)
21407             in
21408               Thumb2
21409                 (BitsN.concat[BitsN.B(0x1F7,9),A,U,BitsN.B(0x0,1),Rn],
21410                  BitsN.concat[Rdlo,Rdhi,BitsN.B(0x0,4),Rm])
21411             end
21412      else BadCode "MultiplyLong")
21413   | MultiplyAccumulateAccumulate(Rdhi,(Rdlo,(Rn,Rm))) =>
21414     (if e = Enc_ARM
21415        then ARM(BitsN.concat
21416                   [c,BitsN.B(0x4,8),Rdhi,Rdlo,Rm,BitsN.B(0x9,4),Rn])
21417      else if not(e = Enc_Narrow)
21418        then Thumb2
21419               (BitsN.@@(BitsN.B(0xFBE,12),Rn),
21420                BitsN.concat[Rdlo,Rdhi,BitsN.B(0x6,4),Rm])
21421      else BadCode "MultiplyAccumulateAccumulate")
21422   | MultiplySubtract(Rd,(Rn,(Rm,Ra))) =>
21423     (if e = Enc_ARM
21424        then ARM(BitsN.concat[c,BitsN.B(0x6,8),Rd,Ra,Rm,BitsN.B(0x9,4),Rn])
21425      else if not(e = Enc_Narrow)
21426        then Thumb2
21427               (BitsN.@@(BitsN.B(0xFB0,12),Rn),
21428                BitsN.concat[Ra,Rd,BitsN.B(0x1,4),Rm])
21429      else BadCode "MultiplySubtract")
21430   | Signed16Multiply32Accumulate(m_high,(n_high,(Rd,(Rn,(Rm,Ra))))) =>
21431     let
21432       val M = BitsN.fromBit m_high
21433       val N = BitsN.fromBit n_high
21434     in
21435       if e = Enc_ARM
21436         then ARM(BitsN.concat
21437                    [c,BitsN.B(0x10,8),Rd,Ra,Rm,BitsN.B(0x1,1),M,N,
21438                     BitsN.B(0x0,1),Rn])
21439       else if not(e = Enc_Narrow)
21440         then Thumb2
21441                (BitsN.@@(BitsN.B(0xFB1,12),Rn),
21442                 BitsN.concat[Ra,Rd,BitsN.B(0x0,2),N,M,Rm])
21443       else BadCode "Signed16Multiply32Accumulate"
21444     end
21445   | Signed16Multiply32Result(m_high,(n_high,(Rd,(Rn,Rm)))) =>
21446     let
21447       val M = BitsN.fromBit m_high
21448       val N = BitsN.fromBit n_high
21449     in
21450       if e = Enc_ARM
21451         then ARM(BitsN.concat
21452                    [c,BitsN.B(0x16,8),Rd,BitsN.B(0x0,4),Rm,
21453                     BitsN.B(0x1,1),M,N,BitsN.B(0x0,1),Rn])
21454       else if not(e = Enc_Narrow)
21455         then Thumb2
21456                (BitsN.@@(BitsN.B(0xFB1,12),Rn),
21457                 BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x0,2),N,M,Rm])
21458       else BadCode "Signed16Multiply32Result"
21459     end
21460   | Signed16x32Multiply32Accumulate(m_high,(Rd,(Rn,(Rm,Ra)))) =>
21461     let
21462       val M = BitsN.fromBit m_high
21463     in
21464       if e = Enc_ARM
21465         then ARM(BitsN.concat
21466                    [c,BitsN.B(0x12,8),Rd,Ra,Rm,BitsN.B(0x1,1),M,
21467                     BitsN.B(0x0,2),Rn])
21468       else if not(e = Enc_Narrow)
21469         then Thumb2
21470                (BitsN.@@(BitsN.B(0xFB3,12),Rn),
21471                 BitsN.concat[Ra,Rd,BitsN.B(0x0,3),M,Rm])
21472       else BadCode "Signed16x32Multiply32Accumulate"
21473     end
21474   | Signed16x32Multiply32Result(m_high,(Rd,(Rn,Rm))) =>
21475     let
21476       val M = BitsN.fromBit m_high
21477     in
21478       if e = Enc_ARM
21479         then ARM(BitsN.concat
21480                    [c,BitsN.B(0x12,8),Rd,BitsN.B(0x0,4),Rm,
21481                     BitsN.B(0x1,1),M,BitsN.B(0x2,2),Rn])
21482       else if not(e = Enc_Narrow)
21483         then Thumb2
21484                (BitsN.@@(BitsN.B(0xFB3,12),Rn),
21485                 BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x0,3),M,Rm])
21486       else BadCode "Signed16x32Multiply32Result"
21487     end
21488   | Signed16Multiply64Accumulate(m_high,(n_high,(Rdhi,(Rdlo,(Rn,Rm))))) =>
21489     let
21490       val M = BitsN.fromBit m_high
21491       val N = BitsN.fromBit n_high
21492     in
21493       if e = Enc_ARM
21494         then ARM(BitsN.concat
21495                    [c,BitsN.B(0x14,8),Rdhi,Rdlo,Rm,BitsN.B(0x1,1),M,N,
21496                     BitsN.B(0x0,1),Rn])
21497       else if not(e = Enc_Narrow)
21498         then Thumb2
21499                (BitsN.@@(BitsN.B(0xFBC,12),Rn),
21500                 BitsN.concat[Rdlo,Rdhi,BitsN.B(0x2,2),N,M,Rm])
21501       else BadCode "Signed16Multiply64Accumulate"
21502     end
21503   | SignedMultiplyDual(sub,(m_swap,(Rd,(Rn,(Rm,Ra))))) =>
21504     let
21505       val M = BitsN.fromBit m_swap
21506     in
21507       if e = Enc_ARM
21508         then let
21509                val S = BitsN.fromBit sub
21510              in
21511                ARM(BitsN.concat
21512                      [c,BitsN.B(0x70,8),Rd,Ra,Rm,BitsN.B(0x0,1),S,M,
21513                       BitsN.B(0x1,1),Rn])
21514              end
21515       else if not(e = Enc_Narrow)
21516         then let
21517                val opc = if sub then BitsN.B(0x4,3) else BitsN.B(0x2,3)
21518              in
21519                Thumb2
21520                  (BitsN.concat[BitsN.B(0x1F6,9),opc,Rn],
21521                   BitsN.concat[Ra,Rd,BitsN.B(0x0,3),M,Rm])
21522              end
21523       else BadCode "SignedMultiplyDual"
21524     end
21525   | SignedMultiplyLongDual(sub,(m_swap,(Rdhi,(Rdlo,(Rn,Rm))))) =>
21526     let
21527       val S = BitsN.fromBit sub
21528       val M = BitsN.fromBit m_swap
21529     in
21530       if e = Enc_ARM
21531         then ARM(BitsN.concat
21532                    [c,BitsN.B(0x74,8),Rdhi,Rdlo,Rm,BitsN.B(0x0,1),S,M,
21533                     BitsN.B(0x1,1),Rn])
21534       else if not(e = Enc_Narrow)
21535         then Thumb2
21536                (BitsN.concat[BitsN.B(0x7DE,11),S,Rn],
21537                 BitsN.concat[Rdlo,Rdhi,BitsN.B(0x6,3),M,Rm])
21538       else BadCode "SignedMultiplyLongDual"
21539     end
21540   | SignedMostSignificantMultiply(round,(Rd,(Rn,(Rm,Ra)))) =>
21541     let
21542       val R = BitsN.fromBit round
21543     in
21544       if e = Enc_ARM
21545         then ARM(BitsN.concat
21546                    [c,BitsN.B(0x75,8),Rd,Ra,Rm,BitsN.B(0x0,2),R,
21547                     BitsN.B(0x1,1),Rn])
21548       else if not(e = Enc_Narrow)
21549         then Thumb2
21550                (BitsN.@@(BitsN.B(0xFB5,12),Rn),
21551                 BitsN.concat[Ra,Rd,BitsN.B(0x0,3),R,Rm])
21552       else BadCode "SignedMostSignificantMultiply"
21553     end
21554   | SignedMostSignificantMultiplySubtract(round,(Rd,(Rn,(Rm,Ra)))) =>
21555     let
21556       val R = BitsN.fromBit round
21557     in
21558       if e = Enc_ARM
21559         then ARM(BitsN.concat
21560                    [c,BitsN.B(0x75,8),Rd,Ra,Rm,BitsN.B(0x3,2),R,
21561                     BitsN.B(0x1,1),Rn])
21562       else if not(e = Enc_Narrow)
21563         then Thumb2
21564                (BitsN.@@(BitsN.B(0xFB6,12),Rn),
21565                 BitsN.concat[Ra,Rd,BitsN.B(0x0,3),R,Rm])
21566       else BadCode "SignedMostSignificantMultiplySubtract"
21567     end;
21568
21569fun e_simd (c,(ast,e)) =
21570  case ast of
21571     SignedAddSub16(opc,(Rd,(Rn,Rm))) =>
21572       (if e = Enc_ARM
21573          then ARM(BitsN.concat
21574                     [c,BitsN.B(0x61,8),Rn,Rd,BitsN.B(0x1E,5),opc,
21575                      BitsN.B(0x1,1),Rm])
21576        else if not(e = Enc_Narrow)
21577          then let
21578                 val op1 = EncodeAddSubOpc opc
21579               in
21580                 Thumb2
21581                   (BitsN.concat[BitsN.B(0x1F5,9),op1,Rn],
21582                    BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x0,4),Rm])
21583               end
21584        else BadCode "SignedAddSub16")
21585   | UnsignedAddSub16(opc,(Rd,(Rn,Rm))) =>
21586     (if e = Enc_ARM
21587        then ARM(BitsN.concat
21588                   [c,BitsN.B(0x65,8),Rn,Rd,BitsN.B(0x1E,5),opc,
21589                    BitsN.B(0x1,1),Rm])
21590      else if not(e = Enc_Narrow)
21591        then let
21592               val op1 = EncodeAddSubOpc opc
21593             in
21594               Thumb2
21595                 (BitsN.concat[BitsN.B(0x1F5,9),op1,Rn],
21596                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x4,4),Rm])
21597             end
21598      else BadCode "UnsignedAddSub16")
21599   | SignedSaturatingAddSub16(opc,(Rd,(Rn,Rm))) =>
21600     (if e = Enc_ARM
21601        then ARM(BitsN.concat
21602                   [c,BitsN.B(0x62,8),Rn,Rd,BitsN.B(0x1E,5),opc,
21603                    BitsN.B(0x1,1),Rm])
21604      else if not(e = Enc_Narrow)
21605        then let
21606               val op1 = EncodeAddSubOpc opc
21607             in
21608               Thumb2
21609                 (BitsN.concat[BitsN.B(0x1F5,9),op1,Rn],
21610                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x1,4),Rm])
21611             end
21612      else BadCode "SignedSaturatingAddSub16")
21613   | UnsignedSaturatingAddSub16(opc,(Rd,(Rn,Rm))) =>
21614     (if e = Enc_ARM
21615        then ARM(BitsN.concat
21616                   [c,BitsN.B(0x66,8),Rn,Rd,BitsN.B(0x1E,5),opc,
21617                    BitsN.B(0x1,1),Rm])
21618      else if not(e = Enc_Narrow)
21619        then let
21620               val op1 = EncodeAddSubOpc opc
21621               val op2 = BitsN.-(opc,BitsN.B(0x1,2))
21622             in
21623               Thumb2
21624                 (BitsN.concat[BitsN.B(0x1F5,9),op1,Rn],
21625                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x5,4),Rm])
21626             end
21627      else BadCode "UnsignedSaturatingAddSub16")
21628   | SignedHalvingAddSub16(opc,(Rd,(Rn,Rm))) =>
21629     (if e = Enc_ARM
21630        then ARM(BitsN.concat
21631                   [c,BitsN.B(0x63,8),Rn,Rd,BitsN.B(0x1E,5),opc,
21632                    BitsN.B(0x1,1),Rm])
21633      else if not(e = Enc_Narrow)
21634        then let
21635               val op1 = EncodeAddSubOpc opc
21636             in
21637               Thumb2
21638                 (BitsN.concat[BitsN.B(0x1F5,9),op1,Rn],
21639                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x2,4),Rm])
21640             end
21641      else BadCode "SignedHalvingAddSub16")
21642   | UnsignedHalvingAddSub16(opc,(Rd,(Rn,Rm))) =>
21643     (if e = Enc_ARM
21644        then ARM(BitsN.concat
21645                   [c,BitsN.B(0x67,8),Rn,Rd,BitsN.B(0x1E,5),opc,
21646                    BitsN.B(0x1,1),Rm])
21647      else if not(e = Enc_Narrow)
21648        then let
21649               val op1 = EncodeAddSubOpc opc
21650               val op2 = BitsN.-(opc,BitsN.B(0x1,2))
21651             in
21652               Thumb2
21653                 (BitsN.concat[BitsN.B(0x1F5,9),op1,Rn],
21654                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x6,4),Rm])
21655             end
21656      else BadCode "UnsignedHalvingAddSub16")
21657   | SignedAddSub8(sub,(Rd,(Rn,Rm))) =>
21658     (if e = Enc_ARM
21659        then let
21660               val opc = if sub then BitsN.B(0x7,3) else BitsN.B(0x4,3)
21661             in
21662               ARM(BitsN.concat
21663                     [c,BitsN.B(0x61,8),Rn,Rd,BitsN.B(0xF,4),opc,
21664                      BitsN.B(0x1,1),Rm])
21665             end
21666      else if not(e = Enc_Narrow)
21667        then let
21668               val opc = if sub then BitsN.B(0x4,3) else BitsN.B(0x0,3)
21669             in
21670               Thumb2
21671                 (BitsN.concat[BitsN.B(0x1F5,9),opc,Rn],
21672                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x0,4),Rm])
21673             end
21674      else BadCode "SignedAddSub8")
21675   | UnsignedAddSub8(sub,(Rd,(Rn,Rm))) =>
21676     (if e = Enc_ARM
21677        then let
21678               val opc = if sub then BitsN.B(0x7,3) else BitsN.B(0x4,3)
21679             in
21680               ARM(BitsN.concat
21681                     [c,BitsN.B(0x65,8),Rn,Rd,BitsN.B(0xF,4),opc,
21682                      BitsN.B(0x1,1),Rm])
21683             end
21684      else if not(e = Enc_Narrow)
21685        then let
21686               val opc = if sub then BitsN.B(0x4,3) else BitsN.B(0x0,3)
21687             in
21688               Thumb2
21689                 (BitsN.concat[BitsN.B(0x1F5,9),opc,Rn],
21690                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x4,4),Rm])
21691             end
21692      else BadCode "UnsignedAddSub8")
21693   | SignedSaturatingAddSub8(sub,(Rd,(Rn,Rm))) =>
21694     (if e = Enc_ARM
21695        then let
21696               val opc = if sub then BitsN.B(0x7,3) else BitsN.B(0x4,3)
21697             in
21698               ARM(BitsN.concat
21699                     [c,BitsN.B(0x62,8),Rn,Rd,BitsN.B(0xF,4),opc,
21700                      BitsN.B(0x1,1),Rm])
21701             end
21702      else if not(e = Enc_Narrow)
21703        then let
21704               val opc = if sub then BitsN.B(0x4,3) else BitsN.B(0x0,3)
21705             in
21706               Thumb2
21707                 (BitsN.concat[BitsN.B(0x1F5,9),opc,Rn],
21708                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x1,4),Rm])
21709             end
21710      else BadCode "SignedSaturatingAddSub8")
21711   | UnsignedSaturatingAddSub8(sub,(Rd,(Rn,Rm))) =>
21712     (if e = Enc_ARM
21713        then let
21714               val opc = if sub then BitsN.B(0x7,3) else BitsN.B(0x4,3)
21715             in
21716               ARM(BitsN.concat
21717                     [c,BitsN.B(0x66,8),Rn,Rd,BitsN.B(0xF,4),opc,
21718                      BitsN.B(0x1,1),Rm])
21719             end
21720      else if not(e = Enc_Narrow)
21721        then let
21722               val opc = if sub then BitsN.B(0x4,3) else BitsN.B(0x0,3)
21723             in
21724               Thumb2
21725                 (BitsN.concat[BitsN.B(0x1F5,9),opc,Rn],
21726                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x5,4),Rm])
21727             end
21728      else BadCode "UnsignedSaturatingAddSub8")
21729   | SignedHalvingAddSub8(sub,(Rd,(Rn,Rm))) =>
21730     (if e = Enc_ARM
21731        then let
21732               val opc = if sub then BitsN.B(0x7,3) else BitsN.B(0x4,3)
21733             in
21734               ARM(BitsN.concat
21735                     [c,BitsN.B(0x63,8),Rn,Rd,BitsN.B(0xF,4),opc,
21736                      BitsN.B(0x1,1),Rm])
21737             end
21738      else if not(e = Enc_Narrow)
21739        then let
21740               val opc = if sub then BitsN.B(0x4,3) else BitsN.B(0x0,3)
21741             in
21742               Thumb2
21743                 (BitsN.concat[BitsN.B(0x1F5,9),opc,Rn],
21744                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x2,4),Rm])
21745             end
21746      else BadCode "SignedHalvingAddSub8")
21747   | UnsignedHalvingAddSub8(sub,(Rd,(Rn,Rm))) =>
21748     (if e = Enc_ARM
21749        then let
21750               val opc = if sub then BitsN.B(0x7,3) else BitsN.B(0x4,3)
21751             in
21752               ARM(BitsN.concat
21753                     [c,BitsN.B(0x67,8),Rn,Rd,BitsN.B(0xF,4),opc,
21754                      BitsN.B(0x1,1),Rm])
21755             end
21756      else if not(e = Enc_Narrow)
21757        then let
21758               val opc = if sub then BitsN.B(0x4,3) else BitsN.B(0x0,3)
21759             in
21760               Thumb2
21761                 (BitsN.concat[BitsN.B(0x1F5,9),opc,Rn],
21762                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0x6,4),Rm])
21763             end
21764      else BadCode "UnsignedHalvingAddSub8")
21765   | UnsignedSumAbsoluteDifferences(Rd,(Rn,(Rm,Ra))) =>
21766     (if e = Enc_ARM
21767        then ARM(BitsN.concat
21768                   [c,BitsN.B(0x78,8),Rd,Ra,Rm,BitsN.B(0x1,4),Rn])
21769      else if not(e = Enc_Narrow)
21770        then Thumb2
21771               (BitsN.@@(BitsN.B(0xFB7,12),Rn),
21772                BitsN.concat[Ra,Rd,BitsN.B(0x0,4),Rm])
21773      else BadCode "UnsignedSumAbsoluteDifferences");
21774
21775fun e_load (c,(ast,e)) =
21776  case ast of
21777     LoadWord(_,(false,(false,_))) => BadCode "LoadWord"
21778   | LoadWord(add,(index,(wback,(t,(n,immediate_form1 imm32))))) =>
21779     (if e = Enc_ARM
21780        then if BitsN.<=+(imm32,BitsN.B(0xFFF,32))
21781               then let
21782                      val Rt = t
21783                      val Rn = n
21784                      val P = BitsN.fromBit index
21785                      val U = BitsN.fromBit add
21786                      val W = BitsN.fromBit(index andalso wback)
21787                      val imm12 = BitsN.bits(11,0) imm32
21788                    in
21789                      ARM(BitsN.concat
21790                            [c,BitsN.B(0x2,3),P,U,BitsN.B(0x0,1),W,
21791                             BitsN.B(0x1,1),Rn,Rt,imm12])
21792                    end
21793             else BadCode "LoadWord"
21794      else if index andalso (add andalso (not wback))
21795        then if (n = (BitsN.B(0xD,4))) andalso
21796                ((BitsN.<=+(imm32,BitsN.B(0x3FC,32))) andalso
21797                 ((Aligned 32 (imm32,4)) andalso
21798                  (not((BitsN.bit(t,3)) orelse (e = Enc_Wide)))))
21799               then let
21800                      val Rt = BitsN.bits(2,0) t
21801                      val imm8 = BitsN.bits(9,2) imm32
21802                    in
21803                      Thumb(BitsN.concat[BitsN.B(0x13,5),Rt,imm8])
21804                    end
21805             else if (BitsN.<=+(imm32,BitsN.B(0x7C,32))) andalso
21806                ((Aligned 32 (imm32,4)) andalso
21807                 (not((BitsN.bit(t,3)) orelse
21808                      ((BitsN.bit(n,3)) orelse (e = Enc_Wide)))))
21809               then let
21810                      val Rt = BitsN.bits(2,0) t
21811                      val Rn = BitsN.bits(2,0) n
21812                      val imm5 = BitsN.bits(6,2) imm32
21813                    in
21814                      Thumb(BitsN.concat[BitsN.B(0xD,5),imm5,Rn,Rt])
21815                    end
21816             else if (BitsN.<=+(imm32,BitsN.B(0xFFF,32))) andalso
21817                (not(e = Enc_Narrow))
21818               then let
21819                      val Rt = t
21820                      val Rn = n
21821                      val imm12 = BitsN.bits(11,0) imm32
21822                    in
21823                      Thumb2
21824                        (BitsN.@@(BitsN.B(0xF8D,12),Rn),BitsN.@@(Rt,imm12))
21825                    end
21826             else BadCode "LoadWord"
21827      else if (BitsN.<=+(imm32,BitsN.B(0xFF,32))) andalso
21828         (not(e = Enc_Narrow))
21829        then let
21830               val Rt = t
21831               val Rn = n
21832               val P = BitsN.fromBit index
21833               val U = BitsN.fromBit add
21834               val W = BitsN.fromBit wback
21835               val imm8 = BitsN.bits(7,0) imm32
21836             in
21837               Thumb2
21838                 (BitsN.@@(BitsN.B(0xF85,12),Rn),
21839                  BitsN.concat[Rt,BitsN.B(0x1,1),P,U,W,imm8])
21840             end
21841      else BadCode "LoadWord")
21842   | LoadWord
21843     (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n))))))) =>
21844     let
21845       val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
21846     in
21847       if e = Enc_ARM
21848         then let
21849                val Rn = n
21850                val Rt = t
21851                val Rm = m
21852                val P = BitsN.fromBit index
21853                val U = BitsN.fromBit add
21854                val W = BitsN.fromBit(index andalso wback)
21855              in
21856                ARM(BitsN.concat
21857                      [c,BitsN.B(0x3,3),P,U,BitsN.B(0x0,1),W,
21858                       BitsN.B(0x1,1),Rn,Rt,imm5,typ,BitsN.B(0x0,1),Rm])
21859              end
21860       else if (shift_t = SRType_LSL) andalso
21861          (index andalso (add andalso (not wback)))
21862         then if (shift_n = 0) andalso
21863                 (not((BitsN.bit(m,3)) orelse
21864                      ((BitsN.bit(n,3)) orelse
21865                       ((BitsN.bit(t,3)) orelse (e = Enc_Wide)))))
21866                then let
21867                       val Rm = BitsN.bits(2,0) m
21868                       val Rn = BitsN.bits(2,0) n
21869                       val Rt = BitsN.bits(2,0) t
21870                     in
21871                       Thumb(BitsN.concat[BitsN.B(0x2C,7),Rm,Rn,Rt])
21872                     end
21873              else if (Nat.<(shift_n,4)) andalso (not(e = Enc_Narrow))
21874                then let
21875                       val Rn = n
21876                       val Rt = t
21877                       val Rm = m
21878                       val imm2 = BitsN.bits(1,0) imm5
21879                     in
21880                       Thumb2
21881                         (BitsN.@@(BitsN.B(0xF85,12),Rn),
21882                          BitsN.concat[Rt,BitsN.B(0x0,6),imm2,Rm])
21883                     end
21884              else BadCode "LoadWord"
21885       else BadCode "LoadWord"
21886     end
21887   | LoadLiteral(add,(t,imm32)) =>
21888     (if e = Enc_ARM
21889        then if BitsN.<=+(imm32,BitsN.B(0xFFF,32))
21890               then let
21891                      val Rt = t
21892                      val U = BitsN.fromBit add
21893                      val imm12 = BitsN.bits(11,0) imm32
21894                    in
21895                      ARM(BitsN.concat
21896                            [c,BitsN.B(0x5,4),U,BitsN.B(0x1F,7),Rt,imm12])
21897                    end
21898             else BadCode "LoadLiteral"
21899      else if add andalso
21900         ((BitsN.<=+(imm32,BitsN.B(0x3FC,32))) andalso
21901          ((Aligned 32 (imm32,4)) andalso
21902           (not((BitsN.bit(t,3)) orelse (e = Enc_Wide)))))
21903        then let
21904               val Rt = BitsN.bits(2,0) t
21905               val imm8 = BitsN.bits(9,2) imm32
21906             in
21907               Thumb(BitsN.concat[BitsN.B(0x9,5),Rt,imm8])
21908             end
21909      else if (BitsN.<=+(imm32,BitsN.B(0xFFF,32))) andalso
21910         (not(e = Enc_Narrow))
21911        then let
21912               val Rt = t
21913               val U = BitsN.fromBit add
21914               val imm12 = BitsN.bits(11,0) imm32
21915             in
21916               Thumb2
21917                 (BitsN.concat[BitsN.B(0xF8,8),U,BitsN.B(0x5F,7)],
21918                  BitsN.@@(Rt,imm12))
21919             end
21920      else BadCode "LoadLiteral")
21921   | LoadUnprivileged(add,(postindex,(Rt,(Rn,immediate_form1 imm32)))) =>
21922     (if (e = Enc_ARM) andalso
21923         (postindex andalso (BitsN.<=+(imm32,BitsN.B(0xFFF,32))))
21924        then let
21925               val imm12 = BitsN.bits(11,0) imm32
21926               val U = BitsN.fromBit add
21927             in
21928               ARM(BitsN.concat
21929                     [c,BitsN.B(0x4,4),U,BitsN.B(0x3,3),Rn,Rt,imm12])
21930             end
21931      else if (Set.mem(e,[Enc_Thumb,Enc_Wide])) andalso
21932         (add andalso
21933          ((not postindex) andalso (BitsN.<=+(imm32,BitsN.B(0xFF,32)))))
21934        then let
21935               val imm8 = BitsN.bits(7,0) imm32
21936             in
21937               Thumb2
21938                 (BitsN.@@(BitsN.B(0xF85,12),Rn),
21939                  BitsN.concat[Rt,BitsN.B(0xE,4),imm8])
21940             end
21941      else BadCode "LoadUnprivileged")
21942   | LoadUnprivileged
21943     (add,(postindex,(Rt,(Rn,register_form1(Rm,(shift_t,shift_n)))))) =>
21944     (if (e = Enc_ARM) andalso postindex
21945        then let
21946               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
21947               val U = BitsN.fromBit add
21948             in
21949               ARM(BitsN.concat
21950                     [c,BitsN.B(0x6,4),U,BitsN.B(0x3,3),Rn,Rt,imm5,typ,
21951                      BitsN.B(0x0,1),Rm])
21952             end
21953      else BadCode "LoadUnprivileged")
21954   | LoadByte(_,(_,(false,(false,_)))) => BadCode "LoadByte"
21955   | LoadByte
21956     (unsigned,(add,(index,(wback,(t,(n,immediate_form1 imm32)))))) =>
21957     (if e = Enc_ARM
21958        then let
21959               val Rt = t
21960               val Rn = n
21961               val P = BitsN.fromBit index
21962               val U = BitsN.fromBit add
21963               val W = BitsN.fromBit(index andalso wback)
21964             in
21965               if unsigned andalso (BitsN.<=+(imm32,BitsN.B(0xFFF,32)))
21966                 then let
21967                        val imm12 = BitsN.bits(11,0) imm32
21968                      in
21969                        ARM(BitsN.concat
21970                              [c,BitsN.B(0x2,3),P,U,BitsN.B(0x1,1),W,
21971                               BitsN.B(0x1,1),Rn,Rt,imm12])
21972                      end
21973               else if BitsN.<=+(imm32,BitsN.B(0xFF,32))
21974                 then let
21975                        val imm4H = BitsN.bits(7,4) imm32
21976                        val imm4L = BitsN.bits(3,0) imm32
21977                      in
21978                        ARM(BitsN.concat
21979                              [c,BitsN.B(0x0,3),P,U,BitsN.B(0x1,1),W,
21980                               BitsN.B(0x1,1),Rn,Rt,imm4H,BitsN.B(0xD,4),
21981                               imm4L])
21982                      end
21983               else BadCode "LoadByte"
21984             end
21985      else if index andalso (add andalso (not wback))
21986        then if unsigned andalso
21987                ((BitsN.<=+(imm32,BitsN.B(0x1F,32))) andalso
21988                 (not((BitsN.bit(t,3)) orelse
21989                      ((BitsN.bit(n,3)) orelse (e = Enc_Wide)))))
21990               then let
21991                      val Rt = BitsN.bits(2,0) t
21992                      val Rn = BitsN.bits(2,0) n
21993                      val imm5 = BitsN.bits(4,0) imm32
21994                    in
21995                      Thumb(BitsN.concat[BitsN.B(0xF,5),imm5,Rn,Rt])
21996                    end
21997             else if (BitsN.<=+(imm32,BitsN.B(0xFFF,32))) andalso
21998                (not(e = Enc_Narrow))
21999               then let
22000                      val Rt = t
22001                      val Rn = n
22002                      val imm12 = BitsN.bits(11,0) imm32
22003                      val S = BitsN.fromBit(not unsigned)
22004                    in
22005                      Thumb2
22006                        (BitsN.concat[BitsN.B(0x7C,7),S,BitsN.B(0x9,4),Rn],
22007                         BitsN.@@(Rt,imm12))
22008                    end
22009             else BadCode "LoadByte"
22010      else if (BitsN.<=+(imm32,BitsN.B(0xFF,32))) andalso
22011         (not(e = Enc_Narrow))
22012        then let
22013               val Rt = t
22014               val Rn = n
22015               val P = BitsN.fromBit index
22016               val U = BitsN.fromBit add
22017               val W = BitsN.fromBit wback
22018               val imm8 = BitsN.bits(7,0) imm32
22019               val S = BitsN.fromBit(not unsigned)
22020             in
22021               Thumb2
22022                 (BitsN.concat[BitsN.B(0x7C,7),S,BitsN.B(0x1,4),Rn],
22023                  BitsN.concat[Rt,BitsN.B(0x1,1),P,U,W,imm8])
22024             end
22025      else BadCode "LoadByte")
22026   | LoadByte
22027     (unsigned,
22028      (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n)))))))) =>
22029     let
22030       val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
22031     in
22032       if e = Enc_ARM
22033         then let
22034                val Rt = t
22035                val Rn = n
22036                val Rm = m
22037                val P = BitsN.fromBit index
22038                val U = BitsN.fromBit add
22039                val W = BitsN.fromBit(index andalso wback)
22040              in
22041                if unsigned
22042                  then ARM(BitsN.concat
22043                             [c,BitsN.B(0x3,3),P,U,BitsN.B(0x1,1),W,
22044                              BitsN.B(0x1,1),Rn,Rt,imm5,typ,
22045                              BitsN.B(0x0,1),Rm])
22046                else if (shift_t = SRType_LSL) andalso (shift_n = 0)
22047                  then ARM(BitsN.concat
22048                             [c,BitsN.B(0x0,3),P,U,BitsN.B(0x0,1),W,
22049                              BitsN.B(0x1,1),Rn,Rt,BitsN.B(0xD,8),Rm])
22050                else BadCode "LoadByte"
22051              end
22052       else if (shift_t = SRType_LSL) andalso
22053          (index andalso (add andalso (not wback)))
22054         then if (shift_n = 0) andalso
22055                 (not((BitsN.bit(m,3)) orelse
22056                      ((BitsN.bit(n,3)) orelse
22057                       ((BitsN.bit(t,3)) orelse (e = Enc_Wide)))))
22058                then let
22059                       val Rm = BitsN.bits(2,0) m
22060                       val Rn = BitsN.bits(2,0) n
22061                       val Rt = BitsN.bits(2,0) t
22062                       val U = BitsN.fromBit unsigned
22063                       val S = BitsN.~ U
22064                     in
22065                       Thumb
22066                         (BitsN.concat
22067                            [BitsN.B(0x5,4),U,BitsN.B(0x1,1),S,Rm,Rn,Rt])
22068                     end
22069              else if (Nat.<(shift_n,4)) andalso (not(e = Enc_Narrow))
22070                then let
22071                       val Rt = t
22072                       val Rn = n
22073                       val Rm = m
22074                       val imm2 = BitsN.bits(1,0) imm5
22075                       val S = BitsN.fromBit(not unsigned)
22076                     in
22077                       Thumb2
22078                         (BitsN.concat
22079                            [BitsN.B(0x7C,7),S,BitsN.B(0x1,4),Rn],
22080                          BitsN.concat[Rt,BitsN.B(0x0,6),imm2,Rm])
22081                     end
22082              else BadCode "LoadByte"
22083       else BadCode "LoadByte"
22084     end
22085   | LoadByteLiteral(unsigned,(add,(Rt,imm32))) =>
22086     (if e = Enc_ARM
22087        then let
22088               val U = BitsN.fromBit add
22089             in
22090               if unsigned andalso (BitsN.<=+(imm32,BitsN.B(0xFFF,32)))
22091                 then let
22092                        val imm12 = BitsN.bits(11,0) imm32
22093                      in
22094                        ARM(BitsN.concat
22095                              [c,BitsN.B(0x5,4),U,BitsN.B(0x5F,7),Rt,imm12])
22096                      end
22097               else if BitsN.<=+(imm32,BitsN.B(0xFF,32))
22098                 then let
22099                        val imm4H = BitsN.bits(7,4) imm32
22100                        val imm4L = BitsN.bits(3,0) imm32
22101                      in
22102                        ARM(BitsN.concat
22103                              [c,BitsN.B(0x1,4),U,BitsN.B(0x5F,7),Rt,
22104                               imm4H,BitsN.B(0xD,4),imm4L])
22105                      end
22106               else BadCode "LoadByteLiteral"
22107             end
22108      else if (BitsN.<=+(imm32,BitsN.B(0xFFF,32))) andalso
22109         (not(e = Enc_Narrow))
22110        then let
22111               val U = BitsN.fromBit add
22112               val S = BitsN.fromBit(not unsigned)
22113               val imm12 = BitsN.bits(11,0) imm32
22114             in
22115               Thumb2
22116                 (BitsN.concat[BitsN.B(0x7C,7),S,U,BitsN.B(0x1F,7)],
22117                  BitsN.@@(Rt,imm12))
22118             end
22119      else BadCode "LoadByteLiteral")
22120   | LoadByteUnprivileged(add,(postindex,(Rt,(Rn,immediate_form1 imm32)))) =>
22121     (if (e = Enc_ARM) andalso
22122         (postindex andalso (BitsN.<=+(imm32,BitsN.B(0xFFF,32))))
22123        then let
22124               val imm12 = BitsN.bits(11,0) imm32
22125               val U = BitsN.fromBit add
22126             in
22127               ARM(BitsN.concat
22128                     [c,BitsN.B(0x4,4),U,BitsN.B(0x7,3),Rn,Rt,imm12])
22129             end
22130      else if (Set.mem(e,[Enc_Thumb,Enc_Wide])) andalso
22131         (add andalso
22132          ((not postindex) andalso (BitsN.<=+(imm32,BitsN.B(0xFF,32)))))
22133        then let
22134               val imm8 = BitsN.bits(7,0) imm32
22135             in
22136               Thumb2
22137                 (BitsN.@@(BitsN.B(0xF81,12),Rn),
22138                  BitsN.concat[Rt,BitsN.B(0xE,4),imm8])
22139             end
22140      else BadCode "LoadByteUnprivileged")
22141   | LoadByteUnprivileged
22142     (add,(postindex,(Rt,(Rn,register_form1(Rm,(shift_t,shift_n)))))) =>
22143     (if (e = Enc_ARM) andalso postindex
22144        then let
22145               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
22146               val U = BitsN.fromBit add
22147             in
22148               ARM(BitsN.concat
22149                     [c,BitsN.B(0x6,4),U,BitsN.B(0x7,3),Rn,Rt,imm5,typ,
22150                      BitsN.B(0x0,1),Rm])
22151             end
22152      else BadCode "LoadByteUnprivileged")
22153   | LoadSignedByteUnprivileged
22154     (add,(postindex,(Rt,(Rn,immediate_form2 imm32)))) =>
22155     (if (e = Enc_ARM) andalso
22156         (postindex andalso (BitsN.<=+(imm32,BitsN.B(0xFF,32))))
22157        then let
22158               val imm4H = BitsN.bits(7,4) imm32
22159               val imm4L = BitsN.bits(3,0) imm32
22160               val U = BitsN.fromBit add
22161             in
22162               ARM(BitsN.concat
22163                     [c,BitsN.B(0x0,4),U,BitsN.B(0x7,3),Rn,Rt,imm4H,
22164                      BitsN.B(0xD,4),imm4L])
22165             end
22166      else if (Set.mem(e,[Enc_Thumb,Enc_Wide])) andalso
22167         (add andalso
22168          ((not postindex) andalso (BitsN.<=+(imm32,BitsN.B(0xFF,32)))))
22169        then let
22170               val imm8 = BitsN.bits(7,0) imm32
22171             in
22172               Thumb2
22173                 (BitsN.@@(BitsN.B(0xF91,12),Rn),
22174                  BitsN.concat[Rt,BitsN.B(0xE,4),imm8])
22175             end
22176      else BadCode "LoadSignedByteUnprivileged")
22177   | LoadSignedByteUnprivileged
22178     (add,(postindex,(Rt,(Rn,register_form2 Rm)))) =>
22179     (if (e = Enc_ARM) andalso postindex
22180        then let
22181               val U = BitsN.fromBit add
22182             in
22183               ARM(BitsN.concat
22184                     [c,BitsN.B(0x0,4),U,BitsN.B(0x3,3),Rn,Rt,
22185                      BitsN.B(0xD,8),Rm])
22186             end
22187      else BadCode "LoadSignedByteUnprivileged")
22188   | LoadHalf(_,(_,(false,(false,_)))) => BadCode "LoadHalf"
22189   | LoadHalf
22190     (unsigned,(add,(index,(wback,(t,(n,immediate_form1 imm32)))))) =>
22191     (if e = Enc_ARM
22192        then if BitsN.<=+(imm32,BitsN.B(0xFF,32))
22193               then let
22194                      val Rt = t
22195                      val Rn = n
22196                      val P = BitsN.fromBit index
22197                      val U = BitsN.fromBit add
22198                      val W = BitsN.fromBit(index andalso wback)
22199                      val S = BitsN.fromBit(not unsigned)
22200                      val imm4H = BitsN.bits(7,4) imm32
22201                      val imm4L = BitsN.bits(3,0) imm32
22202                    in
22203                      ARM(BitsN.concat
22204                            [c,BitsN.B(0x0,3),P,U,BitsN.B(0x1,1),W,
22205                             BitsN.B(0x1,1),Rn,Rt,imm4H,BitsN.B(0x1,1),S,
22206                             BitsN.B(0x3,2),imm4L])
22207                    end
22208             else BadCode "LoadHalf"
22209      else if index andalso (add andalso (not wback))
22210        then if unsigned andalso
22211                ((BitsN.<=+(imm32,BitsN.B(0x3E,32))) andalso
22212                 ((Aligned 32 (imm32,2)) andalso
22213                  (not((BitsN.bit(t,3)) orelse
22214                       ((BitsN.bit(n,3)) orelse (e = Enc_Wide))))))
22215               then let
22216                      val Rt = BitsN.bits(2,0) t
22217                      val Rn = BitsN.bits(2,0) n
22218                      val imm5 = BitsN.bits(5,1) imm32
22219                    in
22220                      Thumb(BitsN.concat[BitsN.B(0x11,5),imm5,Rn,Rt])
22221                    end
22222             else if (BitsN.<=+(imm32,BitsN.B(0xFFF,32))) andalso
22223                (not(e = Enc_Narrow))
22224               then let
22225                      val Rt = t
22226                      val Rn = n
22227                      val imm12 = BitsN.bits(11,0) imm32
22228                      val S = BitsN.fromBit(not unsigned)
22229                    in
22230                      Thumb2
22231                        (BitsN.concat[BitsN.B(0x7C,7),S,BitsN.B(0xB,4),Rn],
22232                         BitsN.@@(Rt,imm12))
22233                    end
22234             else BadCode "LoadHalf"
22235      else if (BitsN.<=+(imm32,BitsN.B(0xFF,32))) andalso
22236         (not(e = Enc_Narrow))
22237        then let
22238               val Rt = t
22239               val Rn = n
22240               val P = BitsN.fromBit index
22241               val U = BitsN.fromBit add
22242               val W = BitsN.fromBit wback
22243               val imm8 = BitsN.bits(7,0) imm32
22244               val S = BitsN.fromBit(not unsigned)
22245             in
22246               Thumb2
22247                 (BitsN.concat[BitsN.B(0x7C,7),S,BitsN.B(0x3,4),Rn],
22248                  BitsN.concat[Rt,BitsN.B(0x1,1),P,U,W,imm8])
22249             end
22250      else BadCode "LoadHalf")
22251   | LoadHalf
22252     (unsigned,
22253      (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n)))))))) =>
22254     let
22255       val S = BitsN.fromBit(not unsigned)
22256     in
22257       if e = Enc_ARM
22258         then if (shift_t = SRType_LSL) andalso (shift_n = 0)
22259                then let
22260                       val Rt = t
22261                       val Rn = n
22262                       val Rm = m
22263                       val P = BitsN.fromBit index
22264                       val U = BitsN.fromBit add
22265                       val W = BitsN.fromBit(index andalso wback)
22266                     in
22267                       ARM(BitsN.concat
22268                             [c,BitsN.B(0x0,3),P,U,BitsN.B(0x0,1),W,
22269                              BitsN.B(0x1,1),Rn,Rt,BitsN.B(0x1,5),S,
22270                              BitsN.B(0x3,2),Rm])
22271                     end
22272              else BadCode "LoadHalf"
22273       else if (shift_t = SRType_LSL) andalso
22274          (index andalso (add andalso (not wback)))
22275         then if (shift_n = 0) andalso
22276                 (not((BitsN.bit(m,3)) orelse
22277                      ((BitsN.bit(n,3)) orelse
22278                       ((BitsN.bit(t,3)) orelse (e = Enc_Wide)))))
22279                then let
22280                       val Rm = BitsN.bits(2,0) m
22281                       val Rn = BitsN.bits(2,0) n
22282                       val Rt = BitsN.bits(2,0) t
22283                     in
22284                       Thumb
22285                         (BitsN.concat
22286                            [BitsN.B(0xB,5),S,BitsN.B(0x1,1),Rm,Rn,Rt])
22287                     end
22288              else if (Nat.<(shift_n,4)) andalso (not(e = Enc_Narrow))
22289                then let
22290                       val Rt = t
22291                       val Rn = n
22292                       val Rm = m
22293                       val imm5 = BitsN.fromNat(shift_n,5)
22294                       val imm2 = BitsN.bits(1,0) imm5
22295                     in
22296                       Thumb2
22297                         (BitsN.concat
22298                            [BitsN.B(0x7C,7),S,BitsN.B(0x3,4),Rn],
22299                          BitsN.concat[Rt,BitsN.B(0x0,6),imm2,Rm])
22300                     end
22301              else BadCode "LoadHalf"
22302       else BadCode "LoadHalf"
22303     end
22304   | LoadHalfLiteral(unsigned,(add,(Rt,imm32))) =>
22305     let
22306       val U = BitsN.fromBit add
22307       val S = BitsN.fromBit(not unsigned)
22308     in
22309       if e = Enc_ARM
22310         then if BitsN.<=+(imm32,BitsN.B(0xFF,32))
22311                then let
22312                       val imm4H = BitsN.bits(7,4) imm32
22313                       val imm4L = BitsN.bits(3,0) imm32
22314                     in
22315                       ARM(BitsN.concat
22316                             [c,BitsN.B(0x1,4),U,BitsN.B(0x5F,7),Rt,imm4H,
22317                              BitsN.B(0x1,1),S,BitsN.B(0x3,2),imm4L])
22318                     end
22319              else BadCode "LoadHalfLiteral"
22320       else if (BitsN.<=+(imm32,BitsN.B(0xFFF,32))) andalso
22321          (not(e = Enc_Narrow))
22322         then let
22323                val imm12 = BitsN.bits(11,0) imm32
22324              in
22325                Thumb2
22326                  (BitsN.concat[BitsN.B(0x7C,7),S,U,BitsN.B(0x3F,7)],
22327                   BitsN.@@(Rt,imm12))
22328              end
22329       else BadCode "LoadHalfLiteral"
22330     end
22331   | LoadHalfUnprivileged
22332     (unsigned,(add,(postindex,(Rt,(Rn,immediate_form2 imm32))))) =>
22333     let
22334       val U = BitsN.fromBit add
22335       val S = BitsN.fromBit(not unsigned)
22336     in
22337       if BitsN.<+(BitsN.B(0xFF,32),imm32)
22338         then BadCode "LoadHalfUnprivileged: bad immediate"
22339       else if (e = Enc_ARM) andalso postindex
22340         then let
22341                val imm4H = BitsN.bits(7,4) imm32
22342                val imm4L = BitsN.bits(3,0) imm32
22343              in
22344                ARM(BitsN.concat
22345                      [c,BitsN.B(0x0,4),U,BitsN.B(0x7,3),Rn,Rt,imm4H,
22346                       BitsN.B(0x1,1),S,BitsN.B(0x3,2),imm4L])
22347              end
22348       else if (Set.mem(e,[Enc_Thumb,Enc_Wide])) andalso
22349          (add andalso (not postindex))
22350         then let
22351                val imm8 = BitsN.bits(7,0) imm32
22352              in
22353                Thumb2
22354                  (BitsN.concat[BitsN.B(0x7C,7),S,BitsN.B(0x3,4),Rn],
22355                   BitsN.concat[Rt,BitsN.B(0xE,4),imm8])
22356              end
22357       else BadCode "LoadHalfUnprivileged"
22358     end
22359   | LoadHalfUnprivileged
22360     (unsigned,(add,(postindex,(Rt,(Rn,register_form2 Rm))))) =>
22361     (if (e = Enc_ARM) andalso postindex
22362        then let
22363               val U = BitsN.fromBit add
22364               val S = BitsN.fromBit(not unsigned)
22365             in
22366               ARM(BitsN.concat
22367                     [c,BitsN.B(0x0,4),U,BitsN.B(0x3,3),Rn,Rt,
22368                      BitsN.B(0x1,5),S,BitsN.B(0x3,2),Rm])
22369             end
22370      else BadCode "LoadHalfUnprivileged")
22371   | LoadMultiple(increment,(index,(wback,(n,registers)))) =>
22372     (if e = Enc_ARM
22373        then let
22374               val U = BitsN.fromBit increment
22375               val P = BitsN.fromBit index
22376               val W = BitsN.fromBit wback
22377               val Rn = n
22378             in
22379               ARM(BitsN.concat
22380                     [c,BitsN.B(0x4,3),P,U,BitsN.B(0x0,1),W,
22381                      BitsN.B(0x1,1),Rn,registers])
22382             end
22383      else if (n = (BitsN.B(0xD,4))) andalso
22384         (increment andalso
22385          ((not index) andalso
22386           (wback andalso
22387            (((BitsN.bits(14,8) registers) = (BitsN.B(0x0,7))) andalso
22388             (not(e = Enc_Wide))))))
22389        then let
22390               val P = BitsN.bits(15,15) registers
22391               val register_list = BitsN.bits(7,0) registers
22392             in
22393               Thumb(BitsN.concat[BitsN.B(0x5E,7),P,register_list])
22394             end
22395      else if (not(BitsN.bit(n,3))) andalso
22396         (increment andalso
22397          ((not index) andalso
22398           ((not(wback = (BitsN.bit(registers,BitsN.toNat n)))) andalso
22399            (((BitsN.bits(15,8) registers) = (BitsN.B(0x0,8))) andalso
22400             (not(e = Enc_Wide))))))
22401        then let
22402               val Rn = BitsN.bits(2,0) n
22403               val register_list = BitsN.bits(7,0) registers
22404             in
22405               Thumb(BitsN.concat[BitsN.B(0x19,5),Rn,register_list])
22406             end
22407      else if increment andalso
22408         ((not index) andalso (not(e = Enc_Narrow)))
22409        then let
22410               val Rn = n
22411               val W = BitsN.fromBit wback
22412             in
22413               Thumb2
22414                 (BitsN.concat[BitsN.B(0x3A2,10),W,BitsN.B(0x1,1),Rn],
22415                  registers)
22416             end
22417      else if (not increment) andalso
22418         (index andalso (not(e = Enc_Narrow)))
22419        then let
22420               val Rn = n
22421               val W = BitsN.fromBit wback
22422             in
22423               Thumb2
22424                 (BitsN.concat[BitsN.B(0x3A4,10),W,BitsN.B(0x1,1),Rn],
22425                  registers)
22426             end
22427      else BadCode "LoadMultiple")
22428   | LoadMultipleExceptionReturn
22429     (increment,(wordhigher,(wback,(Rn,registers)))) =>
22430     (if e = Enc_ARM
22431        then let
22432               val W = BitsN.fromBit wback
22433               val U = BitsN.fromBit increment
22434               val P =
22435                 BitsN.fromBit
22436                   (if wordhigher then increment else not increment)
22437             in
22438               ARM(BitsN.concat
22439                     [c,BitsN.B(0x4,3),P,U,BitsN.B(0x1,1),W,
22440                      BitsN.B(0x1,1),Rn,BitsN.B(0x1,1),registers])
22441             end
22442      else BadCode "LoadMultipleExceptionReturn")
22443   | LoadMultipleUserRegisters(increment,(wordhigher,(Rn,registers))) =>
22444     (if e = Enc_ARM
22445        then let
22446               val U = BitsN.fromBit increment
22447               val P =
22448                 BitsN.fromBit
22449                   (if wordhigher then increment else not increment)
22450             in
22451               ARM(BitsN.concat
22452                     [c,BitsN.B(0x4,3),P,U,BitsN.B(0x5,3),Rn,
22453                      BitsN.B(0x0,1),registers])
22454             end
22455      else BadCode "LoadMultipleUserRegisters")
22456   | LoadDual(add,(index,(wback,(Rt,(Rt2,(Rn,immediate_form2 imm32)))))) =>
22457     let
22458       val P = BitsN.fromBit index
22459       val U = BitsN.fromBit add
22460     in
22461       if e = Enc_ARM
22462         then if ((BitsN.+(Rt,BitsN.B(0x1,4))) = Rt2) andalso
22463                 (BitsN.<=+(imm32,BitsN.B(0xFF,32)))
22464                then let
22465                       val W = BitsN.fromBit(index andalso wback)
22466                       val imm4H = BitsN.bits(7,4) imm32
22467                       val imm4L = BitsN.bits(3,0) imm32
22468                     in
22469                       ARM(BitsN.concat
22470                             [c,BitsN.B(0x0,3),P,U,BitsN.B(0x1,1),W,
22471                              BitsN.B(0x0,1),Rn,Rt,imm4H,BitsN.B(0xD,4),
22472                              imm4L])
22473                     end
22474              else BadCode "LoadDual"
22475       else if (BitsN.<=+(imm32,BitsN.B(0x3FC,32))) andalso
22476          ((Aligned 32 (imm32,4)) andalso (not(e = Enc_Narrow)))
22477         then let
22478                val W = BitsN.fromBit wback
22479                val imm8 = BitsN.bits(9,2) imm32
22480              in
22481                Thumb2
22482                  (BitsN.concat
22483                     [BitsN.B(0x74,7),P,U,BitsN.B(0x1,1),W,BitsN.B(0x1,1),
22484                      Rn],BitsN.concat[Rt,Rt2,imm8])
22485              end
22486       else BadCode "LoadDual"
22487     end
22488   | LoadDual(add,(index,(wback,(Rt,(Rt2,(Rn,register_form2 Rm)))))) =>
22489     (if (e = Enc_ARM) andalso ((BitsN.+(Rt,BitsN.B(0x1,4))) = Rt2)
22490        then let
22491               val P = BitsN.fromBit index
22492               val U = BitsN.fromBit add
22493               val W = BitsN.fromBit(index andalso wback)
22494             in
22495               ARM(BitsN.concat
22496                     [c,BitsN.B(0x0,3),P,U,BitsN.B(0x0,1),W,
22497                      BitsN.B(0x0,1),Rn,Rt,BitsN.B(0xD,8),Rm])
22498             end
22499      else BadCode "LoadDual")
22500   | LoadDualLiteral(add,(Rt,(Rt2,imm32))) =>
22501     let
22502       val U = BitsN.fromBit add
22503     in
22504       if e = Enc_ARM
22505         then if ((BitsN.+(Rt,BitsN.B(0x1,4))) = Rt2) andalso
22506                 (BitsN.<=+(imm32,BitsN.B(0xFF,32)))
22507                then let
22508                       val imm4H = BitsN.bits(7,4) imm32
22509                       val imm4L = BitsN.bits(3,0) imm32
22510                     in
22511                       ARM(BitsN.concat
22512                             [c,BitsN.B(0x1,4),U,BitsN.B(0x4F,7),Rt,imm4H,
22513                              BitsN.B(0xD,4),imm4L])
22514                     end
22515              else BadCode "LoadDualLiteral"
22516       else if (BitsN.<=+(imm32,BitsN.B(0x3FC,32))) andalso
22517          ((Aligned 32 (imm32,4)) andalso (not(e = Enc_Narrow)))
22518         then let
22519                val imm8 = BitsN.bits(9,2) imm32
22520              in
22521                Thumb2
22522                  (BitsN.concat[BitsN.B(0xE9,8),U,BitsN.B(0x5F,7)],
22523                   BitsN.concat[Rt,Rt2,imm8])
22524              end
22525       else BadCode "LoadDualLiteral"
22526     end
22527   | LoadExclusive(Rt,(Rn,imm32)) =>
22528     (if e = Enc_ARM
22529        then if imm32 = (BitsN.B(0x0,32))
22530               then ARM(BitsN.concat
22531                          [c,BitsN.B(0x19,8),Rn,Rt,BitsN.B(0xF9F,12)])
22532             else BadCode "LoadExclusive"
22533      else if (BitsN.<=+(imm32,BitsN.B(0x3FC,32))) andalso
22534         ((Aligned 32 (imm32,4)) andalso (not(e = Enc_Narrow)))
22535        then let
22536               val imm8 = BitsN.bits(9,2) imm32
22537             in
22538               Thumb2
22539                 (BitsN.@@(BitsN.B(0xE85,12),Rn),
22540                  BitsN.concat[Rt,BitsN.B(0xF,4),imm8])
22541             end
22542      else BadCode "LoadExclusive")
22543   | LoadExclusiveByte(Rt,Rn) =>
22544     (if e = Enc_ARM
22545        then ARM(BitsN.concat[c,BitsN.B(0x1D,8),Rn,Rt,BitsN.B(0xF9F,12)])
22546      else if not(e = Enc_Narrow)
22547        then Thumb2
22548               (BitsN.@@(BitsN.B(0xE8D,12),Rn),
22549                BitsN.@@(Rt,BitsN.B(0xF4F,12)))
22550      else BadCode "LoadExclusiveByte")
22551   | LoadExclusiveHalf(Rt,Rn) =>
22552     (if e = Enc_ARM
22553        then ARM(BitsN.concat[c,BitsN.B(0x1F,8),Rn,Rt,BitsN.B(0xF9F,12)])
22554      else if not(e = Enc_Narrow)
22555        then Thumb2
22556               (BitsN.@@(BitsN.B(0xE8D,12),Rn),
22557                BitsN.@@(Rt,BitsN.B(0xF5F,12)))
22558      else BadCode "LoadExclusiveHalf")
22559   | LoadExclusiveDoubleword(Rt,(Rt2,Rn)) =>
22560     (if e = Enc_ARM
22561        then if (BitsN.+(Rt,BitsN.B(0x1,4))) = Rt2
22562               then ARM(BitsN.concat
22563                          [c,BitsN.B(0x1B,8),Rn,Rt,BitsN.B(0xF9F,12)])
22564             else BadCode "LoadExclusiveDoubleword"
22565      else if not(e = Enc_Narrow)
22566        then Thumb2
22567               (BitsN.@@(BitsN.B(0xE8D,12),Rn),
22568                BitsN.concat[Rt,Rt2,BitsN.B(0x7F,8)])
22569      else BadCode "LoadExclusiveDoubleword");
22570
22571fun e_store (c,(ast,e)) =
22572  case ast of
22573     StoreWord(_,(false,(false,_))) => BadCode "StoreWord"
22574   | StoreWord(add,(index,(wback,(t,(n,immediate_form1 imm32))))) =>
22575     (if e = Enc_ARM
22576        then if BitsN.<=+(imm32,BitsN.B(0xFFF,32))
22577               then let
22578                      val Rt = t
22579                      val Rn = n
22580                      val P = BitsN.fromBit index
22581                      val U = BitsN.fromBit add
22582                      val W = BitsN.fromBit(index andalso wback)
22583                      val imm12 = BitsN.bits(11,0) imm32
22584                    in
22585                      ARM(BitsN.concat
22586                            [c,BitsN.B(0x2,3),P,U,BitsN.B(0x0,1),W,
22587                             BitsN.B(0x0,1),Rn,Rt,imm12])
22588                    end
22589             else BadCode "StoreWord"
22590      else if index andalso (add andalso (not wback))
22591        then if (n = (BitsN.B(0xD,4))) andalso
22592                ((BitsN.<=+(imm32,BitsN.B(0x3FC,32))) andalso
22593                 ((Aligned 32 (imm32,4)) andalso
22594                  (not((BitsN.bit(t,3)) orelse (e = Enc_Wide)))))
22595               then let
22596                      val Rt = BitsN.bits(2,0) t
22597                      val imm8 = BitsN.bits(9,2) imm32
22598                    in
22599                      Thumb(BitsN.concat[BitsN.B(0x12,5),Rt,imm8])
22600                    end
22601             else if (BitsN.<=+(imm32,BitsN.B(0x7C,32))) andalso
22602                ((Aligned 32 (imm32,4)) andalso
22603                 (not((BitsN.bit(t,3)) orelse
22604                      ((BitsN.bit(n,3)) orelse (e = Enc_Wide)))))
22605               then let
22606                      val Rt = BitsN.bits(2,0) t
22607                      val Rn = BitsN.bits(2,0) n
22608                      val imm5 = BitsN.bits(6,2) imm32
22609                    in
22610                      Thumb(BitsN.concat[BitsN.B(0xC,5),imm5,Rn,Rt])
22611                    end
22612             else if (BitsN.<=+(imm32,BitsN.B(0xFFF,32))) andalso
22613                (not(e = Enc_Narrow))
22614               then let
22615                      val Rt = t
22616                      val Rn = n
22617                      val imm12 = BitsN.bits(11,0) imm32
22618                    in
22619                      Thumb2
22620                        (BitsN.@@(BitsN.B(0xF8C,12),Rn),BitsN.@@(Rt,imm12))
22621                    end
22622             else BadCode "StoreWord"
22623      else if (BitsN.<=+(imm32,BitsN.B(0xFF,32))) andalso
22624         (not(e = Enc_Narrow))
22625        then let
22626               val Rt = t
22627               val Rn = n
22628               val P = BitsN.fromBit index
22629               val U = BitsN.fromBit add
22630               val W = BitsN.fromBit wback
22631               val imm8 = BitsN.bits(7,0) imm32
22632             in
22633               Thumb2
22634                 (BitsN.@@(BitsN.B(0xF84,12),Rn),
22635                  BitsN.concat[Rt,BitsN.B(0x1,1),P,U,W,imm8])
22636             end
22637      else BadCode "StoreWord")
22638   | StoreWord
22639     (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n))))))) =>
22640     let
22641       val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
22642     in
22643       if e = Enc_ARM
22644         then let
22645                val Rn = n
22646                val Rt = t
22647                val Rm = m
22648                val P = BitsN.fromBit index
22649                val U = BitsN.fromBit add
22650                val W = BitsN.fromBit(index andalso wback)
22651              in
22652                ARM(BitsN.concat
22653                      [c,BitsN.B(0x3,3),P,U,BitsN.B(0x0,1),W,
22654                       BitsN.B(0x0,1),Rn,Rt,imm5,typ,BitsN.B(0x0,1),Rm])
22655              end
22656       else if (shift_t = SRType_LSL) andalso
22657          (index andalso (add andalso (not wback)))
22658         then if (shift_n = 0) andalso
22659                 (not((BitsN.bit(m,3)) orelse
22660                      ((BitsN.bit(n,3)) orelse
22661                       ((BitsN.bit(t,3)) orelse (e = Enc_Wide)))))
22662                then let
22663                       val Rm = BitsN.bits(2,0) m
22664                       val Rn = BitsN.bits(2,0) n
22665                       val Rt = BitsN.bits(2,0) t
22666                     in
22667                       Thumb(BitsN.concat[BitsN.B(0x28,7),Rm,Rn,Rt])
22668                     end
22669              else if (Nat.<(shift_n,4)) andalso (not(e = Enc_Narrow))
22670                then let
22671                       val Rn = n
22672                       val Rt = t
22673                       val Rm = m
22674                       val imm2 = BitsN.bits(1,0) imm5
22675                     in
22676                       Thumb2
22677                         (BitsN.@@(BitsN.B(0xF84,12),Rn),
22678                          BitsN.concat[Rt,BitsN.B(0x0,6),imm2,Rm])
22679                     end
22680              else BadCode "StoreWord"
22681       else BadCode "StoreWord"
22682     end
22683   | StoreUnprivileged(add,(postindex,(Rt,(Rn,immediate_form1 imm32)))) =>
22684     (if (e = Enc_ARM) andalso
22685         (postindex andalso (BitsN.<=+(imm32,BitsN.B(0xFFF,32))))
22686        then let
22687               val imm12 = BitsN.bits(11,0) imm32
22688               val U = BitsN.fromBit add
22689             in
22690               ARM(BitsN.concat
22691                     [c,BitsN.B(0x4,4),U,BitsN.B(0x2,3),Rn,Rt,imm12])
22692             end
22693      else if (Set.mem(e,[Enc_Thumb,Enc_Wide])) andalso
22694         (add andalso
22695          ((not postindex) andalso (BitsN.<=+(imm32,BitsN.B(0xFF,32)))))
22696        then let
22697               val imm8 = BitsN.bits(7,0) imm32
22698             in
22699               Thumb2
22700                 (BitsN.@@(BitsN.B(0xF84,12),Rn),
22701                  BitsN.concat[Rt,BitsN.B(0xE,4),imm8])
22702             end
22703      else BadCode "StoreUnprivileged")
22704   | StoreUnprivileged
22705     (add,(postindex,(Rt,(Rn,register_form1(Rm,(shift_t,shift_n)))))) =>
22706     (if (e = Enc_ARM) andalso postindex
22707        then let
22708               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
22709               val U = BitsN.fromBit add
22710             in
22711               ARM(BitsN.concat
22712                     [c,BitsN.B(0x6,4),U,BitsN.B(0x2,3),Rn,Rt,imm5,typ,
22713                      BitsN.B(0x0,1),Rm])
22714             end
22715      else BadCode "StoreUnprivileged")
22716   | StoreByte(_,(false,(false,_))) => BadCode "StoreByte"
22717   | StoreByte(add,(index,(wback,(t,(n,immediate_form1 imm32))))) =>
22718     (if e = Enc_ARM
22719        then if BitsN.<=+(imm32,BitsN.B(0xFFF,32))
22720               then let
22721                      val Rt = t
22722                      val Rn = n
22723                      val P = BitsN.fromBit index
22724                      val U = BitsN.fromBit add
22725                      val W = BitsN.fromBit(index andalso wback)
22726                      val imm12 = BitsN.bits(11,0) imm32
22727                    in
22728                      ARM(BitsN.concat
22729                            [c,BitsN.B(0x2,3),P,U,BitsN.B(0x1,1),W,
22730                             BitsN.B(0x0,1),Rn,Rt,imm12])
22731                    end
22732             else BadCode "StoreByte"
22733      else if index andalso (add andalso (not wback))
22734        then if (BitsN.<=+(imm32,BitsN.B(0x1F,32))) andalso
22735                (not((BitsN.bit(t,3)) orelse
22736                     ((BitsN.bit(n,3)) orelse (e = Enc_Wide))))
22737               then let
22738                      val Rt = BitsN.bits(2,0) t
22739                      val Rn = BitsN.bits(2,0) n
22740                      val imm5 = BitsN.bits(4,0) imm32
22741                    in
22742                      Thumb(BitsN.concat[BitsN.B(0xE,5),imm5,Rn,Rt])
22743                    end
22744             else if (BitsN.<=+(imm32,BitsN.B(0xFFF,32))) andalso
22745                (not(e = Enc_Narrow))
22746               then let
22747                      val Rt = t
22748                      val Rn = n
22749                      val imm12 = BitsN.bits(11,0) imm32
22750                    in
22751                      Thumb2
22752                        (BitsN.@@(BitsN.B(0xF88,12),Rn),BitsN.@@(Rt,imm12))
22753                    end
22754             else BadCode "StoreByte"
22755      else if (BitsN.<=+(imm32,BitsN.B(0xFF,32))) andalso
22756         (not(e = Enc_Narrow))
22757        then let
22758               val Rt = t
22759               val Rn = n
22760               val P = BitsN.fromBit index
22761               val U = BitsN.fromBit add
22762               val W = BitsN.fromBit wback
22763               val imm8 = BitsN.bits(7,0) imm32
22764             in
22765               Thumb2
22766                 (BitsN.@@(BitsN.B(0xF80,12),Rn),
22767                  BitsN.concat[Rt,BitsN.B(0x1,1),P,U,W,imm8])
22768             end
22769      else BadCode "StoreByte")
22770   | StoreByte
22771     (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n))))))) =>
22772     let
22773       val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
22774     in
22775       if e = Enc_ARM
22776         then let
22777                val Rt = t
22778                val Rn = n
22779                val Rm = m
22780                val P = BitsN.fromBit index
22781                val U = BitsN.fromBit add
22782                val W = BitsN.fromBit(index andalso wback)
22783              in
22784                ARM(BitsN.concat
22785                      [c,BitsN.B(0x3,3),P,U,BitsN.B(0x1,1),W,
22786                       BitsN.B(0x0,1),Rn,Rt,imm5,typ,BitsN.B(0x0,1),Rm])
22787              end
22788       else if (shift_t = SRType_LSL) andalso
22789          (index andalso (add andalso (not wback)))
22790         then if (shift_n = 0) andalso
22791                 (not((BitsN.bit(m,3)) orelse
22792                      ((BitsN.bit(n,3)) orelse
22793                       ((BitsN.bit(t,3)) orelse (e = Enc_Wide)))))
22794                then let
22795                       val Rm = BitsN.bits(2,0) m
22796                       val Rn = BitsN.bits(2,0) n
22797                       val Rt = BitsN.bits(2,0) t
22798                     in
22799                       Thumb(BitsN.concat[BitsN.B(0x2A,7),Rm,Rn,Rt])
22800                     end
22801              else if (Nat.<(shift_n,4)) andalso (not(e = Enc_Narrow))
22802                then let
22803                       val Rt = t
22804                       val Rn = n
22805                       val Rm = m
22806                       val imm2 = BitsN.bits(1,0) imm5
22807                     in
22808                       Thumb2
22809                         (BitsN.@@(BitsN.B(0xF80,12),Rn),
22810                          BitsN.concat[Rt,BitsN.B(0x0,6),imm2,Rm])
22811                     end
22812              else BadCode "StoreByte"
22813       else BadCode "StoreByte"
22814     end
22815   | StoreByteUnprivileged
22816     (add,(postindex,(Rt,(Rn,immediate_form1 imm32)))) =>
22817     (if (e = Enc_ARM) andalso
22818         (postindex andalso (BitsN.<=+(imm32,BitsN.B(0xFFF,32))))
22819        then let
22820               val imm12 = BitsN.bits(11,0) imm32
22821               val U = BitsN.fromBit add
22822             in
22823               ARM(BitsN.concat
22824                     [c,BitsN.B(0x4,4),U,BitsN.B(0x6,3),Rn,Rt,imm12])
22825             end
22826      else if (Set.mem(e,[Enc_Thumb,Enc_Wide])) andalso
22827         (add andalso
22828          ((not postindex) andalso (BitsN.<=+(imm32,BitsN.B(0xFF,32)))))
22829        then let
22830               val imm8 = BitsN.bits(7,0) imm32
22831             in
22832               Thumb2
22833                 (BitsN.@@(BitsN.B(0xF80,12),Rn),
22834                  BitsN.concat[Rt,BitsN.B(0xE,4),imm8])
22835             end
22836      else BadCode "StoreByteUnprivileged")
22837   | StoreByteUnprivileged
22838     (add,(postindex,(Rt,(Rn,register_form1(Rm,(shift_t,shift_n)))))) =>
22839     (if (e = Enc_ARM) andalso postindex
22840        then let
22841               val (typ,imm5) = EncodeImmShift(shift_t,shift_n)
22842               val U = BitsN.fromBit add
22843             in
22844               ARM(BitsN.concat
22845                     [c,BitsN.B(0x6,4),U,BitsN.B(0x6,3),Rn,Rt,imm5,typ,
22846                      BitsN.B(0x0,1),Rm])
22847             end
22848      else BadCode "StoreByteUnprivileged")
22849   | StoreHalf(_,(false,(false,_))) => BadCode "StoreHalf"
22850   | StoreHalf(add,(index,(wback,(t,(n,immediate_form1 imm32))))) =>
22851     (if e = Enc_ARM
22852        then if BitsN.<=+(imm32,BitsN.B(0xFF,32))
22853               then let
22854                      val Rt = t
22855                      val Rn = n
22856                      val P = BitsN.fromBit index
22857                      val U = BitsN.fromBit add
22858                      val W = BitsN.fromBit(index andalso wback)
22859                      val imm4H = BitsN.bits(7,4) imm32
22860                      val imm4L = BitsN.bits(3,0) imm32
22861                    in
22862                      ARM(BitsN.concat
22863                            [c,BitsN.B(0x0,3),P,U,BitsN.B(0x1,1),W,
22864                             BitsN.B(0x0,1),Rn,Rt,imm4H,BitsN.B(0xB,4),
22865                             imm4L])
22866                    end
22867             else BadCode "StoreHalf"
22868      else if index andalso (add andalso (not wback))
22869        then if (BitsN.<=+(imm32,BitsN.B(0x3E,32))) andalso
22870                ((Aligned 32 (imm32,2)) andalso
22871                 (not((BitsN.bit(t,3)) orelse
22872                      ((BitsN.bit(n,3)) orelse (e = Enc_Wide)))))
22873               then let
22874                      val Rt = BitsN.bits(2,0) t
22875                      val Rn = BitsN.bits(2,0) n
22876                      val imm5 = BitsN.bits(5,1) imm32
22877                    in
22878                      Thumb(BitsN.concat[BitsN.B(0x10,5),imm5,Rn,Rt])
22879                    end
22880             else if (BitsN.<=+(imm32,BitsN.B(0xFFF,32))) andalso
22881                (not(e = Enc_Narrow))
22882               then let
22883                      val Rt = t
22884                      val Rn = n
22885                      val imm12 = BitsN.bits(11,0) imm32
22886                    in
22887                      Thumb2
22888                        (BitsN.@@(BitsN.B(0xF8A,12),Rn),BitsN.@@(Rt,imm12))
22889                    end
22890             else BadCode "StoreHalf"
22891      else if (BitsN.<=+(imm32,BitsN.B(0xFF,32))) andalso
22892         (not(e = Enc_Narrow))
22893        then let
22894               val Rt = t
22895               val Rn = n
22896               val P = BitsN.fromBit index
22897               val U = BitsN.fromBit add
22898               val W = BitsN.fromBit wback
22899               val imm8 = BitsN.bits(7,0) imm32
22900             in
22901               Thumb2
22902                 (BitsN.@@(BitsN.B(0xF82,12),Rn),
22903                  BitsN.concat[Rt,BitsN.B(0x1,1),P,U,W,imm8])
22904             end
22905      else BadCode "StoreHalf")
22906   | StoreHalf
22907     (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n))))))) =>
22908     (if e = Enc_ARM
22909        then if (shift_t = SRType_LSL) andalso (shift_n = 0)
22910               then let
22911                      val Rt = t
22912                      val Rn = n
22913                      val Rm = m
22914                      val P = BitsN.fromBit index
22915                      val U = BitsN.fromBit add
22916                      val W = BitsN.fromBit(index andalso wback)
22917                    in
22918                      ARM(BitsN.concat
22919                            [c,BitsN.B(0x0,3),P,U,BitsN.B(0x0,1),W,
22920                             BitsN.B(0x0,1),Rn,Rt,BitsN.B(0xB,8),Rm])
22921                    end
22922             else BadCode "StoreHalf"
22923      else if (shift_t = SRType_LSL) andalso
22924         (index andalso (add andalso (not wback)))
22925        then if (shift_n = 0) andalso
22926                (not((BitsN.bit(m,3)) orelse
22927                     ((BitsN.bit(n,3)) orelse
22928                      ((BitsN.bit(t,3)) orelse (e = Enc_Wide)))))
22929               then let
22930                      val Rm = BitsN.bits(2,0) m
22931                      val Rn = BitsN.bits(2,0) n
22932                      val Rt = BitsN.bits(2,0) t
22933                    in
22934                      Thumb(BitsN.concat[BitsN.B(0x29,7),Rm,Rn,Rt])
22935                    end
22936             else if (Nat.<(shift_n,4)) andalso (not(e = Enc_Narrow))
22937               then let
22938                      val Rt = t
22939                      val Rn = n
22940                      val Rm = m
22941                      val imm5 = BitsN.fromNat(shift_n,5)
22942                      val imm2 = BitsN.bits(1,0) imm5
22943                    in
22944                      Thumb2
22945                        (BitsN.@@(BitsN.B(0xF82,12),Rn),
22946                         BitsN.concat[Rt,BitsN.B(0x0,6),imm2,Rm])
22947                    end
22948             else BadCode "StoreHalf"
22949      else BadCode "StoreHalf")
22950   | StoreHalfUnprivileged
22951     (add,(postindex,(Rt,(Rn,immediate_form2 imm32)))) =>
22952     let
22953       val U = BitsN.fromBit add
22954     in
22955       if BitsN.<+(BitsN.B(0xFF,32),imm32)
22956         then BadCode "StoreHalfUnprivileged: bad immediate"
22957       else if (e = Enc_ARM) andalso postindex
22958         then let
22959                val imm4H = BitsN.bits(7,4) imm32
22960                val imm4L = BitsN.bits(3,0) imm32
22961              in
22962                ARM(BitsN.concat
22963                      [c,BitsN.B(0x0,4),U,BitsN.B(0x6,3),Rn,Rt,imm4H,
22964                       BitsN.B(0xB,4),imm4L])
22965              end
22966       else if (Set.mem(e,[Enc_Thumb,Enc_Wide])) andalso
22967          (add andalso (not postindex))
22968         then let
22969                val imm8 = BitsN.bits(7,0) imm32
22970              in
22971                Thumb2
22972                  (BitsN.@@(BitsN.B(0xF82,12),Rn),
22973                   BitsN.concat[Rt,BitsN.B(0xE,4),imm8])
22974              end
22975       else BadCode "StoreHalfUnprivileged"
22976     end
22977   | StoreHalfUnprivileged(add,(postindex,(Rt,(Rn,register_form2 Rm)))) =>
22978     (if (e = Enc_ARM) andalso postindex
22979        then let
22980               val U = BitsN.fromBit add
22981             in
22982               ARM(BitsN.concat
22983                     [c,BitsN.B(0x0,4),U,BitsN.B(0x2,3),Rn,Rt,
22984                      BitsN.B(0xB,8),Rm])
22985             end
22986      else BadCode "StoreHalfUnprivileged")
22987   | StoreMultiple(increment,(index,(wback,(n,registers)))) =>
22988     (if e = Enc_ARM
22989        then let
22990               val U = BitsN.fromBit increment
22991               val P = BitsN.fromBit index
22992               val W = BitsN.fromBit wback
22993               val Rn = n
22994             in
22995               ARM(BitsN.concat
22996                     [c,BitsN.B(0x4,3),P,U,BitsN.B(0x0,1),W,
22997                      BitsN.B(0x0,1),Rn,registers])
22998             end
22999      else if (n = (BitsN.B(0xD,4))) andalso
23000         ((not increment) andalso
23001          (index andalso
23002           (wback andalso
23003            ((not(BitsN.bit(registers,15))) andalso
23004             (((BitsN.bits(13,8) registers) = (BitsN.B(0x0,6))) andalso
23005              (not(e = Enc_Wide)))))))
23006        then let
23007               val M = BitsN.bits(14,14) registers
23008               val register_list = BitsN.bits(7,0) registers
23009             in
23010               Thumb(BitsN.concat[BitsN.B(0x5A,7),M,register_list])
23011             end
23012      else if (not(BitsN.bit(n,3))) andalso
23013         (increment andalso
23014          ((not index) andalso
23015           (wback andalso
23016            (((BitsN.bits(15,8) registers) = (BitsN.B(0x0,8))) andalso
23017             (not(e = Enc_Wide))))))
23018        then let
23019               val Rn = BitsN.bits(2,0) n
23020               val register_list = BitsN.bits(7,0) registers
23021             in
23022               Thumb(BitsN.concat[BitsN.B(0x18,5),Rn,register_list])
23023             end
23024      else if (not(increment = index)) andalso (not(e = Enc_Narrow))
23025        then let
23026               val Rn = n
23027               val U = BitsN.fromBit increment
23028               val P = BitsN.fromBit index
23029               val W = BitsN.fromBit wback
23030             in
23031               Thumb2
23032                 (BitsN.concat
23033                    [BitsN.B(0x74,7),P,U,BitsN.B(0x0,1),W,BitsN.B(0x0,1),
23034                     Rn],registers)
23035             end
23036      else BadCode "StoreHalfUnprivileged")
23037   | StoreMultipleUserRegisters(increment,(wordhigher,(Rn,registers))) =>
23038     (if e = Enc_ARM
23039        then let
23040               val U = BitsN.fromBit increment
23041               val P =
23042                 BitsN.fromBit
23043                   (if wordhigher then increment else not increment)
23044             in
23045               ARM(BitsN.concat
23046                     [c,BitsN.B(0x4,3),P,U,BitsN.B(0x4,3),Rn,registers])
23047             end
23048      else BadCode "StoreMultipleUserRegisters")
23049   | StoreDual(add,(index,(wback,(Rt,(Rt2,(Rn,immediate_form2 imm32)))))) =>
23050     let
23051       val P = BitsN.fromBit index
23052       val U = BitsN.fromBit add
23053     in
23054       if e = Enc_ARM
23055         then if ((BitsN.+(Rt,BitsN.B(0x1,4))) = Rt2) andalso
23056                 (BitsN.<=+(imm32,BitsN.B(0xFF,32)))
23057                then let
23058                       val W = BitsN.fromBit(index andalso wback)
23059                       val imm4H = BitsN.bits(7,4) imm32
23060                       val imm4L = BitsN.bits(3,0) imm32
23061                     in
23062                       ARM(BitsN.concat
23063                             [c,BitsN.B(0x0,3),P,U,BitsN.B(0x1,1),W,
23064                              BitsN.B(0x0,1),Rn,Rt,imm4H,BitsN.B(0xF,4),
23065                              imm4L])
23066                     end
23067              else BadCode "StoreDual"
23068       else if (BitsN.<=+(imm32,BitsN.B(0x3FC,32))) andalso
23069          ((Aligned 32 (imm32,4)) andalso (not(e = Enc_Narrow)))
23070         then let
23071                val W = BitsN.fromBit wback
23072                val imm8 = BitsN.bits(9,2) imm32
23073              in
23074                Thumb2
23075                  (BitsN.concat
23076                     [BitsN.B(0x74,7),P,U,BitsN.B(0x1,1),W,BitsN.B(0x0,1),
23077                      Rn],BitsN.concat[Rt,Rt2,imm8])
23078              end
23079       else BadCode "StoreDual"
23080     end
23081   | StoreDual(add,(index,(wback,(Rt,(Rt2,(Rn,register_form2 Rm)))))) =>
23082     (if (e = Enc_ARM) andalso ((BitsN.+(Rt,BitsN.B(0x1,4))) = Rt2)
23083        then let
23084               val P = BitsN.fromBit index
23085               val U = BitsN.fromBit add
23086               val W = BitsN.fromBit(index andalso wback)
23087             in
23088               ARM(BitsN.concat
23089                     [c,BitsN.B(0x0,3),P,U,BitsN.B(0x0,1),W,
23090                      BitsN.B(0x0,1),Rn,Rt,BitsN.B(0xF,8),Rm])
23091             end
23092      else BadCode "StoreDual")
23093   | StoreExclusive(Rd,(Rt,(Rn,imm32))) =>
23094     (if e = Enc_ARM
23095        then if imm32 = (BitsN.B(0x0,32))
23096               then ARM(BitsN.concat
23097                          [c,BitsN.B(0x18,8),Rn,Rd,BitsN.B(0xF9,8),Rt])
23098             else BadCode "StoreExclusive"
23099      else if (BitsN.<=+(imm32,BitsN.B(0x3FC,32))) andalso
23100         ((Aligned 32 (imm32,4)) andalso (not(e = Enc_Narrow)))
23101        then let
23102               val imm8 = BitsN.bits(9,2) imm32
23103             in
23104               Thumb2
23105                 (BitsN.@@(BitsN.B(0xE84,12),Rn),BitsN.concat[Rt,Rd,imm8])
23106             end
23107      else BadCode "StoreExclusive")
23108   | StoreExclusiveByte(Rd,(Rt,Rn)) =>
23109     (if e = Enc_ARM
23110        then ARM(BitsN.concat[c,BitsN.B(0x1C,8),Rn,Rd,BitsN.B(0xF9,8),Rt])
23111      else if not(e = Enc_Narrow)
23112        then Thumb2
23113               (BitsN.@@(BitsN.B(0xE8C,12),Rn),
23114                BitsN.concat[Rt,BitsN.B(0xF4,8),Rd])
23115      else BadCode "StoreExclusiveByte")
23116   | StoreExclusiveHalf(Rd,(Rt,Rn)) =>
23117     (if e = Enc_ARM
23118        then ARM(BitsN.concat[c,BitsN.B(0x1E,8),Rn,Rd,BitsN.B(0xF9,8),Rt])
23119      else if not(e = Enc_Narrow)
23120        then Thumb2
23121               (BitsN.@@(BitsN.B(0xE8C,12),Rn),
23122                BitsN.concat[Rt,BitsN.B(0xF5,8),Rd])
23123      else BadCode "StoreExclusiveByte")
23124   | StoreExclusiveDoubleword(Rd,(Rt,(Rt2,Rn))) =>
23125     (if e = Enc_ARM
23126        then if (BitsN.+(Rt,BitsN.B(0x1,4))) = Rt2
23127               then ARM(BitsN.concat
23128                          [c,BitsN.B(0x1A,8),Rn,Rd,BitsN.B(0xF9,8),Rt])
23129             else BadCode "StoreExclusiveDoubleword"
23130      else if not(e = Enc_Narrow)
23131        then Thumb2
23132               (BitsN.@@(BitsN.B(0xE8C,12),Rn),
23133                BitsN.concat[Rt,Rt2,BitsN.B(0x7,4),Rd])
23134      else BadCode "StoreExclusiveDoubleword");
23135
23136fun instructionEncode (c,(ast,e)) =
23137  case ast of
23138     Branch b => e_branch(c,(b,e))
23139   | Data d => e_data(c,(d,e))
23140   | Load l => e_load(c,(l,e))
23141   | Store s => e_store(c,(s,e))
23142   | Multiply m => e_multiply(c,(m,e))
23143   | Media m => e_media(c,(m,e))
23144   | SIMD m => e_simd(c,(m,e))
23145   | System s => e_system(c,(s,e))
23146   | Hint h => e_hint(c,(h,e))
23147   | VFP v => e_vfp(c,(v,e))
23148   | IfThen(firstcond,mask) =>
23149     (if Set.mem(e,[Enc_Thumb,Enc_Narrow])
23150        then Thumb(BitsN.concat[BitsN.B(0xBF,8),firstcond,mask])
23151      else BadCode "IfThen")
23152   | Divide(unsigned,(Rd,(Rn,Rm))) =>
23153     (if Set.mem(e,[Enc_Thumb,Enc_Wide])
23154        then let
23155               val U = BitsN.fromBit unsigned
23156             in
23157               Thumb2
23158                 (BitsN.concat[BitsN.B(0x3EE,10),U,BitsN.B(0x1,1),Rn],
23159                  BitsN.concat[BitsN.B(0xF,4),Rd,BitsN.B(0xF,4),Rm])
23160             end
23161      else BadCode "Divide")
23162   | ClearExclusive =>
23163     if e = Enc_ARM
23164       then if c = (BitsN.B(0xE,4))
23165              then ARM(BitsN.B(0xF57FF01F,32))
23166            else BadCode "ClearExclusive"
23167     else if not(e = Enc_Narrow)
23168       then Thumb2(BitsN.B(0xF3BF,16),BitsN.B(0x8F2F,16))
23169     else BadCode "ClearExclusive"
23170   | Swap(byte,(Rt,(Rt2,Rn))) =>
23171     (if e = Enc_ARM
23172        then let
23173               val B = BitsN.fromBit byte
23174             in
23175               ARM(BitsN.concat
23176                     [c,BitsN.B(0x2,5),B,BitsN.B(0x0,2),Rn,Rt,
23177                      BitsN.B(0x9,8),Rt2])
23178             end
23179      else BadCode "Swap")
23180   | Undefined imm32 =>
23181     (if e = Enc_ARM
23182        then let
23183               val imm12 = BitsN.bits(15,4) imm32
23184               val imm4 = BitsN.bits(3,0) imm32
23185             in
23186               ARM(BitsN.concat
23187                     [BitsN.B(0xE7F,12),imm12,BitsN.B(0xF,4),imm4])
23188             end
23189      else if (not(e = Enc_Wide)) andalso
23190         ((BitsN.bits(31,8) imm32) = (BitsN.B(0x0,24)))
23191        then let
23192               val imm8 = BitsN.bits(7,0) imm32
23193             in
23194               Thumb(BitsN.@@(BitsN.B(0xDE,8),imm8))
23195             end
23196      else if not(e = Enc_Narrow)
23197        then let
23198               val imm4 = BitsN.bits(15,12) imm32
23199               val imm12 = BitsN.bits(11,0) imm32
23200             in
23201               Thumb2
23202                 (BitsN.@@(BitsN.B(0xF7F,12),imm4),
23203                  BitsN.@@(BitsN.B(0xA,4),imm12))
23204             end
23205      else BadCode "Undefined")
23206   | NoOperation =>
23207     if e = Enc_ARM
23208       then ARM(BitsN.@@(c,BitsN.B(0x320F000,28)))
23209     else if e = Enc_Wide
23210       then Thumb2(BitsN.B(0xF3AF,16),BitsN.B(0x8000,16))
23211     else Thumb(BitsN.B(0xBF00,16));
23212
23213fun SetPassCondition c =
23214  case c of
23215     BitsN.B(0x0,_) => CPSR := (PSR_Z_rupd((!CPSR),true))
23216   | BitsN.B(0x1,_) => CPSR := (PSR_Z_rupd((!CPSR),false))
23217   | BitsN.B(0x2,_) => CPSR := (PSR_C_rupd((!CPSR),true))
23218   | BitsN.B(0x3,_) => CPSR := (PSR_C_rupd((!CPSR),false))
23219   | BitsN.B(0x4,_) => CPSR := (PSR_N_rupd((!CPSR),true))
23220   | BitsN.B(0x5,_) => CPSR := (PSR_N_rupd((!CPSR),false))
23221   | BitsN.B(0x6,_) => CPSR := (PSR_V_rupd((!CPSR),true))
23222   | BitsN.B(0x7,_) => CPSR := (PSR_V_rupd((!CPSR),false))
23223   | BitsN.B(0x8,_) =>
23224     ( CPSR := (PSR_C_rupd((!CPSR),true))
23225     ; CPSR := (PSR_Z_rupd((!CPSR),false))
23226     )
23227   | BitsN.B(0x9,_) => CPSR := (PSR_C_rupd((!CPSR),false))
23228   | BitsN.B(0xA,_) =>
23229     ( CPSR := (PSR_N_rupd((!CPSR),false))
23230     ; CPSR := (PSR_V_rupd((!CPSR),false))
23231     )
23232   | BitsN.B(0xB,_) =>
23233     ( CPSR := (PSR_N_rupd((!CPSR),false))
23234     ; CPSR := (PSR_V_rupd((!CPSR),true))
23235     )
23236   | BitsN.B(0xC,_) =>
23237     ( CPSR := (PSR_N_rupd((!CPSR),false))
23238     ; CPSR := (PSR_V_rupd((!CPSR),false))
23239     ; CPSR := (PSR_Z_rupd((!CPSR),false))
23240     )
23241   | BitsN.B(0xD,_) =>
23242     ( CPSR := (PSR_N_rupd((!CPSR),false))
23243     ; CPSR := (PSR_V_rupd((!CPSR),true))
23244     )
23245   | _ => ();
23246
23247fun Encode (c,(ast,enc)) =
23248  let
23249    val mc = instructionEncode(c,(ast,enc))
23250  in
23251    ( case mc of
23252         ARM _ => Encoding := Encoding_ARM
23253       | Thumb2 _ => Encoding := Encoding_Thumb2
23254       | Thumb _ => Encoding := Encoding_Thumb
23255       | ThumbEE _ => Encoding := Encoding_Thumb
23256       | BadCode _ => ()
23257    ; SetPassCondition c
23258    ; if ((Decode mc) = ast) andalso
23259         (((!CurrentCondition) = c) orelse
23260          (((!CurrentCondition) = (BitsN.B(0xE,4))) andalso
23261           (c = (BitsN.B(0xF,4)))))
23262        then mc
23263      else BadCode "Does not decode to the same instruction"
23264    )
23265  end;
23266
23267val al = (BitsN.B(0xE,4),"")
23268
23269fun stripSpaces s =
23270  L3.fst
23271    (L3.splitr
23272       (fn c => Char.isSpace c,L3.snd(L3.splitl(fn c => Char.isSpace c,s))));
23273
23274fun p_number s =
23275  case String.explode(stripSpaces s) of
23276     #"0" :: (#"b" :: t) => Nat.fromBinString(String.implode t)
23277   | #"0" :: (#"x" :: t) => Nat.fromHexString(String.implode t)
23278   | _ => Nat.fromString s;
23279
23280fun p_signed_number (b,s) =
23281  case p_number s of Option.SOME n => Option.SOME(b,n) | NONE => NONE;
23282
23283fun p_encode_immediate N s =
23284  case p_number s of
23285     Option.SOME n =>
23286       let
23287         val r = BitsN.fromNat(n,N)
23288       in
23289         Option.SOME(n = (BitsN.toNat r),r)
23290       end
23291   | NONE => NONE;
23292
23293fun p_encode_signed_immediate N x =
23294  case p_signed_number x of
23295     Option.SOME(sub,n) =>
23296       let
23297         val r = BitsN.fromNat(n,N)
23298       in
23299         Option.SOME(sub,(n = (BitsN.toNat r),r))
23300       end
23301   | NONE => NONE;
23302
23303fun p_encode_signed_immediate_offset N x =
23304  case p_signed_number x of
23305     Option.SOME(sub,n) =>
23306       let
23307         val (sub,n) =
23308           if sub
23309             then (true,Nat.+(n,8))
23310           else if Nat.<(n,8)
23311             then (true,Nat.-(8,n))
23312           else (false,Nat.-(n,8))
23313         val r = BitsN.fromNat(n,N)
23314       in
23315         Option.SOME(sub,(n = (BitsN.toNat r),r))
23316       end
23317   | NONE => NONE;
23318
23319fun p_encode_signed_offset N x =
23320  case p_signed_number x of
23321     Option.SOME(sub,n) =>
23322       let
23323         val i =
23324           IntInf.-(if sub then IntInf.~(Nat.toInt n) else Nat.toInt n,8)
23325         val r = BitsN.fromInt(i,N)
23326       in
23327         Option.SOME(i = (BitsN.toInt r),r)
23328       end
23329   | NONE => NONE;
23330
23331fun p_unbounded_immediate s =
23332  case String.explode(stripSpaces s) of
23333     #"#" :: t => p_number(String.implode t)
23334   | _ => NONE;
23335
23336fun p_immediate N s =
23337  case String.explode(stripSpaces s) of
23338     #"#" :: t => p_encode_immediate N (String.implode t)
23339   | _ => NONE;
23340
23341fun p_immediate_number N s =
23342  case String.explode(stripSpaces s) of
23343     #"#" :: t => p_encode_immediate N (String.implode t)
23344   | t => p_encode_immediate N (String.implode t);
23345
23346fun p_signed_immediate N s =
23347  case String.explode(stripSpaces s) of
23348     #"#" :: (#"-" :: t) =>
23349       p_encode_signed_immediate N (true,String.implode t)
23350   | #"#" :: (#"+" :: t) =>
23351     p_encode_signed_immediate N (false,String.implode t)
23352   | #"#" :: t => p_encode_signed_immediate N (false,String.implode t)
23353   | _ => NONE;
23354
23355fun p_signed_offset N s =
23356  case String.explode(stripSpaces s) of
23357     #"-" :: (#"#" :: t) =>
23358       p_encode_signed_immediate_offset N (true,String.implode t)
23359   | #"+" :: (#"#" :: t) =>
23360     p_encode_signed_immediate_offset N (false,String.implode t)
23361   | _ => NONE;
23362
23363fun p_offset N s =
23364  case String.explode(stripSpaces s) of
23365     #"-" :: (#"#" :: t) =>
23366       p_encode_signed_offset N (true,String.implode t)
23367   | #"+" :: (#"#" :: t) =>
23368     p_encode_signed_offset N (false,String.implode t)
23369   | _ => NONE;
23370
23371fun p_arm_immediate s =
23372  case p_immediate 32 s of
23373     Option.SOME(true,imm32) =>
23374       (case EncodeARMImmediate imm32 of
23375           Option.SOME imm12 => Option.SOME("",imm12)
23376         | NONE => Option.SOME("immediate not encodable",BitsN.B(0x0,12)))
23377   | Option.SOME(false,_) =>
23378     Option.SOME("immediate too large",BitsN.B(0x0,12))
23379   | NONE => NONE;
23380
23381fun p_arm_fp_immediate (single,s) =
23382  case p_immediate 64 s of
23383     Option.SOME(true,imm64) => Option.SOME("",imm64)
23384   | Option.SOME(false,_) =>
23385     Option.SOME("FP immediate too large",BitsN.B(0x0,64))
23386   | NONE =>
23387     (case p_encode_immediate 8 s of
23388         Option.SOME(true,w) => Option.SOME("",VFPExpandImm(w,single))
23389       | Option.SOME(false,_) =>
23390         Option.SOME("FP too large",BitsN.B(0x0,64))
23391       | NONE => NONE);
23392
23393fun p_range_imm (mn,(mx,s)) =
23394  case String.explode(stripSpaces s) of
23395     #"#" :: t =>
23396       (case p_number(String.implode t) of
23397           Option.SOME n =>
23398             (if (Nat.<=(mn,n)) andalso (Nat.<=(n,mx))
23399                then ("",n)
23400              else (String.concat
23401                      ["immediate not in range ",Nat.toString mn," to ",
23402                       Nat.toString mx],0))
23403         | NONE => ("syntax error",0))
23404   | _ => ("syntax error",0);
23405
23406fun p_label s =
23407  case L3.uncurry String.tokens (fn c => Char.isSpace c,s) of
23408     [t] =>
23409       let
23410         val (l,r) =
23411           L3.splitl
23412             (fn c => (Char.isAlphaNum c) orelse (Set.mem(c,[#"_",#"."])),
23413              t)
23414       in
23415         if (r = "") andalso
23416            ((not(l = "")) andalso (not(Char.isDigit(L3.strHd l))))
23417           then Option.SOME l
23418         else NONE
23419       end
23420   | _ => NONE;
23421
23422fun p_cond s =
23423  case s of
23424     "eq" => Option.SOME(BitsN.B(0x0,4))
23425   | "ne" => Option.SOME(BitsN.B(0x1,4))
23426   | "cs" => Option.SOME(BitsN.B(0x2,4))
23427   | "hs" => Option.SOME(BitsN.B(0x2,4))
23428   | "cc" => Option.SOME(BitsN.B(0x3,4))
23429   | "lo" => Option.SOME(BitsN.B(0x3,4))
23430   | "mi" => Option.SOME(BitsN.B(0x4,4))
23431   | "pl" => Option.SOME(BitsN.B(0x5,4))
23432   | "vs" => Option.SOME(BitsN.B(0x6,4))
23433   | "vc" => Option.SOME(BitsN.B(0x7,4))
23434   | "hi" => Option.SOME(BitsN.B(0x8,4))
23435   | "ls" => Option.SOME(BitsN.B(0x9,4))
23436   | "ge" => Option.SOME(BitsN.B(0xA,4))
23437   | "lt" => Option.SOME(BitsN.B(0xB,4))
23438   | "gt" => Option.SOME(BitsN.B(0xC,4))
23439   | "le" => Option.SOME(BitsN.B(0xD,4))
23440   | "al" => Option.SOME(BitsN.B(0xE,4))
23441   | "" => Option.SOME(BitsN.B(0xE,4))
23442   | _ => NONE;
23443
23444fun p_suffix s =
23445  case L3.uncurry String.fields (fn c => c = #".",s) of
23446     [cond,s] =>
23447       (case (p_cond cond,
23448         Set.mem(s,["w","n","f32","f64","32","64","s32","u32"])) of
23449           (Option.SOME c,true) => Option.SOME(c,s)
23450         | _ => NONE)
23451   | [cond] =>
23452     (case p_cond cond of
23453         Option.SOME c => Option.SOME(c,"")
23454       | NONE => NONE)
23455   | _ => NONE;
23456
23457fun p_suffix2 s =
23458  case L3.uncurry String.fields (fn c => c = #".",s) of
23459     [cond,s1,s2] =>
23460       (case (p_cond cond,
23461         (Set.mem(s1,["f32","f64","s32","u32"])) andalso
23462         (Set.mem(s2,["f32","f64","s32","u32"]))) of
23463           (Option.SOME c,true) => Option.SOME(c,(s1,s2))
23464         | _ => NONE)
23465   | _ => NONE;
23466
23467fun p_register s =
23468  case stripSpaces s of
23469     "r0" => Option.SOME(BitsN.B(0x0,4))
23470   | "r1" => Option.SOME(BitsN.B(0x1,4))
23471   | "r2" => Option.SOME(BitsN.B(0x2,4))
23472   | "r3" => Option.SOME(BitsN.B(0x3,4))
23473   | "r4" => Option.SOME(BitsN.B(0x4,4))
23474   | "r5" => Option.SOME(BitsN.B(0x5,4))
23475   | "r6" => Option.SOME(BitsN.B(0x6,4))
23476   | "r7" => Option.SOME(BitsN.B(0x7,4))
23477   | "r8" => Option.SOME(BitsN.B(0x8,4))
23478   | "r9" => Option.SOME(BitsN.B(0x9,4))
23479   | "r10" => Option.SOME(BitsN.B(0xA,4))
23480   | "r11" => Option.SOME(BitsN.B(0xB,4))
23481   | "r12" => Option.SOME(BitsN.B(0xC,4))
23482   | "r13" => Option.SOME(BitsN.B(0xD,4))
23483   | "r14" => Option.SOME(BitsN.B(0xE,4))
23484   | "r15" => Option.SOME(BitsN.B(0xF,4))
23485   | "sp" => Option.SOME(BitsN.B(0xD,4))
23486   | "lr" => Option.SOME(BitsN.B(0xE,4))
23487   | "pc" => Option.SOME(BitsN.B(0xF,4))
23488   | _ => NONE;
23489
23490fun p_register1 l = case l of [r1] => p_register r1 | _ => NONE;
23491
23492fun p_register2 l =
23493  case l of
23494     [r1,r2] =>
23495       (case (p_register r1,p_register r2) of
23496           (Option.SOME v1,Option.SOME v2) => Option.SOME(v1,v2)
23497         | _ => NONE)
23498   | _ => NONE;
23499
23500fun p_register3 l =
23501  case l of
23502     [r1,r2,r3] =>
23503       (case (p_register r1,(p_register r2,p_register r3)) of
23504           (Option.SOME v1,(Option.SOME v2,Option.SOME v3)) =>
23505             Option.SOME(v1,(v2,v3))
23506         | _ => NONE)
23507   | _ => NONE;
23508
23509fun p_register4 l =
23510  case l of
23511     [r1,r2,r3,r4] =>
23512       (case (p_register r1,(p_register r2,(p_register r3,p_register r4))) of
23513           (Option.SOME v1,
23514            (Option.SOME v2,(Option.SOME v3,Option.SOME v4))) =>
23515             Option.SOME(v1,(v2,(v3,v4)))
23516         | _ => NONE)
23517   | _ => NONE;
23518
23519fun p_reg_offset (sub,s) =
23520  case p_register s of Option.SOME r => Option.SOME(sub,r) | NONE => NONE;
23521
23522fun p_register_offset s =
23523  case String.explode(stripSpaces s) of
23524     #"-" :: t => p_reg_offset(false,String.implode t)
23525   | #"+" :: t => p_reg_offset(true,String.implode t)
23526   | t => p_reg_offset(true,String.implode t);
23527
23528fun p_fp_register (single,s) =
23529  case (String.explode(stripSpaces s),single) of
23530     (#"s" :: r,true) =>
23531       (case Nat.fromString(String.implode r) of
23532           Option.SOME n =>
23533             (if Nat.<(n,32)
23534                then Option.SOME(BitsN.fromNat(n,5))
23535              else NONE)
23536         | NONE => NONE)
23537   | (#"d" :: r,false) =>
23538     (case Nat.fromString(String.implode r) of
23539         Option.SOME n =>
23540           (if Nat.<(n,32) then Option.SOME(BitsN.fromNat(n,5)) else NONE)
23541       | NONE => NONE)
23542   | _ => NONE;
23543
23544fun p_any_fp_register (s,t) =
23545  case (p_fp_register(true,s),Set.mem(t,["","32"])) of
23546     (Option.SOME r,true) => Option.SOME(true,r)
23547   | _ =>
23548     (case (p_fp_register(false,s),Set.mem(t,["","64"])) of
23549         (Option.SOME r,true) => Option.SOME(false,r)
23550       | _ => NONE);
23551
23552fun p_fp_register3 (single,l) =
23553  case l of
23554     [r1,r2,r3] =>
23555       (case (p_fp_register(single,r1),
23556         (p_fp_register(single,r2),p_fp_register(single,r3))) of
23557           (Option.SOME v1,(Option.SOME v2,Option.SOME v3)) =>
23558             Option.SOME(v1,(v2,v3))
23559         | _ => NONE)
23560   | _ => NONE;
23561
23562fun closingRegList s =
23563  let
23564    val (l,caret) = L3.splitr(fn c => c = #"^",stripSpaces s)
23565    val (l,r) = L3.splitr(fn c => c = #"}",stripSpaces l)
23566  in
23567    if (r = "}") andalso (Nat.<(L3.size caret,2))
23568      then Option.SOME(caret = "^",l)
23569    else NONE
23570  end;
23571
23572fun p_reg_list (w,s) =
23573  case p_register s of
23574     Option.SOME r =>
23575       let
23576         val n = BitsN.toNat r
23577       in
23578         if BitsN.bit(w,n)
23579           then NONE
23580         else Option.SOME(BitsN.||(w,BitsN.<<(BitsN.B(0x1,16),n)))
23581       end
23582   | NONE =>
23583     (case L3.uncurry String.fields (fn c => c = #"-",s) of
23584         [r1,r2] =>
23585           (case p_register2[r1,r2] of
23586               Option.SOME(rlo,rhi) =>
23587                 let
23588                   val lo = BitsN.toNat rlo
23589                   val hi = BitsN.toNat rhi
23590                   val mask =
23591                     BitsN.-
23592                       (BitsN.<<(BitsN.B(0x1,16),Nat.+(hi,1)),
23593                        BitsN.<<(BitsN.B(0x1,16),lo))
23594                 in
23595                   if (Nat.<(lo,hi)) andalso
23596                      ((BitsN.&&(w,mask)) = (BitsN.B(0x0,16)))
23597                     then Option.SOME(BitsN.||(w,mask))
23598                   else NONE
23599                 end
23600             | NONE => NONE)
23601       | _ => NONE);
23602
23603fun p_registers_loop (w,l) =
23604  case l of
23605     [s] =>
23606       (case closingRegList s of
23607           Option.SOME(caret,h) =>
23608             (case p_reg_list(w,h) of
23609                 Option.SOME r => Option.SOME(caret,r)
23610               | NONE => NONE)
23611         | NONE => NONE)
23612   | h :: t =>
23613     (case p_reg_list(w,h) of
23614         Option.SOME r => p_registers_loop(r,t)
23615       | NONE => NONE)
23616   | [] => NONE;
23617
23618fun p_registers l =
23619  case l of
23620     h :: t =>
23621       (case String.explode(stripSpaces h) of
23622           #"{" :: r =>
23623             let
23624               val r = stripSpaces(String.implode r)
23625             in
23626               p_registers_loop
23627                 (BitsN.B(0x0,16),if r = "" then t else r :: t)
23628             end
23629         | _ => NONE)
23630   | _ => NONE;
23631
23632fun p_fp_reg_list (single,(w,s)) =
23633  case p_fp_register(single,s) of
23634     Option.SOME r =>
23635       let
23636         val n = BitsN.toNat r
23637       in
23638         if BitsN.bit(w,n)
23639           then NONE
23640         else Option.SOME(BitsN.||(w,BitsN.<<(BitsN.B(0x1,32),n)))
23641       end
23642   | NONE =>
23643     (case L3.uncurry String.fields (fn c => c = #"-",s) of
23644         [r1,r2] =>
23645           (case (p_fp_register(single,r1),p_fp_register(single,r2)) of
23646               (Option.SOME rlo,Option.SOME rhi) =>
23647                 let
23648                   val lo = BitsN.toNat rlo
23649                   val hi = BitsN.toNat rhi
23650                   val mask =
23651                     BitsN.-
23652                       (BitsN.<<(BitsN.B(0x1,32),Nat.+(hi,1)),
23653                        BitsN.<<(BitsN.B(0x1,32),lo))
23654                 in
23655                   if (Nat.<(lo,hi)) andalso
23656                      ((BitsN.&&(w,mask)) = (BitsN.B(0x0,32)))
23657                     then Option.SOME(BitsN.||(w,mask))
23658                   else NONE
23659                 end
23660             | _ => NONE)
23661       | _ => NONE);
23662
23663fun p_fp_registers_loop (single,(w,l)) =
23664  case l of
23665     [s] =>
23666       (case closingRegList s of
23667           Option.SOME(false,h) =>
23668             (case p_fp_reg_list(single,(w,h)) of
23669                 Option.SOME r => Option.SOME r
23670               | NONE => NONE)
23671         | _ => NONE)
23672   | h :: t =>
23673     (case p_fp_reg_list(single,(w,h)) of
23674         Option.SOME r => p_fp_registers_loop(single,(r,t))
23675       | NONE => NONE)
23676   | [] => NONE;
23677
23678fun fp_reg_list (single,imm32) =
23679  if imm32 = (BitsN.B(0x0,32))
23680    then NONE
23681  else let
23682         val lo = LowestSetBit 32 imm32
23683         val hi = Nat.fromInt(HighestSetBit 32 imm32)
23684         val n = Nat.-(Nat.+(hi,1),lo)
23685       in
23686         if imm32 =
23687            (BitsN.<<
23688               (BitsN.-(BitsN.<<(BitsN.B(0x1,32),n),BitsN.B(0x1,32)),lo))
23689           then Option.SOME
23690                  (single,
23691                   (BitsN.fromNat(lo,5),
23692                    BitsN.fromNat(if single then n else Nat.*(n,2),8)))
23693         else NONE
23694       end;
23695
23696fun p_fp_registers l =
23697  case l of
23698     h :: t =>
23699       (case String.explode(stripSpaces h) of
23700           #"{" :: r =>
23701             let
23702               val r = stripSpaces(String.implode r)
23703               val l = if r = "" then t else r :: t
23704             in
23705               case p_fp_registers_loop(true,(BitsN.B(0x0,32),l)) of
23706                  Option.SOME imm32 => fp_reg_list(true,imm32)
23707                | NONE =>
23708                  (case p_fp_registers_loop(false,(BitsN.B(0x0,32),l)) of
23709                      Option.SOME imm32 => fp_reg_list(false,imm32)
23710                    | NONE => NONE)
23711             end
23712         | _ => NONE)
23713   | _ => NONE;
23714
23715fun p_shift_amount (typ,(h,s)) =
23716  if Char.isSpace h
23717    then case p_unbounded_immediate s of
23718            Option.SOME n =>
23719              (if (Nat.<(n,32)) orelse
23720                  ((n = 32) andalso (Set.mem(typ,[SRType_LSR,SRType_ASR])))
23721                 then ("",(typ,NAT n))
23722               else ("shift amount too large",(SRType_LSL,NAT 0)))
23723          | NONE =>
23724            (case p_register s of
23725                Option.SOME rs => ("",(typ,REGISTER rs))
23726              | NONE => ("syntax error",(SRType_LSL,NAT 0)))
23727  else ("syntax error",(SRType_LSL,NAT 0));
23728
23729fun p_shift_imm_or_reg s =
23730  case String.explode(stripSpaces s) of
23731     [#"r",#"r",#"x"] => ("",(SRType_RRX,NAT 1))
23732   | #"l" :: (#"s" :: (#"l" :: (h :: t))) =>
23733     p_shift_amount(SRType_LSL,(h,String.implode t))
23734   | #"l" :: (#"s" :: (#"r" :: (h :: t))) =>
23735     p_shift_amount(SRType_LSR,(h,String.implode t))
23736   | #"a" :: (#"s" :: (#"r" :: (h :: t))) =>
23737     p_shift_amount(SRType_ASR,(h,String.implode t))
23738   | #"r" :: (#"o" :: (#"r" :: (h :: t))) =>
23739     p_shift_amount(SRType_ROR,(h,String.implode t))
23740   | _ => ("syntax error",(SRType_LSL,NAT 0));
23741
23742fun p_rotation s =
23743  case String.explode(stripSpaces s) of
23744     #"r" :: (#"o" :: (#"r" :: (h :: t))) =>
23745       (if Char.isSpace h
23746          then case p_unbounded_immediate(String.implode t) of
23747                  Option.SOME n =>
23748                    (if Set.mem(n,[0,8,16,24])
23749                       then ("",n)
23750                     else ("rotation not 0, 8, 16 or 24",0))
23751                | NONE => ("syntax error",0)
23752        else ("syntax error",0))
23753   | _ => ("syntax error",0);
23754
23755fun p_arith_logic_full (c,(opc,(setflags,l))) =
23756  case (p_suffix c,l) of
23757     (Option.SOME c,[r1,r2,x]) =>
23758       (case p_register2[r1,r2] of
23759           Option.SOME(rd,rn) =>
23760             (case p_register x of
23761                 Option.SOME rm =>
23762                   OK(c,
23763                      Data
23764                        (Register
23765                           (opc,(setflags,(rd,(rn,(rm,(SRType_LSL,0))))))))
23766               | NONE =>
23767                 (case p_arm_immediate x of
23768                     Option.SOME("",imm12) =>
23769                       OK(c,
23770                          Data
23771                            (ArithLogicImmediate
23772                               (opc,(setflags,(rd,(rn,imm12))))))
23773                   | Option.SOME(s,_) => FAIL s
23774                   | NONE => FAIL "syntax error"))
23775         | NONE => FAIL "syntax error")
23776   | (Option.SOME c,[r1,r2,r3,sh]) =>
23777     (case (p_register3[r1,r2,r3],p_shift_imm_or_reg sh) of
23778         (Option.SOME(rd,(rn,rm)),("",(typ,NAT n))) =>
23779           OK(c,Data(Register(opc,(setflags,(rd,(rn,(rm,(typ,n))))))))
23780       | (Option.SOME(rd,(rn,rm)),("",(typ,REGISTER rs))) =>
23781         OK(c,
23782            Data
23783              (RegisterShiftedRegister
23784                 (opc,(setflags,(rd,(rn,(rm,(typ,rs))))))))
23785       | (Option.SOME _,(err,_)) => FAIL err
23786       | _ => FAIL "syntax error")
23787   | _ => FAIL "syntax error";
23788
23789fun p_arith_logic (c,(opc,(setflags,l))) =
23790  case l of
23791     h :: _ =>
23792       (case p_arith_logic_full(c,(opc,(setflags,l))) of
23793           FAIL "syntax error" =>
23794             p_arith_logic_full(c,(opc,(setflags,h :: l)))
23795         | r => r)
23796   | [] => FAIL "syntax error";
23797
23798fun p_test_compare (c,(opc,l)) =
23799  case (p_suffix c,l) of
23800     (Option.SOME c,[r1,x]) =>
23801       (case p_register r1 of
23802           Option.SOME rn =>
23803             (case p_register x of
23804                 Option.SOME rm =>
23805                   OK(c,
23806                      Data
23807                        (TestCompareRegister(opc,(rn,(rm,(SRType_LSL,0))))))
23808               | NONE =>
23809                 (case p_arm_immediate x of
23810                     Option.SOME("",imm12) =>
23811                       OK(c,Data(TestCompareImmediate(opc,(rn,imm12))))
23812                   | Option.SOME(s,_) => FAIL s
23813                   | NONE => FAIL "syntax error"))
23814         | NONE => FAIL "syntax error")
23815   | (Option.SOME c,[r1,r2,sh]) =>
23816     (case (p_register2[r1,r2],p_shift_imm_or_reg sh) of
23817         (Option.SOME(rn,rm),("",(typ,NAT n))) =>
23818           OK(c,Data(TestCompareRegister(opc,(rn,(rm,(typ,n))))))
23819       | (Option.SOME(rn,rm),("",(typ,REGISTER rs))) =>
23820         OK(c,
23821            Data
23822              (RegisterShiftedRegister
23823                 (BitsN.@@(BitsN.B(0x2,2),opc),
23824                  (true,(BitsN.B(0x0,4),(rn,(rm,(typ,rs))))))))
23825       | (Option.SOME _,(err,_)) => FAIL err
23826       | _ => FAIL "syntax error")
23827   | _ => FAIL "syntax error";
23828
23829fun p_mov_mvn (c,(negate,(setflags,l))) =
23830  case (p_suffix c,l) of
23831     (Option.SOME c,[r1,x]) =>
23832       (case p_register r1 of
23833           Option.SOME rd =>
23834             (case p_register x of
23835                 Option.SOME rm =>
23836                   OK(c,
23837                      Data
23838                        (ShiftImmediate
23839                           (negate,(setflags,(rd,(rm,(SRType_LSL,0)))))))
23840               | NONE =>
23841                 (case p_arm_immediate x of
23842                     Option.SOME("",imm12) =>
23843                       OK(c,Data(Move(setflags,(negate,(rd,imm12)))))
23844                   | Option.SOME(s,_) => FAIL s
23845                   | NONE => FAIL "syntax error"))
23846         | NONE => FAIL "syntax error")
23847   | (Option.SOME c,[r1,r2,sh]) =>
23848     (case (p_register2[r1,r2],p_shift_imm_or_reg sh) of
23849         (Option.SOME(rd,rm),("",(typ,NAT n))) =>
23850           OK(c,Data(ShiftImmediate(negate,(setflags,(rd,(rm,(typ,n)))))))
23851       | (Option.SOME(rd,rm),("",(typ,REGISTER rs))) =>
23852         OK(c,Data(ShiftRegister(negate,(setflags,(rd,(rm,(typ,rs)))))))
23853       | (Option.SOME _,(err,_)) => FAIL err
23854       | _ => FAIL "syntax error")
23855   | _ => FAIL "syntax error";
23856
23857fun p_shift_full (c,(typ,(setflags,l))) =
23858  case (p_suffix c,l) of
23859     (Option.SOME c,[r1,r2,s]) =>
23860       (case p_register2[r1,r2] of
23861           Option.SOME(rd,rn) =>
23862             (case p_register s of
23863                 Option.SOME rm =>
23864                   OK(c,
23865                      Data
23866                        (ShiftRegister
23867                           (false,(setflags,(rd,(rn,(typ,rm)))))))
23868               | NONE =>
23869                 (case p_unbounded_immediate s of
23870                     Option.SOME n =>
23871                       (if (Nat.<(n,32)) orelse
23872                           ((n = 32) andalso
23873                            (Set.mem(typ,[SRType_LSR,SRType_ASR])))
23874                          then OK(c,
23875                                  Data
23876                                    (ShiftImmediate
23877                                       (false,(setflags,(rd,(rn,(typ,n)))))))
23878                        else FAIL "shift amount too large")
23879                   | NONE => FAIL "syntax error"))
23880         | NONE => FAIL "syntax error")
23881   | _ => FAIL "syntax error";
23882
23883fun p_shift (c,(typ,(setflags,l))) =
23884  case l of
23885     h :: _ =>
23886       (case p_shift_full(c,(typ,(setflags,l))) of
23887           FAIL "syntax error" => p_shift_full(c,(typ,(setflags,h :: l)))
23888         | r => r)
23889   | [] => FAIL "syntax error";
23890
23891fun p_rrx (c,(setflags,l)) =
23892  case (p_suffix c,p_register2 l) of
23893     (Option.SOME c,Option.SOME(d,m)) =>
23894       OK(c,Data(ShiftImmediate(false,(setflags,(d,(m,(SRType_RRX,1)))))))
23895   | _ => FAIL "syntax error";
23896
23897fun p_adr (c,l) =
23898  case (p_suffix c,l) of
23899     (Option.SOME c,[r,n]) =>
23900       (case p_register r of
23901           Option.SOME d =>
23902             (case p_signed_offset 32 n of
23903                 Option.SOME(sub,(true,imm32)) =>
23904                   (case EncodeARMImmediate imm32 of
23905                       Option.SOME imm12 =>
23906                         OK(c,
23907                            Data
23908                              (ArithLogicImmediate
23909                                 (if sub
23910                                    then BitsN.B(0x2,4)
23911                                  else BitsN.B(0x4,4),
23912                                  (false,(d,(BitsN.B(0xF,4),imm12))))))
23913                     | NONE => FAIL "offset not encodable")
23914               | Option.SOME _ => FAIL "bad offset"
23915               | NONE =>
23916                 (case p_label n of
23917                     Option.SOME s =>
23918                       PENDING
23919                         (s,
23920                          (c,
23921                           Data
23922                             (ArithLogicImmediate
23923                                (BitsN.B(0x4,4),
23924                                 (false,
23925                                  (d,(BitsN.B(0xF,4),BitsN.B(0x0,12))))))))
23926                   | NONE => FAIL "syntax error"))
23927         | NONE => FAIL "syntax error")
23928   | _ => FAIL "syntax error";
23929
23930fun p_bx (c,l) =
23931  case (p_suffix c,p_register1 l) of
23932     (Option.SOME c,Option.SOME rm) => OK(c,Branch(BranchExchange rm))
23933   | _ => FAIL "syntax error";
23934
23935fun p_bl (c,l) =
23936  case (p_suffix c,l) of
23937     (Option.SOME c,[a]) =>
23938       (case p_offset 32 a of
23939           Option.SOME(true,offset) =>
23940             OK(c,Branch(BranchLinkExchangeImmediate(InstrSet_ARM,offset)))
23941         | Option.SOME(false,_) => FAIL "bad offset"
23942         | NONE =>
23943           (case p_label a of
23944               Option.SOME label =>
23945                 PENDING
23946                   (label,
23947                    (c,
23948                     Branch
23949                       (BranchLinkExchangeImmediate
23950                          (InstrSet_ARM,BitsN.B(0x0,32)))))
23951             | NONE => FAIL "syntax error"))
23952   | _ => FAIL "syntax error";
23953
23954fun p_b (c,l) =
23955  case (p_suffix c,l) of
23956     (Option.SOME c,[a]) =>
23957       (case p_offset 32 a of
23958           Option.SOME(true,offset) => OK(c,Branch(BranchTarget offset))
23959         | Option.SOME(false,_) => FAIL "bad offset"
23960         | NONE =>
23961           (case p_label a of
23962               Option.SOME label =>
23963                 PENDING(label,(c,Branch(BranchTarget(BitsN.B(0x0,32)))))
23964             | NONE => FAIL "syntax error"))
23965   | _ => FAIL "syntax error";
23966
23967fun p_blx (c,l) =
23968  case (p_suffix c,l) of
23969     (Option.SOME c,[a]) =>
23970       (case p_register a of
23971           Option.SOME rm => OK(c,Branch(BranchLinkExchangeRegister rm))
23972         | NONE =>
23973           (case p_offset 32 a of
23974               Option.SOME(true,offset) =>
23975                 OK(c,
23976                    Branch
23977                      (BranchLinkExchangeImmediate(InstrSet_Thumb,offset)))
23978             | Option.SOME(false,_) => FAIL "bad offset"
23979             | NONE =>
23980               (case p_label a of
23981                   Option.SOME label =>
23982                     PENDING
23983                       (label,
23984                        (c,
23985                         Branch
23986                           (BranchLinkExchangeImmediate
23987                              (InstrSet_Thumb,BitsN.B(0x0,32)))))
23988                 | NONE => FAIL "syntax error")))
23989   | _ => FAIL "syntax error";
23990
23991fun p_clz (c,l) =
23992  case (p_suffix c,p_register2 l) of
23993     (Option.SOME c,Option.SOME(rd,rm)) =>
23994       OK(c,Data(CountLeadingZeroes(rd,rm)))
23995   | _ => FAIL "syntax error";
23996
23997fun p_movt_movw (c,(high,l)) =
23998  case l of
23999     [r,imm] =>
24000       (case (p_suffix c,(p_register r,p_immediate 16 imm)) of
24001           (Option.SOME c,(Option.SOME rd,Option.SOME(true,imm16))) =>
24002             OK(c,Data(MoveHalfword(high,(rd,imm16))))
24003         | (Option.SOME _,(Option.SOME _,Option.SOME(false,_))) =>
24004           FAIL "immediate too large"
24005         | _ => FAIL "syntax error")
24006   | _ => FAIL "syntax error";
24007
24008fun p_addw_subw (c,(sub,l)) =
24009  case l of
24010     [r1,r2,imm] =>
24011       (case (p_suffix c,(p_register2[r1,r2],p_immediate 12 imm)) of
24012           (Option.SOME c,(Option.SOME(rd,rn),Option.SOME(true,imm12))) =>
24013             OK(c,Data(AddSub(sub,(rd,(rn,imm12)))))
24014         | (Option.SOME _,(Option.SOME _,Option.SOME(false,_))) =>
24015           FAIL "immediate too large"
24016         | _ => FAIL "syntax error")
24017   | _ => FAIL "syntax error";
24018
24019fun p_mul (c,(setflags,l)) =
24020  case (p_suffix c,p_register3 l) of
24021     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24022       OK(c,Multiply(Multiply32(setflags,(rd,(rn,rm)))))
24023   | _ => FAIL "syntax error";
24024
24025fun p_mla (c,(setflags,l)) =
24026  case (p_suffix c,p_register4 l) of
24027     (Option.SOME c,Option.SOME(rd,(rn,(rm,ra)))) =>
24028       OK(c,Multiply(MultiplyAccumulate(setflags,(rd,(rn,(rm,ra))))))
24029   | _ => FAIL "syntax error";
24030
24031fun p_umull_etc (c,(acc,(signed,(setflags,l)))) =
24032  case (p_suffix c,p_register4 l) of
24033     (Option.SOME c,Option.SOME(rdlo,(rdhi,(rn,rm)))) =>
24034       OK(c,
24035          Multiply
24036            (MultiplyLong(acc,(signed,(setflags,(rdhi,(rdlo,(rn,rm))))))))
24037   | _ => FAIL "syntax error";
24038
24039fun p_umaal (c,l) =
24040  case (p_suffix c,p_register4 l) of
24041     (Option.SOME c,Option.SOME(rdlo,(rdhi,(rn,rm)))) =>
24042       OK(c,Multiply(MultiplyAccumulateAccumulate(rdhi,(rdlo,(rn,rm)))))
24043   | _ => FAIL "syntax error";
24044
24045fun p_mls (c,l) =
24046  case (p_suffix c,p_register4 l) of
24047     (Option.SOME c,Option.SOME(rd,(rn,(rm,ra)))) =>
24048       OK(c,Multiply(MultiplySubtract(rd,(rn,(rm,ra)))))
24049   | _ => FAIL "syntax error";
24050
24051fun p_smla (c,(m_high,(n_high,l))) =
24052  case (p_suffix c,p_register4 l) of
24053     (Option.SOME c,Option.SOME(rd,(rn,(rm,ra)))) =>
24054       OK(c,
24055          Multiply
24056            (Signed16Multiply32Accumulate
24057               (m_high,(n_high,(rd,(rn,(rm,ra)))))))
24058   | _ => FAIL "syntax error";
24059
24060fun p_smul (c,(m_high,(n_high,l))) =
24061  case (p_suffix c,p_register3 l) of
24062     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24063       OK(c,
24064          Multiply(Signed16Multiply32Result(m_high,(n_high,(rd,(rn,rm))))))
24065   | _ => FAIL "syntax error";
24066
24067fun p_smlaw (c,(m_high,l)) =
24068  case (p_suffix c,p_register4 l) of
24069     (Option.SOME c,Option.SOME(rd,(rn,(rm,ra)))) =>
24070       OK(c,
24071          Multiply
24072            (Signed16x32Multiply32Accumulate(m_high,(rd,(rn,(rm,ra))))))
24073   | _ => FAIL "syntax error";
24074
24075fun p_smulw (c,(m_high,l)) =
24076  case (p_suffix c,p_register3 l) of
24077     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24078       OK(c,Multiply(Signed16x32Multiply32Result(m_high,(rd,(rn,rm)))))
24079   | _ => FAIL "syntax error";
24080
24081fun p_smlal (c,(m_high,(n_high,l))) =
24082  case (p_suffix c,p_register4 l) of
24083     (Option.SOME c,Option.SOME(rdlo,(rdhi,(rn,rm)))) =>
24084       OK(c,
24085          Multiply
24086            (Signed16Multiply64Accumulate
24087               (m_high,(n_high,(rdhi,(rdlo,(rn,rm)))))))
24088   | _ => FAIL "syntax error";
24089
24090fun p_smuad_smusd (c,(sub,(swap,l))) =
24091  case (p_suffix c,p_register3 l) of
24092     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24093       OK(c,
24094          Multiply
24095            (SignedMultiplyDual(sub,(swap,(rd,(rn,(rm,BitsN.B(0xF,4))))))))
24096   | _ => FAIL "syntax error";
24097
24098fun p_smlad_smlsd (c,(sub,(swap,l))) =
24099  case (p_suffix c,p_register4 l) of
24100     (Option.SOME c,Option.SOME(rd,(rn,(rm,ra)))) =>
24101       OK(c,Multiply(SignedMultiplyDual(sub,(swap,(rd,(rn,(rm,ra)))))))
24102   | _ => FAIL "syntax error";
24103
24104fun p_smlald_smlsld (c,(sub,(swap,l))) =
24105  case (p_suffix c,p_register4 l) of
24106     (Option.SOME c,Option.SOME(rdlo,(rdhi,(rn,rm)))) =>
24107       OK(c,
24108          Multiply
24109            (SignedMultiplyLongDual(sub,(swap,(rdhi,(rdlo,(rn,rm)))))))
24110   | _ => FAIL "syntax error";
24111
24112fun p_smmul (c,(round,l)) =
24113  case (p_suffix c,p_register3 l) of
24114     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24115       OK(c,
24116          Multiply
24117            (SignedMostSignificantMultiply
24118               (round,(rd,(rn,(rm,BitsN.B(0xF,4)))))))
24119   | _ => FAIL "syntax error";
24120
24121fun p_smmla (c,(round,l)) =
24122  case (p_suffix c,p_register4 l) of
24123     (Option.SOME c,Option.SOME(rd,(rn,(rm,ra)))) =>
24124       OK(c,
24125          Multiply(SignedMostSignificantMultiply(round,(rd,(rn,(rm,ra))))))
24126   | _ => FAIL "syntax error";
24127
24128fun p_smmls (c,(round,l)) =
24129  case (p_suffix c,p_register4 l) of
24130     (Option.SOME c,Option.SOME(rd,(rn,(rm,ra)))) =>
24131       OK(c,
24132          Multiply
24133            (SignedMostSignificantMultiplySubtract
24134               (round,(rd,(rn,(rm,ra))))))
24135   | _ => FAIL "syntax error";
24136
24137fun p_qadd_etc (c,(opc,l)) =
24138  case (p_suffix c,p_register3 l) of
24139     (Option.SOME c,Option.SOME(rd,(rm,rn))) =>
24140       OK(c,Media(SaturatingAddSubtract(opc,(rd,(rm,rn)))))
24141   | _ => FAIL "syntax error";
24142
24143fun p_sadd16_etc (c,(opc,l)) =
24144  case (p_suffix c,p_register3 l) of
24145     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24146       OK(c,SIMD(SignedAddSub16(opc,(rd,(rn,rm)))))
24147   | _ => FAIL "syntax error";
24148
24149fun p_qadd16_etc (c,(opc,l)) =
24150  case (p_suffix c,p_register3 l) of
24151     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24152       OK(c,SIMD(SignedSaturatingAddSub16(opc,(rd,(rn,rm)))))
24153   | _ => FAIL "syntax error";
24154
24155fun p_shadd16_etc (c,(opc,l)) =
24156  case (p_suffix c,p_register3 l) of
24157     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24158       OK(c,SIMD(SignedHalvingAddSub16(opc,(rd,(rn,rm)))))
24159   | _ => FAIL "syntax error";
24160
24161fun p_sadd8_etc (c,(sub,l)) =
24162  case (p_suffix c,p_register3 l) of
24163     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24164       OK(c,SIMD(SignedAddSub8(sub,(rd,(rn,rm)))))
24165   | _ => FAIL "syntax error";
24166
24167fun p_qadd8_etc (c,(sub,l)) =
24168  case (p_suffix c,p_register3 l) of
24169     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24170       OK(c,SIMD(SignedSaturatingAddSub8(sub,(rd,(rn,rm)))))
24171   | _ => FAIL "syntax error";
24172
24173fun p_shadd8_etc (c,(sub,l)) =
24174  case (p_suffix c,p_register3 l) of
24175     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24176       OK(c,SIMD(SignedHalvingAddSub8(sub,(rd,(rn,rm)))))
24177   | _ => FAIL "syntax error";
24178
24179fun p_uadd16_etc (c,(opc,l)) =
24180  case (p_suffix c,p_register3 l) of
24181     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24182       OK(c,SIMD(UnsignedAddSub16(opc,(rd,(rn,rm)))))
24183   | _ => FAIL "syntax error";
24184
24185fun p_uqadd16_etc (c,(opc,l)) =
24186  case (p_suffix c,p_register3 l) of
24187     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24188       OK(c,SIMD(UnsignedSaturatingAddSub16(opc,(rd,(rn,rm)))))
24189   | _ => FAIL "syntax error";
24190
24191fun p_uhadd16_etc (c,(opc,l)) =
24192  case (p_suffix c,p_register3 l) of
24193     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24194       OK(c,SIMD(UnsignedHalvingAddSub16(opc,(rd,(rn,rm)))))
24195   | _ => FAIL "syntax error";
24196
24197fun p_uadd8_etc (c,(sub,l)) =
24198  case (p_suffix c,p_register3 l) of
24199     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24200       OK(c,SIMD(UnsignedAddSub8(sub,(rd,(rn,rm)))))
24201   | _ => FAIL "syntax error";
24202
24203fun p_uqadd8_etc (c,(sub,l)) =
24204  case (p_suffix c,p_register3 l) of
24205     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24206       OK(c,SIMD(UnsignedSaturatingAddSub8(sub,(rd,(rn,rm)))))
24207   | _ => FAIL "syntax error";
24208
24209fun p_uhadd8_etc (c,(sub,l)) =
24210  case (p_suffix c,p_register3 l) of
24211     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24212       OK(c,SIMD(UnsignedHalvingAddSub8(sub,(rd,(rn,rm)))))
24213   | _ => FAIL "syntax error";
24214
24215fun p_usad8 (c,l) =
24216  case (p_suffix c,p_register3 l) of
24217     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24218       OK(c,
24219          SIMD
24220            (UnsignedSumAbsoluteDifferences(rd,(rn,(rm,BitsN.B(0xF,4))))))
24221   | _ => FAIL "syntax error";
24222
24223fun p_usada8 (c,l) =
24224  case (p_suffix c,p_register4 l) of
24225     (Option.SOME c,Option.SOME(rd,(rn,(rm,ra)))) =>
24226       OK(c,SIMD(UnsignedSumAbsoluteDifferences(rd,(rn,(rm,ra)))))
24227   | _ => FAIL "syntax error";
24228
24229fun p_pkhbt_pkhtb (c,(tbform,l)) =
24230  case (p_suffix c,l) of
24231     (Option.SOME c,[r1,r2,r3]) =>
24232       (case p_register3[r1,r2,r3] of
24233           Option.SOME(rd,(rn,rm)) =>
24234             let
24235               val (rn,rm) = if tbform then (rm,rn) else (rn,rm)
24236             in
24237               OK(c,
24238                  Media(PackHalfword(SRType_LSL,(0,(false,(rd,(rn,rm)))))))
24239             end
24240         | NONE => FAIL "syntax error")
24241   | (Option.SOME c,[r1,r2,r3,sh]) =>
24242     (case p_register3[r1,r2,r3] of
24243         Option.SOME(rd,(rn,rm)) =>
24244           let
24245             val sh = stripSpaces sh
24246           in
24247             if tbform
24248               then case String.explode sh of
24249                       #"a" :: (#"s" :: (#"r" :: (h :: t))) =>
24250                         (case p_shift_amount
24251                            (SRType_ASR,(h,String.implode t)) of
24252                             ("",(_,NAT n)) =>
24253                               OK(c,
24254                                  Media
24255                                    (PackHalfword
24256                                       (SRType_ASR,(n,(true,(rd,(rn,rm)))))))
24257                           | ("",(_,REGISTER _)) => FAIL "syntax error"
24258                           | (err,_) => FAIL err)
24259                     | _ => FAIL "syntax error"
24260             else case String.explode sh of
24261                     #"l" :: (#"s" :: (#"l" :: (h :: t))) =>
24262                       (case p_shift_amount
24263                          (SRType_LSL,(h,String.implode t)) of
24264                           ("",(_,NAT n)) =>
24265                             OK(c,
24266                                Media
24267                                  (PackHalfword
24268                                     (SRType_LSL,(n,(false,(rd,(rn,rm)))))))
24269                         | ("",(_,REGISTER _)) => FAIL "syntax error"
24270                         | (err,_) => FAIL err)
24271                   | _ => FAIL "syntax error"
24272           end
24273       | NONE => FAIL "syntax error")
24274   | _ => FAIL "syntax error";
24275
24276fun p_sat (c,(unsigned,l)) =
24277  case (p_suffix c,l) of
24278     (Option.SOME c,r1 :: (imm :: (r2 :: t))) =>
24279       let
24280         val (s,sat_to) =
24281           if unsigned
24282             then p_range_imm(0,(31,imm))
24283           else p_range_imm(1,(32,imm))
24284       in
24285         case (s,p_register2[r1,r2]) of
24286            ("",Option.SOME(rd,rn)) =>
24287              (case t of
24288                  [] =>
24289                    OK(c,
24290                       Media
24291                         (Saturate
24292                            (SRType_LSL,(0,(sat_to,(unsigned,(rd,rn)))))))
24293                | [sh] =>
24294                  (case p_shift_imm_or_reg sh of
24295                      ("",(SRType_LSL,NAT n)) =>
24296                        OK(c,
24297                           Media
24298                             (Saturate
24299                                (SRType_LSL,
24300                                 (n,(sat_to,(unsigned,(rd,rn)))))))
24301                    | ("",(SRType_ASR,NAT n)) =>
24302                      OK(c,
24303                         Media
24304                           (Saturate
24305                              (SRType_ASR,(n,(sat_to,(unsigned,(rd,rn)))))))
24306                    | ("",_) => FAIL "syntax error"
24307                    | (s,_) => FAIL s)
24308                | _ => FAIL "syntax error")
24309          | (s,Option.SOME _) => FAIL s
24310          | _ => FAIL "syntax error"
24311       end
24312   | _ => FAIL "syntax error";
24313
24314fun p_sat16 (c,(unsigned,l)) =
24315  case (p_suffix c,l) of
24316     (Option.SOME c,[r1,imm,r2]) =>
24317       let
24318         val (s,sat_to) =
24319           if unsigned
24320             then p_range_imm(0,(15,imm))
24321           else p_range_imm(1,(16,imm))
24322       in
24323         case (s,p_register2[r1,r2]) of
24324            ("",Option.SOME(rd,rn)) =>
24325              OK(c,Media(Saturate16(sat_to,(unsigned,(rd,rn)))))
24326          | (s,Option.SOME _) => FAIL s
24327          | _ => FAIL "syntax error"
24328       end
24329   | _ => FAIL "syntax error";
24330
24331fun pick_sxtb (opc,a) =
24332  Media
24333    (if opc = 0
24334       then ExtendByte16 a
24335     else if opc = 1 then ExtendByte a else ExtendHalfword a);
24336
24337fun p_sxtb_etc (c,(opc,(unsigned,l))) =
24338  case (p_suffix c,l) of
24339     (Option.SOME c,[r1,r2]) =>
24340       (case p_register2[r1,r2] of
24341           Option.SOME(rd,rm) =>
24342             OK(c,pick_sxtb(opc,(unsigned,(rd,(BitsN.B(0xF,4),(rm,0))))))
24343         | NONE => FAIL "syntax error")
24344   | (Option.SOME c,[r1,r2,rot]) =>
24345     (case (p_register2[r1,r2],p_rotation rot) of
24346         (Option.SOME(rd,rm),("",r)) =>
24347           OK(c,pick_sxtb(opc,(unsigned,(rd,(BitsN.B(0xF,4),(rm,r))))))
24348       | (Option.SOME _,(s,_)) => FAIL s
24349       | _ => FAIL "syntax error")
24350   | _ => FAIL "syntax error";
24351
24352fun p_sxtab_etc (c,(opc,(unsigned,l))) =
24353  case (p_suffix c,l) of
24354     (Option.SOME c,[r1,r2,r3]) =>
24355       (case p_register3[r1,r2,r3] of
24356           Option.SOME(rd,(rn,rm)) =>
24357             OK(c,pick_sxtb(opc,(unsigned,(rd,(rn,(rm,0))))))
24358         | NONE => FAIL "syntax error")
24359   | (Option.SOME c,[r1,r2,r3,rot]) =>
24360     (case (p_register3[r1,r2,r3],p_rotation rot) of
24361         (Option.SOME(rd,(rn,rm)),("",r)) =>
24362           OK(c,pick_sxtb(opc,(unsigned,(rd,(rn,(rm,r))))))
24363       | (Option.SOME _,(s,_)) => FAIL s
24364       | _ => FAIL "syntax error")
24365   | _ => FAIL "syntax error";
24366
24367fun p_sel (c,l) =
24368  case (p_suffix c,p_register3 l) of
24369     (Option.SOME c,Option.SOME(rd,(rn,rm))) =>
24370       OK(c,Media(SelectBytes(rd,(rn,rm))))
24371   | _ => FAIL "syntax error";
24372
24373fun p_rev (c,l) =
24374  case (p_suffix c,p_register2 l) of
24375     (Option.SOME c,Option.SOME(rd,rm)) => OK(c,Media(ByteReverse(rd,rm)))
24376   | _ => FAIL "syntax error";
24377
24378fun p_rev16 (c,l) =
24379  case (p_suffix c,p_register2 l) of
24380     (Option.SOME c,Option.SOME(rd,rm)) =>
24381       OK(c,Media(ByteReversePackedHalfword(rd,rm)))
24382   | _ => FAIL "syntax error";
24383
24384fun p_revsh (c,l) =
24385  case (p_suffix c,p_register2 l) of
24386     (Option.SOME c,Option.SOME(rd,rm)) =>
24387       OK(c,Media(ByteReverseSignedHalfword(rd,rm)))
24388   | _ => FAIL "syntax error";
24389
24390fun p_rbit (c,l) =
24391  case (p_suffix c,p_register2 l) of
24392     (Option.SOME c,Option.SOME(rd,rm)) => OK(c,Media(ReverseBits(rd,rm)))
24393   | _ => FAIL "syntax error";
24394
24395fun p_sbfx_ubfx (c,(unsigned,l)) =
24396  case (p_suffix c,l) of
24397     (Option.SOME c,[r1,r2,lsb,width]) =>
24398       (case p_register2[r1,r2] of
24399           Option.SOME(rd,rn) =>
24400             (case p_range_imm(0,(31,lsb)) of
24401                 ("",l) =>
24402                   (case p_range_imm(1,(Nat.-(32,l),width)) of
24403                       ("",w) =>
24404                         OK(c,
24405                            Media
24406                              (BitFieldExtract
24407                                 (unsigned,(rd,(rn,(l,Nat.-(w,1)))))))
24408                     | (err,_) => FAIL err)
24409               | (err,_) => FAIL err)
24410         | NONE => FAIL "syntax error")
24411   | _ => FAIL "syntax error";
24412
24413fun p_bfc (c,l) =
24414  case (p_suffix c,l) of
24415     (Option.SOME c,[r1,lsb,width]) =>
24416       (case p_register r1 of
24417           Option.SOME rd =>
24418             (case p_range_imm(0,(31,lsb)) of
24419                 ("",l) =>
24420                   (case p_range_imm(1,(Nat.-(32,l),width)) of
24421                       ("",w) =>
24422                         OK(c,
24423                            Media
24424                              (BitFieldClearOrInsert
24425                                 (rd,
24426                                  (BitsN.B(0xF,4),(l,Nat.-(Nat.+(l,w),1))))))
24427                     | (err,_) => FAIL err)
24428               | (err,_) => FAIL err)
24429         | NONE => FAIL "syntax error")
24430   | _ => FAIL "syntax error";
24431
24432fun p_bfi (c,l) =
24433  case (p_suffix c,l) of
24434     (Option.SOME c,[r1,r2,lsb,width]) =>
24435       (case p_register2[r1,r2] of
24436           Option.SOME(rd,rn) =>
24437             (case p_range_imm(0,(31,lsb)) of
24438                 ("",l) =>
24439                   (case p_range_imm(1,(Nat.-(32,l),width)) of
24440                       ("",w) =>
24441                         OK(c,
24442                            Media
24443                              (BitFieldClearOrInsert
24444                                 (rd,(rn,(l,Nat.-(Nat.+(l,w),1))))))
24445                     | (err,_) => FAIL err)
24446               | (err,_) => FAIL err)
24447         | NONE => FAIL "syntax error")
24448   | _ => FAIL "syntax error";
24449
24450fun closingAddress s =
24451  let
24452    val (l,wb) = L3.splitr(fn c => c = #"!",stripSpaces s)
24453    val (l,r) = L3.splitr(fn c => c = #"]",stripSpaces l)
24454  in
24455    if (r = "]") andalso (Nat.<(L3.size wb,2))
24456      then Option.SOME(wb = "!",l)
24457    else NONE
24458  end;
24459
24460fun p_address_mode1 l =
24461  case l of
24462     h1 :: t1 =>
24463       (case String.explode(stripSpaces h1) of
24464           #"[" :: r1 =>
24465             let
24466               val r1 = String.implode r1
24467             in
24468               case p_register r1 of
24469                  Option.SOME rn =>
24470                    (case t1 of
24471                        [offset] =>
24472                          (case closingAddress offset of
24473                              Option.SOME(wb,offset1) =>
24474                                (case p_signed_immediate 32 offset1 of
24475                                    Option.SOME(sub,(true,imm32)) =>
24476                                      ("",
24477                                       Option.SOME
24478                                         (not sub,
24479                                          (true,
24480                                           (wb,(rn,immediate_form1 imm32)))))
24481                                  | Option.SOME(_,(false,_)) =>
24482                                    ("immediate too large",NONE)
24483                                  | NONE =>
24484                                    (case p_register_offset offset1 of
24485                                        Option.SOME(add,rm) =>
24486                                          ("",
24487                                           Option.SOME
24488                                             (add,
24489                                              (true,
24490                                               (wb,
24491                                                (rn,
24492                                                 register_form1
24493                                                   (rm,(SRType_LSL,0)))))))
24494                                      | NONE => ("syntax error",NONE)))
24495                            | NONE => ("syntax error",NONE))
24496                      | [offset,sh] =>
24497                        (case closingAddress sh of
24498                            Option.SOME(wb,sh1) =>
24499                              (case (p_register_offset offset,
24500                                p_shift_imm_or_reg sh1) of
24501                                  (Option.SOME(add,rm),("",(typ,NAT n))) =>
24502                                    ("",
24503                                     Option.SOME
24504                                       (add,
24505                                        (true,
24506                                         (wb,
24507                                          (rn,register_form1(rm,(typ,n)))))))
24508                                | (Option.SOME _,(err,(_,NAT _))) =>
24509                                  (err,NONE)
24510                                | _ => ("syntax error",NONE))
24511                          | NONE => ("syntax error",NONE))
24512                      | _ => ("syntax error",NONE))
24513                | NONE =>
24514                  (case closingAddress r1 of
24515                      Option.SOME(wb,r2) =>
24516                        (case (p_register r2,t1) of
24517                            (Option.SOME rn,[]) =>
24518                              ("",
24519                               Option.SOME
24520                                 (true,
24521                                  (true,
24522                                   (wb,
24523                                    (rn,immediate_form1(BitsN.B(0x0,32)))))))
24524                          | (Option.SOME rn,[offset]) =>
24525                            (if wb
24526                               then ("syntax error",NONE)
24527                             else case p_signed_immediate 32 offset of
24528                                     Option.SOME(sub,(true,imm32)) =>
24529                                       ("",
24530                                        Option.SOME
24531                                          (not sub,
24532                                           (false,
24533                                            (true,
24534                                             (rn,immediate_form1 imm32)))))
24535                                   | Option.SOME(_,(false,_)) =>
24536                                     ("immediate too large",NONE)
24537                                   | NONE =>
24538                                     (case p_register_offset offset of
24539                                         Option.SOME(add,rm) =>
24540                                           ("",
24541                                            Option.SOME
24542                                              (add,
24543                                               (false,
24544                                                (true,
24545                                                 (rn,
24546                                                  register_form1
24547                                                    (rm,(SRType_LSL,0)))))))
24548                                       | NONE => ("syntax error",NONE)))
24549                          | (Option.SOME rn,[offset,sh]) =>
24550                            (if wb
24551                               then ("syntax error",NONE)
24552                             else case (p_register_offset offset,
24553                                   p_shift_imm_or_reg sh) of
24554                                     (Option.SOME(add,rm),("",(typ,NAT n))) =>
24555                                       ("",
24556                                        Option.SOME
24557                                          (add,
24558                                           (false,
24559                                            (true,
24560                                             (rn,
24561                                              register_form1(rm,(typ,n)))))))
24562                                   | (Option.SOME _,(err,(_,NAT _))) =>
24563                                     (err,NONE)
24564                                   | _ => ("syntax error",NONE))
24565                          | _ => ("syntax error",NONE))
24566                    | NONE => ("syntax error",NONE))
24567             end
24568         | _ =>
24569           (case (p_signed_offset 32 h1,t1) of
24570               (Option.SOME(sub,(true,imm32)),[]) =>
24571                 ("",
24572                  Option.SOME
24573                    (not sub,
24574                     (true,(false,(BitsN.B(0xF,4),immediate_form1 imm32)))))
24575             | (Option.SOME(_,(false,_)),[]) => ("bad offset",NONE)
24576             | _ => ("syntax error",NONE)))
24577   | _ => ("syntax error",NONE);
24578
24579fun p_address_mode2 l =
24580  case p_address_mode1 l of
24581     ("",Option.SOME(add,(index,(wback,(r,immediate_form1 imm32))))) =>
24582       ("",Option.SOME(add,(index,(wback,(r,immediate_form2 imm32)))))
24583   | ("",
24584    Option.SOME(add,(index,(wback,(r,register_form1(m,(SRType_LSL,0))))))) =>
24585     ("",Option.SOME(add,(index,(wback,(r,register_form2 m)))))
24586   | (_,Option.SOME _) => ("syntax error",NONE)
24587   | (s,_) => (s,NONE);
24588
24589fun p_address_mode3 l =
24590  case l of
24591     [r1,imm] =>
24592       (case (String.explode(stripSpaces r1),closingAddress imm) of
24593           (#"[" :: r2,Option.SOME(false,imm10)) =>
24594             (case (p_register(String.implode r2),p_immediate 32 imm10) of
24595                 (Option.SOME rn,Option.SOME(true,imm32)) =>
24596                   ("",Option.SOME(rn,Option.SOME imm32))
24597               | (Option.SOME _,Option.SOME(false,_)) =>
24598                 ("immediate too large",NONE)
24599               | _ => ("syntax error",NONE))
24600         | _ => ("syntax error",NONE))
24601   | [r1] =>
24602     (case String.explode(stripSpaces r1) of
24603         #"[" :: r2 =>
24604           (case closingAddress(String.implode r2) of
24605               Option.SOME(false,r3) =>
24606                 (case p_register r3 of
24607                     Option.SOME rn => ("",Option.SOME(rn,NONE))
24608                   | NONE => ("syntax error",NONE))
24609             | Option.SOME _ => ("write-back not allowed",NONE)
24610             | NONE => ("syntax error",NONE))
24611       | _ => ("syntax error",NONE))
24612   | _ => ("syntax error",NONE);
24613
24614fun pick_ldr_str (opc,(add,(index,(wback,(rt,(rn,offset)))))) =
24615  let
24616    val r = (add,(index,(wback,(rt,(rn,offset)))))
24617  in
24618    case opc of
24619       0 =>
24620         (case (index,(wback,(rn,offset))) of
24621             (true,(false,(BitsN.B(0xF,_),immediate_form1 imm32))) =>
24622               Load(LoadLiteral(add,(rt,imm32)))
24623           | _ => Load(LoadWord r))
24624     | 1 => Store(StoreByte r)
24625     | 2 => Store(StoreHalf r)
24626     | _ => Store(StoreWord r)
24627  end;
24628
24629fun p_ldr_str (c,(opc,l)) =
24630  case (p_suffix c,l) of
24631     (Option.SOME c,h :: t) =>
24632       (case p_register h of
24633           Option.SOME rt =>
24634             (case p_address_mode1 t of
24635                 ("",Option.SOME(add,(index,(wback,(rn,offset))))) =>
24636                   OK(c,
24637                      pick_ldr_str
24638                        (opc,(add,(index,(wback,(rt,(rn,offset)))))))
24639               | (err,_) =>
24640                 (case t of
24641                     [l] =>
24642                       (case p_label l of
24643                           Option.SOME s =>
24644                             PENDING
24645                               (s,
24646                                (c,
24647                                 pick_ldr_str
24648                                   (opc,
24649                                    (false,
24650                                     (true,
24651                                      (false,
24652                                       (rt,
24653                                        (BitsN.B(0xF,4),
24654                                         immediate_form1(BitsN.B(0x0,32))))))))))
24655                         | NONE => FAIL err)
24656                   | _ => FAIL err))
24657         | NONE => FAIL "syntax error")
24658   | _ => FAIL "syntax error";
24659
24660fun pick_ldrb_ldrh
24661  (byte,(unsigned,(add,(index,(wback,(rt,(rn,offset))))))) =
24662  case (index,(wback,(rn,offset))) of
24663     (true,(false,(BitsN.B(0xF,_),immediate_form1 imm32))) =>
24664       let
24665         val r = (unsigned,(add,(rt,imm32)))
24666       in
24667         Load(if byte then LoadByteLiteral r else LoadHalfLiteral r)
24668       end
24669   | _ =>
24670     let
24671       val r = (unsigned,(add,(index,(wback,(rt,(rn,offset))))))
24672     in
24673       Load(if byte then LoadByte r else LoadHalf r)
24674     end;
24675
24676fun p_ldrb_ldrh (c,(unsigned,(byte,l))) =
24677  case (p_suffix c,l) of
24678     (Option.SOME c,h :: t) =>
24679       (case p_register h of
24680           Option.SOME rt =>
24681             (case p_address_mode1 t of
24682                 ("",Option.SOME(add,(index,(wback,(rn,offset))))) =>
24683                   OK(c,
24684                      pick_ldrb_ldrh
24685                        (byte,
24686                         (unsigned,(add,(index,(wback,(rt,(rn,offset))))))))
24687               | (err,_) =>
24688                 (case t of
24689                     [l] =>
24690                       (case p_label l of
24691                           Option.SOME s =>
24692                             let
24693                               val r =
24694                                 (unsigned,(false,(rt,BitsN.B(0x0,32))))
24695                               val a =
24696                                 if byte
24697                                   then LoadByteLiteral r
24698                                 else LoadHalfLiteral r
24699                             in
24700                               PENDING(s,(c,Load a))
24701                             end
24702                         | NONE => FAIL err)
24703                   | _ => FAIL err))
24704         | NONE => FAIL "syntax error")
24705   | _ => FAIL "syntax error";
24706
24707fun pick_ldrd_strd (load,(add,(index,(wback,(rt1,(rt2,(rn,offset))))))) =
24708  let
24709    val r = (add,(index,(wback,(rt1,(rt2,(rn,offset))))))
24710  in
24711    if load
24712      then case (index,(wback,(rn,offset))) of
24713              (true,(false,(BitsN.B(0xF,_),immediate_form2 imm32))) =>
24714                Load(LoadDualLiteral(add,(rt1,(rt2,imm32))))
24715            | _ => Load(LoadDual r)
24716    else Store(StoreDual r)
24717  end;
24718
24719fun p_ldrd_strd (c,(load,l)) =
24720  case (p_suffix c,l) of
24721     (Option.SOME c,r1 :: (r2 :: t)) =>
24722       (case p_register2[r1,r2] of
24723           Option.SOME(rt1,rt2) =>
24724             (case p_address_mode2 t of
24725                 ("",Option.SOME(add,(index,(wback,(rn,offset))))) =>
24726                   OK(c,
24727                      pick_ldrd_strd
24728                        (load,
24729                         (add,(index,(wback,(rt1,(rt2,(rn,offset))))))))
24730               | (err,_) =>
24731                 (case t of
24732                     [l] =>
24733                       (case p_label l of
24734                           Option.SOME s =>
24735                             PENDING
24736                               (s,
24737                                (c,
24738                                 pick_ldrd_strd
24739                                   (load,
24740                                    (false,
24741                                     (true,
24742                                      (false,
24743                                       (rt1,
24744                                        (rt2,
24745                                         (BitsN.B(0xF,4),
24746                                          immediate_form2(BitsN.B(0x0,32)))))))))))
24747                         | NONE => FAIL err)
24748                   | _ => FAIL err))
24749         | NONE => FAIL "syntax error")
24750   | _ => FAIL "syntax error";
24751
24752fun p_ldrt_strt1 (c,(opc,l)) =
24753  case p_ldr_str(c,(3,l)) of
24754     OK(c,Store(StoreWord(_,(true,(_,(_,(_,register_form1 _))))))) =>
24755       FAIL "syntax error"
24756   | OK(c,Store(StoreWord(false,(true,_)))) => FAIL "syntax error"
24757   | OK(c,Store(StoreWord(_,(true,(true,_))))) => FAIL "syntax error"
24758   | OK(c,Store(StoreWord(add,(index,(wback,(t,(n,m))))))) =>
24759     let
24760       val a = (add,(not(index = wback),(t,(n,m))))
24761     in
24762       case opc of
24763          0 => OK(c,Load(LoadUnprivileged a))
24764        | 1 => OK(c,Load(LoadByteUnprivileged a))
24765        | 2 => OK(c,Store(StoreUnprivileged a))
24766        | _ => OK(c,Store(StoreByteUnprivileged a))
24767     end
24768   | _ => FAIL "syntax error";
24769
24770fun p_ldrt_strt2 (c,(opc,l)) =
24771  case p_ldrd_strd(c,(false,"r0" :: l)) of
24772     OK(c,Store(StoreDual(_,(true,(_,(_,(_,(_,register_form2 _)))))))) =>
24773       FAIL "syntax error"
24774   | OK(c,Store(StoreDual(false,(true,_)))) => FAIL "syntax error"
24775   | OK(c,Store(StoreDual(_,(true,(true,_))))) => FAIL "syntax error"
24776   | OK(c,Store(StoreDual(add,(index,(wback,(_,(t,(n,m)))))))) =>
24777     let
24778       val a = (add,(not(index = wback),(t,(n,m))))
24779     in
24780       case opc of
24781          0 => OK(c,Load(LoadSignedByteUnprivileged a))
24782        | 1 => OK(c,Load(LoadHalfUnprivileged(false,a)))
24783        | 2 => OK(c,Load(LoadHalfUnprivileged(true,a)))
24784        | _ => OK(c,Store(StoreHalfUnprivileged a))
24785     end
24786   | _ => FAIL "syntax error";
24787
24788fun p_pld (c,(is_pldw,l)) =
24789  case p_ldr_str(c,(0,"r0" :: l)) of
24790     OK(c,Load(LoadWord(add,(true,(false,(_,(n,m))))))) =>
24791       OK(c,Hint(PreloadData(add,(is_pldw,(n,m)))))
24792   | OK(c,Load(LoadLiteral(add,(_,imm32)))) =>
24793     OK(c,Hint(PreloadDataLiteral(add,imm32)))
24794   | PENDING(s,(c,Load(LoadLiteral(false,(_,BitsN.B(0x0,32)))))) =>
24795     PENDING(s,(c,Hint(PreloadDataLiteral(false,BitsN.B(0x0,32)))))
24796   | _ => FAIL "syntax error";
24797
24798fun p_pli (c,l) =
24799  case p_ldr_str(c,(0,"r0" :: l)) of
24800     OK(c,Load(LoadWord(add,(true,(false,(_,(n,m))))))) =>
24801       OK(c,Hint(PreloadInstruction(add,(n,m))))
24802   | OK(c,Load(LoadLiteral(add,(_,imm32)))) =>
24803     OK(c,
24804        Hint
24805          (PreloadInstruction(add,(BitsN.B(0xF,4),immediate_form1 imm32))))
24806   | _ => FAIL "syntax error";
24807
24808fun p_ldrex (c,l) =
24809  case (p_suffix c,l) of
24810     (Option.SOME c,h :: t) =>
24811       (case (p_register h,p_address_mode3 t) of
24812           (Option.SOME rt,("",Option.SOME(rn,Option.SOME imm32))) =>
24813             OK(c,Load(LoadExclusive(rt,(rn,imm32))))
24814         | (Option.SOME rt,("",Option.SOME(rn,NONE))) =>
24815           OK(c,Load(LoadExclusive(rt,(rn,BitsN.B(0x0,32)))))
24816         | (Option.SOME _,(err,Option.SOME _)) => FAIL err
24817         | _ => FAIL "syntax error")
24818   | _ => FAIL "syntax error";
24819
24820fun p_ldrexb_ldrexh (c,(byte,l)) =
24821  case (p_suffix c,l) of
24822     (Option.SOME c,h :: t) =>
24823       (case (p_register h,p_address_mode3 t) of
24824           (Option.SOME rt,("",Option.SOME(rn,NONE))) =>
24825             OK(c,
24826                Load
24827                  (if byte
24828                     then LoadExclusiveByte(rt,rn)
24829                   else LoadExclusiveHalf(rt,rn)))
24830         | _ => FAIL "syntax error")
24831   | _ => FAIL "syntax error";
24832
24833fun p_ldrexd (c,l) =
24834  case (p_suffix c,l) of
24835     (Option.SOME c,[r1,r2,a]) =>
24836       (case (p_register2[r1,r2],p_address_mode3[a]) of
24837           (Option.SOME(rt1,rt2),("",Option.SOME(rn,NONE))) =>
24838             OK(c,Load(LoadExclusiveDoubleword(rt1,(rt2,rn))))
24839         | _ => FAIL "syntax error")
24840   | _ => FAIL "syntax error";
24841
24842fun p_strex (c,l) =
24843  case (p_suffix c,l) of
24844     (Option.SOME c,r1 :: (r2 :: a)) =>
24845       (case (p_register2[r1,r2],p_address_mode3 a) of
24846           (Option.SOME(rd,rt),("",Option.SOME(rn,Option.SOME imm32))) =>
24847             OK(c,Store(StoreExclusive(rd,(rt,(rn,imm32)))))
24848         | (Option.SOME(rd,rt),("",Option.SOME(rn,NONE))) =>
24849           OK(c,Store(StoreExclusive(rd,(rt,(rn,BitsN.B(0x0,32))))))
24850         | _ => FAIL "syntax error")
24851   | _ => FAIL "syntax error";
24852
24853fun p_strexb_strexh (c,(byte,l)) =
24854  case (p_suffix c,l) of
24855     (Option.SOME c,[r1,r2,a]) =>
24856       (case (p_register2[r1,r2],p_address_mode3[a]) of
24857           (Option.SOME(rd,rt),("",Option.SOME(rn,NONE))) =>
24858             OK(c,
24859                Store
24860                  (if byte
24861                     then StoreExclusiveByte(rd,(rt,rn))
24862                   else StoreExclusiveHalf(rd,(rt,rn))))
24863         | _ => FAIL "syntax error")
24864   | _ => FAIL "syntax error";
24865
24866fun p_strexd (c,l) =
24867  case (p_suffix c,l) of
24868     (Option.SOME c,[r1,r2,r3,a]) =>
24869       (case (p_register3[r1,r2,r3],p_address_mode3[a]) of
24870           (Option.SOME(rd,(rt1,rt2)),("",Option.SOME(rn,NONE))) =>
24871             OK(c,Store(StoreExclusiveDoubleword(rd,(rt1,(rt2,rn)))))
24872         | _ => FAIL "syntax error")
24873   | _ => FAIL "syntax error";
24874
24875fun p_swp (c,(byte,l)) =
24876  case (p_suffix c,l) of
24877     (Option.SOME c,[r1,r2,a]) =>
24878       (case (p_register2[r1,r2],p_address_mode3[a]) of
24879           (Option.SOME(rt1,rt2),("",Option.SOME(rn,NONE))) =>
24880             OK(c,Swap(byte,(rt1,(rt2,rn))))
24881         | _ => FAIL "syntax error")
24882   | _ => FAIL "syntax error";
24883
24884fun p_pop_push (c,(pop,l)) =
24885  case (p_suffix c,p_registers l) of
24886     (Option.SOME c,Option.SOME(false,w)) =>
24887       OK(c,
24888          if pop
24889            then Load
24890                   (LoadMultiple(true,(false,(true,(BitsN.B(0xD,4),w)))))
24891          else Store
24892                 (StoreMultiple(false,(true,(true,(BitsN.B(0xD,4),w))))))
24893   | (NONE,_) => FAIL "syntax error"
24894   | _ => FAIL "bad register list";
24895
24896fun p_vpop_vpush (c,(pop,l)) =
24897  case (p_suffix c,p_fp_registers l) of
24898     (Option.SOME c,Option.SOME(single,(d,imm8))) =>
24899       OK(c,
24900          if pop
24901            then VFP(vldm(single,(true,(true,(d,(BitsN.B(0xD,4),imm8))))))
24902          else VFP(vstm(single,(false,(true,(d,(BitsN.B(0xD,4),imm8)))))))
24903   | (NONE,_) => FAIL "syntax error"
24904   | _ => FAIL "bad floating-point register list";
24905
24906fun p_ldm_stm (c,(load,(inc,(index,l)))) =
24907  case (p_suffix c,l) of
24908     (Option.SOME c,h :: t) =>
24909       let
24910         val (r,wb) = L3.splitr(fn c => c = #"!",stripSpaces h)
24911       in
24912         case (p_register r,(p_registers t,Set.mem(wb,["","!"]))) of
24913            (Option.SOME rn,(Option.SOME(false,w),true)) =>
24914              let
24915                val r = (inc,(index,(wb = "!",(rn,w))))
24916              in
24917                OK(c,
24918                   if load
24919                     then Load(LoadMultiple r)
24920                   else Store(StoreMultiple r))
24921              end
24922          | (Option.SOME rn,(Option.SOME(true,w),true)) =>
24923            (if load
24924               then if BitsN.bit(w,15)
24925                      then OK(c,
24926                              Load
24927                                (LoadMultipleExceptionReturn
24928                                   (inc,
24929                                    (index = inc,
24930                                     (wb = "!",(rn,BitsN.bits(14,0) w))))))
24931                    else if wb = ""
24932                      then OK(c,
24933                              Load
24934                                (LoadMultipleUserRegisters
24935                                   (inc,
24936                                    (index = inc,(rn,BitsN.bits(14,0) w)))))
24937                    else FAIL
24938                           "write-back not allowed for LDM (user registers)"
24939             else if wb = ""
24940               then OK(c,
24941                       Store
24942                         (StoreMultipleUserRegisters
24943                            (inc,(index = inc,(rn,w)))))
24944             else FAIL "write-back not allowed for STM (user registers)")
24945          | (Option.SOME _,(NONE,true)) => FAIL "bad register list"
24946          | _ => FAIL "syntax error"
24947       end
24948   | _ => FAIL "syntax error";
24949
24950fun p_vldm_vstm (c,(load,(inc,l))) =
24951  case (p_suffix c,l) of
24952     (Option.SOME c,h :: t) =>
24953       let
24954         val (r,wb) = L3.splitr(fn c => c = #"!",stripSpaces h)
24955       in
24956         case (p_register r,(p_fp_registers t,Set.mem(wb,["","!"]))) of
24957            (Option.SOME rn,(Option.SOME(single,(d,imm8)),true)) =>
24958              let
24959                val wback = wb = "!"
24960                val a = (single,(inc,(wback,(d,(rn,imm8)))))
24961              in
24962                if not(inc orelse wback)
24963                  then FAIL "write-back required for VLDMDB and VSTMDB"
24964                else OK(c,VFP(if load then vldm a else vstm a))
24965              end
24966          | (Option.SOME _,(NONE,true)) =>
24967            FAIL "bad floating-point register list"
24968          | _ => FAIL "syntax error"
24969       end
24970   | _ => FAIL "syntax error";
24971
24972fun p_setend l =
24973  case l of
24974     [e] =>
24975       (case stripSpaces e of
24976           "be" => OK(al,System(Setend true))
24977         | "le" => OK(al,System(Setend false))
24978         | _ => FAIL "syntax error")
24979   | _ => FAIL "syntax error";
24980
24981fun p_aif (a,(i,(f,s))) =
24982  case String.explode s of
24983     [] => Option.SOME(a,(i,f))
24984   | #"a" :: r => p_aif(true,(i,(f,String.implode r)))
24985   | #"i" :: r => p_aif(a,(true,(f,String.implode r)))
24986   | #"f" :: r => p_aif(a,(i,(true,String.implode r)))
24987   | _ => NONE;
24988
24989fun p_cps (enable,(disable,l)) =
24990  case l of
24991     [aif_m] =>
24992       (case p_immediate 5 aif_m of
24993           Option.SOME(true,mode) =>
24994             (if enable orelse disable
24995                then FAIL "syntax error"
24996              else OK(al,
24997                      System
24998                        (ChangeProcessorState
24999                           (false,
25000                            (false,
25001                             (false,(false,(false,Option.SOME mode))))))))
25002         | Option.SOME(false,_) =>
25003           (if enable orelse disable
25004              then FAIL "syntax error"
25005            else FAIL "immediate too large")
25006         | NONE =>
25007           if enable orelse disable
25008             then case p_aif(false,(false,(false,stripSpaces aif_m))) of
25009                     Option.SOME(a,(i,f)) =>
25010                       OK(al,
25011                          System
25012                            (ChangeProcessorState
25013                               (enable,(disable,(a,(i,(f,NONE)))))))
25014                   | NONE => FAIL "syntax error"
25015           else FAIL "syntax error")
25016   | [aif,m] =>
25017     (case (p_aif(false,(false,(false,stripSpaces aif))),p_immediate 5 m) of
25018         (Option.SOME _,Option.SOME(false,_)) =>
25019           (if enable orelse disable
25020              then FAIL "immediate too large"
25021            else FAIL "syntax error")
25022       | (Option.SOME(a,(i,f)),Option.SOME(true,mode)) =>
25023         (if enable orelse disable
25024            then OK(al,
25025                    System
25026                      (ChangeProcessorState
25027                         (enable,(disable,(a,(i,(f,Option.SOME mode)))))))
25028          else FAIL "syntax error")
25029       | _ => FAIL "syntax error")
25030   | _ => FAIL "syntax error";
25031
25032fun p_mode s =
25033  case s of
25034     "fiq" => Option.SOME(BitsN.B(0xE,5))
25035   | "irq" => Option.SOME(BitsN.B(0x10,5))
25036   | "svc" => Option.SOME(BitsN.B(0x12,5))
25037   | "abt" => Option.SOME(BitsN.B(0x14,5))
25038   | "und" => Option.SOME(BitsN.B(0x16,5))
25039   | "mon" => Option.SOME(BitsN.B(0x1C,5))
25040   | "hyp" => Option.SOME(BitsN.B(0x1E,5))
25041   | _ =>
25042     (case Nat.fromString s of
25043         Option.SOME n => Option.SOME(BitsN.fromNat(n,5))
25044       | NONE => NONE);
25045
25046fun banked_register (r,mode) =
25047  case mode of
25048     "usr" =>
25049       let
25050         val i = BitsN.-(r,BitsN.B(0x8,4))
25051       in
25052         if BitsN.<+(i,BitsN.B(0x7,4))
25053           then Option.SOME
25054                  (BitsN.@@(BitsN.B(0x0,2),BitsN.fromNat(BitsN.toNat i,3)))
25055         else NONE
25056       end
25057   | "fiq" =>
25058     let
25059       val i = BitsN.-(r,BitsN.B(0x8,4))
25060     in
25061       if BitsN.<+(i,BitsN.B(0x7,4))
25062         then Option.SOME
25063                (BitsN.@@(BitsN.B(0x1,2),BitsN.fromNat(BitsN.toNat i,3)))
25064       else NONE
25065     end
25066   | "irq" =>
25067     if r = (BitsN.B(0xD,4))
25068       then Option.SOME(BitsN.B(0x11,5))
25069     else if r = (BitsN.B(0xE,4))
25070       then Option.SOME(BitsN.B(0x10,5))
25071     else NONE
25072   | "svc" =>
25073     if r = (BitsN.B(0xD,4))
25074       then Option.SOME(BitsN.B(0x13,5))
25075     else if r = (BitsN.B(0xE,4))
25076       then Option.SOME(BitsN.B(0x12,5))
25077     else NONE
25078   | "abt" =>
25079     if r = (BitsN.B(0xD,4))
25080       then Option.SOME(BitsN.B(0x15,5))
25081     else if r = (BitsN.B(0xE,4))
25082       then Option.SOME(BitsN.B(0x14,5))
25083     else NONE
25084   | "und" =>
25085     if r = (BitsN.B(0xD,4))
25086       then Option.SOME(BitsN.B(0x17,5))
25087     else if r = (BitsN.B(0xE,4))
25088       then Option.SOME(BitsN.B(0x16,5))
25089     else NONE
25090   | "mon" =>
25091     if r = (BitsN.B(0xD,4))
25092       then Option.SOME(BitsN.B(0x1D,5))
25093     else if r = (BitsN.B(0xE,4))
25094       then Option.SOME(BitsN.B(0x1C,5))
25095     else NONE
25096   | "hyp" =>
25097     if r = (BitsN.B(0xD,4)) then Option.SOME(BitsN.B(0x1F,5)) else NONE
25098   | _ => NONE;
25099
25100fun p_banked_register s =
25101  case L3.uncurry String.tokens (fn c => c = #"_",s) of
25102     [r,m] =>
25103       (case p_register r of
25104           Option.SOME r0 => banked_register(r0,stripSpaces m)
25105         | NONE => NONE)
25106   | _ => NONE;
25107
25108fun p_mrs (c,l) =
25109  case (p_suffix c,l) of
25110     (Option.SOME c,[r1,r2]) =>
25111       (case p_register r1 of
25112           Option.SOME rd =>
25113             (case String.explode(stripSpaces r2) of
25114                 [#"a",#"p",#"s",#"r"] =>
25115                   OK(c,System(MoveToRegisterFromSpecial(false,rd)))
25116               | [#"c",#"p",#"s",#"r"] =>
25117                 OK(c,System(MoveToRegisterFromSpecial(false,rd)))
25118               | [#"s",#"p",#"s",#"r"] =>
25119                 OK(c,System(MoveToRegisterFromSpecial(true,rd)))
25120               | [#"e",#"l",#"r",#"_",#"h",#"y",#"p"] =>
25121                 OK(c,
25122                    System
25123                      (MoveToRegisterFromBankedOrSpecial
25124                         (false,(BitsN.B(0x1E,5),rd))))
25125               | #"s" :: (#"p" :: (#"s" :: (#"r" :: (#"_" :: m)))) =>
25126                 (case p_mode(String.implode m) of
25127                     Option.SOME sysm =>
25128                       OK(c,
25129                          System
25130                            (MoveToRegisterFromBankedOrSpecial
25131                               (true,(sysm,rd))))
25132                   | NONE => FAIL "syntax error")
25133               | r_mode =>
25134                 (case p_banked_register(String.implode r_mode) of
25135                     Option.SOME sysm =>
25136                       OK(c,
25137                          System
25138                            (MoveToRegisterFromBankedOrSpecial
25139                               (false,(sysm,rd))))
25140                   | NONE => FAIL "syntax error"))
25141         | NONE => FAIL "syntax error")
25142   | _ => FAIL "syntax error";
25143
25144fun p_cxsf (mask,s) =
25145  case String.explode s of
25146     [] => Option.SOME mask
25147   | #"c" :: r =>
25148     (if BitsN.bit(mask,0)
25149        then NONE
25150      else p_cxsf(BitsN.||(mask,BitsN.B(0x1,4)),String.implode r))
25151   | #"x" :: r =>
25152     (if BitsN.bit(mask,1)
25153        then NONE
25154      else p_cxsf(BitsN.||(mask,BitsN.B(0x2,4)),String.implode r))
25155   | #"s" :: r =>
25156     (if BitsN.bit(mask,2)
25157        then NONE
25158      else p_cxsf(BitsN.||(mask,BitsN.B(0x4,4)),String.implode r))
25159   | #"f" :: r =>
25160     (if BitsN.bit(mask,3)
25161        then NONE
25162      else p_cxsf(BitsN.||(mask,BitsN.B(0x8,4)),String.implode r))
25163   | _ => NONE;
25164
25165fun p_spec_reg s =
25166  case String.explode(stripSpaces s) of
25167     [#"a",#"p",#"s",#"r"] => Option.SOME(false,BitsN.B(0xF,4))
25168   | [#"c",#"p",#"s",#"r"] => Option.SOME(false,BitsN.B(0xF,4))
25169   | [#"s",#"p",#"s",#"r"] => Option.SOME(true,BitsN.B(0xF,4))
25170   | [#"a",#"p",#"s",#"r",#"_",#"n",#"z",#"c",#"v",#"q"] =>
25171     Option.SOME(false,BitsN.B(0x8,4))
25172   | [#"a",#"p",#"s",#"r",#"_",#"g"] => Option.SOME(false,BitsN.B(0x4,4))
25173   | [#"a",#"p",#"s",#"r",#"_",#"n",#"z",#"c",#"v",#"q",#"g"] =>
25174     Option.SOME(false,BitsN.B(0xC,4))
25175   | #"c" :: (#"p" :: (#"s" :: (#"r" :: (#"_" :: r)))) =>
25176     (case p_cxsf(BitsN.B(0x0,4),String.implode r) of
25177         Option.SOME mask => Option.SOME(false,mask)
25178       | NONE => NONE)
25179   | #"s" :: (#"p" :: (#"s" :: (#"r" :: (#"_" :: r)))) =>
25180     (case p_cxsf(BitsN.B(0x0,4),String.implode r) of
25181         Option.SOME mask => Option.SOME(true,mask)
25182       | NONE => NONE)
25183   | _ => NONE;
25184
25185fun p_msr (c,l) =
25186  case (p_suffix c,l) of
25187     (Option.SOME c,[r1,r2]) =>
25188       (case p_immediate 32 r2 of
25189           Option.SOME(true,imm32) =>
25190             (case p_spec_reg r1 of
25191                 Option.SOME(write_spsr,mask) =>
25192                   OK(c,
25193                      System
25194                        (MoveToSpecialFromImmediate
25195                           (write_spsr,(imm32,mask))))
25196               | NONE => FAIL "syntax error")
25197         | Option.SOME(false,_) => FAIL "immediate too large"
25198         | NONE =>
25199           (case (p_spec_reg r1,p_register r2) of
25200               (Option.SOME(write_spsr,mask),Option.SOME n) =>
25201                 OK(c,
25202                    System(MoveToSpecialFromRegister(write_spsr,(n,mask))))
25203             | (NONE,Option.SOME n) =>
25204               (case String.explode(stripSpaces r1) of
25205                   [#"e",#"l",#"r",#"_",#"h",#"y",#"p"] =>
25206                     OK(c,
25207                        System
25208                          (MoveToBankedOrSpecialRegister
25209                             (false,(BitsN.B(0x1E,5),n))))
25210                 | #"s" :: (#"p" :: (#"s" :: (#"r" :: (#"_" :: m)))) =>
25211                   (case p_mode(String.implode m) of
25212                       Option.SOME sysm =>
25213                         OK(c,
25214                            System
25215                              (MoveToBankedOrSpecialRegister
25216                                 (true,(sysm,n))))
25217                     | NONE => FAIL "syntax error")
25218                 | r_mode =>
25219                   (case p_banked_register(String.implode r_mode) of
25220                       Option.SOME sysm =>
25221                         OK(c,
25222                            System
25223                              (MoveToBankedOrSpecialRegister
25224                                 (false,(sysm,n))))
25225                     | NONE => FAIL "syntax error"))
25226             | _ => FAIL "syntax error"))
25227   | _ => FAIL "syntax error";
25228
25229fun p_rfe (c,(increment,(wordhigher,l))) =
25230  case (p_suffix c,l) of
25231     (Option.SOME c,[h]) =>
25232       let
25233         val (r,wb) = L3.splitr(fn c => c = #"!",stripSpaces h)
25234       in
25235         case (p_register r,Set.mem(wb,["","!"])) of
25236            (Option.SOME n,true) =>
25237              OK(c,
25238                 System
25239                   (ReturnFromException
25240                      (increment,(wordhigher,(wb = "!",n)))))
25241          | _ => FAIL "syntax error"
25242       end
25243   | _ => FAIL "syntax error";
25244
25245fun p_srs (c,(increment,(wordhigher,l))) =
25246  case (p_suffix c,l) of
25247     (Option.SOME c,[h,m]) =>
25248       let
25249         val (r,wb) = L3.splitr(fn c => c = #"!",stripSpaces h)
25250       in
25251         case (p_register r,(Set.mem(wb,["","!"]),p_immediate_number 5 m)) of
25252            (Option.SOME(BitsN.B(0xD,_)),(true,Option.SOME(ok,mode))) =>
25253              (if ok
25254                 then OK(c,
25255                         System
25256                           (StoreReturnState
25257                              (increment,(wordhigher,(wb = "!",mode)))))
25258               else FAIL "immediate too large")
25259          | _ => FAIL "syntax error"
25260       end
25261   | _ => FAIL "syntax error";
25262
25263fun p_call (c,(e,l)) =
25264  case (p_suffix c,l) of
25265     (Option.SOME c,[imm]) =>
25266       (case p_immediate_number 32 imm of
25267           Option.SOME(true,imm32) =>
25268             let
25269               val ast =
25270                 case e of
25271                    0 => Undefined imm32
25272                  | 1 => Hint(Debug(BitsN.fromNat(BitsN.toNat imm32,4)))
25273                  | 2 =>
25274                    System
25275                      (SecureMonitorCall
25276                         (BitsN.fromNat(BitsN.toNat imm32,4)))
25277                  | 3 => System(SupervisorCall imm32)
25278                  | 4 =>
25279                    System
25280                      (HypervisorCall(BitsN.fromNat(BitsN.toNat imm32,16)))
25281                  | _ => Hint(Breakpoint imm32)
25282             in
25283               if (((e = 1) orelse (e = 2)) andalso
25284                   (BitsN.<+(BitsN.B(0xF,32),imm32))) orelse
25285                  ((e = 4) andalso (BitsN.<+(BitsN.B(0xFFFF,32),imm32)))
25286                 then FAIL "immediate too large"
25287               else OK(c,ast)
25288             end
25289         | Option.SOME(false,_) => FAIL "immediate too large"
25290         | _ => FAIL "syntax error")
25291   | _ => FAIL "syntax error";
25292
25293fun p_barrier_option l =
25294  case l of
25295     [] => Option.SOME(BitsN.B(0xF,4))
25296   | [s] =>
25297     (case stripSpaces s of
25298         "sy" => Option.SOME(BitsN.B(0xF,4))
25299       | "st" => Option.SOME(BitsN.B(0xE,4))
25300       | "ish" => Option.SOME(BitsN.B(0xB,4))
25301       | "ishst" => Option.SOME(BitsN.B(0xA,4))
25302       | "nsh" => Option.SOME(BitsN.B(0x7,4))
25303       | "nshst" => Option.SOME(BitsN.B(0x6,4))
25304       | "osh" => Option.SOME(BitsN.B(0x3,4))
25305       | "oshst" => Option.SOME(BitsN.B(0x2,4))
25306       | n =>
25307         (case Nat.fromString n of
25308             Option.SOME v => Option.SOME(BitsN.fromNat(v,4))
25309           | NONE => NONE))
25310   | _ => NONE;
25311
25312fun p_dmb_dsb (c,(sync,l)) =
25313  case (p_suffix c,p_barrier_option l) of
25314     (Option.SOME c,Option.SOME option) =>
25315       OK(c,
25316          Hint
25317            (if sync
25318               then DataSynchronizationBarrier option
25319             else DataMemoryBarrier option))
25320   | _ => FAIL "syntax error";
25321
25322fun p_isb (c,l) =
25323  case (p_suffix c,p_barrier_option l) of
25324     (Option.SOME c,Option.SOME(BitsN.B(0xF,_))) =>
25325       OK(c,Hint(InstructionSynchronizationBarrier(BitsN.B(0xF,4))))
25326   | _ => FAIL "syntax error";
25327
25328fun p_vcmpe (c,l) =
25329  case (p_suffix c,l) of
25330     (Option.SOME(c,s),[d,v]) =>
25331       let
25332         val single = s = "f32"
25333       in
25334         if single orelse (s = "f64")
25335           then case p_fp_register(single,d) of
25336                   Option.SOME dd =>
25337                     (case p_fp_register(single,v) of
25338                         Option.SOME dm =>
25339                           OK((c,""),
25340                              VFP(vcmp(not single,(dd,Option.SOME dm))))
25341                       | NONE =>
25342                         if (stripSpaces v) = "#0.0"
25343                           then OK((c,""),VFP(vcmp(not single,(dd,NONE))))
25344                         else FAIL "syntax error")
25345                 | NONE => FAIL "syntax error"
25346         else FAIL "syntax error"
25347       end
25348   | _ => FAIL "syntax error";
25349
25350fun p_vmrs_register s =
25351  case p_register s of
25352     Option.SOME n =>
25353       (if n = (BitsN.B(0xF,4)) then NONE else Option.SOME n)
25354   | NONE =>
25355     if (stripSpaces s) = "apsr_nzcv"
25356       then Option.SOME(BitsN.B(0xF,4))
25357     else NONE;
25358
25359fun p_vmrs (c,l) =
25360  case (p_suffix c,l) of
25361     (Option.SOME c,[t,s]) =>
25362       (case (p_vmrs_register t,stripSpaces s) of
25363           (Option.SOME rt,"fpscr") => OK(c,VFP(vmrs rt))
25364         | _ => FAIL "syntax error")
25365   | _ => FAIL "syntax error";
25366
25367fun p_vmsr (c,l) =
25368  case (p_suffix c,l) of
25369     (Option.SOME c,[t,s]) =>
25370       (case (p_register s,stripSpaces t) of
25371           (Option.SOME rt,"fpscr") => OK(c,VFP(vmsr rt))
25372         | _ => FAIL "syntax error")
25373   | _ => FAIL "syntax error";
25374
25375fun p_vcvt (c,(r,l)) =
25376  case (r,(p_suffix2 c,l)) of
25377     (false,(Option.SOME(c,("f32","f64")),[d,m])) =>
25378       (case (p_fp_register(true,d),p_fp_register(false,m)) of
25379           (Option.SOME dd,Option.SOME mm) =>
25380             OK((c,""),VFP(vcvt_float(true,(dd,mm))))
25381         | _ => FAIL "syntax error")
25382   | (false,(Option.SOME(c,("f64","f32")),[d,m])) =>
25383     (case (p_fp_register(false,d),p_fp_register(true,m)) of
25384         (Option.SOME dd,Option.SOME mm) =>
25385           OK((c,""),VFP(vcvt_float(false,(dd,mm))))
25386       | _ => FAIL "syntax error")
25387   | (_,(Option.SOME(c,(s1,s2)),[d,m])) =>
25388     (if (not r) andalso
25389         ((Set.mem(s1,["f32","f64"])) andalso (Set.mem(s2,["u32","s32"])))
25390        then let
25391               val single = s1 = "f32"
25392             in
25393               case (p_fp_register(single,d),p_fp_register(true,m)) of
25394                  (Option.SOME dd,Option.SOME mm) =>
25395                    OK((c,""),
25396                       VFP(vcvt_from_integer
25397                             (not single,(s2 = "u32",(dd,mm)))))
25398                | _ => FAIL "syntax error"
25399             end
25400      else if (Set.mem(s2,["f32","f64"])) andalso
25401         (Set.mem(s1,["u32","s32"]))
25402        then let
25403               val single = s2 = "f32"
25404             in
25405               case (p_fp_register(true,d),p_fp_register(single,m)) of
25406                  (Option.SOME dd,Option.SOME mm) =>
25407                    OK((c,""),
25408                       VFP(vcvt_to_integer
25409                             (not single,(s1 = "u32",(not r,(dd,mm))))))
25410                | _ => FAIL "syntax error"
25411             end
25412      else FAIL "syntax error")
25413   | _ => FAIL "syntax error";
25414
25415fun p_fp2 (c,(opc,l)) =
25416  case (p_suffix c,l) of
25417     (Option.SOME(c,""),[r1,r2,r3,r4]) =>
25418       (case (opc = 0,
25419         (p_fp_register(true,r1),
25420          (p_fp_register(true,r2),(p_register r3,p_register r4)))) of
25421           (true,
25422            (Option.SOME rr1,
25423             (Option.SOME rr2,(Option.SOME rr3,Option.SOME rr4)))) =>
25424             (if rr2 = (BitsN.+(rr1,BitsN.B(0x1,5)))
25425                then OK((c,""),
25426                        VFP(vmov_two_singles(false,(rr3,(rr4,rr1)))))
25427              else FAIL "syntax error")
25428         | (true,_) =>
25429           (case (p_register r1,
25430             (p_register r2,
25431              (p_fp_register(true,r3),p_fp_register(true,r4)))) of
25432               (Option.SOME rr1,
25433                (Option.SOME rr2,(Option.SOME rr3,Option.SOME rr4))) =>
25434                 (if rr4 = (BitsN.+(rr3,BitsN.B(0x1,5)))
25435                    then OK((c,""),
25436                            VFP(vmov_two_singles(true,(rr1,(rr2,rr3)))))
25437                  else FAIL "syntax error")
25438             | _ => FAIL "syntax error")
25439         | _ => FAIL "syntax error")
25440   | (Option.SOME(c,""),[r1,r2,r3]) =>
25441     (case (opc = 0,
25442       (p_fp_register(false,r1),(p_register r2,p_register r3))) of
25443         (true,(Option.SOME rr1,(Option.SOME rr2,Option.SOME rr3))) =>
25444           OK((c,""),VFP(vmov_double(false,(rr2,(rr3,rr1)))))
25445       | (true,_) =>
25446         (case (p_register r1,(p_register r2,p_fp_register(false,r3))) of
25447             (Option.SOME rr1,(Option.SOME rr2,Option.SOME rr3)) =>
25448               OK((c,""),VFP(vmov_double(true,(rr1,(rr2,rr3)))))
25449           | _ => FAIL "syntax error")
25450       | _ => FAIL "syntax error")
25451   | (Option.SOME(c,""),[d,t]) =>
25452     (case (opc = 0,(p_fp_register(true,d),p_register t)) of
25453         (true,(Option.SOME dd,Option.SOME tt)) =>
25454           OK((c,""),VFP(vmov_single(false,(tt,dd))))
25455       | (true,_) =>
25456         (case (p_register d,p_fp_register(true,t)) of
25457             (Option.SOME tt,Option.SOME dd) =>
25458               OK((c,""),VFP(vmov_single(true,(tt,dd))))
25459           | _ => FAIL "syntax error")
25460       | _ => FAIL "syntax error")
25461   | (Option.SOME(c,s),[d,v]) =>
25462     let
25463       val single = s = "f32"
25464       val double = s = "f64"
25465     in
25466       if single orelse double
25467         then case p_fp_register(single,d) of
25468                 Option.SOME dd =>
25469                   (case p_fp_register(single,v) of
25470                       Option.SOME dm =>
25471                         OK((c,""),
25472                            VFP(case opc of
25473                                   0 => vmov(single,(dd,dm))
25474                                 | 1 => vabs(double,(dd,dm))
25475                                 | 2 => vneg(double,(dd,dm))
25476                                 | _ => vsqrt(double,(dd,dm))))
25477                     | NONE =>
25478                       if opc = 0
25479                         then case p_arm_fp_immediate(single,v) of
25480                                 Option.SOME("",imm64) =>
25481                                   OK((c,""),
25482                                      VFP(vmov_imm(single,(dd,imm64))))
25483                               | Option.SOME(err,_) => FAIL err
25484                               | NONE => FAIL "syntax error"
25485                       else FAIL "syntax error")
25486               | NONE => FAIL "syntax error"
25487       else FAIL "syntax error"
25488     end
25489   | _ => FAIL "syntax error";
25490
25491fun p_fp3 (c,(opc,l)) =
25492  case p_suffix c of
25493     Option.SOME(c,s) =>
25494       let
25495         val single = s = "f32"
25496         val double = s = "f64"
25497       in
25498         if single orelse double
25499           then case p_fp_register3(single,l) of
25500                   Option.SOME(d,(n,m)) =>
25501                     OK((c,""),
25502                        VFP(case opc of
25503                               0 => vadd(double,(d,(n,m)))
25504                             | 1 => vsub(double,(d,(n,m)))
25505                             | 2 => vmul(double,(d,(n,m)))
25506                             | 3 => vdiv(double,(d,(n,m)))
25507                             | 4 => vmla_vmls(double,(true,(d,(n,m))))
25508                             | 5 => vmla_vmls(double,(false,(d,(n,m))))
25509                             | 6 => vfma_vfms(double,(true,(d,(n,m))))
25510                             | 7 => vfma_vfms(double,(false,(d,(n,m))))
25511                             | 8 => vfnma_vfnms(double,(true,(d,(n,m))))
25512                             | 9 => vfnma_vfnms(double,(false,(d,(n,m))))
25513                             | 10 =>
25514                               vneg_mul
25515                                 (double,(VFPNegMul_VNMLA,(d,(n,m))))
25516                             | 11 =>
25517                               vneg_mul
25518                                 (double,(VFPNegMul_VNMLS,(d,(n,m))))
25519                             | _ =>
25520                               vneg_mul
25521                                 (double,(VFPNegMul_VNMUL,(d,(n,m))))))
25522                 | NONE => FAIL "syntax error"
25523         else FAIL "syntax error"
25524       end
25525   | _ => FAIL "syntax error";
25526
25527fun p_vldr_vstr (c,(load,l)) =
25528  case (p_suffix c,l) of
25529     (Option.SOME(c,s),r :: t) =>
25530       (case p_any_fp_register(r,s) of
25531           Option.SOME(single,d) =>
25532             (case p_address_mode2 t of
25533                 ("",
25534                  Option.SOME
25535                    (add,(true,(false,(n,immediate_form2 imm32))))) =>
25536                   let
25537                     val arg = (single,(add,(d,(n,imm32))))
25538                   in
25539                     OK((c,""),VFP(if load then vldr arg else vstr arg))
25540                   end
25541               | ("",Option.SOME _) => FAIL "syntax error"
25542               | (err,_) =>
25543                 (case t of
25544                     [l] =>
25545                       (case p_label l of
25546                           Option.SOME s =>
25547                             let
25548                               val arg =
25549                                 (single,
25550                                  (false,
25551                                   (d,(BitsN.B(0xF,4),BitsN.B(0x0,32)))))
25552                             in
25553                               PENDING
25554                                 (s,
25555                                  ((c,""),
25556                                   VFP(if load then vldr arg else vstr arg)))
25557                             end
25558                         | NONE => FAIL err)
25559                   | _ => FAIL err))
25560         | NONE => FAIL "syntax error")
25561   | _ => FAIL "syntax error";
25562
25563fun p_noarg (c,i) =
25564  case p_suffix c of
25565     Option.SOME c => OK(c,i)
25566   | NONE => FAIL "syntax error";
25567
25568fun p_tokens s =
25569  let
25570    val (l,r) =
25571      L3.splitl
25572        (fn c => not(Char.isSpace c),
25573         L3.lowercase(L3.snd(L3.splitl(fn c => Char.isSpace c,s))))
25574    val r = L3.uncurry String.fields (fn c => c = #",",r)
25575    val r =
25576      if ((L3.length r) = 1) andalso ((stripSpaces(List.hd r)) = "")
25577        then []
25578      else r
25579  in
25580    l :: r
25581  end;
25582
25583fun instructionFromString s =
25584  case p_tokens s of
25585     v'0 :: v'1 =>
25586       (case (String.explode v'0,v'1) of
25587           (#"c" :: (#"l" :: (#"z" :: c)),l) => p_clz(String.implode c,l)
25588         | (#"m" :: (#"o" :: (#"v" :: (#"t" :: c))),l) =>
25589           p_movt_movw(String.implode c,(true,l))
25590         | (#"m" :: (#"o" :: (#"v" :: (#"w" :: c))),l) =>
25591           p_movt_movw(String.implode c,(false,l))
25592         | (#"a" :: (#"d" :: (#"d" :: (#"w" :: c))),l) =>
25593           p_addw_subw(String.implode c,(false,l))
25594         | (#"s" :: (#"u" :: (#"b" :: (#"w" :: c))),l) =>
25595           p_addw_subw(String.implode c,(true,l))
25596         | (#"a" :: (#"d" :: (#"r" :: c)),l) => p_adr(String.implode c,l)
25597         | (#"a" :: (#"n" :: (#"d" :: (#"s" :: c))),l) =>
25598           p_arith_logic(String.implode c,(BitsN.B(0x0,4),(true,l)))
25599         | (#"a" :: (#"n" :: (#"d" :: c)),l) =>
25600           p_arith_logic(String.implode c,(BitsN.B(0x0,4),(false,l)))
25601         | (#"e" :: (#"o" :: (#"r" :: (#"s" :: c))),l) =>
25602           p_arith_logic(String.implode c,(BitsN.B(0x1,4),(true,l)))
25603         | (#"e" :: (#"o" :: (#"r" :: c)),l) =>
25604           p_arith_logic(String.implode c,(BitsN.B(0x1,4),(false,l)))
25605         | (#"s" :: (#"u" :: (#"b" :: (#"s" :: c))),l) =>
25606           p_arith_logic(String.implode c,(BitsN.B(0x2,4),(true,l)))
25607         | (#"s" :: (#"u" :: (#"b" :: c)),l) =>
25608           p_arith_logic(String.implode c,(BitsN.B(0x2,4),(false,l)))
25609         | (#"r" :: (#"s" :: (#"b" :: (#"s" :: c))),l) =>
25610           p_arith_logic(String.implode c,(BitsN.B(0x3,4),(true,l)))
25611         | (#"r" :: (#"s" :: (#"b" :: c)),l) =>
25612           p_arith_logic(String.implode c,(BitsN.B(0x3,4),(false,l)))
25613         | (#"a" :: (#"d" :: (#"d" :: (#"s" :: c))),l) =>
25614           p_arith_logic(String.implode c,(BitsN.B(0x4,4),(true,l)))
25615         | (#"a" :: (#"d" :: (#"d" :: c)),l) =>
25616           p_arith_logic(String.implode c,(BitsN.B(0x4,4),(false,l)))
25617         | (#"a" :: (#"d" :: (#"c" :: (#"s" :: c))),l) =>
25618           p_arith_logic(String.implode c,(BitsN.B(0x5,4),(true,l)))
25619         | (#"a" :: (#"d" :: (#"c" :: c)),l) =>
25620           p_arith_logic(String.implode c,(BitsN.B(0x5,4),(false,l)))
25621         | (#"s" :: (#"b" :: (#"c" :: (#"s" :: c))),l) =>
25622           p_arith_logic(String.implode c,(BitsN.B(0x6,4),(true,l)))
25623         | (#"s" :: (#"b" :: (#"c" :: c)),l) =>
25624           p_arith_logic(String.implode c,(BitsN.B(0x6,4),(false,l)))
25625         | (#"r" :: (#"s" :: (#"c" :: (#"s" :: c))),l) =>
25626           p_arith_logic(String.implode c,(BitsN.B(0x7,4),(true,l)))
25627         | (#"r" :: (#"s" :: (#"c" :: c)),l) =>
25628           p_arith_logic(String.implode c,(BitsN.B(0x7,4),(false,l)))
25629         | (#"o" :: (#"r" :: (#"r" :: (#"s" :: c))),l) =>
25630           p_arith_logic(String.implode c,(BitsN.B(0xC,4),(true,l)))
25631         | (#"o" :: (#"r" :: (#"r" :: c)),l) =>
25632           p_arith_logic(String.implode c,(BitsN.B(0xC,4),(false,l)))
25633         | (#"b" :: (#"i" :: (#"c" :: (#"s" :: c))),l) =>
25634           p_arith_logic(String.implode c,(BitsN.B(0xE,4),(true,l)))
25635         | (#"b" :: (#"i" :: (#"c" :: c)),l) =>
25636           p_arith_logic(String.implode c,(BitsN.B(0xE,4),(false,l)))
25637         | (#"t" :: (#"s" :: (#"t" :: c)),l) =>
25638           p_test_compare(String.implode c,(BitsN.B(0x0,2),l))
25639         | (#"t" :: (#"e" :: (#"q" :: c)),l) =>
25640           p_test_compare(String.implode c,(BitsN.B(0x1,2),l))
25641         | (#"c" :: (#"m" :: (#"p" :: c)),l) =>
25642           p_test_compare(String.implode c,(BitsN.B(0x2,2),l))
25643         | (#"c" :: (#"m" :: (#"n" :: c)),l) =>
25644           p_test_compare(String.implode c,(BitsN.B(0x3,2),l))
25645         | (#"m" :: (#"o" :: (#"v" :: (#"s" :: c))),l) =>
25646           p_mov_mvn(String.implode c,(false,(true,l)))
25647         | (#"m" :: (#"o" :: (#"v" :: c)),l) =>
25648           p_mov_mvn(String.implode c,(false,(false,l)))
25649         | (#"m" :: (#"v" :: (#"n" :: (#"s" :: c))),l) =>
25650           p_mov_mvn(String.implode c,(true,(true,l)))
25651         | (#"m" :: (#"v" :: (#"n" :: c)),l) =>
25652           p_mov_mvn(String.implode c,(true,(false,l)))
25653         | (#"l" :: (#"s" :: (#"l" :: (#"s" :: c))),l) =>
25654           p_shift(String.implode c,(SRType_LSL,(true,l)))
25655         | (#"l" :: (#"s" :: (#"l" :: c)),l) =>
25656           p_shift(String.implode c,(SRType_LSL,(false,l)))
25657         | (#"l" :: (#"s" :: (#"r" :: (#"s" :: c))),l) =>
25658           p_shift(String.implode c,(SRType_LSR,(true,l)))
25659         | (#"l" :: (#"s" :: (#"r" :: c)),l) =>
25660           p_shift(String.implode c,(SRType_LSR,(false,l)))
25661         | (#"a" :: (#"s" :: (#"r" :: (#"s" :: c))),l) =>
25662           p_shift(String.implode c,(SRType_ASR,(true,l)))
25663         | (#"a" :: (#"s" :: (#"r" :: c)),l) =>
25664           p_shift(String.implode c,(SRType_ASR,(false,l)))
25665         | (#"r" :: (#"o" :: (#"r" :: (#"s" :: c))),l) =>
25666           p_shift(String.implode c,(SRType_ROR,(true,l)))
25667         | (#"r" :: (#"o" :: (#"r" :: c)),l) =>
25668           p_shift(String.implode c,(SRType_ROR,(false,l)))
25669         | (#"r" :: (#"r" :: (#"x" :: (#"s" :: c))),l) =>
25670           p_rrx(String.implode c,(true,l))
25671         | (#"r" :: (#"r" :: (#"x" :: c)),l) =>
25672           p_rrx(String.implode c,(false,l))
25673         | (#"m" :: (#"u" :: (#"l" :: (#"s" :: c))),l) =>
25674           p_mul(String.implode c,(true,l))
25675         | (#"m" :: (#"u" :: (#"l" :: c)),l) =>
25676           p_mul(String.implode c,(false,l))
25677         | (#"m" :: (#"l" :: (#"a" :: (#"s" :: c))),l) =>
25678           p_mla(String.implode c,(true,l))
25679         | (#"m" :: (#"l" :: (#"a" :: c)),l) =>
25680           p_mla(String.implode c,(false,l))
25681         | (#"m" :: (#"l" :: (#"s" :: c)),l) => p_mls(String.implode c,l)
25682         | (#"u" :: (#"m" :: (#"a" :: (#"a" :: (#"l" :: c)))),l) =>
25683           p_umaal(String.implode c,l)
25684         | (#"s" ::
25685          (#"m" :: (#"l" :: (#"a" :: (#"l" :: (#"b" :: (#"b" :: c)))))),l) =>
25686           p_smlal(String.implode c,(false,(false,l)))
25687         | (#"s" ::
25688          (#"m" :: (#"l" :: (#"a" :: (#"l" :: (#"b" :: (#"t" :: c)))))),l) =>
25689           p_smlal(String.implode c,(false,(true,l)))
25690         | (#"s" ::
25691          (#"m" :: (#"l" :: (#"a" :: (#"l" :: (#"t" :: (#"b" :: c)))))),l) =>
25692           p_smlal(String.implode c,(true,(false,l)))
25693         | (#"s" ::
25694          (#"m" :: (#"l" :: (#"a" :: (#"l" :: (#"t" :: (#"t" :: c)))))),l) =>
25695           p_smlal(String.implode c,(true,(true,l)))
25696         | (#"s" ::
25697          (#"m" :: (#"l" :: (#"a" :: (#"l" :: (#"d" :: (#"x" :: c)))))),l) =>
25698           p_smlald_smlsld(String.implode c,(false,(true,l)))
25699         | (#"s" ::
25700          (#"m" :: (#"l" :: (#"s" :: (#"l" :: (#"d" :: (#"x" :: c)))))),l) =>
25701           p_smlald_smlsld(String.implode c,(true,(true,l)))
25702         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"l" :: (#"d" :: c))))),l) =>
25703           p_smlald_smlsld(String.implode c,(false,(false,l)))
25704         | (#"s" :: (#"m" :: (#"l" :: (#"s" :: (#"l" :: (#"d" :: c))))),l) =>
25705           p_smlald_smlsld(String.implode c,(true,(false,l)))
25706         | (#"u" :: (#"m" :: (#"u" :: (#"l" :: (#"l" :: (#"s" :: c))))),l) =>
25707           p_umull_etc(String.implode c,(false,(false,(true,l))))
25708         | (#"u" :: (#"m" :: (#"u" :: (#"l" :: (#"l" :: c)))),l) =>
25709           p_umull_etc(String.implode c,(false,(false,(false,l))))
25710         | (#"s" :: (#"m" :: (#"u" :: (#"l" :: (#"l" :: (#"s" :: c))))),l) =>
25711           p_umull_etc(String.implode c,(false,(true,(true,l))))
25712         | (#"s" :: (#"m" :: (#"u" :: (#"l" :: (#"l" :: c)))),l) =>
25713           p_umull_etc(String.implode c,(false,(true,(false,l))))
25714         | (#"u" :: (#"m" :: (#"l" :: (#"a" :: (#"l" :: (#"s" :: c))))),l) =>
25715           p_umull_etc(String.implode c,(true,(false,(true,l))))
25716         | (#"u" :: (#"m" :: (#"l" :: (#"a" :: (#"l" :: c)))),l) =>
25717           p_umull_etc(String.implode c,(true,(false,(false,l))))
25718         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"l" :: (#"s" :: c))))),l) =>
25719           p_umull_etc(String.implode c,(true,(true,(true,l))))
25720         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"l" :: c)))),l) =>
25721           p_umull_etc(String.implode c,(true,(true,(false,l))))
25722         | (#"s" :: (#"m" :: (#"u" :: (#"l" :: (#"b" :: (#"b" :: c))))),l) =>
25723           p_smul(String.implode c,(false,(false,l)))
25724         | (#"s" :: (#"m" :: (#"u" :: (#"l" :: (#"b" :: (#"t" :: c))))),l) =>
25725           p_smul(String.implode c,(false,(true,l)))
25726         | (#"s" :: (#"m" :: (#"u" :: (#"l" :: (#"t" :: (#"b" :: c))))),l) =>
25727           p_smul(String.implode c,(true,(false,l)))
25728         | (#"s" :: (#"m" :: (#"u" :: (#"l" :: (#"t" :: (#"t" :: c))))),l) =>
25729           p_smul(String.implode c,(true,(true,l)))
25730         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"b" :: (#"b" :: c))))),l) =>
25731           p_smla(String.implode c,(false,(false,l)))
25732         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"b" :: (#"t" :: c))))),l) =>
25733           p_smla(String.implode c,(false,(true,l)))
25734         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"t" :: (#"b" :: c))))),l) =>
25735           p_smla(String.implode c,(true,(false,l)))
25736         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"t" :: (#"t" :: c))))),l) =>
25737           p_smla(String.implode c,(true,(true,l)))
25738         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"w" :: (#"b" :: c))))),l) =>
25739           p_smlaw(String.implode c,(false,l))
25740         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"w" :: (#"t" :: c))))),l) =>
25741           p_smlaw(String.implode c,(true,l))
25742         | (#"s" :: (#"m" :: (#"u" :: (#"l" :: (#"w" :: (#"b" :: c))))),l) =>
25743           p_smulw(String.implode c,(false,l))
25744         | (#"s" :: (#"m" :: (#"u" :: (#"l" :: (#"w" :: (#"t" :: c))))),l) =>
25745           p_smulw(String.implode c,(true,l))
25746         | (#"s" :: (#"m" :: (#"u" :: (#"a" :: (#"d" :: (#"x" :: c))))),l) =>
25747           p_smuad_smusd(String.implode c,(false,(true,l)))
25748         | (#"s" :: (#"m" :: (#"u" :: (#"s" :: (#"d" :: (#"x" :: c))))),l) =>
25749           p_smuad_smusd(String.implode c,(true,(true,l)))
25750         | (#"s" :: (#"m" :: (#"u" :: (#"a" :: (#"d" :: c)))),l) =>
25751           p_smuad_smusd(String.implode c,(false,(false,l)))
25752         | (#"s" :: (#"m" :: (#"u" :: (#"s" :: (#"d" :: c)))),l) =>
25753           p_smuad_smusd(String.implode c,(true,(false,l)))
25754         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"d" :: (#"x" :: c))))),l) =>
25755           p_smlad_smlsd(String.implode c,(false,(true,l)))
25756         | (#"s" :: (#"m" :: (#"l" :: (#"s" :: (#"d" :: (#"x" :: c))))),l) =>
25757           p_smlad_smlsd(String.implode c,(true,(true,l)))
25758         | (#"s" :: (#"m" :: (#"l" :: (#"a" :: (#"d" :: c)))),l) =>
25759           p_smlad_smlsd(String.implode c,(false,(false,l)))
25760         | (#"s" :: (#"m" :: (#"l" :: (#"s" :: (#"d" :: c)))),l) =>
25761           p_smlad_smlsd(String.implode c,(true,(false,l)))
25762         | (#"s" :: (#"m" :: (#"m" :: (#"u" :: (#"l" :: (#"r" :: c))))),l) =>
25763           p_smmul(String.implode c,(true,l))
25764         | (#"s" :: (#"m" :: (#"m" :: (#"u" :: (#"l" :: c)))),l) =>
25765           p_smmul(String.implode c,(false,l))
25766         | (#"s" :: (#"m" :: (#"m" :: (#"l" :: (#"a" :: (#"r" :: c))))),l) =>
25767           p_smmla(String.implode c,(true,l))
25768         | (#"s" :: (#"m" :: (#"m" :: (#"l" :: (#"a" :: c)))),l) =>
25769           p_smmla(String.implode c,(false,l))
25770         | (#"s" :: (#"m" :: (#"m" :: (#"l" :: (#"s" :: (#"r" :: c))))),l) =>
25771           p_smmls(String.implode c,(true,l))
25772         | (#"s" :: (#"m" :: (#"m" :: (#"l" :: (#"s" :: c)))),l) =>
25773           p_smmls(String.implode c,(false,l))
25774         | (#"s" :: (#"a" :: (#"d" :: (#"d" :: (#"1" :: (#"6" :: c))))),l) =>
25775           p_sadd16_etc(String.implode c,(BitsN.B(0x0,2),l))
25776         | (#"s" :: (#"a" :: (#"s" :: (#"x" :: c))),l) =>
25777           p_sadd16_etc(String.implode c,(BitsN.B(0x1,2),l))
25778         | (#"s" :: (#"s" :: (#"a" :: (#"x" :: c))),l) =>
25779           p_sadd16_etc(String.implode c,(BitsN.B(0x2,2),l))
25780         | (#"s" :: (#"s" :: (#"u" :: (#"b" :: (#"1" :: (#"6" :: c))))),l) =>
25781           p_sadd16_etc(String.implode c,(BitsN.B(0x3,2),l))
25782         | (#"q" :: (#"a" :: (#"d" :: (#"d" :: (#"1" :: (#"6" :: c))))),l) =>
25783           p_qadd16_etc(String.implode c,(BitsN.B(0x0,2),l))
25784         | (#"q" :: (#"a" :: (#"s" :: (#"x" :: c))),l) =>
25785           p_qadd16_etc(String.implode c,(BitsN.B(0x1,2),l))
25786         | (#"q" :: (#"s" :: (#"a" :: (#"x" :: c))),l) =>
25787           p_qadd16_etc(String.implode c,(BitsN.B(0x2,2),l))
25788         | (#"q" :: (#"s" :: (#"u" :: (#"b" :: (#"1" :: (#"6" :: c))))),l) =>
25789           p_qadd16_etc(String.implode c,(BitsN.B(0x3,2),l))
25790         | (#"s" ::
25791          (#"h" :: (#"a" :: (#"d" :: (#"d" :: (#"1" :: (#"6" :: c)))))),l) =>
25792           p_shadd16_etc(String.implode c,(BitsN.B(0x0,2),l))
25793         | (#"s" :: (#"h" :: (#"a" :: (#"s" :: (#"x" :: c)))),l) =>
25794           p_shadd16_etc(String.implode c,(BitsN.B(0x1,2),l))
25795         | (#"s" :: (#"h" :: (#"s" :: (#"a" :: (#"x" :: c)))),l) =>
25796           p_shadd16_etc(String.implode c,(BitsN.B(0x2,2),l))
25797         | (#"s" ::
25798          (#"h" :: (#"s" :: (#"u" :: (#"b" :: (#"1" :: (#"6" :: c)))))),l) =>
25799           p_shadd16_etc(String.implode c,(BitsN.B(0x3,2),l))
25800         | (#"s" :: (#"a" :: (#"d" :: (#"d" :: (#"8" :: c)))),l) =>
25801           p_sadd8_etc(String.implode c,(false,l))
25802         | (#"s" :: (#"s" :: (#"u" :: (#"b" :: (#"8" :: c)))),l) =>
25803           p_sadd8_etc(String.implode c,(true,l))
25804         | (#"q" :: (#"a" :: (#"d" :: (#"d" :: (#"8" :: c)))),l) =>
25805           p_qadd8_etc(String.implode c,(false,l))
25806         | (#"q" :: (#"s" :: (#"u" :: (#"b" :: (#"8" :: c)))),l) =>
25807           p_qadd8_etc(String.implode c,(true,l))
25808         | (#"s" :: (#"h" :: (#"a" :: (#"d" :: (#"d" :: (#"8" :: c))))),l) =>
25809           p_shadd8_etc(String.implode c,(false,l))
25810         | (#"s" :: (#"h" :: (#"s" :: (#"u" :: (#"b" :: (#"8" :: c))))),l) =>
25811           p_shadd8_etc(String.implode c,(true,l))
25812         | (#"u" :: (#"a" :: (#"d" :: (#"d" :: (#"1" :: (#"6" :: c))))),l) =>
25813           p_uadd16_etc(String.implode c,(BitsN.B(0x0,2),l))
25814         | (#"u" :: (#"a" :: (#"s" :: (#"x" :: c))),l) =>
25815           p_uadd16_etc(String.implode c,(BitsN.B(0x1,2),l))
25816         | (#"u" :: (#"s" :: (#"a" :: (#"x" :: c))),l) =>
25817           p_uadd16_etc(String.implode c,(BitsN.B(0x2,2),l))
25818         | (#"u" :: (#"s" :: (#"u" :: (#"b" :: (#"1" :: (#"6" :: c))))),l) =>
25819           p_uadd16_etc(String.implode c,(BitsN.B(0x3,2),l))
25820         | (#"u" ::
25821          (#"q" :: (#"a" :: (#"d" :: (#"d" :: (#"1" :: (#"6" :: c)))))),l) =>
25822           p_uqadd16_etc(String.implode c,(BitsN.B(0x0,2),l))
25823         | (#"u" :: (#"q" :: (#"a" :: (#"s" :: (#"x" :: c)))),l) =>
25824           p_uqadd16_etc(String.implode c,(BitsN.B(0x1,2),l))
25825         | (#"u" :: (#"q" :: (#"s" :: (#"a" :: (#"x" :: c)))),l) =>
25826           p_uqadd16_etc(String.implode c,(BitsN.B(0x2,2),l))
25827         | (#"u" ::
25828          (#"q" :: (#"s" :: (#"u" :: (#"b" :: (#"1" :: (#"6" :: c)))))),l) =>
25829           p_uqadd16_etc(String.implode c,(BitsN.B(0x3,2),l))
25830         | (#"u" ::
25831          (#"h" :: (#"a" :: (#"d" :: (#"d" :: (#"1" :: (#"6" :: c)))))),l) =>
25832           p_uhadd16_etc(String.implode c,(BitsN.B(0x0,2),l))
25833         | (#"u" :: (#"h" :: (#"a" :: (#"s" :: (#"x" :: c)))),l) =>
25834           p_uhadd16_etc(String.implode c,(BitsN.B(0x1,2),l))
25835         | (#"u" :: (#"h" :: (#"s" :: (#"a" :: (#"x" :: c)))),l) =>
25836           p_uhadd16_etc(String.implode c,(BitsN.B(0x2,2),l))
25837         | (#"u" ::
25838          (#"h" :: (#"s" :: (#"u" :: (#"b" :: (#"1" :: (#"6" :: c)))))),l) =>
25839           p_uhadd16_etc(String.implode c,(BitsN.B(0x3,2),l))
25840         | (#"u" :: (#"a" :: (#"d" :: (#"d" :: (#"8" :: c)))),l) =>
25841           p_uadd8_etc(String.implode c,(false,l))
25842         | (#"u" :: (#"s" :: (#"u" :: (#"b" :: (#"8" :: c)))),l) =>
25843           p_uadd8_etc(String.implode c,(true,l))
25844         | (#"u" :: (#"q" :: (#"a" :: (#"d" :: (#"d" :: (#"8" :: c))))),l) =>
25845           p_uqadd8_etc(String.implode c,(false,l))
25846         | (#"u" :: (#"q" :: (#"s" :: (#"u" :: (#"b" :: (#"8" :: c))))),l) =>
25847           p_uqadd8_etc(String.implode c,(true,l))
25848         | (#"u" :: (#"h" :: (#"a" :: (#"d" :: (#"d" :: (#"8" :: c))))),l) =>
25849           p_uhadd8_etc(String.implode c,(false,l))
25850         | (#"u" :: (#"h" :: (#"s" :: (#"u" :: (#"b" :: (#"8" :: c))))),l) =>
25851           p_uhadd8_etc(String.implode c,(true,l))
25852         | (#"u" :: (#"s" :: (#"a" :: (#"d" :: (#"8" :: c)))),l) =>
25853           p_usad8(String.implode c,l)
25854         | (#"u" :: (#"s" :: (#"a" :: (#"d" :: (#"a" :: (#"8" :: c))))),l) =>
25855           p_usada8(String.implode c,l)
25856         | (#"q" :: (#"a" :: (#"d" :: (#"d" :: c))),l) =>
25857           p_qadd_etc(String.implode c,(BitsN.B(0x0,2),l))
25858         | (#"q" :: (#"s" :: (#"u" :: (#"b" :: c))),l) =>
25859           p_qadd_etc(String.implode c,(BitsN.B(0x1,2),l))
25860         | (#"q" :: (#"d" :: (#"a" :: (#"d" :: (#"d" :: c)))),l) =>
25861           p_qadd_etc(String.implode c,(BitsN.B(0x2,2),l))
25862         | (#"q" :: (#"d" :: (#"s" :: (#"u" :: (#"b" :: c)))),l) =>
25863           p_qadd_etc(String.implode c,(BitsN.B(0x3,2),l))
25864         | (#"p" :: (#"k" :: (#"h" :: (#"t" :: (#"b" :: c)))),l) =>
25865           p_pkhbt_pkhtb(String.implode c,(true,l))
25866         | (#"p" :: (#"k" :: (#"h" :: (#"b" :: (#"t" :: c)))),l) =>
25867           p_pkhbt_pkhtb(String.implode c,(false,l))
25868         | (#"s" :: (#"s" :: (#"a" :: (#"t" :: (#"1" :: (#"6" :: c))))),l) =>
25869           p_sat16(String.implode c,(false,l))
25870         | (#"u" :: (#"s" :: (#"a" :: (#"t" :: (#"1" :: (#"6" :: c))))),l) =>
25871           p_sat16(String.implode c,(true,l))
25872         | (#"s" :: (#"s" :: (#"a" :: (#"t" :: c))),l) =>
25873           p_sat(String.implode c,(false,l))
25874         | (#"u" :: (#"s" :: (#"a" :: (#"t" :: c))),l) =>
25875           p_sat(String.implode c,(true,l))
25876         | (#"s" :: (#"x" :: (#"t" :: (#"b" :: (#"1" :: (#"6" :: c))))),l) =>
25877           p_sxtb_etc(String.implode c,(0,(false,l)))
25878         | (#"u" :: (#"x" :: (#"t" :: (#"b" :: (#"1" :: (#"6" :: c))))),l) =>
25879           p_sxtb_etc(String.implode c,(0,(true,l)))
25880         | (#"s" :: (#"x" :: (#"t" :: (#"b" :: c))),l) =>
25881           p_sxtb_etc(String.implode c,(1,(false,l)))
25882         | (#"u" :: (#"x" :: (#"t" :: (#"b" :: c))),l) =>
25883           p_sxtb_etc(String.implode c,(1,(true,l)))
25884         | (#"s" :: (#"x" :: (#"t" :: (#"h" :: c))),l) =>
25885           p_sxtb_etc(String.implode c,(2,(false,l)))
25886         | (#"u" :: (#"x" :: (#"t" :: (#"h" :: c))),l) =>
25887           p_sxtb_etc(String.implode c,(2,(true,l)))
25888         | (#"s" ::
25889          (#"x" :: (#"t" :: (#"a" :: (#"b" :: (#"1" :: (#"6" :: c)))))),l) =>
25890           p_sxtab_etc(String.implode c,(0,(false,l)))
25891         | (#"u" ::
25892          (#"x" :: (#"t" :: (#"a" :: (#"b" :: (#"1" :: (#"6" :: c)))))),l) =>
25893           p_sxtab_etc(String.implode c,(0,(true,l)))
25894         | (#"s" :: (#"x" :: (#"t" :: (#"a" :: (#"b" :: c)))),l) =>
25895           p_sxtab_etc(String.implode c,(1,(false,l)))
25896         | (#"u" :: (#"x" :: (#"t" :: (#"a" :: (#"b" :: c)))),l) =>
25897           p_sxtab_etc(String.implode c,(1,(true,l)))
25898         | (#"s" :: (#"x" :: (#"t" :: (#"a" :: (#"h" :: c)))),l) =>
25899           p_sxtab_etc(String.implode c,(2,(false,l)))
25900         | (#"u" :: (#"x" :: (#"t" :: (#"a" :: (#"h" :: c)))),l) =>
25901           p_sxtab_etc(String.implode c,(2,(true,l)))
25902         | (#"s" :: (#"e" :: (#"l" :: c)),l) => p_sel(String.implode c,l)
25903         | (#"r" :: (#"e" :: (#"v" :: (#"1" :: (#"6" :: c)))),l) =>
25904           p_rev16(String.implode c,l)
25905         | (#"r" :: (#"e" :: (#"v" :: (#"s" :: (#"h" :: c)))),l) =>
25906           p_revsh(String.implode c,l)
25907         | (#"r" :: (#"e" :: (#"v" :: c)),l) => p_rev(String.implode c,l)
25908         | (#"r" :: (#"b" :: (#"i" :: (#"t" :: c))),l) =>
25909           p_rbit(String.implode c,l)
25910         | (#"s" :: (#"b" :: (#"f" :: (#"x" :: c))),l) =>
25911           p_sbfx_ubfx(String.implode c,(false,l))
25912         | (#"u" :: (#"b" :: (#"f" :: (#"x" :: c))),l) =>
25913           p_sbfx_ubfx(String.implode c,(true,l))
25914         | (#"b" :: (#"f" :: (#"c" :: c)),l) => p_bfc(String.implode c,l)
25915         | (#"b" :: (#"f" :: (#"i" :: c)),l) => p_bfi(String.implode c,l)
25916         | (#"p" :: (#"l" :: (#"d" :: (#"w" :: c))),l) =>
25917           p_pld(String.implode c,(true,l))
25918         | (#"p" :: (#"l" :: (#"d" :: c)),l) =>
25919           p_pld(String.implode c,(false,l))
25920         | (#"p" :: (#"l" :: (#"i" :: c)),l) => p_pli(String.implode c,l)
25921         | (#"l" :: (#"d" :: (#"r" :: (#"t" :: c))),l) =>
25922           p_ldrt_strt1(String.implode c,(0,l))
25923         | (#"l" :: (#"d" :: (#"r" :: (#"b" :: (#"t" :: c)))),l) =>
25924           p_ldrt_strt1(String.implode c,(1,l))
25925         | (#"s" :: (#"t" :: (#"r" :: (#"t" :: c))),l) =>
25926           p_ldrt_strt1(String.implode c,(2,l))
25927         | (#"s" :: (#"t" :: (#"r" :: (#"b" :: (#"t" :: c)))),l) =>
25928           p_ldrt_strt1(String.implode c,(3,l))
25929         | (#"l" :: (#"d" :: (#"r" :: (#"s" :: (#"b" :: (#"t" :: c))))),l) =>
25930           p_ldrt_strt2(String.implode c,(0,l))
25931         | (#"l" :: (#"d" :: (#"r" :: (#"s" :: (#"h" :: (#"t" :: c))))),l) =>
25932           p_ldrt_strt2(String.implode c,(1,l))
25933         | (#"l" :: (#"d" :: (#"r" :: (#"h" :: (#"t" :: c)))),l) =>
25934           p_ldrt_strt2(String.implode c,(2,l))
25935         | (#"s" :: (#"t" :: (#"r" :: (#"h" :: (#"t" :: c)))),l) =>
25936           p_ldrt_strt2(String.implode c,(3,l))
25937         | (#"l" :: (#"d" :: (#"r" :: (#"b" :: c))),l) =>
25938           p_ldrb_ldrh(String.implode c,(true,(true,l)))
25939         | (#"l" :: (#"d" :: (#"r" :: (#"s" :: (#"b" :: c)))),l) =>
25940           p_ldrb_ldrh(String.implode c,(false,(true,l)))
25941         | (#"l" :: (#"d" :: (#"r" :: (#"h" :: c))),l) =>
25942           p_ldrb_ldrh(String.implode c,(true,(false,l)))
25943         | (#"l" :: (#"d" :: (#"r" :: (#"s" :: (#"h" :: c)))),l) =>
25944           p_ldrb_ldrh(String.implode c,(false,(false,l)))
25945         | (#"l" :: (#"d" :: (#"r" :: (#"d" :: c))),l) =>
25946           p_ldrd_strd(String.implode c,(true,l))
25947         | (#"s" :: (#"t" :: (#"r" :: (#"d" :: c))),l) =>
25948           p_ldrd_strd(String.implode c,(false,l))
25949         | (#"l" :: (#"d" :: (#"r" :: (#"e" :: (#"x" :: (#"b" :: c))))),l) =>
25950           p_ldrexb_ldrexh(String.implode c,(true,l))
25951         | (#"l" :: (#"d" :: (#"r" :: (#"e" :: (#"x" :: (#"h" :: c))))),l) =>
25952           p_ldrexb_ldrexh(String.implode c,(false,l))
25953         | (#"l" :: (#"d" :: (#"r" :: (#"e" :: (#"x" :: (#"d" :: c))))),l) =>
25954           p_ldrexd(String.implode c,l)
25955         | (#"l" :: (#"d" :: (#"r" :: (#"e" :: (#"x" :: c)))),l) =>
25956           p_ldrex(String.implode c,l)
25957         | (#"s" :: (#"t" :: (#"r" :: (#"e" :: (#"x" :: (#"b" :: c))))),l) =>
25958           p_strexb_strexh(String.implode c,(true,l))
25959         | (#"s" :: (#"t" :: (#"r" :: (#"e" :: (#"x" :: (#"h" :: c))))),l) =>
25960           p_strexb_strexh(String.implode c,(false,l))
25961         | (#"s" :: (#"t" :: (#"r" :: (#"e" :: (#"x" :: (#"d" :: c))))),l) =>
25962           p_strexd(String.implode c,l)
25963         | (#"s" :: (#"t" :: (#"r" :: (#"e" :: (#"x" :: c)))),l) =>
25964           p_strex(String.implode c,l)
25965         | (#"l" :: (#"d" :: (#"r" :: c)),l) =>
25966           p_ldr_str(String.implode c,(0,l))
25967         | (#"s" :: (#"t" :: (#"r" :: (#"b" :: c))),l) =>
25968           p_ldr_str(String.implode c,(1,l))
25969         | (#"s" :: (#"t" :: (#"r" :: (#"h" :: c))),l) =>
25970           p_ldr_str(String.implode c,(2,l))
25971         | (#"s" :: (#"t" :: (#"r" :: c)),l) =>
25972           p_ldr_str(String.implode c,(3,l))
25973         | (#"p" :: (#"o" :: (#"p" :: c)),l) =>
25974           p_pop_push(String.implode c,(true,l))
25975         | (#"p" :: (#"u" :: (#"s" :: (#"h" :: c))),l) =>
25976           p_pop_push(String.implode c,(false,l))
25977         | (#"l" :: (#"d" :: (#"m" :: (#"d" :: (#"a" :: c)))),l) =>
25978           p_ldm_stm(String.implode c,(true,(false,(false,l))))
25979         | (#"l" :: (#"d" :: (#"m" :: (#"f" :: (#"a" :: c)))),l) =>
25980           p_ldm_stm(String.implode c,(true,(false,(false,l))))
25981         | (#"l" :: (#"d" :: (#"m" :: (#"d" :: (#"b" :: c)))),l) =>
25982           p_ldm_stm(String.implode c,(true,(false,(true,l))))
25983         | (#"l" :: (#"d" :: (#"m" :: (#"e" :: (#"a" :: c)))),l) =>
25984           p_ldm_stm(String.implode c,(true,(false,(true,l))))
25985         | (#"l" :: (#"d" :: (#"m" :: (#"i" :: (#"b" :: c)))),l) =>
25986           p_ldm_stm(String.implode c,(true,(true,(true,l))))
25987         | (#"l" :: (#"d" :: (#"m" :: (#"e" :: (#"d" :: c)))),l) =>
25988           p_ldm_stm(String.implode c,(true,(true,(true,l))))
25989         | (#"l" :: (#"d" :: (#"m" :: (#"i" :: (#"a" :: c)))),l) =>
25990           p_ldm_stm(String.implode c,(true,(true,(false,l))))
25991         | (#"l" :: (#"d" :: (#"m" :: (#"f" :: (#"d" :: c)))),l) =>
25992           p_ldm_stm(String.implode c,(true,(true,(false,l))))
25993         | (#"l" :: (#"d" :: (#"m" :: c)),l) =>
25994           p_ldm_stm(String.implode c,(true,(true,(false,l))))
25995         | (#"s" :: (#"t" :: (#"m" :: (#"d" :: (#"a" :: c)))),l) =>
25996           p_ldm_stm(String.implode c,(false,(false,(false,l))))
25997         | (#"s" :: (#"t" :: (#"m" :: (#"e" :: (#"d" :: c)))),l) =>
25998           p_ldm_stm(String.implode c,(false,(false,(false,l))))
25999         | (#"s" :: (#"t" :: (#"m" :: (#"d" :: (#"b" :: c)))),l) =>
26000           p_ldm_stm(String.implode c,(false,(false,(true,l))))
26001         | (#"s" :: (#"t" :: (#"m" :: (#"f" :: (#"d" :: c)))),l) =>
26002           p_ldm_stm(String.implode c,(false,(false,(true,l))))
26003         | (#"s" :: (#"t" :: (#"m" :: (#"i" :: (#"b" :: c)))),l) =>
26004           p_ldm_stm(String.implode c,(false,(true,(true,l))))
26005         | (#"s" :: (#"t" :: (#"m" :: (#"f" :: (#"a" :: c)))),l) =>
26006           p_ldm_stm(String.implode c,(false,(true,(true,l))))
26007         | (#"s" :: (#"t" :: (#"m" :: (#"i" :: (#"a" :: c)))),l) =>
26008           p_ldm_stm(String.implode c,(false,(true,(false,l))))
26009         | (#"s" :: (#"t" :: (#"m" :: (#"e" :: (#"a" :: c)))),l) =>
26010           p_ldm_stm(String.implode c,(false,(true,(false,l))))
26011         | (#"s" :: (#"t" :: (#"m" :: c)),l) =>
26012           p_ldm_stm(String.implode c,(false,(true,(false,l))))
26013         | (#"s" :: (#"w" :: (#"p" :: (#"b" :: c))),l) =>
26014           p_swp(String.implode c,(true,l))
26015         | (#"s" :: (#"w" :: (#"p" :: c)),l) =>
26016           p_swp(String.implode c,(false,l))
26017         | ([#"s",#"e",#"t",#"e",#"n",#"d"],l) => p_setend l
26018         | ([#"c",#"p",#"s",#"i",#"e"],l) => p_cps(true,(false,l))
26019         | ([#"c",#"p",#"s",#"i",#"d"],l) => p_cps(false,(true,l))
26020         | ([#"c",#"p",#"s"],l) => p_cps(false,(false,l))
26021         | (#"r" :: (#"f" :: (#"e" :: (#"d" :: (#"a" :: c)))),l) =>
26022           p_rfe(String.implode c,(false,(true,l)))
26023         | (#"r" :: (#"f" :: (#"e" :: (#"d" :: (#"b" :: c)))),l) =>
26024           p_rfe(String.implode c,(false,(false,l)))
26025         | (#"r" :: (#"f" :: (#"e" :: (#"i" :: (#"a" :: c)))),l) =>
26026           p_rfe(String.implode c,(true,(false,l)))
26027         | (#"r" :: (#"f" :: (#"e" :: (#"i" :: (#"b" :: c)))),l) =>
26028           p_rfe(String.implode c,(true,(true,l)))
26029         | (#"r" :: (#"f" :: (#"e" :: c)),l) =>
26030           p_rfe(String.implode c,(true,(false,l)))
26031         | (#"s" :: (#"r" :: (#"s" :: (#"d" :: (#"a" :: c)))),l) =>
26032           p_srs(String.implode c,(false,(true,l)))
26033         | (#"s" :: (#"r" :: (#"s" :: (#"d" :: (#"b" :: c)))),l) =>
26034           p_srs(String.implode c,(false,(false,l)))
26035         | (#"s" :: (#"r" :: (#"s" :: (#"i" :: (#"a" :: c)))),l) =>
26036           p_srs(String.implode c,(true,(false,l)))
26037         | (#"s" :: (#"r" :: (#"s" :: (#"i" :: (#"b" :: c)))),l) =>
26038           p_srs(String.implode c,(true,(true,l)))
26039         | (#"s" :: (#"r" :: (#"s" :: c)),l) =>
26040           p_srs(String.implode c,(true,(false,l)))
26041         | (#"m" :: (#"r" :: (#"s" :: c)),l) => p_mrs(String.implode c,l)
26042         | (#"m" :: (#"s" :: (#"r" :: c)),l) => p_msr(String.implode c,l)
26043         | (#"u" :: (#"d" :: (#"f" :: c)),l) =>
26044           p_call(String.implode c,(0,l))
26045         | (#"d" :: (#"b" :: (#"g" :: c)),l) =>
26046           p_call(String.implode c,(1,l))
26047         | (#"s" :: (#"m" :: (#"c" :: c)),l) =>
26048           p_call(String.implode c,(2,l))
26049         | (#"s" :: (#"v" :: (#"c" :: c)),l) =>
26050           p_call(String.implode c,(3,l))
26051         | ([#"h",#"v",#"c"],l) => p_call("",(4,l))
26052         | ([#"b",#"k",#"p",#"t"],l) => p_call("",(5,l))
26053         | (#"d" :: (#"m" :: (#"b" :: c)),l) =>
26054           p_dmb_dsb(String.implode c,(false,l))
26055         | (#"d" :: (#"s" :: (#"b" :: c)),l) =>
26056           p_dmb_dsb(String.implode c,(true,l))
26057         | (#"i" :: (#"s" :: (#"b" :: c)),l) => p_isb(String.implode c,l)
26058         | (#"n" :: (#"o" :: (#"p" :: c)),[]) =>
26059           p_noarg(String.implode c,NoOperation)
26060         | (#"c" :: (#"l" :: (#"r" :: (#"e" :: (#"x" :: c)))),[]) =>
26061           p_noarg(String.implode c,ClearExclusive)
26062         | (#"s" :: (#"e" :: (#"v" :: c)),[]) =>
26063           p_noarg(String.implode c,Hint SendEvent)
26064         | (#"w" :: (#"f" :: (#"e" :: c)),[]) =>
26065           p_noarg(String.implode c,Hint WaitForEvent)
26066         | (#"w" :: (#"f" :: (#"i" :: c)),[]) =>
26067           p_noarg(String.implode c,Hint WaitForInterrupt)
26068         | (#"y" :: (#"i" :: (#"e" :: (#"l" :: (#"d" :: c)))),[]) =>
26069           p_noarg(String.implode c,Hint Yield)
26070         | (#"e" :: (#"r" :: (#"e" :: (#"t" :: c))),[]) =>
26071           p_noarg(String.implode c,System ExceptionReturn)
26072         | (#"e" :: (#"n" :: (#"t" :: (#"e" :: (#"r" :: (#"x" :: c))))),[]) =>
26073           p_noarg(String.implode c,System(EnterxLeavex true))
26074         | (#"l" :: (#"e" :: (#"a" :: (#"v" :: (#"e" :: (#"x" :: c))))),[]) =>
26075           p_noarg(String.implode c,System(EnterxLeavex false))
26076         | (#"v" :: (#"m" :: (#"o" :: (#"v" :: c))),l) =>
26077           p_fp2(String.implode c,(0,l))
26078         | (#"v" :: (#"a" :: (#"b" :: (#"s" :: c))),l) =>
26079           p_fp2(String.implode c,(1,l))
26080         | (#"v" :: (#"n" :: (#"e" :: (#"g" :: c))),l) =>
26081           p_fp2(String.implode c,(2,l))
26082         | (#"v" :: (#"s" :: (#"q" :: (#"r" :: (#"t" :: c)))),l) =>
26083           p_fp2(String.implode c,(3,l))
26084         | (#"v" :: (#"a" :: (#"d" :: (#"d" :: c))),l) =>
26085           p_fp3(String.implode c,(0,l))
26086         | (#"v" :: (#"s" :: (#"u" :: (#"b" :: c))),l) =>
26087           p_fp3(String.implode c,(1,l))
26088         | (#"v" :: (#"m" :: (#"u" :: (#"l" :: c))),l) =>
26089           p_fp3(String.implode c,(2,l))
26090         | (#"v" :: (#"d" :: (#"i" :: (#"v" :: c))),l) =>
26091           p_fp3(String.implode c,(3,l))
26092         | (#"v" :: (#"m" :: (#"l" :: (#"a" :: c))),l) =>
26093           p_fp3(String.implode c,(4,l))
26094         | (#"v" :: (#"m" :: (#"l" :: (#"s" :: c))),l) =>
26095           p_fp3(String.implode c,(5,l))
26096         | (#"v" :: (#"f" :: (#"m" :: (#"a" :: c))),l) =>
26097           p_fp3(String.implode c,(6,l))
26098         | (#"v" :: (#"f" :: (#"m" :: (#"s" :: c))),l) =>
26099           p_fp3(String.implode c,(7,l))
26100         | (#"v" :: (#"f" :: (#"n" :: (#"m" :: (#"a" :: c)))),l) =>
26101           p_fp3(String.implode c,(8,l))
26102         | (#"v" :: (#"f" :: (#"n" :: (#"m" :: (#"s" :: c)))),l) =>
26103           p_fp3(String.implode c,(9,l))
26104         | (#"v" :: (#"n" :: (#"m" :: (#"l" :: (#"a" :: c)))),l) =>
26105           p_fp3(String.implode c,(10,l))
26106         | (#"v" :: (#"n" :: (#"m" :: (#"l" :: (#"s" :: c)))),l) =>
26107           p_fp3(String.implode c,(11,l))
26108         | (#"v" :: (#"n" :: (#"m" :: (#"u" :: (#"l" :: c)))),l) =>
26109           p_fp3(String.implode c,(12,l))
26110         | (#"v" :: (#"c" :: (#"m" :: (#"p" :: (#"e" :: c)))),l) =>
26111           p_vcmpe(String.implode c,l)
26112         | (#"v" :: (#"c" :: (#"v" :: (#"t" :: (#"r" :: c)))),l) =>
26113           p_vcvt(String.implode c,(true,l))
26114         | (#"v" :: (#"c" :: (#"v" :: (#"t" :: c))),l) =>
26115           p_vcvt(String.implode c,(false,l))
26116         | (#"v" :: (#"m" :: (#"r" :: (#"s" :: c))),l) =>
26117           p_vmrs(String.implode c,l)
26118         | (#"v" :: (#"m" :: (#"s" :: (#"r" :: c))),l) =>
26119           p_vmsr(String.implode c,l)
26120         | (#"v" :: (#"l" :: (#"d" :: (#"r" :: c))),l) =>
26121           p_vldr_vstr(String.implode c,(true,l))
26122         | (#"v" :: (#"s" :: (#"t" :: (#"r" :: c))),l) =>
26123           p_vldr_vstr(String.implode c,(false,l))
26124         | (#"v" :: (#"p" :: (#"o" :: (#"p" :: c))),l) =>
26125           p_vpop_vpush(String.implode c,(true,l))
26126         | (#"v" :: (#"p" :: (#"u" :: (#"s" :: (#"h" :: c)))),l) =>
26127           p_vpop_vpush(String.implode c,(false,l))
26128         | (#"v" :: (#"l" :: (#"d" :: (#"m" :: (#"d" :: (#"b" :: c))))),l) =>
26129           p_vldm_vstm(String.implode c,(true,(false,l)))
26130         | (#"v" :: (#"l" :: (#"d" :: (#"m" :: (#"i" :: (#"a" :: c))))),l) =>
26131           p_vldm_vstm(String.implode c,(true,(true,l)))
26132         | (#"v" :: (#"l" :: (#"d" :: (#"m" :: c))),l) =>
26133           p_vldm_vstm(String.implode c,(true,(true,l)))
26134         | (#"v" :: (#"s" :: (#"t" :: (#"m" :: (#"d" :: (#"b" :: c))))),l) =>
26135           p_vldm_vstm(String.implode c,(false,(false,l)))
26136         | (#"v" :: (#"s" :: (#"t" :: (#"m" :: (#"i" :: (#"a" :: c))))),l) =>
26137           p_vldm_vstm(String.implode c,(false,(true,l)))
26138         | (#"v" :: (#"s" :: (#"t" :: (#"m" :: c))),l) =>
26139           p_vldm_vstm(String.implode c,(false,(true,l)))
26140         | (#"b" :: (#"x" :: c),l) => p_bx(String.implode c,l)
26141         | (#"b" :: (#"l" :: (#"x" :: c)),l) => p_blx(String.implode c,l)
26142         | ([#"b",#"l",c1,c2,#".",e],l) =>
26143           p_bl(String.implode[c1,c2,#".",e],l)
26144         | ([#"b",#"l",c1,c2],l) => p_bl(String.implode[c1,c2],l)
26145         | ([#"b",#"l"],l) => p_bl("",l)
26146         | (#"b" :: c,l) => p_b(String.implode c,l)
26147         | ([#"w",#"o",#"r",#"d"],[w]) =>
26148           (case p_encode_immediate 32 w of
26149               Option.SOME(true,w) => WORD w
26150             | Option.SOME _ => FAIL "immediate too large"
26151             | NONE => FAIL "syntax error")
26152         | _ => FAIL "Unrecognised op-code")
26153   | _ => FAIL "Unrecognised op-code";
26154
26155fun s_cond c =
26156  case c of
26157     BitsN.B(0x0,_) => "eq"
26158   | BitsN.B(0x1,_) => "ne"
26159   | BitsN.B(0x2,_) => "cs"
26160   | BitsN.B(0x3,_) => "cc"
26161   | BitsN.B(0x4,_) => "mi"
26162   | BitsN.B(0x5,_) => "pl"
26163   | BitsN.B(0x6,_) => "vs"
26164   | BitsN.B(0x7,_) => "vc"
26165   | BitsN.B(0x8,_) => "hi"
26166   | BitsN.B(0x9,_) => "ls"
26167   | BitsN.B(0xA,_) => "ge"
26168   | BitsN.B(0xB,_) => "lt"
26169   | BitsN.B(0xC,_) => "gt"
26170   | BitsN.B(0xD,_) => "le"
26171   | _ => "";
26172
26173fun s_reg r =
26174  case r of
26175     BitsN.B(0xD,_) => "sp"
26176   | BitsN.B(0xE,_) => "lr"
26177   | BitsN.B(0xF,_) => "pc"
26178   | _ => "r" ^ (Nat.toString(BitsN.toNat r));
26179
26180fun s_reg2 (r1,r2) = String.concat[s_reg r1,", ",s_reg r2];
26181
26182fun s_reg3 (r1,(r2,r3)) = String.concat[s_reg2(r1,r2),", ",s_reg r3];
26183
26184fun s_reg4 (r1,(r2,(r3,r4))) =
26185  String.concat[s_reg3(r1,(r2,r3)),", ",s_reg r4];
26186
26187fun s_vfp_reg (dp,n) =
26188  (if dp then "d" else "s") ^ (Nat.toString(BitsN.toNat n));
26189
26190fun s_any_reg (dpo,n) =
26191  case dpo of
26192     NONE => s_reg(BitsN.fromNat(n,4))
26193   | Option.SOME dp => s_vfp_reg(dp,BitsN.fromNat(n,5));
26194
26195fun contiguous (a,(i,l)) =
26196  case l of
26197     [] => a
26198   | y :: x =>
26199     contiguous
26200       (if y
26201          then case a of
26202                  [] => [(i,i)]
26203                | (b,t) :: r =>
26204                  (if (Nat.+(i,1)) = b then (i,t) :: r else (i,i) :: a)
26205        else a,(Nat.-(i,1),x));
26206
26207fun s_registers_from_contiguous (dpo,(a,l)) =
26208  case l of
26209     [] => a
26210   | (b,t) :: r =>
26211     let
26212       val d = Nat.-(t,b)
26213     in
26214       s_registers_from_contiguous
26215         (dpo,
26216          (if d = 0
26217             then String.concat[a,", ",s_any_reg(dpo,b)]
26218           else if d = 1
26219             then String.concat
26220                    [a,", ",s_any_reg(dpo,b),", ",s_any_reg(dpo,t)]
26221           else String.concat
26222                  [a,", ",s_any_reg(dpo,b),"-",s_any_reg(dpo,t)],r))
26223     end;
26224
26225fun s_registers N (dpo,l) =
26226  case String.explode
26227    (s_registers_from_contiguous
26228       (dpo,
26229        ("",
26230         contiguous
26231           ([],(Nat.-(BitsN.size(BitsN.BV(0x0,N)),1),BitsN.toBitstring l))))) of
26232     [] => "{}"
26233   | #"," :: (#" " :: s) => String.concat["{",String.implode s,"}"]
26234   | _ => "???";
26235
26236fun s_arm_registers N l = s_registers N (NONE,l);
26237
26238fun s_fp_registers N (dp,l) = s_registers N (Option.SOME dp,l);
26239
26240fun s_hex N v =
26241  if BitsN.<+(v,BitsN.BV(0x64,N))
26242    then Nat.toString(BitsN.toNat v)
26243  else "0x" ^ (BitsN.toHexString v);
26244
26245fun s_offset imm32 =
26246  let
26247    val imm32 = BitsN.+(imm32,BitsN.B(0x8,32))
26248  in
26249    if BitsN.<(imm32,BitsN.B(0x0,32))
26250      then "-#" ^ (s_hex 32 (BitsN.neg imm32))
26251    else "+#" ^ (s_hex 32 imm32)
26252  end;
26253
26254fun s_add_sub_offset (add,imm32) =
26255  if add andalso (imm32 = (BitsN.B(0x0,32)))
26256    then ""
26257  else String.concat[", #",if add then "" else "-",s_hex 32 imm32];
26258
26259fun s_branch (c,ast) =
26260  case ast of
26261     BranchTarget imm32 => ("b" ^ (s_cond c),s_offset imm32)
26262   | BranchExchange m => ("bx" ^ (s_cond c),s_reg m)
26263   | BranchLinkExchangeImmediate(targetInstrSet,imm32) =>
26264     (String.concat
26265        ["bl",if (CurrentInstrSet ()) = targetInstrSet then "" else "x",
26266         s_cond c],s_offset imm32)
26267   | BranchLinkExchangeRegister m => ("blx" ^ (s_cond c),s_reg m)
26268   | CompareBranch(nonzero,(n,imm32)) =>
26269     (String.concat["cb",if nonzero then "n" else "",s_cond c],
26270      String.concat[s_reg n,", ",s_offset imm32])
26271   | TableBranchByte(true,(m,n)) =>
26272     ("tbh" ^ (s_cond c),String.concat["[",s_reg2(n,m),", lsl #1]"])
26273   | TableBranchByte(false,(m,n)) =>
26274     ("tbb" ^ (s_cond c),String.concat["[",s_reg2(n,m),"]"])
26275   | CheckArray(m,n) => ("chka" ^ (s_cond c),s_reg2(n,m))
26276   | HandlerBranchLink(generate_link,handler_offset) =>
26277     (String.concat["hb",if generate_link then "l" else "",s_cond c],
26278      "#" ^ (BitsN.toHexString handler_offset))
26279   | HandlerBranchLinkParameter(imm32,handler_offset) =>
26280     ("hblp" ^ (s_cond c),
26281      String.concat
26282        ["#",s_hex 32 imm32,", #",BitsN.toHexString handler_offset])
26283   | HandlerBranchParameter(imm32,handler_offset) =>
26284     ("hbp" ^ (s_cond c),
26285      String.concat
26286        ["#",s_hex 32 imm32,", #",BitsN.toHexString handler_offset]);
26287
26288fun s_vfp_suffix (c,dp) = (s_cond c) ^ (if dp then ".f64" else ".f32");
26289
26290fun s_vfp (c,ast) =
26291  case ast of
26292     vmrs t =>
26293       ("vmrs" ^ (s_cond c),
26294        (if t = (BitsN.B(0xF,4)) then "APSR_nzcv" else s_reg t)
26295          ^
26296          ", FPSCR")
26297   | vmsr t => ("vmsr" ^ (s_cond c),"FPSCR, " ^ (s_reg t))
26298   | vcmp(dp,(d,Option.SOME m)) =>
26299     ("vcmpe" ^ (s_vfp_suffix(c,dp)),
26300      String.concat[s_vfp_reg(dp,d),", ",s_vfp_reg(dp,m)])
26301   | vcmp(dp,(d,NONE)) =>
26302     ("vcmpe" ^ (s_vfp_suffix(c,dp)),(s_vfp_reg(dp,d)) ^ ", #0.0")
26303   | vcvt_float(double_to_single,(d,m)) =>
26304     (String.concat
26305        ["vcvt",s_cond c,
26306         if double_to_single then ".f32.f64" else ".f64.f32"],
26307      String.concat
26308        [s_vfp_reg(not double_to_single,d),", ",
26309         s_vfp_reg(double_to_single,m)])
26310   | vcvt_from_integer(dp,(unsigned,(d,m))) =>
26311     (String.concat
26312        ["vcvt",s_vfp_suffix(c,dp),if unsigned then ".u" else ".s","32"],
26313      String.concat[s_vfp_reg(dp,d),", ",s_vfp_reg(false,m)])
26314   | vcvt_to_integer(dp,(unsigned,(round_zero,(d,m)))) =>
26315     (String.concat
26316        ["vcvt",if round_zero then "" else "r",s_cond c,
26317         if unsigned then ".u" else ".s","32",
26318         if dp then ".f64" else ".f32"],
26319      String.concat[s_vfp_reg(false,d),", ",s_vfp_reg(dp,m)])
26320   | vmov_imm(sp,(d,imm64)) =>
26321     ("vmov" ^ (s_vfp_suffix(c,not sp)),
26322      String.concat[s_vfp_reg(not sp,d),", #0x",BitsN.toHexString imm64])
26323   | vmov(sp,(d,m)) =>
26324     ("vmov" ^ (s_vfp_suffix(c,not sp)),
26325      String.concat[s_vfp_reg(not sp,d),", ",s_vfp_reg(not sp,m)])
26326   | vmov_single(to_arm_register,(t,n)) =>
26327     ("vmov" ^ (s_cond c),
26328      if to_arm_register
26329        then String.concat[s_reg t,", ",s_vfp_reg(false,n)]
26330      else String.concat[s_vfp_reg(false,n),", ",s_reg t])
26331   | vmov_two_singles(to_arm_registers,(t,(t2,m))) =>
26332     ("vmov" ^ (s_cond c),
26333      if to_arm_registers
26334        then String.concat
26335               [s_reg2(t,t2),", ",s_vfp_reg(false,m),", ",
26336                s_vfp_reg(false,BitsN.+(m,BitsN.B(0x1,5)))]
26337      else String.concat
26338             [s_vfp_reg(false,m),", ",
26339              s_vfp_reg(false,BitsN.+(m,BitsN.B(0x1,5))),", ",s_reg2(t,t2)])
26340   | vmov_double(to_arm_registers,(t,(t2,m))) =>
26341     ("vmov" ^ (s_cond c),
26342      if to_arm_registers
26343        then String.concat[s_reg2(t,t2),", ",s_vfp_reg(true,m)]
26344      else String.concat[s_vfp_reg(true,m),", ",s_reg2(t,t2)])
26345   | vabs(dp,(d,m)) =>
26346     ("vabs" ^ (s_vfp_suffix(c,dp)),
26347      String.concat[s_vfp_reg(dp,d),", ",s_vfp_reg(dp,m)])
26348   | vneg(dp,(d,m)) =>
26349     ("vneg" ^ (s_vfp_suffix(c,dp)),
26350      String.concat[s_vfp_reg(dp,d),", ",s_vfp_reg(dp,m)])
26351   | vsqrt(dp,(d,m)) =>
26352     ("vsqrt" ^ (s_vfp_suffix(c,dp)),
26353      String.concat[s_vfp_reg(dp,d),", ",s_vfp_reg(dp,m)])
26354   | vadd(dp,(d,(n,m))) =>
26355     ("vadd" ^ (s_vfp_suffix(c,dp)),
26356      String.concat
26357        [s_vfp_reg(dp,d),", ",s_vfp_reg(dp,n),", ",s_vfp_reg(dp,m)])
26358   | vsub(dp,(d,(n,m))) =>
26359     ("vsub" ^ (s_vfp_suffix(c,dp)),
26360      String.concat
26361        [s_vfp_reg(dp,d),", ",s_vfp_reg(dp,n),", ",s_vfp_reg(dp,m)])
26362   | vmul(dp,(d,(n,m))) =>
26363     ("vmul" ^ (s_vfp_suffix(c,dp)),
26364      String.concat
26365        [s_vfp_reg(dp,d),", ",s_vfp_reg(dp,n),", ",s_vfp_reg(dp,m)])
26366   | vdiv(dp,(d,(n,m))) =>
26367     ("vdiv" ^ (s_vfp_suffix(c,dp)),
26368      String.concat
26369        [s_vfp_reg(dp,d),", ",s_vfp_reg(dp,n),", ",s_vfp_reg(dp,m)])
26370   | vneg_mul(dp,(typ,(d,(n,m)))) =>
26371     ((case typ of
26372          VFPNegMul_VNMLA => "vnmla"
26373        | VFPNegMul_VNMLS => "vnmls"
26374        | VFPNegMul_VNMUL => "vnmul")
26375        ^
26376        (s_vfp_suffix(c,dp)),
26377      String.concat
26378        [s_vfp_reg(dp,d),", ",s_vfp_reg(dp,n),", ",s_vfp_reg(dp,m)])
26379   | vmla_vmls(dp,(add,(d,(n,m)))) =>
26380     ((if add then "vmla" else "vmls") ^ (s_vfp_suffix(c,dp)),
26381      String.concat
26382        [s_vfp_reg(dp,d),", ",s_vfp_reg(dp,n),", ",s_vfp_reg(dp,m)])
26383   | vfma_vfms(dp,(add,(d,(n,m)))) =>
26384     ((if add then "vfma" else "vfms") ^ (s_vfp_suffix(c,dp)),
26385      String.concat
26386        [s_vfp_reg(dp,d),", ",s_vfp_reg(dp,n),", ",s_vfp_reg(dp,m)])
26387   | vfnma_vfnms(dp,(add,(d,(n,m)))) =>
26388     ((if add then "vfnma" else "vfnms") ^ (s_vfp_suffix(c,dp)),
26389      String.concat
26390        [s_vfp_reg(dp,d),", ",s_vfp_reg(dp,n),", ",s_vfp_reg(dp,m)])
26391   | vldr(sp,(add,(d,(n,imm32)))) =>
26392     ("vldr" ^ (s_cond c),
26393      String.concat
26394        [s_vfp_reg(not sp,d),", [",s_reg n,
26395         if add andalso (imm32 = (BitsN.B(0x0,32)))
26396           then ""
26397         else (if add then ", #+" else ", #-") ^ (s_hex 32 imm32),"]"])
26398   | vstr(sp,(add,(d,(n,imm32)))) =>
26399     ("vstr" ^ (s_cond c),
26400      String.concat
26401        [s_vfp_reg(not sp,d),", [",s_reg n,
26402         if add andalso (imm32 = (BitsN.B(0x0,32)))
26403           then ""
26404         else (if add then ", #+" else ", #-") ^ (s_hex 32 imm32),"]"])
26405   | vldm(sp,(true,(true,(d,(BitsN.B(0xD,4),imm8))))) =>
26406     let
26407       val regs =
26408         BitsN.fromNat
26409           (BitsN.toNat(if sp then imm8 else BitsN.>>(imm8,1)),32)
26410     in
26411       ("vpop" ^ (s_cond c),
26412        s_fp_registers 32
26413          (not sp,
26414           BitsN.<<
26415             (BitsN.-(BitsN.<<^(BitsN.B(0x1,32),regs),BitsN.B(0x1,32)),
26416              BitsN.toNat d)))
26417     end
26418   | vldm(sp,(add,(wback,(d,(n,imm8))))) =>
26419     let
26420       val regs =
26421         BitsN.fromNat
26422           (BitsN.toNat(if sp then imm8 else BitsN.>>(imm8,1)),32)
26423     in
26424       (String.concat["vldm",if add then "ia" else "db",s_cond c],
26425        String.concat
26426          [s_reg n,if wback then "!" else "",", ",
26427           s_fp_registers 32
26428             (not sp,
26429              BitsN.<<
26430                (BitsN.-(BitsN.<<^(BitsN.B(0x1,32),regs),BitsN.B(0x1,32)),
26431                 BitsN.toNat d))])
26432     end
26433   | vstm(sp,(false,(true,(d,(BitsN.B(0xD,4),imm8))))) =>
26434     let
26435       val regs =
26436         BitsN.fromNat
26437           (BitsN.toNat(if sp then imm8 else BitsN.>>(imm8,1)),32)
26438     in
26439       ("vpush" ^ (s_cond c),
26440        s_fp_registers 32
26441          (not sp,
26442           BitsN.<<
26443             (BitsN.-(BitsN.<<^(BitsN.B(0x1,32),regs),BitsN.B(0x1,32)),
26444              BitsN.toNat d)))
26445     end
26446   | vstm(sp,(add,(wback,(d,(n,imm8))))) =>
26447     let
26448       val regs =
26449         BitsN.fromNat
26450           (BitsN.toNat(if sp then imm8 else BitsN.>>(imm8,1)),32)
26451     in
26452       (String.concat["vstm",if add then "ia" else "db",s_cond c],
26453        String.concat
26454          [s_reg n,if wback then "!" else "",", ",
26455           s_fp_registers 32
26456             (not sp,
26457              BitsN.<<
26458                (BitsN.-(BitsN.<<^(BitsN.B(0x1,32),regs),BitsN.B(0x1,32)),
26459                 BitsN.toNat d))])
26460     end;
26461
26462fun s_test_compare opc =
26463  case opc of
26464     BitsN.B(0x0,_) => "tst"
26465   | BitsN.B(0x1,_) => "teq"
26466   | BitsN.B(0x2,_) => "cmp"
26467   | BitsN.B(0x3,_) => "cmn"
26468   | _ => raise General.Bind;
26469
26470fun s_arith_logic opc =
26471  case opc of
26472     BitsN.B(0x0,_) => "and"
26473   | BitsN.B(0x1,_) => "eor"
26474   | BitsN.B(0x2,_) => "sub"
26475   | BitsN.B(0x3,_) => "rsb"
26476   | BitsN.B(0x4,_) => "add"
26477   | BitsN.B(0x5,_) => "adc"
26478   | BitsN.B(0x6,_) => "sbc"
26479   | BitsN.B(0x7,_) => "rsc"
26480   | BitsN.B(0x8,_) => "tst"
26481   | BitsN.B(0x9,_) => "teq"
26482   | BitsN.B(0xA,_) => "cmp"
26483   | BitsN.B(0xB,_) => "cmn"
26484   | BitsN.B(0xC,_) => "orr"
26485   | BitsN.B(0xD,_) => "mov"
26486   | BitsN.B(0xE,_) => "bic"
26487   | BitsN.B(0xF,_) => "mvn"
26488   | _ => raise General.Bind;
26489
26490fun s_shift shift_t =
26491  case shift_t of
26492     SRType_LSL => "lsl"
26493   | SRType_LSR => "lsr"
26494   | SRType_ASR => "asr"
26495   | SRType_ROR => "ror"
26496   | SRType_RRX => "rrx";
26497
26498fun s_shift_n (shift_t,shift_n) =
26499  case (shift_t,shift_n) of
26500     (SRType_LSL,0) => ""
26501   | (SRType_RRX,1) => ", rrx"
26502   | _ => String.concat[", ",s_shift shift_t," #",Nat.toString shift_n];
26503
26504fun s_shift_r (add,(r,(shift_t,shift_n))) =
26505  String.concat
26506    [", ",if add then "" else "-",s_reg r,s_shift_n(shift_t,shift_n)];
26507
26508fun s_expand_imm imm12 = s_hex 32 (L3.fst(ExpandImm_C(imm12,false)));
26509
26510fun s_data (c,ast) =
26511  case ast of
26512     CountLeadingZeroes(d,m) => ("clz" ^ (s_cond c),s_reg2(d,m))
26513   | MoveHalfword(high,(d,imm16)) =>
26514     (String.concat["mov",if high then "t" else "w",s_cond c],
26515      String.concat[s_reg d,", #",s_hex 16 imm16])
26516   | Move(setflags,(negate,(d,imm12))) =>
26517     (String.concat
26518        [if negate then "mvn" else "mov",if setflags then "s" else "",
26519         s_cond c],String.concat[s_reg d,", #",s_expand_imm imm12])
26520   | AddSub(sub,(d,(n,imm12))) =>
26521     ((if sub then "subw" else "addw") ^ (s_cond c),
26522      String.concat[s_reg2(d,n),", #",s_hex 12 imm12])
26523   | TestCompareImmediate(opc,(n,imm12)) =>
26524     ((s_test_compare opc) ^ (s_cond c),
26525      String.concat[s_reg n,", #",s_expand_imm imm12])
26526   | ArithLogicImmediate(opc,(setflags,(d,(n,imm12)))) =>
26527     (String.concat
26528        [s_arith_logic opc,if setflags then "s" else "",s_cond c],
26529      String.concat[s_reg2(d,n),", #",s_expand_imm imm12])
26530   | Register(opc,(setflags,(d,(n,(m,(shift_t,shift_n)))))) =>
26531     (String.concat
26532        [s_arith_logic opc,if setflags then "s" else "",s_cond c],
26533      (s_reg3(d,(n,m))) ^ (s_shift_n(shift_t,shift_n)))
26534   | TestCompareRegister(opc,(n,(m,(shift_t,shift_n)))) =>
26535     ((s_test_compare opc) ^ (s_cond c),
26536      (s_reg2(n,m)) ^ (s_shift_n(shift_t,shift_n)))
26537   | ShiftImmediate(true,(setflags,(d,(m,(shift_t,shift_n))))) =>
26538     (String.concat["mvn",if setflags then "s" else "",s_cond c],
26539      (s_reg2(d,m)) ^ (s_shift_n(shift_t,shift_n)))
26540   | ShiftImmediate(false,(setflags,(d,(m,(SRType_LSL,0))))) =>
26541     (String.concat["mov",if setflags then "s" else "",s_cond c],
26542      s_reg2(d,m))
26543   | ShiftImmediate(false,(setflags,(d,(m,(shift_t,shift_n))))) =>
26544     (String.concat[s_shift shift_t,if setflags then "s" else "",s_cond c],
26545      (s_reg2(d,m))
26546        ^
26547        (if (shift_t = SRType_RRX) andalso (shift_n = 1)
26548           then ""
26549         else ", #" ^ (Nat.toString shift_n)))
26550   | RegisterShiftedRegister(opc,(setflags,(d,(n,(m,(shift_t,s)))))) =>
26551     let
26552       val tstcmp = (BitsN.bits(3,2) opc) = (BitsN.B(0x2,2))
26553     in
26554       (String.concat
26555          [s_arith_logic opc,
26556           if setflags andalso (not tstcmp) then "s" else "",s_cond c],
26557        String.concat
26558          [if tstcmp then "" else (s_reg d) ^ ", ",s_reg2(n,m),", ",
26559           s_shift shift_t," ",s_reg s])
26560     end
26561   | ShiftRegister(true,(setflags,(d,(n,(shift_t,m))))) =>
26562     (String.concat["mvn",if setflags then "s" else "",s_cond c],
26563      String.concat[s_reg2(d,n),", ",s_shift shift_t," ",s_reg m])
26564   | ShiftRegister(false,(setflags,(d,(n,(shift_t,m))))) =>
26565     (String.concat[s_shift shift_t,if setflags then "s" else "",s_cond c],
26566      s_reg3(d,(n,m)));
26567
26568fun s_multiply (c,ast) =
26569  case ast of
26570     MultiplyAccumulate(setflags,(d,(n,(m,a)))) =>
26571       (String.concat["mla",if setflags then "s" else "",s_cond c],
26572        s_reg4(d,(n,(m,a))))
26573   | Multiply32(setflags,(d,(n,m))) =>
26574     (String.concat["mul",if setflags then "s" else "",s_cond c],
26575      s_reg3(d,(n,m)))
26576   | MultiplyLong(accumulate,(signed,(setflags,(dhi,(dlo,(n,m)))))) =>
26577     (String.concat
26578        [if signed then "s" else "u",
26579         if accumulate then "mlal" else "mull",
26580         if setflags then "s" else "",s_cond c],s_reg4(dlo,(dhi,(n,m))))
26581   | MultiplyAccumulateAccumulate(dhi,(dlo,(n,m))) =>
26582     ("umaal" ^ (s_cond c),s_reg4(dlo,(dhi,(n,m))))
26583   | MultiplySubtract(d,(n,(m,a))) =>
26584     ("mls" ^ (s_cond c),s_reg4(d,(n,(m,a))))
26585   | Signed16Multiply32Accumulate(m_high,(n_high,(d,(n,(m,a))))) =>
26586     (String.concat
26587        ["smla",if m_high then "t" else "b",if n_high then "t" else "b",
26588         s_cond c],s_reg4(d,(n,(m,a))))
26589   | Signed16Multiply32Result(m_high,(n_high,(d,(n,m)))) =>
26590     (String.concat
26591        ["smul",if m_high then "t" else "b",if n_high then "t" else "b",
26592         s_cond c],s_reg3(d,(n,m)))
26593   | Signed16x32Multiply32Accumulate(m_high,(d,(n,(m,a)))) =>
26594     (String.concat["smlaw",if m_high then "t" else "b",s_cond c],
26595      s_reg4(d,(n,(m,a))))
26596   | Signed16x32Multiply32Result(m_high,(d,(n,m))) =>
26597     (String.concat["smulw",if m_high then "t" else "b",s_cond c],
26598      s_reg3(d,(n,m)))
26599   | Signed16Multiply64Accumulate(m_high,(n_high,(dhi,(dlo,(n,m))))) =>
26600     (String.concat
26601        ["smlal",if m_high then "t" else "b",if n_high then "t" else "b",
26602         s_cond c],s_reg4(dlo,(dhi,(n,m))))
26603   | SignedMultiplyDual(sub,(m_swap,(d,(n,(m,a))))) =>
26604     (String.concat
26605        [case (sub,a = (BitsN.B(0xF,4))) of
26606            (false,false) => "smlad"
26607          | (false,true) => "smuad"
26608          | (true,false) => "smlsd"
26609          | (true,true) => "smusd",if m_swap then "x" else "",s_cond c],
26610      (s_reg3(d,(n,m)))
26611        ^
26612        (if a = (BitsN.B(0xF,4)) then "" else ", " ^ (s_reg a)))
26613   | SignedMultiplyLongDual(sub,(m_swap,(dhi,(dlo,(n,m))))) =>
26614     (String.concat
26615        [if sub then "smlsld" else "smlald",if m_swap then "x" else "",
26616         s_cond c],s_reg4(dlo,(dhi,(n,m))))
26617   | SignedMostSignificantMultiply(round,(d,(n,(m,a)))) =>
26618     (String.concat
26619        [if a = (BitsN.B(0xF,4)) then "smmul" else "smmla",
26620         if round then "r" else "",s_cond c],
26621      (s_reg3(d,(n,m)))
26622        ^
26623        (if a = (BitsN.B(0xF,4)) then "" else ", " ^ (s_reg a)))
26624   | SignedMostSignificantMultiplySubtract(round,(d,(n,(m,a)))) =>
26625     (String.concat["smmls",if round then "r" else "",s_cond c],
26626      s_reg4(d,(n,(m,a))));
26627
26628fun s_imm_form (add,(index,(wback,(t,(n,imm32))))) =
26629  String.concat
26630    [s_reg t,", [",s_reg n,
26631     if index
26632       then String.concat
26633              [s_add_sub_offset(add,imm32),"]",if wback then "!" else ""]
26634     else String.concat["], #",if add then "" else "-",s_hex 32 imm32]];
26635
26636fun s_reg_form (add,(index,(wback,(t,(n,(m,(shift_t,shift_n))))))) =
26637  String.concat
26638    [s_reg t,", [",s_reg n,
26639     if index
26640       then String.concat
26641              [s_shift_r(add,(m,(shift_t,shift_n))),"]",
26642               if wback then "!" else ""]
26643     else "]" ^ (s_shift_r(add,(m,(shift_t,shift_n))))];
26644
26645fun s_stack (increment,wordhigher) =
26646  case (increment,wordhigher) of
26647     (false,false) => "db"
26648   | (false,true) => "da"
26649   | (true,false) => ""
26650   | (true,true) => "ib";
26651
26652fun s_load (c,ast) =
26653  case ast of
26654     LoadWord(add,(index,(wback,(t,(n,immediate_form1 imm32))))) =>
26655       ("ldr" ^ (s_cond c),s_imm_form(add,(index,(wback,(t,(n,imm32))))))
26656   | LoadWord
26657     (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n))))))) =>
26658     ("ldr" ^ (s_cond c),
26659      s_reg_form(add,(index,(wback,(t,(n,(m,(shift_t,shift_n))))))))
26660   | LoadLiteral(add,(t,imm32)) =>
26661     ("ldr" ^ (s_cond c),
26662      String.concat[s_reg t,", [pc",s_add_sub_offset(add,imm32),"]"])
26663   | LoadUnprivileged(add,(postindex,(t,(n,immediate_form1 imm32)))) =>
26664     ("ldrt" ^ (s_cond c),
26665      s_imm_form(add,(not postindex,(false,(t,(n,imm32))))))
26666   | LoadUnprivileged
26667     (add,(postindex,(t,(n,register_form1(m,(shift_t,shift_n)))))) =>
26668     ("ldrt" ^ (s_cond c),
26669      s_reg_form
26670        (add,(not postindex,(false,(t,(n,(m,(shift_t,shift_n))))))))
26671   | LoadByte
26672     (unsigned,(add,(index,(wback,(t,(n,immediate_form1 imm32)))))) =>
26673     (String.concat["ldr",if unsigned then "b" else "sb",s_cond c],
26674      s_imm_form(add,(index,(wback,(t,(n,imm32))))))
26675   | LoadByte
26676     (unsigned,
26677      (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n)))))))) =>
26678     (String.concat["ldr",if unsigned then "b" else "sb",s_cond c],
26679      s_reg_form(add,(index,(wback,(t,(n,(m,(shift_t,shift_n))))))))
26680   | LoadByteLiteral(unsigned,(add,(t,imm32))) =>
26681     (String.concat["ldr",if unsigned then "b" else "sb",s_cond c],
26682      String.concat[s_reg t,", [pc",s_add_sub_offset(add,imm32),"]"])
26683   | LoadByteUnprivileged(add,(postindex,(t,(n,immediate_form1 imm32)))) =>
26684     ("ldrbt" ^ (s_cond c),
26685      s_imm_form(add,(not postindex,(false,(t,(n,imm32))))))
26686   | LoadByteUnprivileged
26687     (add,(postindex,(t,(n,register_form1(m,(shift_t,shift_n)))))) =>
26688     ("ldrbt" ^ (s_cond c),
26689      s_reg_form
26690        (add,(not postindex,(false,(t,(n,(m,(shift_t,shift_n))))))))
26691   | LoadSignedByteUnprivileged
26692     (add,(postindex,(t,(n,immediate_form2 imm32)))) =>
26693     ("ldrsbt" ^ (s_cond c),
26694      s_imm_form(add,(not postindex,(false,(t,(n,imm32))))))
26695   | LoadSignedByteUnprivileged(add,(postindex,(t,(n,register_form2 m)))) =>
26696     ("ldrsbt" ^ (s_cond c),
26697      s_reg_form(add,(not postindex,(false,(t,(n,(m,(SRType_LSL,0))))))))
26698   | LoadHalf
26699     (unsigned,(add,(index,(wback,(t,(n,immediate_form1 imm32)))))) =>
26700     (String.concat["ldr",if unsigned then "h" else "sh",s_cond c],
26701      s_imm_form(add,(index,(wback,(t,(n,imm32))))))
26702   | LoadHalf
26703     (unsigned,
26704      (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n)))))))) =>
26705     (String.concat["ldr",if unsigned then "h" else "sh",s_cond c],
26706      s_reg_form(add,(index,(wback,(t,(n,(m,(shift_t,shift_n))))))))
26707   | LoadHalfLiteral(unsigned,(add,(t,imm32))) =>
26708     (String.concat["ldr",if unsigned then "h" else "sh",s_cond c],
26709      String.concat[s_reg t,", [pc",s_add_sub_offset(add,imm32),"]"])
26710   | LoadHalfUnprivileged
26711     (unsigned,(add,(postindex,(t,(n,immediate_form2 imm32))))) =>
26712     (String.concat["ldr",if unsigned then "ht" else "sht",s_cond c],
26713      s_imm_form(add,(not postindex,(false,(t,(n,imm32))))))
26714   | LoadHalfUnprivileged
26715     (unsigned,(add,(postindex,(t,(n,register_form2 m))))) =>
26716     (String.concat["ldr",if unsigned then "ht" else "sht",s_cond c],
26717      s_reg_form(add,(not postindex,(false,(t,(n,(m,(SRType_LSL,0))))))))
26718   | LoadMultiple(true,(false,(true,(BitsN.B(0xD,4),registers)))) =>
26719     ("pop" ^ (s_cond c),s_arm_registers 16 registers)
26720   | LoadMultiple(increment,(index,(wback,(n,registers)))) =>
26721     (String.concat["ldm",s_stack(increment,increment = index),s_cond c],
26722      String.concat
26723        [s_reg n,if wback then "!" else "",", ",
26724         s_arm_registers 16 registers])
26725   | LoadMultipleExceptionReturn
26726     (increment,(wordhigher,(wback,(n,registers)))) =>
26727     (String.concat["ldm",s_stack(increment,wordhigher),s_cond c],
26728      String.concat
26729        [s_reg n,if wback then "!" else "",", ",
26730         s_arm_registers 16 (BitsN.@@(BitsN.B(0x1,1),registers)),"^"])
26731   | LoadMultipleUserRegisters(increment,(wordhigher,(n,registers))) =>
26732     (String.concat["ldm",s_stack(increment,wordhigher),s_cond c],
26733      String.concat[s_reg n,", ",s_arm_registers 15 registers,"^"])
26734   | LoadDual(add,(index,(wback,(t,(t2,(n,immediate_form2 imm32)))))) =>
26735     ("ldrd" ^ (s_cond c),
26736      String.concat
26737        [s_reg t,", ",s_imm_form(add,(index,(wback,(t2,(n,imm32)))))])
26738   | LoadDual(add,(index,(wback,(t,(t2,(n,register_form2 m)))))) =>
26739     ("ldrd" ^ (s_cond c),
26740      String.concat
26741        [s_reg t,", ",
26742         s_reg_form(add,(index,(wback,(t2,(n,(m,(SRType_LSL,0)))))))])
26743   | LoadDualLiteral(add,(t,(t2,imm32))) =>
26744     ("ldrd" ^ (s_cond c),
26745      String.concat[s_reg2(t,t2),", [pc",s_add_sub_offset(add,imm32),"]"])
26746   | LoadExclusive(t,(n,imm32)) =>
26747     ("ldrex" ^ (s_cond c),
26748      String.concat
26749        [s_reg t,", [",s_reg n,s_add_sub_offset(true,imm32),"]"])
26750   | LoadExclusiveByte(t,n) =>
26751     ("ldrexb" ^ (s_cond c),String.concat[s_reg t,", [",s_reg n,"]"])
26752   | LoadExclusiveHalf(t,n) =>
26753     ("ldrexh" ^ (s_cond c),String.concat[s_reg t,", [",s_reg n,"]"])
26754   | LoadExclusiveDoubleword(t,(t2,n)) =>
26755     ("ldrexd" ^ (s_cond c),String.concat[s_reg2(t,t2),", [",s_reg n,"]"]);
26756
26757fun s_store (c,ast) =
26758  case ast of
26759     StoreWord(add,(index,(wback,(t,(n,immediate_form1 imm32))))) =>
26760       ("str" ^ (s_cond c),s_imm_form(add,(index,(wback,(t,(n,imm32))))))
26761   | StoreWord
26762     (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n))))))) =>
26763     ("str" ^ (s_cond c),
26764      s_reg_form(add,(index,(wback,(t,(n,(m,(shift_t,shift_n))))))))
26765   | StoreUnprivileged(add,(postindex,(t,(n,immediate_form1 imm32)))) =>
26766     ("strt" ^ (s_cond c),
26767      s_imm_form(add,(not postindex,(false,(t,(n,imm32))))))
26768   | StoreUnprivileged
26769     (add,(postindex,(t,(n,register_form1(m,(shift_t,shift_n)))))) =>
26770     ("strt" ^ (s_cond c),
26771      s_reg_form
26772        (add,(not postindex,(false,(t,(n,(m,(shift_t,shift_n))))))))
26773   | StoreByte(add,(index,(wback,(t,(n,immediate_form1 imm32))))) =>
26774     ("strb" ^ (s_cond c),s_imm_form(add,(index,(wback,(t,(n,imm32))))))
26775   | StoreByte
26776     (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n))))))) =>
26777     ("strb" ^ (s_cond c),
26778      s_reg_form(add,(index,(wback,(t,(n,(m,(shift_t,shift_n))))))))
26779   | StoreByteUnprivileged(add,(postindex,(t,(n,immediate_form1 imm32)))) =>
26780     ("strbt" ^ (s_cond c),
26781      s_imm_form(add,(not postindex,(false,(t,(n,imm32))))))
26782   | StoreByteUnprivileged
26783     (add,(postindex,(t,(n,register_form1(m,(shift_t,shift_n)))))) =>
26784     ("strbt" ^ (s_cond c),
26785      s_reg_form
26786        (add,(not postindex,(false,(t,(n,(m,(shift_t,shift_n))))))))
26787   | StoreHalf(add,(index,(wback,(t,(n,immediate_form1 imm32))))) =>
26788     ("strh" ^ (s_cond c),s_imm_form(add,(index,(wback,(t,(n,imm32))))))
26789   | StoreHalf
26790     (add,(index,(wback,(t,(n,register_form1(m,(shift_t,shift_n))))))) =>
26791     ("strh" ^ (s_cond c),
26792      s_reg_form(add,(index,(wback,(t,(n,(m,(shift_t,shift_n))))))))
26793   | StoreHalfUnprivileged(add,(postindex,(t,(n,immediate_form2 imm32)))) =>
26794     ("strht" ^ (s_cond c),
26795      s_imm_form(add,(not postindex,(false,(t,(n,imm32))))))
26796   | StoreHalfUnprivileged(add,(postindex,(t,(n,register_form2 m)))) =>
26797     ("strht" ^ (s_cond c),
26798      s_reg_form(add,(not postindex,(false,(t,(n,(m,(SRType_LSL,0))))))))
26799   | StoreMultiple(false,(true,(true,(BitsN.B(0xD,4),registers)))) =>
26800     ("push" ^ (s_cond c),s_arm_registers 16 registers)
26801   | StoreMultiple(increment,(index,(wback,(n,registers)))) =>
26802     (String.concat["stm",s_stack(increment,increment = index),s_cond c],
26803      String.concat
26804        [s_reg n,if wback then "!" else "",", ",
26805         s_arm_registers 16 registers])
26806   | StoreMultipleUserRegisters(increment,(wordhigher,(n,registers))) =>
26807     (String.concat["stm",s_stack(increment,wordhigher),s_cond c],
26808      String.concat[s_reg n,", ",s_arm_registers 16 registers,"^"])
26809   | StoreDual(add,(index,(wback,(t,(t2,(n,immediate_form2 imm32)))))) =>
26810     ("strd" ^ (s_cond c),
26811      String.concat
26812        [s_reg t,", ",s_imm_form(add,(index,(wback,(t2,(n,imm32)))))])
26813   | StoreDual(add,(index,(wback,(t,(t2,(n,register_form2 m)))))) =>
26814     ("strd" ^ (s_cond c),
26815      String.concat
26816        [s_reg t,", ",
26817         s_reg_form(add,(index,(wback,(t2,(n,(m,(SRType_LSL,0)))))))])
26818   | StoreExclusive(d,(t,(n,imm32))) =>
26819     ("strex" ^ (s_cond c),
26820      String.concat
26821        [s_reg2(d,t),", [",s_reg n,s_add_sub_offset(true,imm32),"]"])
26822   | StoreExclusiveByte(d,(t,n)) =>
26823     ("strexb" ^ (s_cond c),String.concat[s_reg2(d,t),", [",s_reg n,"]"])
26824   | StoreExclusiveHalf(d,(t,n)) =>
26825     ("strexh" ^ (s_cond c),String.concat[s_reg2(d,t),", [",s_reg n,"]"])
26826   | StoreExclusiveDoubleword(d,(t,(t2,n))) =>
26827     ("strexd" ^ (s_cond c),
26828      String.concat[s_reg3(d,(t,t2)),", [",s_reg n,"]"]);
26829
26830fun s_barrier_option option =
26831  case option of
26832     BitsN.B(0x2,_) => "oshst"
26833   | BitsN.B(0x3,_) => "osh"
26834   | BitsN.B(0x6,_) => "nshst"
26835   | BitsN.B(0x7,_) => "nsh"
26836   | BitsN.B(0xA,_) => "ishst"
26837   | BitsN.B(0xB,_) => "ish"
26838   | BitsN.B(0xE,_) => "st"
26839   | BitsN.B(0xF,_) => "sy"
26840   | _ => Nat.toString(BitsN.toNat option);
26841
26842fun s_hint (c,ast) =
26843  case ast of
26844     Breakpoint imm32 => ("bkpt" ^ (s_cond c),"#" ^ (s_hex 32 imm32))
26845   | Debug option =>
26846     ("dbg" ^ (s_cond c),"#" ^ (Nat.toString(BitsN.toNat option)))
26847   | DataMemoryBarrier option =>
26848     ("dmb" ^ (s_cond c),s_barrier_option option)
26849   | DataSynchronizationBarrier option =>
26850     ("dsb" ^ (s_cond c),s_barrier_option option)
26851   | InstructionSynchronizationBarrier option =>
26852     ("isb" ^ (s_cond c),s_barrier_option option)
26853   | SendEvent => ("sev" ^ (s_cond c),"")
26854   | WaitForEvent => ("wfe" ^ (s_cond c),"")
26855   | WaitForInterrupt => ("wfi" ^ (s_cond c),"")
26856   | Yield => ("yield" ^ (s_cond c),"")
26857   | PreloadData(add,(is_pldw,(n,immediate_form1 imm32))) =>
26858     (String.concat["pld",if is_pldw then "w" else "",s_cond c],
26859      String.concat["[",s_reg n,s_add_sub_offset(add,imm32),"]"])
26860   | PreloadData(add,(is_pldw,(n,register_form1(m,(shift_t,shift_n))))) =>
26861     (String.concat["pld",if is_pldw then "w" else "",s_cond c],
26862      String.concat
26863        ["[",s_reg n,if add then ", " else ", -",s_reg m,
26864         s_shift_n(shift_t,shift_n),"]"])
26865   | PreloadDataLiteral(add,imm32) =>
26866     ("pld" ^ (s_cond c),
26867      String.concat["[pc",s_add_sub_offset(add,imm32),"]"])
26868   | PreloadInstruction(add,(n,immediate_form1 imm32)) =>
26869     ("pli" ^ (s_cond c),
26870      String.concat["[",s_reg n,s_add_sub_offset(add,imm32),"]"])
26871   | PreloadInstruction(add,(n,register_form1(m,(shift_t,shift_n)))) =>
26872     ("pli" ^ (s_cond c),
26873      String.concat
26874        ["[",s_reg n,if add then ", " else ", -",s_reg m,
26875         s_shift_n(shift_t,shift_n),"]"]);
26876
26877fun s_add_sub16 (s,(c,(opc,a))) =
26878  (String.concat
26879     [s,
26880      case opc of
26881         BitsN.B(0x0,_) => "add16"
26882       | BitsN.B(0x1,_) => "asx"
26883       | BitsN.B(0x2,_) => "sax"
26884       | BitsN.B(0x3,_) => "sub16"
26885       | _ => raise General.Bind,s_cond c],s_reg3 a);
26886
26887fun s_add_sub8 (s,(c,(sub,a))) =
26888  (String.concat[s,if sub then "sub8" else "add8",s_cond c],s_reg3 a);
26889
26890fun s_simd (c,ast) =
26891  case ast of
26892     SignedAddSub16(opc,(d,(n,m))) => s_add_sub16("s",(c,(opc,(d,(n,m)))))
26893   | UnsignedAddSub16(opc,(d,(n,m))) =>
26894     s_add_sub16("u",(c,(opc,(d,(n,m)))))
26895   | SignedSaturatingAddSub16(opc,(d,(n,m))) =>
26896     s_add_sub16("q",(c,(opc,(d,(n,m)))))
26897   | UnsignedSaturatingAddSub16(opc,(d,(n,m))) =>
26898     s_add_sub16("uq",(c,(opc,(d,(n,m)))))
26899   | SignedHalvingAddSub16(opc,(d,(n,m))) =>
26900     s_add_sub16("sh",(c,(opc,(d,(n,m)))))
26901   | UnsignedHalvingAddSub16(opc,(d,(n,m))) =>
26902     s_add_sub16("uh",(c,(opc,(d,(n,m)))))
26903   | SignedAddSub8(sub,(d,(n,m))) => s_add_sub8("s",(c,(sub,(d,(n,m)))))
26904   | UnsignedAddSub8(sub,(d,(n,m))) => s_add_sub8("u",(c,(sub,(d,(n,m)))))
26905   | SignedSaturatingAddSub8(sub,(d,(n,m))) =>
26906     s_add_sub8("q",(c,(sub,(d,(n,m)))))
26907   | UnsignedSaturatingAddSub8(sub,(d,(n,m))) =>
26908     s_add_sub8("uq",(c,(sub,(d,(n,m)))))
26909   | SignedHalvingAddSub8(sub,(d,(n,m))) =>
26910     s_add_sub8("sh",(c,(sub,(d,(n,m)))))
26911   | UnsignedHalvingAddSub8(sub,(d,(n,m))) =>
26912     s_add_sub8("uh",(c,(sub,(d,(n,m)))))
26913   | UnsignedSumAbsoluteDifferences(d,(n,(m,a))) =>
26914     (if a = (BitsN.B(0xF,4))
26915        then ("usad8" ^ (s_cond c),s_reg3(d,(n,m)))
26916      else ("usada8" ^ (s_cond c),s_reg4(d,(n,(m,a)))));
26917
26918fun s_xt_rotation (d,(n,(m,rotation))) =
26919  String.concat
26920    [s_reg d,", ",if n = (BitsN.B(0xF,4)) then "" else (s_reg n) ^ ", ",
26921     s_reg m,
26922     if rotation = 0 then "" else ", ror #" ^ (Nat.toString rotation)];
26923
26924fun s_media (c,ast) =
26925  case ast of
26926     SaturatingAddSubtract(opc,(d,(m,n))) =>
26927       ((case opc of
26928            BitsN.B(0x0,_) => "qadd"
26929          | BitsN.B(0x1,_) => "qsub"
26930          | BitsN.B(0x2,_) => "qdadd"
26931          | BitsN.B(0x3,_) => "qdsub"
26932          | _ => raise General.Bind)
26933          ^
26934          (s_cond c),s_reg3(d,(m,n)))
26935   | PackHalfword(shift_t,(shift_n,(tbform,(d,(n,m))))) =>
26936     ((if tbform then "pkhtb" else "pkhbt") ^ (s_cond c),
26937      (s_reg3(d,(n,m)))
26938        ^
26939        (if shift_n = 0 then "" else s_shift_n(shift_t,shift_n)))
26940   | Saturate(shift_t,(shift_n,(saturate_to,(unsigned,(d,n))))) =>
26941     (String.concat[if unsigned then "u" else "s","sat",s_cond c],
26942      String.concat
26943        [s_reg d,", #",Nat.toString saturate_to,", ",s_reg n,
26944         if shift_n = 0 then "" else s_shift_n(shift_t,shift_n)])
26945   | Saturate16(saturate_to,(unsigned,(d,n))) =>
26946     (String.concat[if unsigned then "u" else "s","sat16",s_cond c],
26947      String.concat[s_reg d,", #",Nat.toString saturate_to,", ",s_reg n])
26948   | ExtendByte(unsigned,(d,(n,(m,rotation)))) =>
26949     (String.concat
26950        [if unsigned then "u" else "s","xt",
26951         if n = (BitsN.B(0xF,4)) then "b" else "ab",s_cond c],
26952      s_xt_rotation(d,(n,(m,rotation))))
26953   | ExtendHalfword(unsigned,(d,(n,(m,rotation)))) =>
26954     (String.concat
26955        [if unsigned then "u" else "s","xt",
26956         if n = (BitsN.B(0xF,4)) then "h" else "ah",s_cond c],
26957      s_xt_rotation(d,(n,(m,rotation))))
26958   | ExtendByte16(unsigned,(d,(n,(m,rotation)))) =>
26959     (String.concat
26960        [if unsigned then "u" else "s","xt",
26961         if n = (BitsN.B(0xF,4)) then "b16" else "ab16",s_cond c],
26962      s_xt_rotation(d,(n,(m,rotation))))
26963   | SelectBytes(d,(n,m)) => ("sel" ^ (s_cond c),s_reg3(d,(n,m)))
26964   | ByteReverse(d,m) => ("rev" ^ (s_cond c),s_reg2(d,m))
26965   | ByteReversePackedHalfword(d,m) => ("rev16" ^ (s_cond c),s_reg2(d,m))
26966   | ByteReverseSignedHalfword(d,m) => ("revsh" ^ (s_cond c),s_reg2(d,m))
26967   | ReverseBits(d,m) => ("rbit" ^ (s_cond c),s_reg2(d,m))
26968   | BitFieldExtract(unsigned,(d,(n,(lsbit,widthminus1)))) =>
26969     (String.concat[if unsigned then "u" else "s","bfx",s_cond c],
26970      String.concat
26971        [s_reg2(d,n),", #",Nat.toString lsbit,", #",
26972         Nat.toString(Nat.+(widthminus1,1))])
26973   | BitFieldClearOrInsert(d,(BitsN.B(0xF,4),(lsbit,msbit))) =>
26974     ("bfc" ^ (s_cond c),
26975      String.concat
26976        [s_reg d,", #",Nat.toString lsbit,", #",
26977         Nat.toString(Nat.-(Nat.+(msbit,1),lsbit))])
26978   | BitFieldClearOrInsert(d,(n,(lsbit,msbit))) =>
26979     ("bfi" ^ (s_cond c),
26980      String.concat
26981        [s_reg2(d,n),", #",Nat.toString lsbit,", #",
26982         Nat.toString(Nat.-(Nat.+(msbit,1),lsbit))]);
26983
26984fun s_psr (write_spsr,mask) =
26985  String.concat
26986    [if write_spsr then "S" else "C","PSR_",
26987     if BitsN.bit(mask,0) then "c" else "",
26988     if BitsN.bit(mask,1) then "x" else "",
26989     if BitsN.bit(mask,2) then "s" else "",
26990     if BitsN.bit(mask,3) then "f" else ""];
26991
26992fun s_special (spsr,SYSm) =
26993  if spsr
26994    then "SPSR_"
26995           ^
26996           (case SYSm of
26997               BitsN.B(0xE,_) => "fiq"
26998             | BitsN.B(0x10,_) => "irq"
26999             | BitsN.B(0x12,_) => "svc"
27000             | BitsN.B(0x14,_) => "abt"
27001             | BitsN.B(0x16,_) => "und"
27002             | BitsN.B(0x1C,_) => "mon"
27003             | BitsN.B(0x1E,_) => "hyp"
27004             | _ => Nat.toString(BitsN.toNat SYSm))
27005  else case boolify'5 SYSm of
27006          (false,(false,(m'2,(m'1,m'0)))) =>
27007            String.concat
27008              ["r",
27009               Nat.toString
27010                 (Nat.+
27011                    (BitsN.toNat(BitsN.fromBitstring([m'2,m'1,m'0],3)),8)),
27012               "_usr"]
27013        | (false,(true,(m'2,(m'1,m'0)))) =>
27014          String.concat
27015            ["r",
27016             Nat.toString
27017               (Nat.+(BitsN.toNat(BitsN.fromBitstring([m'2,m'1,m'0],3)),8)),
27018             "_fiq"]
27019        | (true,(true,(_,(false,false)))) => "lr_mon"
27020        | (true,(true,(_,(false,true)))) => "sp_mon"
27021        | (true,(true,(_,(true,false)))) => "elr_hyp"
27022        | (true,(true,(_,(true,true)))) => "sp_hyp"
27023        | (true,(false,(false,(false,false)))) => "lr_irq"
27024        | (true,(false,(false,(false,true)))) => "sp_irq"
27025        | (true,(false,(false,(true,false)))) => "lr_svc"
27026        | (true,(false,(false,(true,true)))) => "sp_svc"
27027        | (true,(false,(true,(false,false)))) => "lr_abt"
27028        | (true,(false,(true,(false,true)))) => "sp_abt"
27029        | (true,(false,(true,(true,false)))) => "lr_und"
27030        | (true,(false,(true,(true,true)))) => "sp_und";
27031
27032fun s_system (c,ast) =
27033  case ast of
27034     EnterxLeavex false => ("leavex" ^ (s_cond c),"")
27035   | EnterxLeavex true => ("enterx" ^ (s_cond c),"")
27036   | ChangeProcessorState
27037     (enable,(disable,(affectA,(affectI,(affectF,changemode))))) =>
27038     (String.concat
27039        ["cps",if enable then "ie" else "",if disable then "id" else "",
27040         s_cond c],
27041      String.concat
27042        [if affectA then "a" else "",if affectI then "i" else "",
27043         if affectF then "f" else "",
27044         case changemode of
27045            Option.SOME m =>
27046              (if affectA orelse (affectI orelse affectF)
27047                 then ", #"
27048               else "#")
27049                ^
27050                (Nat.toString(BitsN.toNat m))
27051          | NONE => ""])
27052   | ExceptionReturn => ("eret" ^ (s_cond c),"")
27053   | HypervisorCall imm16 => ("hvc" ^ (s_cond c),"#" ^ (s_hex 16 imm16))
27054   | MoveToRegisterFromSpecial(read_spsr,d) =>
27055     ("mrs" ^ (s_cond c),
27056      String.concat[s_reg d,", ",if read_spsr then "SPSR" else "CPSR"])
27057   | MoveToRegisterFromBankedOrSpecial(read_spsr,(SYSm,d)) =>
27058     ("mrs" ^ (s_cond c),
27059      String.concat[s_reg d,", ",s_special(read_spsr,SYSm)])
27060   | MoveToSpecialFromImmediate(write_spsr,(imm32,mask)) =>
27061     ("msr" ^ (s_cond c),
27062      String.concat[s_psr(write_spsr,mask),", #",s_hex 32 imm32])
27063   | MoveToSpecialFromRegister(write_spsr,(n,mask)) =>
27064     ("msr" ^ (s_cond c),
27065      String.concat[s_psr(write_spsr,mask),", ",s_reg n])
27066   | MoveToBankedOrSpecialRegister(write_spsr,(SYSm,n)) =>
27067     ("msr" ^ (s_cond c),
27068      String.concat[s_special(write_spsr,SYSm),", ",s_reg n])
27069   | ReturnFromException(increment,(wordhigher,(wback,n))) =>
27070     (String.concat["rfe",s_stack(increment,wordhigher),s_cond c],
27071      (s_reg n) ^ (if wback then "!" else ""))
27072   | SecureMonitorCall imm4 =>
27073     ("smc" ^ (s_cond c),"#" ^ (Nat.toString(BitsN.toNat imm4)))
27074   | StoreReturnState(increment,(wordhigher,(wback,mode))) =>
27075     (String.concat["srs",s_stack(increment,wordhigher),s_cond c],
27076      String.concat
27077        ["sp",if wback then "!" else "",", #",
27078         Nat.toString(BitsN.toNat mode)])
27079   | SupervisorCall imm32 => ("svc" ^ (s_cond c),"#" ^ (s_hex 32 imm32))
27080   | Setend E => ("setend" ^ (s_cond c),if E then "be" else "le");
27081
27082fun s_it_mask (c0,mask) =
27083  case (c0,mask) of
27084     (_,BitsN.B(0x8,_)) => ""
27085   | (true,BitsN.B(0xC,_)) => "t"
27086   | (false,BitsN.B(0x4,_)) => "t"
27087   | (true,BitsN.B(0x4,_)) => "e"
27088   | (false,BitsN.B(0xC,_)) => "e"
27089   | (true,BitsN.B(0xE,_)) => "tt"
27090   | (false,BitsN.B(0x2,_)) => "tt"
27091   | (true,BitsN.B(0x6,_)) => "et"
27092   | (false,BitsN.B(0xA,_)) => "et"
27093   | (true,BitsN.B(0xA,_)) => "te"
27094   | (false,BitsN.B(0x6,_)) => "te"
27095   | (true,BitsN.B(0x2,_)) => "ee"
27096   | (false,BitsN.B(0xE,_)) => "ee"
27097   | (true,BitsN.B(0xF,_)) => "ttt"
27098   | (false,BitsN.B(0x1,_)) => "ttt"
27099   | (true,BitsN.B(0x7,_)) => "ett"
27100   | (false,BitsN.B(0x9,_)) => "ett"
27101   | (true,BitsN.B(0xB,_)) => "tet"
27102   | (false,BitsN.B(0x5,_)) => "tet"
27103   | (true,BitsN.B(0x3,_)) => "eet"
27104   | (false,BitsN.B(0xD,_)) => "eet"
27105   | (true,BitsN.B(0xD,_)) => "tte"
27106   | (false,BitsN.B(0x3,_)) => "tte"
27107   | (true,BitsN.B(0x5,_)) => "ete"
27108   | (false,BitsN.B(0xB,_)) => "ete"
27109   | (true,BitsN.B(0x9,_)) => "tee"
27110   | (false,BitsN.B(0x7,_)) => "tee"
27111   | (true,BitsN.B(0x1,_)) => "eee"
27112   | (false,BitsN.B(0xF,_)) => "eee"
27113   | _ => "???";
27114
27115fun instructionToString (c,ast) =
27116  case ast of
27117     Branch b => s_branch(c,b)
27118   | Data d => s_data(c,d)
27119   | Load l => s_load(c,l)
27120   | Store s => s_store(c,s)
27121   | Multiply m => s_multiply(c,m)
27122   | Media m => s_media(c,m)
27123   | SIMD m => s_simd(c,m)
27124   | System s => s_system(c,s)
27125   | Hint h => s_hint(c,h)
27126   | VFP v => s_vfp(c,v)
27127   | IfThen(firstcond,mask) =>
27128     ("it" ^ (s_it_mask(BitsN.bit(firstcond,0),mask)),
27129      if firstcond = (BitsN.B(0xE,4)) then "al" else s_cond firstcond)
27130   | Divide(unsigned,(d,(n,m))) =>
27131     (String.concat[if unsigned then "u" else "s","div",s_cond c],
27132      s_reg3(d,(n,m)))
27133   | ClearExclusive => ("clrex" ^ (s_cond c),"")
27134   | Swap(byte,(t,(t2,n))) =>
27135     (String.concat["swp",if byte then "b" else "",s_cond c],
27136      String.concat[s_reg2(t,t2),", [",s_reg n,"]"])
27137   | Undefined imm32 => ("udf" ^ (s_cond c),"#" ^ (s_hex 32 imm32))
27138   | NoOperation => ("nop" ^ (s_cond c),"");
27139
27140end