1 #pragma once
2 #include <type_traits>
3 #include <vector>
4 #include "crash.h"
5 #include "matcher.h"
6 #include "operand.h"
7 
8 template <typename... OperandAtT>
9 struct OperandList {
10     template <typename OperandAtT0>
11     using prefix = OperandList<OperandAtT0, OperandAtT...>;
12 };
13 
14 template <typename... OperandAtT>
15 struct FilterOperand;
16 
17 template <>
18 struct FilterOperand<> {
19     using result = OperandList<>;
20 };
21 
22 template <bool keep, typename OperandAtT0, typename... OperandAtT>
23 struct FilterOperandHelper;
24 
25 template <typename OperandAtT0, typename... OperandAtT>
26 struct FilterOperandHelper<false, OperandAtT0, OperandAtT...> {
27     using result = typename FilterOperand<OperandAtT...>::result;
28 };
29 
30 template <typename OperandAtT0, typename... OperandAtT>
31 struct FilterOperandHelper<true, OperandAtT0, OperandAtT...> {
32     using result = typename FilterOperand<OperandAtT...>::result ::template prefix<OperandAtT0>;
33 };
34 
35 template <typename OperandAtT0, typename... OperandAtT>
36 struct FilterOperand<OperandAtT0, OperandAtT...> {
37     using result =
38         typename FilterOperandHelper<OperandAtT0::PassAsParameter, OperandAtT0, OperandAtT...>::result;
39 };
40 
41 template <typename V, typename OperandListT>
42 struct VisitorFunctionWithoutFilter;
43 
44 template <typename V, typename... OperandAtT>
45 struct VisitorFunctionWithoutFilter<V, OperandList<OperandAtT...>> {
46     using type = typename V::instruction_return_type (V::*)(typename OperandAtT::FilterResult...);
47 };
48 
49 template <typename V, typename... OperandAtT>
50 struct VisitorFunction {
51     using type =
52         typename VisitorFunctionWithoutFilter<V, typename FilterOperand<OperandAtT...>::result>::type;
53 };
54 
55 template <typename V, u16 expected, typename... OperandAtT>
56 struct MatcherCreator {
57     template <typename OperandListT>
58     struct Proxy;
59 
60     using F = typename VisitorFunction<V, OperandAtT...>::type;
61 
62     template <typename... OperandAtTs>
63     struct Proxy<OperandList<OperandAtTs...>> {
64         F func;
65         auto operator()(V& visitor, [[maybe_unused]] u16 opcode,
66                         [[maybe_unused]] u16 expansion) const {
67             return (visitor.*func)(OperandAtTs::Extract(opcode, expansion)...);
68         }
69     };
70 
71     static Matcher<V> Create(const char* name, F func) {
72         // Operands shouldn't overlap each other, nor overlap with the expected ones
73         static_assert(NoOverlap<u16, expected, OperandAtT::Mask...>, "Error");
74 
75         Proxy<typename FilterOperand<OperandAtT...>::result> proxy{func};
76 
77         constexpr u16 mask = (~OperandAtT::Mask & ... & 0xFFFF);
78         constexpr bool expanded = (OperandAtT::NeedExpansion || ...);
79         return Matcher<V>(name, mask, expected, expanded, proxy);
80     }
81 };
82 
83 template <typename... OperandAtConstT>
84 struct RejectorCreator {
85     static constexpr Rejector rejector{(OperandAtConstT::Mask | ...), (OperandAtConstT::Pad | ...)};
86 };
87 
88 // clang-format off
89 
90 template <typename V>
91 std::vector<Matcher<V>> GetDecodeTable() {
92     return {
93 
94 #define INST(name, ...) MatcherCreator<V, __VA_ARGS__>::Create(#name, &V::name)
95 #define EXCEPT(...) Except(RejectorCreator<__VA_ARGS__>::rejector)
96 
97     // <<< Misc >>>
98     INST(nop, 0x0000),
99     INST(norm, 0x94C0, At<Ax, 8>, At<Rn, 0>, At<StepZIDS, 3>),
100     INST(swap, 0x4980, At<SwapType, 0>),
101     INST(trap, 0x0020),
102 
103     // <<< ALM normal >>>
104     INST(alm, 0xA000, At<Alm, 9>, At<MemImm8, 0>, At<Ax, 8>),
105     INST(alm, 0x8080, At<Alm, 9>, At<Rn, 0>, At<StepZIDS, 3>, At<Ax, 8>),
106     INST(alm, 0x80A0, At<Alm, 9>, At<Register, 0>, At<Ax, 8>),
107 
108     // <<< ALM r6 >>>
109     INST(alm_r6, 0xD388, Const<Alm, 0>, At<Ax, 4>),
110     INST(alm_r6, 0xD389, Const<Alm, 1>, At<Ax, 4>),
111     INST(alm_r6, 0xD38A, Const<Alm, 2>, At<Ax, 4>),
112     INST(alm_r6, 0xD38B, Const<Alm, 3>, At<Ax, 4>),
113     INST(alm_r6, 0xD38C, Const<Alm, 4>, At<Ax, 4>),
114     INST(alm_r6, 0xD38D, Const<Alm, 5>, At<Ax, 4>),
115     INST(alm_r6, 0xD38E, Const<Alm, 6>, At<Ax, 4>),
116     INST(alm_r6, 0xD38F, Const<Alm, 7>, At<Ax, 4>),
117     INST(alm_r6, 0x9462, Const<Alm, 8>, At<Ax, 0>),
118     INST(alm_r6, 0x9464, Const<Alm, 9>, At<Ax, 0>),
119     INST(alm_r6, 0x9466, Const<Alm, 10>, At<Ax, 0>),
120     INST(alm_r6, 0x5E23, Const<Alm, 11>, At<Ax, 8>),
121     INST(alm_r6, 0x5E22, Const<Alm, 12>, At<Ax, 8>),
122     INST(alm_r6, 0x5F41, Const<Alm, 13>, Const<Ax, 0>),
123     INST(alm_r6, 0x9062, Const<Alm, 14>, At<Ax, 8>, Unused<0>),
124     INST(alm_r6, 0x8A63, Const<Alm, 15>, At<Ax, 3>),
125 
126     // <<< ALU normal >>>
127     INST(alu, 0xD4F8, At<Alu, 0>, At<MemImm16, 16>, At<Ax, 8>)
128         .EXCEPT(AtConst<Alu, 0, 4>).EXCEPT(AtConst<Alu, 0, 5>),
129     INST(alu, 0xD4D8, At<Alu, 0>, At<MemR7Imm16, 16>, At<Ax, 8>)
130         .EXCEPT(AtConst<Alu, 0, 4>).EXCEPT(AtConst<Alu, 0, 5>),
131     INST(alu, 0x80C0, At<Alu, 9>, At<Imm16, 16>, At<Ax, 8>)
132         .EXCEPT(AtConst<Alu, 9, 4>).EXCEPT(AtConst<Alu, 9, 5>),
133     INST(alu, 0xC000, At<Alu, 9>, At<Imm8, 0>, At<Ax, 8>)
134         .EXCEPT(AtConst<Alu, 9, 4>).EXCEPT(AtConst<Alu, 9, 5>),
135     INST(alu, 0x4000, At<Alu, 9>, At<MemR7Imm7s, 0>, At<Ax, 8>)
136         .EXCEPT(AtConst<Alu, 9, 4>).EXCEPT(AtConst<Alu, 9, 5>),
137 
138     // <<< OR Extra >>>
139     INST(or_, 0xD291, At<Ab, 10>, At<Ax, 6>, At<Ax, 5>),
140     INST(or_, 0xD4A4, At<Ax, 8>, At<Bx, 1>, At<Ax, 0>),
141     INST(or_, 0xD3C4, At<Bx, 10>, At<Bx, 1>, At<Ax, 0>),
142 
143     // <<< ALB normal >>>
144     INST(alb, 0xE100, At<Alb, 9>, At<Imm16, 16>, At<MemImm8, 0>),
145     INST(alb, 0x80E0, At<Alb, 9>, At<Imm16, 16>, At<Rn, 0>, At<StepZIDS, 3>),
146     INST(alb, 0x81E0, At<Alb, 9>, At<Imm16, 16>, At<Register, 0>),
147     INST(alb_r6, 0x47B8, At<Alb, 0>, At<Imm16, 16>),
148 
149     // <<< ALB SttMod >>>
150     INST(alb, 0x43C8, Const<Alb, 0>, At<Imm16, 16>, At<SttMod, 0>),
151     INST(alb, 0x4388, Const<Alb, 1>, At<Imm16, 16>, At<SttMod, 0>),
152     INST(alb, 0x0038, Const<Alb, 2>, At<Imm16, 16>, At<SttMod, 0>),
153     //INST(alb, 0x????, Const<Alb, 3>, At<Imm,16, 16>, At<SttMod, 0>),
154     INST(alb, 0x9470, Const<Alb, 4>, At<Imm16, 16>, At<SttMod, 0>),
155     INST(alb, 0x9478, Const<Alb, 5>, At<Imm16, 16>, At<SttMod, 0>),
156     //INST(alb, 0x????, Const<Alb, 6>, At<Imm,16, 16>, At<SttMod, 0>),
157     //INST(alb, 0x????, Const<Alb, 7>, At<Imm,16, 16>, At<SttMod, 0>),
158 
159     // <<< Add extra >>>
160     INST(add, 0xD2DA, At<Ab, 10>, At<Bx, 0>),
161     INST(add, 0x5DF0, At<Bx, 1>, At<Ax, 0>),
162     INST(add_p1, 0xD782, At<Ax, 0>),
163     INST(add, 0x5DF8, At<Px, 1>, At<Bx, 0>),
164 
165     // <<< Sub extra >>>
166     INST(sub, 0x8A61, At<Ab, 3>, At<Bx, 8>),
167     INST(sub, 0x8861, At<Bx, 4>, At<Ax, 3>),
168     INST(sub_p1, 0xD4B9, At<Ax, 8>),
169     INST(sub, 0x8FD0, At<Px, 1>, At<Bx, 0>),
170 
171     /// <<< addsub p0 p1 >>>
172     INST(app, 0x5DC0, At<Ab, 2>, BZr, Add, PP, Add, PP),
173     INST(app, 0x5DC1, At<Ab, 2>, BZr, Add, PP, Add, PA),
174     INST(app, 0x4590, At<Ab, 2>, BAc, Add, PP, Add, PP),
175     INST(app, 0x4592, At<Ab, 2>, BAc, Add, PP, Add, PA),
176     INST(app, 0x4593, At<Ab, 2>, BAc, Add, PA, Add, PA),
177     INST(app, 0x5DC2, At<Ab, 2>, BZr, Add, PP, Sub, PP),
178     INST(app, 0x5DC3, At<Ab, 2>, BZr, Add, PP, Sub, PA),
179     INST(app, 0x80C6, At<Ab, 10>, BAc, Sub, PP, Sub, PP),
180     INST(app, 0x82C6, At<Ab, 10>, BAc, Sub, PP, Sub, PA),
181     INST(app, 0x83C6, At<Ab, 10>, BAc, Sub, PA, Sub, PA),
182     INST(app, 0x906C, At<Ab, 0>, BAc, Add, PP, Sub, PP),
183     INST(app, 0x49C2, At<Ab, 4>, BAc, Sub, PP, Add, PP),
184     INST(app, 0x916C, At<Ab, 0>, BAc, Add, PP, Sub, PA),
185     INST(app, 0x49C3, At<Ab, 4>, BAc, Sub, PP, Add, PA),
186 
187     /// <<< add||sub >>>
188     INST(add_add, 0x6F80, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ab, 3>),
189     INST(add_sub, 0x6FA0, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ab, 3>),
190     INST(sub_add, 0x6FC0, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ab, 3>),
191     INST(sub_sub, 0x6FE0, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ab, 3>),
192 
193     /// <<< add||sub sv >>>
194     INST(add_sub_sv, 0x5DB0, At<ArRn1, 1>, At<ArStep1, 0>, At<Ab, 2>),
195     INST(sub_add_sv, 0x5DE0, At<ArRn1, 1>, At<ArStep1, 0>, At<Ab, 2>),
196 
197     /// <<< add||sub||mov sv >>>
198     INST(sub_add_i_mov_j_sv, 0x8064, At<ArpRn1, 8>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ab, 3>),
199     INST(sub_add_j_mov_i_sv, 0x5D80, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ab, 3>),
200     INST(add_sub_i_mov_j, 0x9070, At<ArpRn1, 8>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ab, 2>),
201     INST(add_sub_j_mov_i, 0x5E30, At<ArpRn1, 8>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ab, 2>),
202 
203     // <<< Mul >>>
204     INST(mul, 0x8000, At<Mul3, 8>, At<Rn, 0>, At<StepZIDS, 3>, At<Imm16, 16>, At<Ax, 11>),
205     INST(mul_y0, 0x8020, At<Mul3, 8>, At<Rn, 0>, At<StepZIDS, 3>, At<Ax, 11>),
206     INST(mul_y0, 0x8040, At<Mul3, 8>, At<Register, 0>, At<Ax, 11>),
207     INST(mul, 0xD000, At<Mul3, 8>, At<R45, 2>, At<StepZIDS, 5>, At<R0123, 0>, At<StepZIDS, 3>, At<Ax, 11>),
208     INST(mul_y0_r6, 0x5EA0, At<Mul3, 1>, At<Ax, 0>),
209     INST(mul_y0, 0xE000, At<Mul2, 9>, At<MemImm8, 0>, At<Ax, 11>),
210 
211     // <<< Mul Extra >>>
212     INST(mpyi, 0x0800, At<Imm8s, 0>),
213     INST(msu, 0xD080, At<R45, 2>, At<StepZIDS, 5>, At<R0123, 0>, At<StepZIDS, 3>, At<Ax, 8>),
214     INST(msu, 0x90C0, At<Rn, 0>, At<StepZIDS, 3>, At<Imm16, 16>, At<Ax, 8>),
215     INST(msusu, 0x8264, At<ArRn2, 3>, At<ArStep2, 0>, At<Ax, 8>),
216     INST(mac_x1to0, 0x4D84, At<Ax, 1>, Unused<0>),
217     INST(mac1, 0x5E28, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ax, 8>),
218 
219     // <<< MODA >>>
220     INST(moda4, 0x6700, At<Moda4, 4>, At<Ax, 12>, At<Cond, 0>)
221         .EXCEPT(AtConst<Moda4, 4, 7>),
222     INST(moda3, 0x6F00, At<Moda3, 4>, At<Bx, 12>, At<Cond, 0>),
223     INST(pacr1, 0xD7C2, At<Ax, 0>),
224     INST(clr, 0x8ED0, At<Ab, 2>, At<Ab, 0>),
225     INST(clrr, 0x8DD0, At<Ab, 2>, At<Ab, 0>),
226 
227     // <<< Block repeat >>>
228     INST(bkrep, 0x5C00, At<Imm8, 0>, At<Address16, 16>),
229     INST(bkrep, 0x5D00, At<Register, 0>, At<Address18_16, 16>, At<Address18_2, 5>),
230     INST(bkrep_r6, 0x8FDC, At<Address18_16, 16>, At<Address18_2, 0>),
231     INST(bkreprst, 0xDA9C, At<ArRn2, 0>),
232     INST(bkreprst_memsp, 0x5F48, Unused<0>, Unused<1>),
233     INST(bkrepsto, 0xDADC, At<ArRn2, 0>, Unused<10>),
234     INST(bkrepsto_memsp, 0x9468, Unused<0>, Unused<1>, Unused<2>),
235 
236     // <<< Bank >>>
237     INST(banke, 0x4B80, At<BankFlags, 0>),
238     INST(bankr, 0x8CDF),
239     INST(bankr, 0x8CDC, At<Ar, 0>),
240     INST(bankr, 0x8CD0, At<Ar, 2>, At<Arp, 0>),
241     INST(bankr, 0x8CD8, At<Arp, 0>),
242 
243     // <<< Bitrev >>>
244     INST(bitrev, 0x5EB8, At<Rn, 0>),
245     INST(bitrev_dbrv, 0xD7E8, At<Rn, 0>),
246     INST(bitrev_ebrv, 0xD7E0, At<Rn, 0>),
247 
248     // <<< Branching >>>
249     INST(br, 0x4180, At<Address18_16, 16>, At<Address18_2, 4>, At<Cond, 0>),
250     INST(brr, 0x5000, At<RelAddr7, 4>, At<Cond, 0>),
251 
252     // <<< Break >>>
253     INST(break_, 0xD3C0),
254 
255     // <<< Call >>>
256     INST(call, 0x41C0, At<Address18_16, 16>, At<Address18_2, 4>, At<Cond, 0>),
257     INST(calla, 0xD480, At<Axl, 8>),
258     INST(calla, 0xD381, At<Ax, 4>),
259     INST(callr, 0x1000, At<RelAddr7, 4>, At<Cond, 0>),
260 
261     // <<< Context >>>
262     INST(cntx_s, 0xD380),
263     INST(cntx_r, 0xD390),
264 
265     // <<< Return >>>
266     INST(ret, 0x4580, At<Cond, 0>),
267     INST(retd, 0xD780),
268     INST(reti, 0x45C0, At<Cond, 0>),
269     INST(retic, 0x45D0, At<Cond, 0>),
270     INST(retid, 0xD7C0),
271     INST(retidc, 0xD3C3),
272     INST(rets, 0x0900, At<Imm8, 0>),
273 
274     // <<< Load >>>
275     INST(load_ps, 0x4D80, At<Imm2, 0>),
276     INST(load_stepi, 0xDB80, At<Imm7s, 0>),
277     INST(load_stepj, 0xDF80, At<Imm7s, 0>),
278     INST(load_page, 0x0400, At<Imm8, 0>),
279     INST(load_modi, 0x0200, At<Imm9, 0>),
280     INST(load_modj, 0x0A00, At<Imm9, 0>),
281     INST(load_movpd, 0xD7D8, At<Imm2, 1>, Unused<0>),
282     INST(load_ps01, 0x0010, At<Imm4, 0>),
283 
284     // <<< Push >>>
285     INST(push, 0x5F40, At<Imm16, 16>),
286     INST(push, 0x5E40, At<Register, 0>),
287     INST(push, 0xD7C8, At<Abe, 1>, Unused<0>),
288     INST(push, 0xD3D0, At<ArArpSttMod, 0>),
289     INST(push_prpage, 0xD7FC, Unused<0>, Unused<1>),
290     INST(push, 0xD78C, At<Px, 1>, Unused<0>),
291     INST(push_r6, 0xD4D7, Unused<5>),
292     INST(push_repc, 0xD7F8, Unused<0>, Unused<1>),
293     INST(push_x0, 0xD4D4, Unused<5>),
294     INST(push_x1, 0xD4D5, Unused<5>),
295     INST(push_y1, 0xD4D6, Unused<5>),
296     INST(pusha, 0x4384, At<Ax, 6>, Unused<0>, Unused<1>),
297     INST(pusha, 0xD788, At<Bx, 1>, Unused<0>),
298 
299     // <<< Pop >>>
300     INST(pop, 0x5E60, At<Register, 0>),
301     INST(pop, 0x47B4, At<Abe, 0>),
302     INST(pop, 0x80C7, At<ArArpSttMod, 8>),
303     INST(pop, 0x0006, At<Bx, 5>, Unused<0>),
304     INST(pop_prpage, 0xD7F4, Unused<0>, Unused<1>),
305     INST(pop, 0xD496, At<Px, 0>),
306     INST(pop_r6, 0x0024, Unused<0>),
307     INST(pop_repc, 0xD7F0, Unused<0>, Unused<1>),
308     INST(pop_x0, 0xD494),
309     INST(pop_x1, 0xD495),
310     INST(pop_y1, 0x0004, Unused<0>),
311     INST(popa, 0x47B0, At<Ab, 0>),
312 
313     // <<< Repeat >>>
314     INST(rep, 0x0C00, At<Imm8, 0>),
315     INST(rep, 0x0D00, At<Register, 0>),
316     INST(rep_r6, 0x0002, Unused<0>),
317 
318     // <<< Shift >>>
319     INST(shfc, 0xD280, At<Ab, 10>, At<Ab, 5>, At<Cond, 0>),
320     INST(shfi, 0x9240, At<Ab, 10>, At<Ab, 7>, At<Imm6s, 0>),
321 
322     // <<< TSTB >>>
323     INST(tst4b, 0x80C1, At<ArRn2, 10>, At<ArStep2, 8>),
324     INST(tst4b, 0x4780, At<ArRn2, 2>, At<ArStep2, 0>, At<Ax, 4>),
325     INST(tstb, 0xF000, At<MemImm8, 0>, At<Imm4, 8>),
326     INST(tstb, 0x9020, At<Rn, 0>, At<StepZIDS, 3>, At<Imm4, 8>),
327     INST(tstb, 0x9000, At<Register, 0>, At<Imm4, 8>)
328         .EXCEPT(AtConst<Register, 0, 24>), // override by tstb_r6
329     INST(tstb_r6, 0x9018, At<Imm4, 8>),
330     INST(tstb, 0x0028, At<SttMod, 0>, At<Imm16, 16>), // unused12@20
331 
332     // <<< AND Extra >>>
333     INST(and_, 0x6770, At<Ab, 2>, At<Ab, 0>, At<Ax, 12>),
334 
335     // <<< Interrupt >>>
336     INST(dint, 0x43C0),
337     INST(eint, 0x4380),
338 
339     // <<< EXP >>>
340     INST(exp, 0x9460, At<Bx, 0>),
341     INST(exp, 0x9060, At<Bx, 0>, At<Ax, 8>),
342     INST(exp, 0x9C40, At<Rn, 0>, At<StepZIDS, 3>),
343     INST(exp, 0x9840, At<Rn, 0>, At<StepZIDS, 3>, At<Ax, 8>),
344     INST(exp, 0x9440, At<Register, 0>),
345     INST(exp, 0x9040, At<Register, 0>, At<Ax, 8>),
346     INST(exp_r6, 0xD7C1),
347     INST(exp_r6, 0xD382, At<Ax, 4>),
348 
349     // <<< MODR >>>
350     INST(modr, 0x0080, At<Rn, 0>, At<StepZIDS, 3>),
351     INST(modr_dmod, 0x00A0, At<Rn, 0>, At<StepZIDS, 3>),
352     INST(modr_i2, 0x4990, At<Rn, 0>),
353     INST(modr_i2_dmod, 0x4998, At<Rn, 0>),
354     INST(modr_d2, 0x5DA0, At<Rn, 0>),
355     INST(modr_d2_dmod, 0x5DA8, At<Rn, 0>),
356     INST(modr_eemod, 0xD294, At<ArpRn2, 10>, At<ArpStep2, 0>, At<ArpStep2, 5>),
357     INST(modr_edmod, 0x0D80, At<ArpRn2, 5>, At<ArpStep2, 1>, At<ArpStep2, 3>),
358     INST(modr_demod, 0x8464, At<ArpRn2, 8>, At<ArpStep2, 0>, At<ArpStep2, 3>),
359     INST(modr_ddmod, 0x0D81, At<ArpRn2, 5>, At<ArpStep2, 1>, At<ArpStep2, 3>),
360 
361     // <<< MOV >>>
362     INST(mov, 0xD290, At<Ab, 10>, At<Ab, 5>),
363     INST(mov_dvm, 0xD298, At<Abl, 10>),
364     INST(mov_x0, 0xD2D8, At<Abl, 10>),
365     INST(mov_x1, 0xD394, At<Abl, 0>),
366     INST(mov_y1, 0xD384, At<Abl, 0>),
367 
368     INST(mov, 0x3000, At<Ablh, 9>, At<MemImm8, 0>),
369     INST(mov, 0xD4BC, At<Axl, 8>, At<MemImm16, 16>),
370     INST(mov, 0xD49C, At<Axl, 8>, At<MemR7Imm16, 16>),
371     INST(mov, 0xDC80, At<Axl, 8>, At<MemR7Imm7s, 0>),
372 
373     INST(mov, 0xD4B8, At<MemImm16, 16>, At<Ax, 8>),
374     INST(mov, 0x6100, At<MemImm8, 0>, At<Ab, 11>),
375     INST(mov, 0x6200, At<MemImm8, 0>, At<Ablh, 10>),
376     INST(mov_eu, 0x6500, At<MemImm8, 0>, At<Axh, 12>),
377     INST(mov, 0x6000, At<MemImm8, 0>, At<RnOld, 10>),
378     INST(mov_sv, 0x6D00, At<MemImm8, 0>),
379 
380     INST(mov_dvm_to, 0xD491, At<Ab, 5>),
381     INST(mov_icr_to, 0xD492, At<Ab, 5>),
382 
383     INST(mov, 0x5E20, At<Imm16, 16>, At<Bx, 8>),
384     INST(mov, 0x5E00, At<Imm16, 16>, At<Register, 0>),
385     INST(mov_icr, 0x4F80, At<Imm5, 0>),
386     INST(mov, 0x2500, At<Imm8s, 0>, At<Axh, 12>),
387     INST(mov_ext0, 0x2900, At<Imm8s, 0>),
388     INST(mov_ext1, 0x2D00, At<Imm8s, 0>),
389     INST(mov_ext2, 0x3900, At<Imm8s, 0>),
390     INST(mov_ext3, 0x3D00, At<Imm8s, 0>),
391     INST(mov, 0x2300, At<Imm8s, 0>, At<RnOld, 10>),
392     INST(mov_sv, 0x0500, At<Imm8s, 0>),
393     INST(mov, 0x2100, At<Imm8, 0>, At<Axl, 12>),
394 
395     INST(mov, 0xD498, At<MemR7Imm16, 16>, At<Ax, 8>),
396     INST(mov, 0xD880, At<MemR7Imm7s, 0>, At<Ax, 8>),
397     INST(mov, 0x98C0, At<Rn, 0>, At<StepZIDS, 3>, At<Bx, 8>),
398     INST(mov, 0x1C00, At<Rn, 0>, At<StepZIDS, 3>, At<Register, 5>),
399 
400     INST(mov_memsp_to, 0x47E0, At<Register, 0>),
401     INST(mov_mixp_to, 0x47C0, At<Register, 0>),
402     INST(mov, 0x2000, At<RnOld, 9>, At<MemImm8, 0>),
403     INST(mov_icr, 0x4FC0, At<Register, 0>),
404     INST(mov_mixp, 0x5E80, At<Register, 0>),
405     INST(mov, 0x1800, At<Register, 5>, At<Rn, 0>, At<StepZIDS, 3>)
406         .EXCEPT(AtConst<Register, 5, 24>).EXCEPT(AtConst<Register, 5, 25>), // override by mov_r6(_to)
407     INST(mov, 0x5EC0, At<Register, 0>, At<Bx, 5>),
408     INST(mov, 0x5800, At<Register, 0>, At<Register, 5>)
409         .EXCEPT(AtConst<Register, 0, 24>).EXCEPT(AtConst<Register, 0, 25>), // override by mma_mov
410     INST(mov_repc_to, 0xD490, At<Ab, 5>),
411     INST(mov_sv_to, 0x7D00, At<MemImm8, 0>),
412     INST(mov_x0_to, 0xD493, At<Ab, 5>),
413     INST(mov_x1_to, 0x49C1, At<Ab, 4>),
414     INST(mov_y1_to, 0xD299, At<Ab, 10>),
415 
416     // <<< MOV load >>>
417     INST(mov, 0x0008, At<Imm16, 16>, At<ArArp, 0>),
418     INST(mov_r6, 0x0023, At<Imm16, 16>),
419     INST(mov_repc, 0x0001, At<Imm16, 16>),
420     INST(mov_stepi0, 0x8971, At<Imm16, 16>),
421     INST(mov_stepj0, 0x8979, At<Imm16, 16>),
422     INST(mov, 0x0030, At<Imm16, 16>, At<SttMod, 0>),
423     INST(mov_prpage, 0x5DD0, At<Imm4, 0>),
424 
425     // <<< <<< MOV p/d >>>
426     INST(movd, 0x5F80, At<R0123, 0>, At<StepZIDS, 3>, At<R45, 2>, At<StepZIDS, 5>),
427     INST(movp, 0x0040, At<Axl, 5>, At<Register, 0>),
428     INST(movp, 0x0D40, At<Ax, 5>, At<Register, 0>),
429     INST(movp, 0x0600, At<Rn, 0>, At<StepZIDS, 3>, At<R0123, 5>, At<StepZIDS, 7>),
430     INST(movpdw, 0xD499, At<Ax, 8>),
431 
432     // <<< MOV 2 >>>
433     INST(mov_a0h_stepi0, 0xD49B),
434     INST(mov_a0h_stepj0, 0xD59B),
435     INST(mov_stepi0_a0h, 0xD482),
436     INST(mov_stepj0_a0h, 0xD582),
437 
438     INST(mov_prpage, 0x9164, At<Abl, 0>),
439     INST(mov_repc, 0x9064, At<Abl, 0>),
440     INST(mov, 0x9540, At<Abl, 3>, At<ArArp, 0>),
441     INST(mov, 0x9C60, At<Abl, 3>, At<SttMod, 0>),
442 
443     INST(mov_prpage_to, 0x5EB0, At<Abl, 0>),
444     INST(mov_repc_to, 0xD2D9, At<Abl, 10>),
445     INST(mov, 0x9560, At<ArArp, 0>, At<Abl, 3>),
446     INST(mov, 0xD2F8, At<SttMod, 0>, At<Abl, 10>),
447 
448     INST(mov_repc_to, 0xD7D0, At<ArRn1, 1>, At<ArStep1, 0>),
449     INST(mov, 0xD488, At<ArArp, 0>, At<ArRn1, 8>, At<ArStep1, 5>),
450     INST(mov, 0x49A0, At<SttMod, 0>, At<ArRn1, 4>, At<ArStep1, 3>),
451 
452     INST(mov_repc, 0xD7D4, At<ArRn1, 1>, At<ArStep1, 0>),
453     INST(mov, 0x8062, At<ArRn1, 4>, At<ArStep1, 3>, At<ArArp, 8>),
454     INST(mov, 0x8063, At<ArRn1, 4>, At<ArStep1, 3>, At<SttMod, 8>),
455 
456     INST(mov_repc_to, 0xD3C8, At<MemR7Imm16, 16>, Unused<0>, Unused<1>, Unused<2>),
457     INST(mov, 0x5F50, At<ArArpSttMod, 0>, At<MemR7Imm16, 16>),
458 
459     INST(mov_repc, 0xD2DC, At<MemR7Imm16, 16>, Unused<0>, Unused<1>, Unused<10>),
460     INST(mov, 0x4D90, At<MemR7Imm16, 16>, At<ArArpSttMod, 0>),
461 
462     INST(mov_pc, 0x886B, At<Ax, 8>),
463     INST(mov_pc, 0x8863, At<Bx, 8>),
464 
465     INST(mov_mixp_to, 0x8A73, At<Bx, 3>),
466     INST(mov_mixp_r6, 0x4381),
467     INST(mov_p0h_to, 0x4382, At<Bx, 0>),
468     INST(mov_p0h_r6, 0xD3C2),
469     INST(mov_p0h_to, 0x4B60, At<Register, 0>),
470     INST(mov_p0, 0x8FD4, At<Ab, 0>),
471     INST(mov_p1_to, 0x8FD8, At<Ab, 0>),
472 
473     INST(mov2, 0x88D0, At<Px, 1>, At<ArRn2, 8>, At<ArStep2, 2>),
474     INST(mov2s, 0x88D1, At<Px, 1>, At<ArRn2, 8>, At<ArStep2, 2>),
475     INST(mov2, 0xD292, At<ArRn2, 10>, At<ArStep2, 5>, At<Px, 0>),
476     INST(mova, 0x4DC0, At<Ab, 4>, At<ArRn2, 2>, At<ArStep2, 0>),
477     INST(mova, 0x4BC0, At<ArRn2, 2>, At<ArStep2, 0>, At<Ab, 4>),
478 
479     INST(mov_r6_to, 0xD481, At<Bx, 8>),
480     INST(mov_r6_mixp, 0x43C1),
481     INST(mov_r6_to, 0x5F00, At<Register, 0>),
482     INST(mov_r6, 0x5F60, At<Register, 0>),
483     INST(mov_memsp_r6, 0xD29C, Unused<0>, Unused<1>, Unused<10>),
484     INST(mov_r6_to, 0x1B00, At<Rn, 0>, At<StepZIDS, 3>),
485     INST(mov_r6, 0x1B20, At<Rn, 0>, At<StepZIDS, 3>),
486 
487     INST(movs, 0x6300, At<MemImm8, 0>, At<Ab, 11>),
488     INST(movs, 0x0180, At<Rn, 0>, At<StepZIDS, 3>, At<Ab, 5>),
489     INST(movs, 0x0100, At<Register, 0>, At<Ab, 5>),
490     INST(movs_r6_to, 0x5F42, At<Ax, 0>),
491     INST(movsi, 0x4080, At<RnOld, 9>, At<Ab, 5>, At<Imm5s, 0>),
492 
493     // <<< MOV MOV >>>
494     INST(mov2_axh_m_y0_m, 0x4390, At<Axh, 6>, At<ArRn2, 2>, At<ArStep2, 0>),
495     INST(mov2_ax_mij, 0x43A0, At<Ab, 3>, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>),
496     INST(mov2_ax_mji, 0x43E0, At<Ab, 3>, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>),
497     INST(mov2_mij_ax, 0x80C4, At<ArpRn1, 9>, At<ArpStep1, 0>, At<ArpStep1, 8>, At<Ab, 10>),
498     INST(mov2_mji_ax, 0xD4C0, At<ArpRn1, 5>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<Ab, 2>),
499     INST(mov2_abh_m, 0x9D40, At<Abh, 4>, At<Abh, 2>, At<ArRn1, 1>, At<ArStep1, 0>),
500     INST(exchange_iaj, 0x8C60, At<Axh, 4>, At<ArpRn2, 8>, At<ArpStep2, 0>, At<ArpStep2, 2>),
501     INST(exchange_riaj, 0x7F80, At<Axh, 6>, At<ArpRn2, 4>, At<ArpStep2, 0>, At<ArpStep2, 2>),
502     INST(exchange_jai, 0x4900, At<Axh, 6>, At<ArpRn2, 4>, At<ArpStep2, 0>, At<ArpStep2, 2>),
503     INST(exchange_rjai, 0x4800, At<Axh, 6>, At<ArpRn2, 4>, At<ArpStep2, 0>, At<ArpStep2, 2>),
504 
505     // <<< MOVR >>>
506     INST(movr, 0x8864, At<ArRn2, 3>, At<ArStep2, 0>, At<Abh, 8>),
507     INST(movr, 0x9CE0, At<Rn, 0>, At<StepZIDS, 3>, At<Ax, 8>),
508     INST(movr, 0x9CC0, At<Register, 0>, At<Ax, 8>),
509     INST(movr, 0x5DF4, At<Bx, 1>, At<Ax, 0>),
510     INST(movr_r6_to, 0x8961, At<Ax, 3>),
511 
512     // <<< LIM >>>
513     INST(lim, 0x49C0, At<Ax, 5>, At<Ax, 4>),
514 
515     // <<< Viterbi >>>
516     INST(vtrclr0, 0x5F45),
517     INST(vtrclr1, 0x5F46),
518     INST(vtrclr, 0x5F47),
519     INST(vtrmov0, 0xD29A, At<Axl, 0>),
520     INST(vtrmov1, 0xD69A, At<Axl, 0>),
521     INST(vtrmov, 0xD383, At<Axl, 4>),
522     INST(vtrshr, 0xD781),
523 
524     // <<< CLRP >>>
525     INST(clrp0, 0x5DFE),
526     INST(clrp1, 0x5DFD),
527     INST(clrp, 0x5DFF),
528 
529     // <<< min/max >>>
530     INST(max_ge, 0x8460, At<Ax, 8>, At<StepZIDS, 3>),
531     INST(max_gt, 0x8660, At<Ax, 8>, At<StepZIDS, 3>),
532     INST(min_le, 0x8860, At<Ax, 8>, At<StepZIDS, 3>),
533     INST(min_lt, 0x8A60, At<Ax, 8>, At<StepZIDS, 3>),
534     INST(max_ge_r0, 0x8060, At<Ax, 8>, At<StepZIDS, 3>),
535     INST(max_gt_r0, 0x8260, At<Ax, 8>, At<StepZIDS, 3>),
536     INST(min_le_r0, 0x47A0, At<Ax, 3>, At<StepZIDS, 0>),
537     INST(min_lt_r0, 0x47A4, At<Ax, 3>, At<StepZIDS, 0>),
538 
539     // <<< Division Step >>>
540     INST(divs, 0x0E00, At<MemImm8, 0>, At<Ax, 8>),
541 
542     // <<< Sqr >>>
543     INST(sqr_sqr_add3, 0xD790, At<Ab, 2>, At<Ab, 0>),
544     INST(sqr_sqr_add3, 0x4B00, At<ArRn2, 4>, At<ArStep2, 2>, At<Ab, 0>),
545     INST(sqr_mpysu_add3a, 0x49C4, At<Ab, 4>, At<Ab, 0>),
546 
547     // <<< CMP Extra >>>
548     INST(cmp, 0x4D8C, At<Ax, 1>, At<Bx, 0>),
549     INST(cmp_b0_b1, 0xD483),
550     INST(cmp_b1_b0, 0xD583),
551     INST(cmp, 0xDA9A, At<Bx, 10>, At<Ax, 0>),
552     INST(cmp_p1_to, 0x8B63, At<Ax, 4>),
553 
554     // <<< min||max||vtrshr >>>
555     INST(max2_vtr, 0x5E21, At<Ax, 8>),
556     INST(min2_vtr, 0x43C2, At<Ax, 0>),
557     INST(max2_vtr, 0xD784, At<Ax, 1>, At<Bx, 0>),
558     INST(min2_vtr, 0xD4BA, At<Ax, 8>, At<Bx, 0>),
559     INST(max2_vtr_movl, 0x4A40, At<Ax, 3>, At<Bx, 4>, At<ArRn1, 1>, At<ArStep1, 0>),
560     INST(max2_vtr_movh, 0x4A44, At<Ax, 3>, At<Bx, 4>, At<ArRn1, 1>, At<ArStep1, 0>),
561     INST(max2_vtr_movl, 0x4A60, At<Bx, 4>, At<Ax, 3>, At<ArRn1, 1>, At<ArStep1, 0>),
562     INST(max2_vtr_movh, 0x4A64, At<Bx, 4>, At<Ax, 3>, At<ArRn1, 1>, At<ArStep1, 0>),
563     INST(min2_vtr_movl, 0x4A00, At<Ax, 3>, At<Bx, 4>, At<ArRn1, 1>, At<ArStep1, 0>),
564     INST(min2_vtr_movh, 0x4A04, At<Ax, 3>, At<Bx, 4>, At<ArRn1, 1>, At<ArStep1, 0>),
565     INST(min2_vtr_movl, 0x4A20, At<Bx, 4>, At<Ax, 3>, At<ArRn1, 1>, At<ArStep1, 0>),
566     INST(min2_vtr_movh, 0x4A24, At<Bx, 4>, At<Ax, 3>, At<ArRn1, 1>, At<ArStep1, 0>),
567     INST(max2_vtr_movij, 0xD590, At<Ax, 6>, At<Bx, 5>, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>),
568     INST(max2_vtr_movji, 0x45A0, At<Ax, 4>, At<Bx, 3>, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>),
569     INST(min2_vtr_movij, 0xD2B8, At<Ax, 11>, At<Bx, 10>, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>),
570     INST(min2_vtr_movji, 0x45E0, At<Ax, 4>, At<Bx, 3>, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>),
571 
572     // <<< MOV ADDSUB >>>
573     INST(mov_sv_app, 0x4B40, At<ArRn1, 3>, At<ArStep1, 2>, At<Bx, 0>, BSv, Sub, PP, Add, PP),
574     INST(mov_sv_app, 0x9960, At<ArRn1, 4>, At<ArStep1Alt, 3>, At<Bx, 2>, BSv, Sub, PP, Add, PP),
575     INST(mov_sv_app, 0x4B42, At<ArRn1, 3>, At<ArStep1, 2>, At<Bx, 0>, BSr, Sub, PP, Add, PP),
576     INST(mov_sv_app, 0x99E0, At<ArRn1, 4>, At<ArStep1Alt, 3>, At<Bx, 2>, BSr, Sub, PP, Add, PP),
577     INST(mov_sv_app, 0x5F4C, At<ArRn1, 1>, At<ArStep1, 0>, Const<Bx, 0>, BSv, Sub, PP, Sub, PP),
578     INST(mov_sv_app, 0x8873, At<ArRn1, 8>, At<ArStep1, 3>, Const<Bx, 1>, BSv, Sub, PP, Sub, PP),
579     INST(mov_sv_app, 0x9860, At<ArRn1, 4>, At<ArStep1Alt, 3>, At<Bx, 2>, BSv, Sub, PP, Sub, PP),
580     INST(mov_sv_app, 0xDE9C, At<ArRn1, 1>, At<ArStep1, 0>, Const<Bx, 0>, BSr, Sub, PP, Sub, PP),
581     INST(mov_sv_app, 0xD4B4, At<ArRn1, 1>, At<ArStep1, 0>, Const<Bx, 1>, BSr, Sub, PP, Sub, PP),
582     INST(mov_sv_app, 0x98E0, At<ArRn1, 4>, At<ArStep1Alt, 3>, At<Bx, 2>, BSr, Sub, PP, Sub, PP),
583 
584     // <<< CBS >>>
585     INST(cbs, 0x9068, At<Axh, 0>, At<CbsCond, 8>),
586     INST(cbs, 0xD49E, At<Axh, 8>, At<Bxh, 5>, At<CbsCond, 0>),
587     INST(cbs, 0xD5C0, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, At<CbsCond, 3>),
588 
589     // [[[XXX_xy_XXX_xy_XXX]]]
590     INST(mma, 0x4D88, AtNamed<Ax, 1>, SX, SY, SX, SY, BZr, Add, PP, Sub, PP),
591     INST(mma, 0xD49D, AtNamed<Bx, 5>, SX, SY, SX, SY, BZr, Add, PP, Sub, PP),
592     INST(mma, 0x5E24, AtNamed<Ab, 0>, SX, SY, SX, SY, BZr, Add, PP, Add, PP),
593     INST(mma, 0x8061, AtNamed<Ab, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PP),
594     INST(mma, 0x8071, AtNamed<Ab, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PA),
595     INST(mma, 0x8461, AtNamed<Ab, 8>, SX, SY, SX, SY, BAc, Sub, PP, Sub, PP),
596     INST(mma, 0x8471, AtNamed<Ab, 8>, SX, SY, SX, SY, BAc, Sub, PP, Sub, PA),
597     INST(mma, 0xD484, AtNamed<Ab, 0>, SX, SY, SX, SY, BAc, Add, PA, Add, PA),
598     INST(mma, 0xD4A0, AtNamed<Ab, 0>, SX, SY, SX, SY, BAc, Add, PP, Sub, PP),
599     INST(mma, 0x4D89, AtNamed<Ax, 1>, SX, SY, SX, UY, BZr, Add, PP, Sub, PP),
600     INST(mma, 0xD59D, AtNamed<Bx, 5>, SX, SY, SX, UY, BZr, Add, PP, Sub, PP),
601     INST(mma, 0x5F24, AtNamed<Ab, 0>, SX, SY, SX, UY, BZr, Add, PP, Add, PP),
602     INST(mma, 0x8069, AtNamed<Ab, 8>, SX, SY, SX, UY, BAc, Add, PP, Add, PP),
603     INST(mma, 0x8079, AtNamed<Ab, 8>, SX, SY, SX, UY, BAc, Add, PP, Add, PA),
604     INST(mma, 0x8469, AtNamed<Ab, 8>, SX, SY, SX, UY, BAc, Sub, PP, Sub, PP),
605     INST(mma, 0x8479, AtNamed<Ab, 8>, SX, SY, SX, UY, BAc, Sub, PP, Sub, PA),
606     INST(mma, 0xD584, AtNamed<Ab, 0>, SX, SY, SX, UY, BAc, Add, PA, Add, PA),
607     INST(mma, 0xD5A0, AtNamed<Ab, 0>, SX, SY, SX, UY, BAc, Add, PP, Sub, PP),
608 
609     // [[[XXX_mm_XXX_mm_XXX]]]
610     INST(mma, 0xCA00, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, UX, SY, UX, SY, BAc, Sub, PP, Sub, PA),
611     INST(mma, 0xCA01, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, UX, SY, SX, UY, BAc, Sub, PP, Sub, PA),
612     INST(mma, 0xCA02, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, UX, SY, UX, SY, BAc, Sub, PA, Sub, PA),
613     INST(mma, 0xCA03, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, UX, SY, SX, UY, BAc, Sub, PA, Sub, PA),
614     INST(mma, 0xCA04, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, UX, SY, UX, SY, BAc, Add, PP, Add, PA),
615     INST(mma, 0xCA05, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, UX, SY, SX, UY, BAc, Add, PP, Add, PA),
616     INST(mma, 0xCA06, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, UX, SY, UX, SY, BAc, Add, PA, Add, PA),
617     INST(mma, 0xCA07, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, UX, SY, SX, UY, BAc, Add, PA, Add, PA),
618     INST(mma, 0xCB00, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, UX, SY, BAc, Sub, PP, Sub, PP),
619     INST(mma, 0xCB01, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, SX, UY, BAc, Sub, PP, Sub, PP),
620     INST(mma, 0xCB02, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, UX, SY, BAc, Sub, PP, Sub, PA),
621     INST(mma, 0xCB03, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, SX, UY, BAc, Sub, PP, Sub, PA),
622     INST(mma, 0xCB04, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, UX, SY, BAc, Add, PP, Add, PP),
623     INST(mma, 0xCB05, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, SX, UY, BAc, Add, PP, Add, PP),
624     INST(mma, 0xCB06, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, UX, SY, BAc, Add, PP, Add, PA),
625     INST(mma, 0xCB07, At<ArpRn1, 5>, At<ArpStep1, 3>, At<ArpStep1, 4>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, SX, UY, BAc, Add, PP, Add, PA),
626 
627     INST(mma, 0x0D30, At<ArpRn1, 3>, At<ArpStep1, 1>, At<ArpStep1, 2>, EMod, DMod, AtNamed<Ax, 0>, SX, SY, SX, UY, BAc, Add, PP, Add, PA),
628     INST(mma, 0x0D20, At<ArpRn1, 3>, At<ArpStep1, 1>, At<ArpStep1, 2>, DMod, EMod, AtNamed<Ax, 0>, SX, SY, SX, UY, BAc, Add, PP, Add, PA),
629     INST(mma, 0x4B50, At<ArpRn1, 3>, At<ArpStep1, 1>, At<ArpStep1, 2>, DMod, DMod, AtNamed<Ax, 0>, SX, SY, SX, UY, BAc, Add, PP, Add, PA),
630 
631     INST(mma, 0x9861, At<ArpRn1, 4>, At<ArpStep1, 2>, At<ArpStep1, 3>, EMod, DMod, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PP),
632     INST(mma, 0x9862, At<ArpRn1, 4>, At<ArpStep1, 2>, At<ArpStep1, 3>, DMod, EMod, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PP),
633     INST(mma, 0x9863, At<ArpRn1, 4>, At<ArpStep1, 2>, At<ArpStep1, 3>, DMod, DMod, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PP),
634 
635     INST(mma, 0x98E1, At<ArpRn1, 4>, At<ArpStep1, 2>, At<ArpStep1, 3>, EMod, DMod, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PA),
636     INST(mma, 0x98E2, At<ArpRn1, 4>, At<ArpStep1, 2>, At<ArpStep1, 3>, DMod, EMod, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PA),
637     INST(mma, 0x98E3, At<ArpRn1, 4>, At<ArpStep1, 2>, At<ArpStep1, 3>, DMod, DMod, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PA),
638 
639     INST(mma, 0x80C8, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, EMod, EMod, AtNamed<Ab, 10>, SX, SY, SX, SY, BAc, Add, PP, Sub, PP),
640     INST(mma, 0x81C8, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, EMod, EMod, AtNamed<Ab, 10>, SX, SY, SX, SY, BAc, Add, PP, Sub, PA),
641     INST(mma, 0x82C8, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, EMod, EMod, AtNamed<Ab, 10>, SX, SY, SX, SY, BZr, Add, PP, Add, PP),
642     INST(mma, 0x83C8, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, EMod, EMod, AtNamed<Ab, 10>, SX, SY, SX, SY, BZr, Add, PP, Add, PA),
643 
644     INST(mma, 0x80C2, At<ArpRn1, 0>, At<ArpStep1, 8>, At<ArpStep1, 9>, EMod, EMod, AtNamed<Ab, 10>, SX, SY, SX, SY, BAc, Add, PP, Add, PA),
645     INST(mma, 0x49C8, At<ArpRn1, 2>, At<ArpStep1, 0>, At<ArpStep1, 1>, EMod, EMod, AtNamed<Ab, 4>, SX, SY, SX, SY, BAc, Sub, PP, Sub, PA),
646     INST(mma, 0x00C0, At<ArpRn1, 3>, At<ArpStep1, 1>, At<ArpStep1, 2>, EMod, EMod, AtNamed<Ab, 4>, SX, SY, SX, SY, BZr, Add, PP, Sub, PP),
647     INST(mma, 0x00C1, At<ArpRn1, 3>, At<ArpStep1, 1>, At<ArpStep1, 2>, EMod, EMod, AtNamed<Ab, 4>, SX, SY, SX, SY, BZr, Add, PP, Sub, PA),
648     INST(mma, 0xD7A0, At<ArpRn1, 3>, At<ArpStep1, 1>, At<ArpStep1, 2>, EMod, EMod, AtNamed<Ax, 4>, SX, SY, SX, SY, BSv, Add, PP, Add, PP),
649     INST(mma, 0xD7A1, At<ArpRn1, 3>, At<ArpStep1, 1>, At<ArpStep1, 2>, EMod, EMod, AtNamed<Ax, 4>, SX, SY, SX, SY, BSr, Add, PP, Add, PP),
650 
651     INST(mma, 0xC800, At<ArpRn2, 4>, At<ArpStep2, 0>, At<ArpStep2, 2>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, SX, SY, BAc, Add, PP, Add, PP),
652     INST(mma, 0xC900, At<ArpRn2, 4>, At<ArpStep2, 0>, At<ArpStep2, 2>, EMod, EMod, AtNamed<Ab, 6>, SX, SY, SX, SY, BAc, Sub, PP, Sub, PP),
653 
654     // [[[XXX_mx_XXX_xy_XXX]]]
655     INST(mma_mx_xy, 0xD5E0, At<ArRn1, 1>, At<ArStep1, 0>, AtNamed<Ax, 3>, SX, SY, SX, SY, BAc, Sub, PP, Sub, PP),
656     INST(mma_mx_xy, 0xD5E4, At<ArRn1, 1>, At<ArStep1, 0>, AtNamed<Ax, 3>, SX, SY, SX, SY, BAc, Add, PP, Add, PP),
657 
658     // [[[XXX_xy_XXX_mx_XXX]]]
659     INST(mma_xy_mx, 0x8862, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Sub, PP, Sub, PP),
660     INST(mma_xy_mx, 0x8A62, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PP),
661 
662     // [[[XXX_my_XXX_my_XXX]]]
663     INST(mma_my_my, 0x4DA0, At<ArRn1, 3>, At<ArStep1, 2>, AtNamed<Ax, 4>, SX, SY, SX, UY, BAc, Sub, PP, Sub, PP),
664     INST(mma_my_my, 0x4DA1, At<ArRn1, 3>, At<ArStep1, 2>, AtNamed<Ax, 4>, SX, SY, SX, UY, BAc, Sub, PP, Sub, PA),
665     INST(mma_my_my, 0x4DA2, At<ArRn1, 3>, At<ArStep1, 2>, AtNamed<Ax, 4>, SX, SY, SX, UY, BAc, Add, PP, Add, PP),
666     INST(mma_my_my, 0x4DA3, At<ArRn1, 3>, At<ArStep1, 2>, AtNamed<Ax, 4>, SX, SY, SX, UY, BAc, Add, PP, Add, PA),
667 
668     INST(mma_my_my, 0x94E0, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Sub, PP, Sub, PP),
669     INST(mma_my_my, 0x94E1, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, UX, SY, BAc, Sub, PP, Sub, PP),
670     INST(mma_my_my, 0x94E2, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Sub, PP, Sub, PA),
671     INST(mma_my_my, 0x94E3, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, UX, SY, BAc, Sub, PP, Sub, PA),
672     INST(mma_my_my, 0x94E4, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PP),
673     INST(mma_my_my, 0x94E5, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, UX, SY, BAc, Add, PP, Add, PP),
674     INST(mma_my_my, 0x94E6, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, SX, SY, BAc, Add, PP, Add, PA),
675     INST(mma_my_my, 0x94E7, At<ArRn1, 4>, At<ArStep1, 3>, AtNamed<Ax, 8>, SX, SY, UX, SY, BAc, Add, PP, Add, PA),
676 
677     // [[[XXX_xy_XXX_xy_XXX_mov]]]
678     INST(mma_mov, 0x4FA0, At<Axh, 6>, At<Bxh, 2>, At<ArRn1, 1>, At<ArStep1, 0>, AtNamed<Ab, 3>, SX, SY, SX, SY, BAc, Add, PP, Add, PP),
679     INST(mma_mov, 0xD3A0, At<Axh, 6>, At<Bxh, 2>, At<ArRn1, 1>, At<ArStep1, 0>, AtNamed<Ab, 3>, SX, SY, SX, SY, BAc, Add, PP, Sub, PP),
680     INST(mma_mov, 0x80D0, At<Axh, 9>, At<Bxh, 8>, At<ArRn1, 3>, At<ArStep1, 2>, AtNamed<Ax, 10>, SX, SY, SX, SY, BSv, Add, PP, Sub, PP),
681     INST(mma_mov, 0x80D1, At<Axh, 9>, At<Bxh, 8>, At<ArRn1, 3>, At<ArStep1, 2>, AtNamed<Ax, 10>, SX, SY, SX, SY, BSr, Add, PP, Sub, PP),
682     INST(mma_mov, 0x80D2, At<Axh, 9>, At<Bxh, 8>, At<ArRn1, 3>, At<ArStep1, 2>, AtNamed<Ax, 10>, SX, SY, SX, SY, BSv, Add, PP, Add, PP),
683     INST(mma_mov, 0x80D3, At<Axh, 9>, At<Bxh, 8>, At<ArRn1, 3>, At<ArStep1, 2>, AtNamed<Ax, 10>, SX, SY, SX, SY, BSr, Add, PP, Add, PP),
684     INST(mma_mov, 0x5818, At<ArRn2, 7>, At<ArStep1, 6>, AtNamed<Ax, 0>, SX, SY, SX, SY, BSv, Add, PP, Sub, PP),
685     INST(mma_mov, 0x5838, At<ArRn2, 7>, At<ArStep1, 6>, AtNamed<Ax, 0>, SX, SY, SX, SY, BSr, Add, PP, Sub, PP),
686 
687     INST(addhp, 0x90E0, At<ArRn2, 2>, At<ArStep2, 0>, At<Px, 4>, At<Ax, 8>),
688     };
689 
690 #undef INST
691 #undef EXCEPT
692 }
693 
694 // clang-format on
695 
696 template <typename V>
697 Matcher<V> Decode(u16 instruction) {
698     static const auto table = GetDecodeTable<V>();
699 
700     const auto matches_instruction = [instruction](const auto& matcher) {
701         return matcher.Matches(instruction);
702     };
703 
704     auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
705     if (iter == table.end()) {
706         return Matcher<V>::AllMatcher([](V& v, u16 opcode, u16) { return v.undefined(opcode); });
707     } else {
708         auto other = std::find_if(iter + 1, table.end(), matches_instruction);
709         ASSERT(other == table.end());
710         return *iter;
711     }
712 }
713 
714 template <typename V>
715 std::vector<Matcher<V>> GetDecoderTable() {
716     std::vector<Matcher<V>> table;
717     table.reserve(0x10000);
718     for (u32 i = 0; i < 0x10000; ++i) {
719         table.push_back(Decode<V>((u16)i));
720     }
721     return table;
722 }
723