master
    1/// B1.2 Registers in AArch64 Execution state
    2pub const Register = struct {
    3    alias: Alias,
    4    format: Format,
    5
    6    pub const Format = union(enum) {
    7        alias: Format.Alias,
    8        general: GeneralSize,
    9        scalar: ScalarSize,
   10        vector: Arrangement,
   11        element: struct { size: ScalarSize, index: u4 },
   12        scalable,
   13
   14        pub const Alias = enum { general, other, vector, predicate };
   15    };
   16
   17    pub const GeneralSize = enum(u1) {
   18        word = 0b0,
   19        doubleword = 0b1,
   20
   21        pub fn prefix(gs: GeneralSize) u8 {
   22            return (comptime std.enums.EnumArray(GeneralSize, u8).init(.{
   23                .word = 'w',
   24                .doubleword = 'x',
   25            })).get(gs);
   26        }
   27    };
   28
   29    pub const ScalarSize = enum(u3) {
   30        byte = 0,
   31        half = 1,
   32        single = 2,
   33        double = 3,
   34        quad = 4,
   35
   36        pub fn n(ss: ScalarSize) ScalarSize {
   37            return @enumFromInt(@intFromEnum(ss) - 1);
   38        }
   39
   40        pub fn w(ss: ScalarSize) ScalarSize {
   41            return @enumFromInt(@intFromEnum(ss) + 1);
   42        }
   43
   44        pub fn prefix(ss: ScalarSize) u8 {
   45            return (comptime std.enums.EnumArray(ScalarSize, u8).init(.{
   46                .byte = 'b',
   47                .half = 'h',
   48                .single = 's',
   49                .double = 'd',
   50                .quad = 'q',
   51            })).get(ss);
   52        }
   53    };
   54
   55    pub const Arrangement = enum(u3) {
   56        @"2d" = @bitCast(Unwrapped{ .size = .quad, .elem_size = .double }),
   57        @"4s" = @bitCast(Unwrapped{ .size = .quad, .elem_size = .single }),
   58        @"8h" = @bitCast(Unwrapped{ .size = .quad, .elem_size = .half }),
   59        @"16b" = @bitCast(Unwrapped{ .size = .quad, .elem_size = .byte }),
   60
   61        @"1d" = @bitCast(Unwrapped{ .size = .double, .elem_size = .double }),
   62        @"2s" = @bitCast(Unwrapped{ .size = .double, .elem_size = .single }),
   63        @"4h" = @bitCast(Unwrapped{ .size = .double, .elem_size = .half }),
   64        @"8b" = @bitCast(Unwrapped{ .size = .double, .elem_size = .byte }),
   65
   66        pub const Unwrapped = packed struct {
   67            size: Instruction.DataProcessingVector.Q,
   68            elem_size: Instruction.DataProcessingVector.Size,
   69        };
   70        pub fn wrap(unwrapped: Unwrapped) Arrangement {
   71            return @enumFromInt(@as(@typeInfo(Arrangement).@"enum".tag_type, @bitCast(unwrapped)));
   72        }
   73        pub fn unwrap(arrangement: Arrangement) Unwrapped {
   74            return @bitCast(@intFromEnum(arrangement));
   75        }
   76
   77        pub fn len(arrangement: Arrangement) u5 {
   78            return switch (arrangement) {
   79                .@"1d" => 1,
   80                .@"2d", .@"2s" => 2,
   81                .@"4s", .@"4h" => 4,
   82                .@"8h", .@"8b" => 8,
   83                .@"16b" => 16,
   84            };
   85        }
   86
   87        pub fn size(arrangement: Arrangement) Instruction.DataProcessingVector.Q {
   88            return arrangement.unwrap().size;
   89        }
   90        pub fn elemSize(arrangement: Arrangement) Instruction.DataProcessingVector.Size {
   91            return arrangement.unwrap().elem_size;
   92        }
   93        pub fn elemSz(arrangement: Arrangement) Instruction.DataProcessingVector.Sz {
   94            return arrangement.elemSize().toSz();
   95        }
   96    };
   97
   98    pub const x0 = Alias.r0.x();
   99    pub const x1 = Alias.r1.x();
  100    pub const x2 = Alias.r2.x();
  101    pub const x3 = Alias.r3.x();
  102    pub const x4 = Alias.r4.x();
  103    pub const x5 = Alias.r5.x();
  104    pub const x6 = Alias.r6.x();
  105    pub const x7 = Alias.r7.x();
  106    pub const x8 = Alias.r8.x();
  107    pub const x9 = Alias.r9.x();
  108    pub const x10 = Alias.r10.x();
  109    pub const x11 = Alias.r11.x();
  110    pub const x12 = Alias.r12.x();
  111    pub const x13 = Alias.r13.x();
  112    pub const x14 = Alias.r14.x();
  113    pub const x15 = Alias.r15.x();
  114    pub const x16 = Alias.r16.x();
  115    pub const x17 = Alias.r17.x();
  116    pub const x18 = Alias.r18.x();
  117    pub const x19 = Alias.r19.x();
  118    pub const x20 = Alias.r20.x();
  119    pub const x21 = Alias.r21.x();
  120    pub const x22 = Alias.r22.x();
  121    pub const x23 = Alias.r23.x();
  122    pub const x24 = Alias.r24.x();
  123    pub const x25 = Alias.r25.x();
  124    pub const x26 = Alias.r26.x();
  125    pub const x27 = Alias.r27.x();
  126    pub const x28 = Alias.r28.x();
  127    pub const x29 = Alias.r29.x();
  128    pub const x30 = Alias.r30.x();
  129    pub const xzr = Alias.zr.x();
  130    pub const sp = Alias.sp.x();
  131
  132    pub const w0 = Alias.r0.w();
  133    pub const w1 = Alias.r1.w();
  134    pub const w2 = Alias.r2.w();
  135    pub const w3 = Alias.r3.w();
  136    pub const w4 = Alias.r4.w();
  137    pub const w5 = Alias.r5.w();
  138    pub const w6 = Alias.r6.w();
  139    pub const w7 = Alias.r7.w();
  140    pub const w8 = Alias.r8.w();
  141    pub const w9 = Alias.r9.w();
  142    pub const w10 = Alias.r10.w();
  143    pub const w11 = Alias.r11.w();
  144    pub const w12 = Alias.r12.w();
  145    pub const w13 = Alias.r13.w();
  146    pub const w14 = Alias.r14.w();
  147    pub const w15 = Alias.r15.w();
  148    pub const w16 = Alias.r16.w();
  149    pub const w17 = Alias.r17.w();
  150    pub const w18 = Alias.r18.w();
  151    pub const w19 = Alias.r19.w();
  152    pub const w20 = Alias.r20.w();
  153    pub const w21 = Alias.r21.w();
  154    pub const w22 = Alias.r22.w();
  155    pub const w23 = Alias.r23.w();
  156    pub const w24 = Alias.r24.w();
  157    pub const w25 = Alias.r25.w();
  158    pub const w26 = Alias.r26.w();
  159    pub const w27 = Alias.r27.w();
  160    pub const w28 = Alias.r28.w();
  161    pub const w29 = Alias.r29.w();
  162    pub const w30 = Alias.r30.w();
  163    pub const wzr = Alias.zr.w();
  164    pub const wsp = Alias.sp.w();
  165
  166    pub const ip = x16;
  167    pub const ip0 = x16;
  168    pub const ip1 = x17;
  169    pub const fp = x29;
  170    pub const lr = x30;
  171    pub const pc = Alias.pc.alias(.other);
  172
  173    pub const q0 = Alias.v0.q();
  174    pub const q1 = Alias.v1.q();
  175    pub const q2 = Alias.v2.q();
  176    pub const q3 = Alias.v3.q();
  177    pub const q4 = Alias.v4.q();
  178    pub const q5 = Alias.v5.q();
  179    pub const q6 = Alias.v6.q();
  180    pub const q7 = Alias.v7.q();
  181    pub const q8 = Alias.v8.q();
  182    pub const q9 = Alias.v9.q();
  183    pub const q10 = Alias.v10.q();
  184    pub const q11 = Alias.v11.q();
  185    pub const q12 = Alias.v12.q();
  186    pub const q13 = Alias.v13.q();
  187    pub const q14 = Alias.v14.q();
  188    pub const q15 = Alias.v15.q();
  189    pub const q16 = Alias.v16.q();
  190    pub const q17 = Alias.v17.q();
  191    pub const q18 = Alias.v18.q();
  192    pub const q19 = Alias.v19.q();
  193    pub const q20 = Alias.v20.q();
  194    pub const q21 = Alias.v21.q();
  195    pub const q22 = Alias.v22.q();
  196    pub const q23 = Alias.v23.q();
  197    pub const q24 = Alias.v24.q();
  198    pub const q25 = Alias.v25.q();
  199    pub const q26 = Alias.v26.q();
  200    pub const q27 = Alias.v27.q();
  201    pub const q28 = Alias.v28.q();
  202    pub const q29 = Alias.v29.q();
  203    pub const q30 = Alias.v30.q();
  204    pub const q31 = Alias.v31.q();
  205
  206    pub const d0 = Alias.v0.d();
  207    pub const d1 = Alias.v1.d();
  208    pub const d2 = Alias.v2.d();
  209    pub const d3 = Alias.v3.d();
  210    pub const d4 = Alias.v4.d();
  211    pub const d5 = Alias.v5.d();
  212    pub const d6 = Alias.v6.d();
  213    pub const d7 = Alias.v7.d();
  214    pub const d8 = Alias.v8.d();
  215    pub const d9 = Alias.v9.d();
  216    pub const d10 = Alias.v10.d();
  217    pub const d11 = Alias.v11.d();
  218    pub const d12 = Alias.v12.d();
  219    pub const d13 = Alias.v13.d();
  220    pub const d14 = Alias.v14.d();
  221    pub const d15 = Alias.v15.d();
  222    pub const d16 = Alias.v16.d();
  223    pub const d17 = Alias.v17.d();
  224    pub const d18 = Alias.v18.d();
  225    pub const d19 = Alias.v19.d();
  226    pub const d20 = Alias.v20.d();
  227    pub const d21 = Alias.v21.d();
  228    pub const d22 = Alias.v22.d();
  229    pub const d23 = Alias.v23.d();
  230    pub const d24 = Alias.v24.d();
  231    pub const d25 = Alias.v25.d();
  232    pub const d26 = Alias.v26.d();
  233    pub const d27 = Alias.v27.d();
  234    pub const d28 = Alias.v28.d();
  235    pub const d29 = Alias.v29.d();
  236    pub const d30 = Alias.v30.d();
  237    pub const d31 = Alias.v31.d();
  238
  239    pub const s0 = Alias.v0.s();
  240    pub const s1 = Alias.v1.s();
  241    pub const s2 = Alias.v2.s();
  242    pub const s3 = Alias.v3.s();
  243    pub const s4 = Alias.v4.s();
  244    pub const s5 = Alias.v5.s();
  245    pub const s6 = Alias.v6.s();
  246    pub const s7 = Alias.v7.s();
  247    pub const s8 = Alias.v8.s();
  248    pub const s9 = Alias.v9.s();
  249    pub const s10 = Alias.v10.s();
  250    pub const s11 = Alias.v11.s();
  251    pub const s12 = Alias.v12.s();
  252    pub const s13 = Alias.v13.s();
  253    pub const s14 = Alias.v14.s();
  254    pub const s15 = Alias.v15.s();
  255    pub const s16 = Alias.v16.s();
  256    pub const s17 = Alias.v17.s();
  257    pub const s18 = Alias.v18.s();
  258    pub const s19 = Alias.v19.s();
  259    pub const s20 = Alias.v20.s();
  260    pub const s21 = Alias.v21.s();
  261    pub const s22 = Alias.v22.s();
  262    pub const s23 = Alias.v23.s();
  263    pub const s24 = Alias.v24.s();
  264    pub const s25 = Alias.v25.s();
  265    pub const s26 = Alias.v26.s();
  266    pub const s27 = Alias.v27.s();
  267    pub const s28 = Alias.v28.s();
  268    pub const s29 = Alias.v29.s();
  269    pub const s30 = Alias.v30.s();
  270    pub const s31 = Alias.v31.s();
  271
  272    pub const h0 = Alias.v0.h();
  273    pub const h1 = Alias.v1.h();
  274    pub const h2 = Alias.v2.h();
  275    pub const h3 = Alias.v3.h();
  276    pub const h4 = Alias.v4.h();
  277    pub const h5 = Alias.v5.h();
  278    pub const h6 = Alias.v6.h();
  279    pub const h7 = Alias.v7.h();
  280    pub const h8 = Alias.v8.h();
  281    pub const h9 = Alias.v9.h();
  282    pub const h10 = Alias.v10.h();
  283    pub const h11 = Alias.v11.h();
  284    pub const h12 = Alias.v12.h();
  285    pub const h13 = Alias.v13.h();
  286    pub const h14 = Alias.v14.h();
  287    pub const h15 = Alias.v15.h();
  288    pub const h16 = Alias.v16.h();
  289    pub const h17 = Alias.v17.h();
  290    pub const h18 = Alias.v18.h();
  291    pub const h19 = Alias.v19.h();
  292    pub const h20 = Alias.v20.h();
  293    pub const h21 = Alias.v21.h();
  294    pub const h22 = Alias.v22.h();
  295    pub const h23 = Alias.v23.h();
  296    pub const h24 = Alias.v24.h();
  297    pub const h25 = Alias.v25.h();
  298    pub const h26 = Alias.v26.h();
  299    pub const h27 = Alias.v27.h();
  300    pub const h28 = Alias.v28.h();
  301    pub const h29 = Alias.v29.h();
  302    pub const h30 = Alias.v30.h();
  303    pub const h31 = Alias.v31.h();
  304
  305    pub const b0 = Alias.v0.b();
  306    pub const b1 = Alias.v1.b();
  307    pub const b2 = Alias.v2.b();
  308    pub const b3 = Alias.v3.b();
  309    pub const b4 = Alias.v4.b();
  310    pub const b5 = Alias.v5.b();
  311    pub const b6 = Alias.v6.b();
  312    pub const b7 = Alias.v7.b();
  313    pub const b8 = Alias.v8.b();
  314    pub const b9 = Alias.v9.b();
  315    pub const b10 = Alias.v10.b();
  316    pub const b11 = Alias.v11.b();
  317    pub const b12 = Alias.v12.b();
  318    pub const b13 = Alias.v13.b();
  319    pub const b14 = Alias.v14.b();
  320    pub const b15 = Alias.v15.b();
  321    pub const b16 = Alias.v16.b();
  322    pub const b17 = Alias.v17.b();
  323    pub const b18 = Alias.v18.b();
  324    pub const b19 = Alias.v19.b();
  325    pub const b20 = Alias.v20.b();
  326    pub const b21 = Alias.v21.b();
  327    pub const b22 = Alias.v22.b();
  328    pub const b23 = Alias.v23.b();
  329    pub const b24 = Alias.v24.b();
  330    pub const b25 = Alias.v25.b();
  331    pub const b26 = Alias.v26.b();
  332    pub const b27 = Alias.v27.b();
  333    pub const b28 = Alias.v28.b();
  334    pub const b29 = Alias.v29.b();
  335    pub const b30 = Alias.v30.b();
  336    pub const b31 = Alias.v31.b();
  337
  338    pub const fpcr = Alias.fpcr.alias(.other);
  339    pub const fpsr = Alias.fpsr.alias(.other);
  340
  341    pub const z0 = Alias.v0.z();
  342    pub const z1 = Alias.v1.z();
  343    pub const z2 = Alias.v2.z();
  344    pub const z3 = Alias.v3.z();
  345    pub const z4 = Alias.v4.z();
  346    pub const z5 = Alias.v5.z();
  347    pub const z6 = Alias.v6.z();
  348    pub const z7 = Alias.v7.z();
  349    pub const z8 = Alias.v8.z();
  350    pub const z9 = Alias.v9.z();
  351    pub const z10 = Alias.v10.z();
  352    pub const z11 = Alias.v11.z();
  353    pub const z12 = Alias.v12.z();
  354    pub const z13 = Alias.v13.z();
  355    pub const z14 = Alias.v14.z();
  356    pub const z15 = Alias.v15.z();
  357    pub const z16 = Alias.v16.z();
  358    pub const z17 = Alias.v17.z();
  359    pub const z18 = Alias.v18.z();
  360    pub const z19 = Alias.v19.z();
  361    pub const z20 = Alias.v20.z();
  362    pub const z21 = Alias.v21.z();
  363    pub const z22 = Alias.v22.z();
  364    pub const z23 = Alias.v23.z();
  365    pub const z24 = Alias.v24.z();
  366    pub const z25 = Alias.v25.z();
  367    pub const z26 = Alias.v26.z();
  368    pub const z27 = Alias.v27.z();
  369    pub const z28 = Alias.v28.z();
  370    pub const z29 = Alias.v29.z();
  371    pub const z30 = Alias.v30.z();
  372    pub const z31 = Alias.v31.z();
  373
  374    pub const p0 = Alias.p0.p();
  375    pub const p1 = Alias.p1.p();
  376    pub const p2 = Alias.p2.p();
  377    pub const p3 = Alias.p3.p();
  378    pub const p4 = Alias.p4.p();
  379    pub const p5 = Alias.p5.p();
  380    pub const p6 = Alias.p6.p();
  381    pub const p7 = Alias.p7.p();
  382    pub const p8 = Alias.p8.p();
  383    pub const p9 = Alias.p9.p();
  384    pub const p10 = Alias.p10.p();
  385    pub const p11 = Alias.p11.p();
  386    pub const p12 = Alias.p12.p();
  387    pub const p13 = Alias.p13.p();
  388    pub const p14 = Alias.p14.p();
  389    pub const p15 = Alias.p15.p();
  390
  391    pub const ffr = Alias.ffr.alias(.other);
  392
  393    pub const Encoded = enum(u5) {
  394        _,
  395
  396        pub fn decode(enc: Encoded, opts: struct { sp: bool = false, V: bool = false }) Alias {
  397            return switch (opts.V) {
  398                false => @enumFromInt(@intFromEnum(Alias.r0) + @intFromEnum(enc) +
  399                    @intFromBool(opts.sp and enc == comptime Alias.sp.encode(.{ .sp = true }))),
  400                true => @enumFromInt(@intFromEnum(Alias.v0) + @intFromEnum(enc)),
  401            };
  402        }
  403    };
  404
  405    /// One tag per set of aliasing registers.
  406    pub const Alias = enum(u7) {
  407        r0,
  408        r1,
  409        r2,
  410        r3,
  411        r4,
  412        r5,
  413        r6,
  414        r7,
  415        r8,
  416        r9,
  417        r10,
  418        r11,
  419        r12,
  420        r13,
  421        r14,
  422        r15,
  423        r16,
  424        r17,
  425        r18,
  426        r19,
  427        r20,
  428        r21,
  429        r22,
  430        r23,
  431        r24,
  432        r25,
  433        r26,
  434        r27,
  435        r28,
  436        r29,
  437        r30,
  438        zr,
  439        sp,
  440
  441        pc,
  442
  443        v0,
  444        v1,
  445        v2,
  446        v3,
  447        v4,
  448        v5,
  449        v6,
  450        v7,
  451        v8,
  452        v9,
  453        v10,
  454        v11,
  455        v12,
  456        v13,
  457        v14,
  458        v15,
  459        v16,
  460        v17,
  461        v18,
  462        v19,
  463        v20,
  464        v21,
  465        v22,
  466        v23,
  467        v24,
  468        v25,
  469        v26,
  470        v27,
  471        v28,
  472        v29,
  473        v30,
  474        v31,
  475
  476        fpcr,
  477        fpsr,
  478
  479        p0,
  480        p1,
  481        p2,
  482        p3,
  483        p4,
  484        p5,
  485        p6,
  486        p7,
  487        p8,
  488        p9,
  489        p10,
  490        p11,
  491        p12,
  492        p13,
  493        p14,
  494        p15,
  495
  496        ffr,
  497
  498        pub const ip: Alias = .r16;
  499        pub const ip0: Alias = .r16;
  500        pub const ip1: Alias = .r17;
  501        pub const fp: Alias = .r29;
  502        pub const lr: Alias = .r30;
  503
  504        pub fn alias(ra: Alias, fa: Format.Alias) Register {
  505            switch (fa) {
  506                .general => assert(@intFromEnum(ra) >= @intFromEnum(Alias.r0) and @intFromEnum(ra) <= @intFromEnum(Alias.sp)),
  507                .other => switch (ra) {
  508                    else => unreachable,
  509                    .pc, .fpcr, .fpsr, .ffr => {},
  510                },
  511                .vector => assert(@intFromEnum(ra) >= @intFromEnum(Alias.v0) and @intFromEnum(ra) <= @intFromEnum(Alias.v31)),
  512                .predicate => assert(@intFromEnum(ra) >= @intFromEnum(Alias.p0) and @intFromEnum(ra) <= @intFromEnum(Alias.p15)),
  513            }
  514            return .{ .alias = ra, .format = .{ .alias = fa } };
  515        }
  516        pub fn general(ra: Alias, gs: GeneralSize) Register {
  517            assert(@intFromEnum(ra) >= @intFromEnum(Alias.r0) and @intFromEnum(ra) <= @intFromEnum(Alias.sp));
  518            return .{ .alias = ra, .format = .{ .general = gs } };
  519        }
  520        pub fn scalar(ra: Alias, ss: ScalarSize) Register {
  521            assert(@intFromEnum(ra) >= @intFromEnum(Alias.v0) and @intFromEnum(ra) <= @intFromEnum(Alias.v31));
  522            return .{ .alias = ra, .format = .{ .scalar = ss } };
  523        }
  524        pub fn vector(ra: Alias, arrangement: Arrangement) Register {
  525            assert(@intFromEnum(ra) >= @intFromEnum(Alias.v0) and @intFromEnum(ra) <= @intFromEnum(Alias.v31));
  526            return .{ .alias = ra, .format = .{ .vector = arrangement } };
  527        }
  528        pub fn element(ra: Alias, ss: ScalarSize, index: u4) Register {
  529            assert(@intFromEnum(ra) >= @intFromEnum(Alias.v0) and @intFromEnum(ra) <= @intFromEnum(Alias.v31));
  530            return .{ .alias = ra, .format = .{ .element = .{ .size = ss, .index = index } } };
  531        }
  532        pub fn z(ra: Alias) Register {
  533            assert(@intFromEnum(ra) >= @intFromEnum(Alias.v0) and @intFromEnum(ra) <= @intFromEnum(Alias.v31));
  534            return .{ .alias = ra, .format = .scalable };
  535        }
  536        pub fn p(ra: Alias) Register {
  537            assert(@intFromEnum(ra) >= @intFromEnum(Alias.p0) and @intFromEnum(ra) <= @intFromEnum(Alias.p15));
  538            return .{ .alias = ra, .format = .{ .scalar = .predicate } };
  539        }
  540
  541        pub fn r(ra: Alias) Register {
  542            return ra.alias(.general);
  543        }
  544        pub fn x(ra: Alias) Register {
  545            return ra.general(.doubleword);
  546        }
  547        pub fn w(ra: Alias) Register {
  548            return ra.general(.word);
  549        }
  550        pub fn v(ra: Alias) Register {
  551            return ra.alias(.vector);
  552        }
  553        pub fn q(ra: Alias) Register {
  554            return ra.scalar(.quad);
  555        }
  556        pub fn d(ra: Alias) Register {
  557            return ra.scalar(.double);
  558        }
  559        pub fn s(ra: Alias) Register {
  560            return ra.scalar(.single);
  561        }
  562        pub fn h(ra: Alias) Register {
  563            return ra.scalar(.half);
  564        }
  565        pub fn b(ra: Alias) Register {
  566            return ra.scalar(.byte);
  567        }
  568        pub fn @"2d"(ra: Alias) Register {
  569            return ra.vector(.@"2d");
  570        }
  571        pub fn @"4s"(ra: Alias) Register {
  572            return ra.vector(.@"4s");
  573        }
  574        pub fn @"8h"(ra: Alias) Register {
  575            return ra.vector(.@"8h");
  576        }
  577        pub fn @"16b"(ra: Alias) Register {
  578            return ra.vector(.@"16b");
  579        }
  580        pub fn @"1d"(ra: Alias) Register {
  581            return ra.vector(.@"1d");
  582        }
  583        pub fn @"2s"(ra: Alias) Register {
  584            return ra.vector(.@"2s");
  585        }
  586        pub fn @"4h"(ra: Alias) Register {
  587            return ra.vector(.@"4h");
  588        }
  589        pub fn @"8b"(ra: Alias) Register {
  590            return ra.vector(.@"8b");
  591        }
  592        pub fn @"d[]"(ra: Alias, index: u1) Register {
  593            return ra.element(.double, index);
  594        }
  595        pub fn @"s[]"(ra: Alias, index: u2) Register {
  596            return ra.element(.single, index);
  597        }
  598        pub fn @"h[]"(ra: Alias, index: u3) Register {
  599            return ra.element(.half, index);
  600        }
  601        pub fn @"b[]"(ra: Alias, index: u4) Register {
  602            return ra.element(.byte, index);
  603        }
  604
  605        pub fn isVector(ra: Alias) bool {
  606            return switch (ra) {
  607                .r0,
  608                .r1,
  609                .r2,
  610                .r3,
  611                .r4,
  612                .r5,
  613                .r6,
  614                .r7,
  615                .r8,
  616                .r9,
  617                .r10,
  618                .r11,
  619                .r12,
  620                .r13,
  621                .r14,
  622                .r15,
  623                .r16,
  624                .r17,
  625                .r18,
  626                .r19,
  627                .r20,
  628                .r21,
  629                .r22,
  630                .r23,
  631                .r24,
  632                .r25,
  633                .r26,
  634                .r27,
  635                .r28,
  636                .r29,
  637                .r30,
  638                .zr,
  639                .sp,
  640
  641                .pc,
  642
  643                .fpcr,
  644                .fpsr,
  645
  646                .ffr,
  647                => false,
  648
  649                .v0,
  650                .v1,
  651                .v2,
  652                .v3,
  653                .v4,
  654                .v5,
  655                .v6,
  656                .v7,
  657                .v8,
  658                .v9,
  659                .v10,
  660                .v11,
  661                .v12,
  662                .v13,
  663                .v14,
  664                .v15,
  665                .v16,
  666                .v17,
  667                .v18,
  668                .v19,
  669                .v20,
  670                .v21,
  671                .v22,
  672                .v23,
  673                .v24,
  674                .v25,
  675                .v26,
  676                .v27,
  677                .v28,
  678                .v29,
  679                .v30,
  680                .v31,
  681
  682                .p0,
  683                .p1,
  684                .p2,
  685                .p3,
  686                .p4,
  687                .p5,
  688                .p6,
  689                .p7,
  690                .p8,
  691                .p9,
  692                .p10,
  693                .p11,
  694                .p12,
  695                .p13,
  696                .p14,
  697                .p15,
  698                => true,
  699            };
  700        }
  701
  702        pub fn encode(ra: Alias, comptime opts: struct { sp: bool = false, V: bool = false }) Encoded {
  703            return @enumFromInt(@as(u5, switch (ra) {
  704                .r0 => if (opts.V) unreachable else 0,
  705                .r1 => if (opts.V) unreachable else 1,
  706                .r2 => if (opts.V) unreachable else 2,
  707                .r3 => if (opts.V) unreachable else 3,
  708                .r4 => if (opts.V) unreachable else 4,
  709                .r5 => if (opts.V) unreachable else 5,
  710                .r6 => if (opts.V) unreachable else 6,
  711                .r7 => if (opts.V) unreachable else 7,
  712                .r8 => if (opts.V) unreachable else 8,
  713                .r9 => if (opts.V) unreachable else 9,
  714                .r10 => if (opts.V) unreachable else 10,
  715                .r11 => if (opts.V) unreachable else 11,
  716                .r12 => if (opts.V) unreachable else 12,
  717                .r13 => if (opts.V) unreachable else 13,
  718                .r14 => if (opts.V) unreachable else 14,
  719                .r15 => if (opts.V) unreachable else 15,
  720                .r16 => if (opts.V) unreachable else 16,
  721                .r17 => if (opts.V) unreachable else 17,
  722                .r18 => if (opts.V) unreachable else 18,
  723                .r19 => if (opts.V) unreachable else 19,
  724                .r20 => if (opts.V) unreachable else 20,
  725                .r21 => if (opts.V) unreachable else 21,
  726                .r22 => if (opts.V) unreachable else 22,
  727                .r23 => if (opts.V) unreachable else 23,
  728                .r24 => if (opts.V) unreachable else 24,
  729                .r25 => if (opts.V) unreachable else 25,
  730                .r26 => if (opts.V) unreachable else 26,
  731                .r27 => if (opts.V) unreachable else 27,
  732                .r28 => if (opts.V) unreachable else 28,
  733                .r29 => if (opts.V) unreachable else 29,
  734                .r30 => if (opts.V) unreachable else 30,
  735                .zr => if (opts.sp or opts.V) unreachable else 31,
  736                .sp => if (opts.sp and !opts.V) 31 else unreachable,
  737                .pc => unreachable,
  738                .v0 => if (opts.V) 0 else unreachable,
  739                .v1 => if (opts.V) 1 else unreachable,
  740                .v2 => if (opts.V) 2 else unreachable,
  741                .v3 => if (opts.V) 3 else unreachable,
  742                .v4 => if (opts.V) 4 else unreachable,
  743                .v5 => if (opts.V) 5 else unreachable,
  744                .v6 => if (opts.V) 6 else unreachable,
  745                .v7 => if (opts.V) 7 else unreachable,
  746                .v8 => if (opts.V) 8 else unreachable,
  747                .v9 => if (opts.V) 9 else unreachable,
  748                .v10 => if (opts.V) 10 else unreachable,
  749                .v11 => if (opts.V) 11 else unreachable,
  750                .v12 => if (opts.V) 12 else unreachable,
  751                .v13 => if (opts.V) 13 else unreachable,
  752                .v14 => if (opts.V) 14 else unreachable,
  753                .v15 => if (opts.V) 15 else unreachable,
  754                .v16 => if (opts.V) 16 else unreachable,
  755                .v17 => if (opts.V) 17 else unreachable,
  756                .v18 => if (opts.V) 18 else unreachable,
  757                .v19 => if (opts.V) 19 else unreachable,
  758                .v20 => if (opts.V) 20 else unreachable,
  759                .v21 => if (opts.V) 21 else unreachable,
  760                .v22 => if (opts.V) 22 else unreachable,
  761                .v23 => if (opts.V) 23 else unreachable,
  762                .v24 => if (opts.V) 24 else unreachable,
  763                .v25 => if (opts.V) 25 else unreachable,
  764                .v26 => if (opts.V) 26 else unreachable,
  765                .v27 => if (opts.V) 27 else unreachable,
  766                .v28 => if (opts.V) 28 else unreachable,
  767                .v29 => if (opts.V) 29 else unreachable,
  768                .v30 => if (opts.V) 30 else unreachable,
  769                .v31 => if (opts.V) 31 else unreachable,
  770                .fpcr, .fpsr => unreachable,
  771                .p0, .p1, .p2, .p3, .p4, .p5, .p6, .p7, .p8, .p9, .p10, .p11, .p12, .p13, .p14, .p15 => unreachable,
  772                .ffr => unreachable,
  773            }));
  774        }
  775    };
  776
  777    pub fn isVector(reg: Register) bool {
  778        return reg.alias.isVector();
  779    }
  780
  781    pub fn size(reg: Register) ?u5 {
  782        return format: switch (reg.format) {
  783            .alias => unreachable,
  784            .general => |sf| switch (sf) {
  785                .word => 4,
  786                .doubleword => 8,
  787            },
  788            .scalar => |elem_size| switch (elem_size) {
  789                .byte => 1,
  790                .half => 2,
  791                .single => 4,
  792                .double => 8,
  793                .quad => 16,
  794            },
  795            .vector => |arrangement| switch (arrangement) {
  796                .@"2d", .@"4s", .@"8h", .@"16b" => 16,
  797                .@"1d", .@"2s", .@"4h", .@"8b" => 8,
  798            },
  799            .element => |element| continue :format .{ .scalar = element.size },
  800            .scalable => null,
  801        };
  802    }
  803
  804    pub fn parse(reg: []const u8) ?Register {
  805        return if (reg.len == 0) null else switch (std.ascii.toLower(reg[0])) {
  806            else => null,
  807            'r' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| switch (n) {
  808                0...30 => .{
  809                    .alias = @enumFromInt(@intFromEnum(Alias.r0) + n),
  810                    .format = .{ .alias = .general },
  811                },
  812                31 => null,
  813            } else |_| null,
  814            'x' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| switch (n) {
  815                0...30 => .{
  816                    .alias = @enumFromInt(@intFromEnum(Alias.r0) + n),
  817                    .format = .{ .general = .doubleword },
  818                },
  819                31 => null,
  820            } else |_| if (toLowerEqlAssertLower(reg, "xzr")) .xzr else null,
  821            'w' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| switch (n) {
  822                0...30 => .{
  823                    .alias = @enumFromInt(@intFromEnum(Alias.r0) + n),
  824                    .format = .{ .general = .word },
  825                },
  826                31 => null,
  827            } else |_| if (toLowerEqlAssertLower(reg, "wzr"))
  828                .wzr
  829            else if (toLowerEqlAssertLower(reg, "wsp"))
  830                .wsp
  831            else
  832                null,
  833            'i' => return if (toLowerEqlAssertLower(reg, "ip") or toLowerEqlAssertLower(reg, "ip0"))
  834                .ip0
  835            else if (toLowerEqlAssertLower(reg, "ip1"))
  836                .ip1
  837            else
  838                null,
  839            'f' => return if (toLowerEqlAssertLower(reg, "fp")) .fp else null,
  840            'p' => return if (toLowerEqlAssertLower(reg, "pc")) .pc else null,
  841            'v' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{
  842                .alias = @enumFromInt(@intFromEnum(Alias.v0) + n),
  843                .format = .{ .alias = .vector },
  844            } else |_| null,
  845            'q' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{
  846                .alias = @enumFromInt(@intFromEnum(Alias.v0) + n),
  847                .format = .{ .scalar = .quad },
  848            } else |_| null,
  849            'd' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{
  850                .alias = @enumFromInt(@intFromEnum(Alias.v0) + n),
  851                .format = .{ .scalar = .double },
  852            } else |_| null,
  853            's' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{
  854                .alias = @enumFromInt(@intFromEnum(Alias.v0) + n),
  855                .format = .{ .scalar = .single },
  856            } else |_| if (toLowerEqlAssertLower(reg, "sp")) .sp else null,
  857            'h' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{
  858                .alias = @enumFromInt(@intFromEnum(Alias.v0) + n),
  859                .format = .{ .scalar = .half },
  860            } else |_| null,
  861            'b' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{
  862                .alias = @enumFromInt(@intFromEnum(Alias.v0) + n),
  863                .format = .{ .scalar = .byte },
  864            } else |_| null,
  865        };
  866    }
  867
  868    pub fn fmt(reg: Register) aarch64.Disassemble.RegisterFormatter {
  869        return reg.fmtCase(.lower);
  870    }
  871    pub fn fmtCase(reg: Register, case: aarch64.Disassemble.Case) aarch64.Disassemble.RegisterFormatter {
  872        return .{ .reg = reg, .case = case };
  873    }
  874
  875    pub const System = packed struct(u16) {
  876        op2: u3,
  877        CRm: u4,
  878        CRn: u4,
  879        op1: u3,
  880        op0: u2,
  881
  882        // D19.2 General system control registers
  883        /// D19.2.1 ACCDATA_EL1, Accelerator Data
  884        pub const accdata_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b101 };
  885        /// D19.2.2 ACTLR_EL1, Auxiliary Control Register (EL1)
  886        pub const actlr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b001 };
  887        /// D19.2.3 ACTLR_EL2, Auxiliary Control Register (EL2)
  888        pub const actlr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b001 };
  889        /// D19.2.4 ACTLR_EL3, Auxiliary Control Register (EL3)
  890        pub const actlr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b001 };
  891        /// D19.2.5 AFSR0_EL1, Auxiliary Fault Status Register 0 (EL1)
  892        pub const afsr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b000 };
  893        /// D19.2.5 AFSR0_EL12, Auxiliary Fault Status Register 0 (EL12)
  894        pub const afsr0_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b000 };
  895        /// D19.2.6 AFSR0_EL2, Auxiliary Fault Status Register 0 (EL2)
  896        pub const afsr0_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b000 };
  897        /// D19.2.7 AFSR0_EL3, Auxiliary Fault Status Register 0 (EL3)
  898        pub const afsr0_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b000 };
  899        /// D19.2.8 AFSR1_EL1, Auxiliary Fault Status Register 1 (EL1)
  900        pub const afsr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b001 };
  901        /// D19.2.8 AFSR1_EL12, Auxiliary Fault Status Register 1 (EL12)
  902        pub const afsr1_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b001 };
  903        /// D19.2.9 AFSR1_EL2, Auxiliary Fault Status Register 1 (EL2)
  904        pub const afsr1_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b001 };
  905        /// D19.2.10 AFSR1_EL3, Auxiliary Fault Status Register 1 (EL3)
  906        pub const afsr1_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b001 };
  907        /// D19.2.11 AIDR_EL1, Auxiliary ID Register
  908        pub const aidr_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b111 };
  909        /// D19.2.12 AMAIR_EL1, Auxiliary Memory Attribute Indirection Register (EL1)
  910        pub const amair_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0011, .op2 = 0b000 };
  911        /// D19.2.12 AMAIR_EL12, Auxiliary Memory Attribute Indirection Register (EL12)
  912        pub const amair_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1010, .CRm = 0b0011, .op2 = 0b000 };
  913        /// D19.2.13 AMAIR_EL2, Auxiliary Memory Attribute Indirection Register (EL2)
  914        pub const amair_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1010, .CRm = 0b0011, .op2 = 0b000 };
  915        /// D19.2.14 AMAIR_EL3, Auxiliary Memory Attribute Indirection Register (EL3)
  916        pub const amair_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1010, .CRm = 0b0011, .op2 = 0b000 };
  917        /// D19.2.15 APDAKeyHi_EL1, Pointer Authentication Key A for Data (bits[127:64])
  918        pub const apdakeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b001 };
  919        /// D19.2.16 APDAKeyLo_EL1, Pointer Authentication Key A for Data (bits[63:0])
  920        pub const apdakeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b000 };
  921        /// D19.2.17 APDBKeyHi_EL1, Pointer Authentication Key B for Data (bits[127:64])
  922        pub const apdbkeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b011 };
  923        /// D19.2.18 APDAKeyHi_EL1, Pointer Authentication Key B for Data (bits[63:0])
  924        pub const apdbkeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b010 };
  925        /// D19.2.19 APGAKeyHi_EL1, Pointer Authentication Key A for Code (bits[127:64])
  926        pub const apgakeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0011, .op2 = 0b001 };
  927        /// D19.2.20 APGAKeyLo_EL1, Pointer Authentication Key A for Code (bits[63:0])
  928        pub const apgakeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0011, .op2 = 0b000 };
  929        /// D19.2.21 APIAKeyHi_EL1, Pointer Authentication Key A for Instruction (bits[127:64])
  930        pub const apiakeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b001 };
  931        /// D19.2.22 APIAKeyLo_EL1, Pointer Authentication Key A for Instruction (bits[63:0])
  932        pub const apiakeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b000 };
  933        /// D19.2.23 APIBKeyHi_EL1, Pointer Authentication Key B for Instruction (bits[127:64])
  934        pub const apibkeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b011 };
  935        /// D19.2.24 APIBKeyLo_EL1, Pointer Authentication Key B for Instruction (bits[63:0])
  936        pub const apibkeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b010 };
  937        /// D19.2.25 CCSIDR2_EL1, Current Cache Size ID Register 2
  938        pub const ccsidr2_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b010 };
  939        /// D19.2.26 CCSIDR_EL1, Current Cache Size ID Register
  940        pub const ccsidr_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b000 };
  941        /// D19.2.27 CLIDR_EL1, Cache Level ID Register
  942        pub const clidr_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b001 };
  943        /// D19.2.28 CONTEXTIDR_EL1, Context ID Register (EL1)
  944        pub const contextidr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b001 };
  945        /// D19.2.28 CONTEXTIDR_EL12, Context ID Register (EL12)
  946        pub const contextidr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b001 };
  947        /// D19.2.29 CONTEXTIDR_EL2, Context ID Register (EL2)
  948        pub const contextidr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b001 };
  949        /// D19.2.30 CPACR_EL1, Architectural Feature Access Control Register
  950        pub const cpacr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b010 };
  951        /// D19.2.30 CPACR_EL12, Architectural Feature Access Control Register
  952        pub const cpacr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b010 };
  953        /// D19.2.31 CPACR_EL2, Architectural Feature Trap Register (EL2)
  954        pub const cptr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b010 };
  955        /// D19.2.32 CPACR_EL3, Architectural Feature Trap Register (EL3)
  956        pub const cptr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b010 };
  957        /// D19.2.33 CSSELR_EL1, Cache Size Selection Register
  958        pub const csselr_el1: System = .{ .op0 = 0b11, .op1 = 0b010, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b000 };
  959        /// D19.2.34 CTR_EL0, Cache Type Register
  960        pub const ctr_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b001 };
  961        /// D19.2.35 DACR32_EL2, Domain Access Control Register
  962        pub const dacr32_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0011, .CRm = 0b0000, .op2 = 0b000 };
  963        /// D19.2.36 DCZID_EL0, Data Cache Zero ID Register
  964        pub const dczid_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b111 };
  965        /// D19.2.37 ESR_EL1, Exception Syndrome Register (EL1)
  966        pub const esr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0010, .op2 = 0b000 };
  967        /// D19.2.37 ESR_EL12, Exception Syndrome Register (EL12)
  968        pub const esr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0101, .CRm = 0b0010, .op2 = 0b000 };
  969        /// D19.2.38 ESR_EL2, Exception Syndrome Register (EL2)
  970        pub const esr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0010, .op2 = 0b000 };
  971        /// D19.2.39 ESR_EL3, Exception Syndrome Register (EL3)
  972        pub const esr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0101, .CRm = 0b0010, .op2 = 0b000 };
  973        /// D19.2.40 FAR_EL1, Fault Address Register (EL1)
  974        pub const far_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b000 };
  975        /// D19.2.40 FAR_EL12, Fault Address Register (EL12)
  976        pub const far_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b000 };
  977        /// D19.2.41 FAR_EL2, Fault Address Register (EL2)
  978        pub const far_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b000 };
  979        /// D19.2.42 FAR_EL3, Fault Address Register (EL3)
  980        pub const far_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b000 };
  981        /// D19.2.43 FPEXC32_EL2, Floating-Point Exception Control Register
  982        pub const fpexc32_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0011, .op2 = 0b000 };
  983        /// D19.2.44 GCR_EL1, Tag Control Register
  984        pub const gcr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b110 };
  985        /// D19.2.45 GMID_EL1, Tag Control Register
  986        pub const gmid_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b100 };
  987        /// D19.2.46 HACR_EL2, Hypervisor Auxiliary Control Register
  988        pub const hacr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b111 };
  989        /// D19.2.47 HAFGRTR_EL2, Hypervisor Activity Monitors Fine-Grained Read Trap Register
  990        pub const hafgrtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0011, .CRm = 0b0001, .op2 = 0b110 };
  991        /// D19.2.48 HCR_EL2, Hypervisor Configuration Register
  992        pub const hcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b000 };
  993        /// D19.2.49 HCRX_EL2, Extended Hypervisor Configuration Register
  994        pub const hcrx_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b010 };
  995        /// D19.2.50 HDFGRTR_EL2, Hypervisor Debug Fine-Grained Read Trap Register
  996        pub const hdfgrtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0011, .CRm = 0b0001, .op2 = 0b100 };
  997        /// D19.2.51 HDFGWTR_EL2, Hypervisor Debug Fine-Grained Write Trap Register
  998        pub const hdfgwtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0011, .CRm = 0b0001, .op2 = 0b101 };
  999        /// D19.2.52 HFGITR_EL2, Hypervisor Fine-Grained Instruction Trap Register
 1000        pub const hfgitr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b110 };
 1001        /// D19.2.53 HFGRTR_EL2, Hypervisor Fine-Grained Read Trap Register
 1002        pub const hfgrtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b100 };
 1003        /// D19.2.54 HFGWTR_EL2, Hypervisor Fine-Grained Write Trap Register
 1004        pub const hfgwtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b101 };
 1005        /// D19.2.55 HPFAR_EL2, Hypervisor IPA Fault Address Register
 1006        pub const hpfar_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b100 };
 1007        /// D19.2.56 HSTR_EL2, Hypervisor System Trap Register
 1008        pub const hstr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b011 };
 1009        /// D19.2.57 ID_AA64AFR0_EL1, AArch64 Auxiliary Feature Register 0
 1010        pub const id_aa64afr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0101, .op2 = 0b100 };
 1011        /// D19.2.58 ID_AA64AFR1_EL1, AArch64 Auxiliary Feature Register 1
 1012        pub const id_aa64afr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0101, .op2 = 0b101 };
 1013        /// D19.2.59 ID_AA64DFR0_EL1, AArch64 Debug Feature Register 0
 1014        pub const id_aa64dfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0101, .op2 = 0b000 };
 1015        /// D19.2.60 ID_AA64DFR1_EL1, AArch64 Debug Feature Register 1
 1016        pub const id_aa64dfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0101, .op2 = 0b001 };
 1017        /// D19.2.61 ID_AA64ISAR0_EL1, AArch64 Instruction Set Attribute Register 0
 1018        pub const id_aa64isar0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0110, .op2 = 0b000 };
 1019        /// D19.2.62 ID_AA64ISAR1_EL1, AArch64 Instruction Set Attribute Register 1
 1020        pub const id_aa64isar1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0110, .op2 = 0b001 };
 1021        /// D19.2.63 ID_AA64ISAR2_EL1, AArch64 Instruction Set Attribute Register 2
 1022        pub const id_aa64isar2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0110, .op2 = 0b010 };
 1023        /// D19.2.64 ID_AA64MMFR0_EL1, AArch64 Memory Model Feature Register 0
 1024        pub const id_aa64mmfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b000 };
 1025        /// D19.2.65 ID_AA64MMFR1_EL1, AArch64 Memory Model Feature Register 1
 1026        pub const id_aa64mmfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b001 };
 1027        /// D19.2.66 ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2
 1028        pub const id_aa64mmfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b010 };
 1029        /// D19.2.67 ID_AA64MMFR3_EL1, AArch64 Memory Model Feature Register 3
 1030        pub const id_aa64mmfr3_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b011 };
 1031        /// D19.2.68 ID_AA64MMFR4_EL1, AArch64 Memory Model Feature Register 4
 1032        pub const id_aa64mmfr4_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b100 };
 1033        /// D19.2.69 ID_AA64PFR0_EL1, AArch64 Processor Feature Register 0
 1034        pub const id_aa64pfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b000 };
 1035        /// D19.2.70 ID_AA64PFR1_EL1, AArch64 Processor Feature Register 1
 1036        pub const id_aa64pfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b001 };
 1037        /// D19.2.71 ID_AA64PFR2_EL1, AArch64 Processor Feature Register 2
 1038        pub const id_aa64pfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b010 };
 1039        /// D19.2.72 ID_AA64SMFR0_EL1, SME Feature ID Register 0
 1040        pub const id_aa64smfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b101 };
 1041        /// D19.2.73 ID_AA64ZFR0_EL1, SVE Feature ID Register 0
 1042        pub const id_aa64zfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b100 };
 1043        /// D19.2.74 ID_AFR0_EL1, AArch32 Auxiliary Feature Register 0
 1044        pub const id_afr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b011 };
 1045        /// D19.2.75 ID_DFR0_EL1, AArch32 Debug Feature Register 0
 1046        pub const id_dfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b010 };
 1047        /// D19.2.76 ID_DFR1_EL1, AArch32 Debug Feature Register 1
 1048        pub const id_dfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b101 };
 1049        /// D19.2.77 ID_ISAR0_EL1, AArch32 Instruction Set Attribute Register 0
 1050        pub const id_isar0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b000 };
 1051        /// D19.2.78 ID_ISAR1_EL1, AArch32 Instruction Set Attribute Register 1
 1052        pub const id_isar1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b001 };
 1053        /// D19.2.79 ID_ISAR2_EL1, AArch32 Instruction Set Attribute Register 2
 1054        pub const id_isar2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b010 };
 1055        /// D19.2.80 ID_ISAR3_EL1, AArch32 Instruction Set Attribute Register 3
 1056        pub const id_isar3_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b011 };
 1057        /// D19.2.81 ID_ISAR4_EL1, AArch32 Instruction Set Attribute Register 4
 1058        pub const id_isar4_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b100 };
 1059        /// D19.2.82 ID_ISAR5_EL1, AArch32 Instruction Set Attribute Register 5
 1060        pub const id_isar5_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b101 };
 1061        /// D19.2.83 ID_ISAR6_EL1, AArch32 Instruction Set Attribute Register 6
 1062        pub const id_isar6_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b111 };
 1063        /// D19.2.84 ID_MMFR0_EL1, AArch32 Memory Model Feature Register 0
 1064        pub const id_mmfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b100 };
 1065        /// D19.2.85 ID_MMFR1_EL1, AArch32 Memory Model Feature Register 1
 1066        pub const id_mmfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b101 };
 1067        /// D19.2.86 ID_MMFR2_EL1, AArch32 Memory Model Feature Register 2
 1068        pub const id_mmfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b110 };
 1069        /// D19.2.87 ID_MMFR3_EL1, AArch32 Memory Model Feature Register 3
 1070        pub const id_mmfr3_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b111 };
 1071        /// D19.2.88 ID_MMFR4_EL1, AArch32 Memory Model Feature Register 4
 1072        pub const id_mmfr4_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b110 };
 1073        /// D19.2.89 ID_MMFR5_EL1, AArch32 Memory Model Feature Register 5
 1074        pub const id_mmfr5_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b110 };
 1075        /// D19.2.90 ID_PFR0_EL1, AArch32 Processor Feature Register 0
 1076        pub const id_pfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b000 };
 1077        /// D19.2.91 ID_PFR1_EL1, AArch32 Processor Feature Register 1
 1078        pub const id_pfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b001 };
 1079        /// D19.2.92 ID_PFR2_EL1, AArch32 Processor Feature Register 2
 1080        pub const id_pfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b100 };
 1081        /// D19.2.93 IFSR32_EL2, Instruction Fault Status Register (EL2)
 1082        pub const ifsr32_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0000, .op2 = 0b001 };
 1083        /// D19.2.94 ISR_EL1, Interrupt Status Register
 1084        pub const isr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1100, .CRm = 0b0001, .op2 = 0b000 };
 1085        /// D19.2.95 LORC_EL1, LORegion Control (EL1)
 1086        pub const lorc_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b011 };
 1087        /// D19.2.96 LOREA_EL1, LORegion End Address (EL1)
 1088        pub const lorea_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b001 };
 1089        /// D19.2.97 SORID_EL1, LORegionID (EL1)
 1090        pub const lorid_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b111 };
 1091        /// D19.2.98 LORN_EL1, LORegion Number (EL1)
 1092        pub const lorn_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b010 };
 1093        /// D19.2.99 LORSA_EL1, LORegion Start Address (EL1)
 1094        pub const lorsa_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b000 };
 1095        /// D19.2.100 MAIR_EL1, Memory Attribute Indirection Register (EL1)
 1096        pub const mair_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0010, .op2 = 0b000 };
 1097        /// D19.2.100 MAIR_EL12, Memory Attribute Indirection Register (EL12)
 1098        pub const mair_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1010, .CRm = 0b0010, .op2 = 0b000 };
 1099        /// D19.2.101 MAIR_EL2, Memory Attribute Indirection Register (EL2)
 1100        pub const mair_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1010, .CRm = 0b0010, .op2 = 0b000 };
 1101        /// D19.2.102 MAIR_EL3, Memory Attribute Indirection Register (EL3)
 1102        pub const mair_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1010, .CRm = 0b0010, .op2 = 0b000 };
 1103        /// D19.2.103 MIDR_EL1, Main ID Register
 1104        pub const midr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b000 };
 1105        /// D19.2.104 MPIDR_EL1, Multiprocessor Affinity Register
 1106        pub const mpidr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b101 };
 1107        /// D19.2.105 MVFR0_EL1, AArch32 Media and VFP Feature Register 0
 1108        pub const mvfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b000 };
 1109        /// D19.2.106 MVFR1_EL1, AArch32 Media and VFP Feature Register 1
 1110        pub const mvfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b001 };
 1111        /// D19.2.107 MVFR2_EL1, AArch32 Media and VFP Feature Register 2
 1112        pub const mvfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b010 };
 1113        /// D19.2.108 PAR_EL1, Physical Address Register
 1114        pub const par_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0111, .CRm = 0b0100, .op2 = 0b000 };
 1115        /// D19.2.109 REVIDR_EL1, Revision ID Register
 1116        pub const revidr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b110 };
 1117        /// D19.2.110 RGSR_EL1, Random Allocation Tag Seed Register
 1118        pub const rgsr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b101 };
 1119        /// D19.2.111 RMR_EL1, Reset Management Register (EL1)
 1120        pub const rmr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b010 };
 1121        /// D19.2.112 RMR_EL2, Reset Management Register (EL2)
 1122        pub const rmr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b010 };
 1123        /// D19.2.113 RMR_EL3, Reset Management Register (EL3)
 1124        pub const rmr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b010 };
 1125        /// D19.2.114 RNDR, Random Number
 1126        pub const rndr: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b0010, .CRm = 0b0100, .op2 = 0b000 };
 1127        /// D19.2.115 RNDRRS, Reseeded Random Number
 1128        pub const rndrrs: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b0010, .CRm = 0b0100, .op2 = 0b001 };
 1129        /// D19.2.116 RVBAR_EL1, Reset Vector Base Address Register (if EL2 and EL3 not implemented)
 1130        pub const rvbar_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b001 };
 1131        /// D19.2.117 RVBAR_EL2, Reset Vector Base Address Register (if EL3 not implemented)
 1132        pub const rvbar_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b001 };
 1133        /// D19.2.118 RVBAR_EL3, Reset Vector Base Address Register (if EL3 implemented)
 1134        pub const rvbar_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b001 };
 1135        /// D19.2.120 SCR_EL3, Secure Configuration Register
 1136        pub const scr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b000 };
 1137        /// D19.2.121 SCTLR2_EL1, System Control Register (EL1)
 1138        pub const sctlr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b011 };
 1139        /// D19.2.121 SCTLR2_EL12, System Control Register (EL12)
 1140        pub const sctlr2_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b011 };
 1141        /// D19.2.122 SCTLR2_EL2, System Control Register (EL2)
 1142        pub const sctlr2_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b011 };
 1143        /// D19.2.123 SCTLR2_EL3, System Control Register (EL3)
 1144        pub const sctlr2_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b011 };
 1145        /// D19.2.124 SCTLR_EL1, System Control Register (EL1)
 1146        pub const sctlr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b000 };
 1147        /// D19.2.124 SCTLR_EL12, System Control Register (EL12)
 1148        pub const sctlr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b000 };
 1149        /// D19.2.125 SCTLR_EL2, System Control Register (EL2)
 1150        pub const sctlr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b000 };
 1151        /// D19.2.126 SCTLR_EL3, System Control Register (EL3)
 1152        pub const sctlr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b000 };
 1153        /// D19.2.127 SCXTNUM_EL0, EL0 Read/Write Software Context Number
 1154        pub const scxtnum_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 };
 1155        /// D19.2.128 SCXTNUM_EL1, EL1 Read/Write Software Context Number
 1156        pub const scxtnum_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 };
 1157        /// D19.2.128 SCXTNUM_EL12, EL12 Read/Write Software Context Number
 1158        pub const scxtnum_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 };
 1159        /// D19.2.129 SCXTNUM_EL2, EL2 Read/Write Software Context Number
 1160        pub const scxtnum_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 };
 1161        /// D19.2.130 SCXTNUM_EL3, EL3 Read/Write Software Context Number
 1162        pub const scxtnum_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 };
 1163        /// D19.2.131 SMCR_EL1, SME Control Register (EL1)
 1164        pub const smcr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b110 };
 1165        /// D19.2.131 SMCR_EL12, SME Control Register (EL12)
 1166        pub const smcr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b110 };
 1167        /// D19.2.132 SMCR_EL2, SME Control Register (EL2)
 1168        pub const smcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b110 };
 1169        /// D19.2.133 SMCR_EL3, SME Control Register (EL3)
 1170        pub const smcr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b110 };
 1171        /// D19.2.134 SMIDR_EL1, Streaming Mode Identification Register
 1172        pub const smidr_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b110 };
 1173        /// D19.2.135 SMPRIMAP_EL2, Streaming Mode Priority Mapping Register
 1174        pub const smprimap_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b101 };
 1175        /// D19.2.136 SMPRI_EL1, Streaming Mode Priority Register
 1176        pub const smpri_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b100 };
 1177        /// D19.2.137 TCR2_EL1, Extended Translation Control Register (EL1)
 1178        pub const tcr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b011 };
 1179        /// D19.2.137 TCR2_EL12, Extended Translation Control Register (EL12)
 1180        pub const tcr2_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b011 };
 1181        /// D19.2.138 TCR2_EL2, Extended Translation Control Register (EL2)
 1182        pub const tcr2_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b011 };
 1183        /// D19.2.139 TCR_EL1, Translation Control Register (EL1)
 1184        pub const tcr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b010 };
 1185        /// D19.2.139 TCR_EL12, Translation Control Register (EL12)
 1186        pub const tcr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b010 };
 1187        /// D19.2.140 TCR_EL2, Translation Control Register (EL2)
 1188        pub const tcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b010 };
 1189        /// D19.2.141 TCR_EL3, Translation Control Register (EL3)
 1190        pub const tcr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b010 };
 1191        /// D19.2.142 TFSRE0_EL1, Tag Fault Status Register (EL0)
 1192        pub const tfsre0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b001 };
 1193        /// D19.2.143 TFSR_EL1, Tag Fault Status Register (EL1)
 1194        pub const tfsr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b000 };
 1195        /// D19.2.143 TFSR_EL12, Tag Fault Status Register (EL12)
 1196        pub const tfsr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b000 };
 1197        /// D19.2.144 TFSR_EL2, Tag Fault Status Register (EL2)
 1198        pub const tfsr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b000 };
 1199        /// D19.2.145 TFSR_EL3, Tag Fault Status Register (EL3)
 1200        pub const tfsr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b000 };
 1201        /// D19.2.146 TPIDR2_EL0, EL0 Read/Write Software Thread ID Register 2
 1202        pub const tpidr2_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b101 };
 1203        /// D19.2.147 TPIDR_EL0, EL0 Read/Write Software Thread ID Register
 1204        pub const tpidr_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b010 };
 1205        /// D19.2.148 TPIDR_EL1, EL1 Read/Write Software Thread ID Register
 1206        pub const tpidr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b100 };
 1207        /// D19.2.149 TPIDR_EL2, EL2 Read/Write Software Thread ID Register
 1208        pub const tpidr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b010 };
 1209        /// D19.2.150 TPIDR_EL3, EL3 Read/Write Software Thread ID Register
 1210        pub const tpidr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b010 };
 1211        /// D19.2.151 TPIDRRO_EL0, EL0 Read-Only Software Thread ID Register
 1212        pub const tpidrro_el3: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b011 };
 1213        /// D19.2.152 TTBR0_EL1, Translation Table Base Register 0 (EL1)
 1214        pub const ttbr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b000 };
 1215        /// D19.2.152 TTBR0_EL12, Translation Table Base Register 0 (EL12)
 1216        pub const ttbr0_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b000 };
 1217        /// D19.2.153 TTBR0_EL2, Translation Table Base Register 0 (EL2)
 1218        pub const ttbr0_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b000 };
 1219        /// D19.2.154 TTBR0_EL3, Translation Table Base Register 0 (EL3)
 1220        pub const ttbr0_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b000 };
 1221        /// D19.2.155 TTBR1_EL1, Translation Table Base Register 1 (EL1)
 1222        pub const ttbr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b001 };
 1223        /// D19.2.155 TTBR1_EL12, Translation Table Base Register 1 (EL12)
 1224        pub const ttbr1_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b001 };
 1225        /// D19.2.156 TTBR1_EL2, Translation Table Base Register 1 (EL2)
 1226        pub const ttbr1_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b001 };
 1227        /// D19.2.157 VBAR_EL1, Vector Base Address Register (EL1)
 1228        pub const vbar_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b000 };
 1229        /// D19.2.157 VBAR_EL12, Vector Base Address Register (EL12)
 1230        pub const vbar_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b000 };
 1231        /// D19.2.158 VBAR_EL2, Vector Base Address Register (EL2)
 1232        pub const vbar_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b000 };
 1233        /// D19.2.159 VBAR_EL3, Vector Base Address Register (EL3)
 1234        pub const vbar_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b000 };
 1235        /// D19.2.160 VMPIDR_EL2, Virtualization Multiprocessor ID Register
 1236        pub const vmpidr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b101 };
 1237        /// D19.2.161 VNCR_EL2, Virtual Nested Control Register
 1238        pub const nvcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b000 };
 1239        /// D19.2.162 VPIDR_EL2, Virtualization Processor ID Register
 1240        pub const vpidr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b000 };
 1241        /// D19.2.163 VSTCR_EL2, Virtualization Secure Translation Control Register
 1242        pub const vstcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0110, .op2 = 0b010 };
 1243        /// D19.2.164 VSTTBR_EL2, Virtualization Secure Translation Table Base Register
 1244        pub const vsttbr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0110, .op2 = 0b000 };
 1245        /// D19.2.165 VTCR_EL2, Virtualization Translation Control Register
 1246        pub const vtcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b010 };
 1247        /// D19.2.166 VTTBR_EL2, Virtualization Translation Table Base Register
 1248        pub const vttbr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b000 };
 1249        /// D19.2.167 ZCR_EL1, SVE Control Register (EL1)
 1250        pub const zcr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b000 };
 1251        /// D19.2.167 ZCR_EL12, SVE Control Register (EL12)
 1252        pub const zcr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b000 };
 1253        /// D19.2.168 ZCR_EL2, SVE Control Register (EL2)
 1254        pub const zcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b000 };
 1255        /// D19.2.169 ZCR_EL3, SVE Control Register (EL3)
 1256        pub const zcr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b000 };
 1257
 1258        pub fn parse(reg: []const u8) ?System {
 1259            if (reg.len >= 10 and std.ascii.toLower(reg[0]) == 's') encoded: {
 1260                var symbol_it = std.mem.splitScalar(u8, reg[1..], '_');
 1261                const op0 = std.fmt.parseInt(u2, symbol_it.next() orelse break :encoded, 10) catch break :encoded;
 1262                if (op0 < 0b10) break :encoded;
 1263                const op1 = std.fmt.parseInt(u3, symbol_it.next() orelse break :encoded, 10) catch break :encoded;
 1264                const n = symbol_it.next() orelse break :encoded;
 1265                if (n.len == 0 or std.ascii.toLower(n[0]) != 'c') break :encoded;
 1266                const CRn = std.fmt.parseInt(u4, n[1..], 10) catch break :encoded;
 1267                const m = symbol_it.next() orelse break :encoded;
 1268                if (m.len == 0 or std.ascii.toLower(m[0]) != 'c') break :encoded;
 1269                const CRm = std.fmt.parseInt(u4, m[1..], 10) catch break :encoded;
 1270                const op2 = std.fmt.parseInt(u3, symbol_it.next() orelse break :encoded, 10) catch break :encoded;
 1271                if (symbol_it.next() != null) break :encoded;
 1272                return .{ .op0 = op0, .op1 = op1, .CRn = CRn, .CRm = CRm, .op2 = op2 };
 1273            }
 1274            inline for (@typeInfo(System).@"struct".decls) |decl| {
 1275                if (@TypeOf(@field(System, decl.name)) != System) continue;
 1276                if (toLowerEqlAssertLower(reg, decl.name)) return @field(System, decl.name);
 1277            }
 1278            return null;
 1279        }
 1280    };
 1281
 1282    fn toLowerEqlAssertLower(lhs: []const u8, rhs: []const u8) bool {
 1283        if (lhs.len != rhs.len) return false;
 1284        for (lhs, rhs) |l, r| {
 1285            assert(!std.ascii.isUpper(r));
 1286            if (std.ascii.toLower(l) != r) return false;
 1287        }
 1288        return true;
 1289    }
 1290};
 1291
 1292/// C1.2.4 Condition code
 1293pub const ConditionCode = enum(u4) {
 1294    /// integer: Equal
 1295    /// floating-point: Equal
 1296    /// Z == 1
 1297    eq = 0b0000,
 1298    /// integer: Not equal
 1299    /// floating-point: Not equal or unordered
 1300    /// Z == 0
 1301    ne = 0b0001,
 1302    /// integer: Unsigned higher or same
 1303    /// floating-point: Greater than, equal, or unordered
 1304    /// C == 1
 1305    hs = 0b0010,
 1306    /// integer: Unsigned lower
 1307    /// floating-point: Less than
 1308    /// C == 0
 1309    lo = 0b0011,
 1310    /// integer: Minus, negative
 1311    /// floating-point: Less than
 1312    /// N == 1
 1313    mi = 0b0100,
 1314    /// integer: Plus, positive or zero
 1315    /// floating-point: Greater than, equal, or unordered
 1316    /// N == 0
 1317    pl = 0b0101,
 1318    /// integer: Overflow
 1319    /// floating-point: Unordered
 1320    /// V == 1
 1321    vs = 0b0110,
 1322    /// integer: No overflow
 1323    /// floating-point: Ordered
 1324    /// V == 0
 1325    vc = 0b0111,
 1326    /// integer: Unsigned higher
 1327    /// floating-point: Greater than, or unordered
 1328    /// C == 1 and Z == 0
 1329    hi = 0b1000,
 1330    /// integer: Unsigned lower or same
 1331    /// floating-point: Less than or equal
 1332    /// C == 0 or Z == 1
 1333    ls = 0b1001,
 1334    /// integer: Signed greater than or equal
 1335    /// floating-point: Greater than or equal
 1336    /// N == V
 1337    ge = 0b1010,
 1338    /// integer: Signed less than
 1339    /// floating-point: Less than, or unordered
 1340    /// N != V
 1341    lt = 0b1011,
 1342    /// integer: Signed greater than
 1343    /// floating-point: Greater than
 1344    /// Z == 0 and N == V
 1345    gt = 0b1100,
 1346    /// integer: Signed less than or equal
 1347    /// floating-point: Less than, equal, or unordered
 1348    /// Z == 1 or N != V
 1349    le = 0b1101,
 1350    /// integer: Always
 1351    /// floating-point: Always
 1352    /// true
 1353    al = 0b1110,
 1354    /// integer: Always
 1355    /// floating-point: Always
 1356    /// true
 1357    nv = 0b1111,
 1358    /// Carry set
 1359    /// C == 1
 1360    pub const cs: ConditionCode = .hs;
 1361    /// Carry clear
 1362    /// C == 0
 1363    pub const cc: ConditionCode = .lo;
 1364
 1365    pub fn invert(cond: ConditionCode) ConditionCode {
 1366        return @enumFromInt(@intFromEnum(cond) ^ 0b0001);
 1367    }
 1368};
 1369
 1370/// C4.1 A64 instruction set encoding
 1371pub const Instruction = packed union {
 1372    group: Group,
 1373    reserved: Reserved,
 1374    sme: Sme,
 1375    sve: Sve,
 1376    data_processing_immediate: DataProcessingImmediate,
 1377    branch_exception_generating_system: BranchExceptionGeneratingSystem,
 1378    load_store: LoadStore,
 1379    data_processing_register: DataProcessingRegister,
 1380    data_processing_vector: DataProcessingVector,
 1381
 1382    /// Table C4-1 Main encoding table for the A64 instruction set
 1383    pub const Group = packed struct {
 1384        encoded0: u25,
 1385        op1: u4,
 1386        encoded29: u2,
 1387        op0: u1,
 1388    };
 1389
 1390    /// C4.1.1 Reserved
 1391    pub const Reserved = packed union {
 1392        group: @This().Group,
 1393        udf: Udf,
 1394
 1395        /// Table C4-2 Encoding table for the Reserved group
 1396        pub const Group = packed struct {
 1397            encoded0: u16,
 1398            op1: u9,
 1399            decoded25: u4 = 0b0000,
 1400            op0: u2,
 1401            decoded31: u1 = 0b0,
 1402        };
 1403
 1404        /// C6.2.387 UDF
 1405        pub const Udf = packed struct {
 1406            imm16: u16,
 1407            decoded16: u16 = 0b0000000000000000,
 1408        };
 1409
 1410        pub const Decoded = union(enum) {
 1411            unallocated,
 1412            udf: Udf,
 1413        };
 1414        pub fn decode(inst: @This()) @This().Decoded {
 1415            return switch (inst.group.op0) {
 1416                0b00 => switch (inst.group.op1) {
 1417                    0b000000000 => .{ .udf = inst.udf },
 1418                    else => .unallocated,
 1419                },
 1420                else => .unallocated,
 1421            };
 1422        }
 1423    };
 1424
 1425    /// C4.1.2 SME encodings
 1426    pub const Sme = packed union {
 1427        group: @This().Group,
 1428
 1429        /// Table C4-3 Encodings table for the SME encodings group
 1430        pub const Group = packed struct {
 1431            encoded0: u2,
 1432            op2: u3,
 1433            encoded5: u5,
 1434            op1: u15,
 1435            decoded25: u4 = 0b0000,
 1436            op0: u2,
 1437            decoded31: u1 = 0b1,
 1438        };
 1439    };
 1440
 1441    /// C4.1.30 SVE encodings
 1442    pub const Sve = packed union {
 1443        group: @This().Group,
 1444
 1445        /// Table C4-31 Encoding table for the SVE encodings group
 1446        pub const Group = packed struct {
 1447            encoded0: u4,
 1448            op2: u1,
 1449            encoded5: u5,
 1450            op1: u15,
 1451            decoded25: u4 = 0b0010,
 1452            op0: u3,
 1453        };
 1454    };
 1455
 1456    /// C4.1.86 Data Processing -- Immediate
 1457    pub const DataProcessingImmediate = packed union {
 1458        group: @This().Group,
 1459        pc_relative_addressing: PcRelativeAddressing,
 1460        add_subtract_immediate: AddSubtractImmediate,
 1461        add_subtract_immediate_with_tags: AddSubtractImmediateWithTags,
 1462        logical_immediate: LogicalImmediate,
 1463        move_wide_immediate: MoveWideImmediate,
 1464        bitfield: Bitfield,
 1465        extract: Extract,
 1466
 1467        /// Table C4-87 Encoding table for the Data Processing -- Immediate group
 1468        pub const Group = packed struct {
 1469            encoded0: u23,
 1470            op0: u3,
 1471            decoded26: u3 = 0b100,
 1472            encoded29: u3,
 1473        };
 1474
 1475        /// PC-rel. addressing
 1476        pub const PcRelativeAddressing = packed union {
 1477            group: @This().Group,
 1478            adr: Adr,
 1479            adrp: Adrp,
 1480
 1481            pub const Group = packed struct {
 1482                Rd: Register.Encoded,
 1483                immhi: i19,
 1484                decoded24: u5 = 0b10000,
 1485                immlo: u2,
 1486                op: Op,
 1487            };
 1488
 1489            /// C6.2.10 ADR
 1490            pub const Adr = packed struct {
 1491                Rd: Register.Encoded,
 1492                immhi: i19,
 1493                decoded24: u5 = 0b10000,
 1494                immlo: u2,
 1495                op: Op = .adr,
 1496            };
 1497
 1498            /// C6.2.11 ADRP
 1499            pub const Adrp = packed struct {
 1500                Rd: Register.Encoded,
 1501                immhi: i19,
 1502                decoded24: u5 = 0b10000,
 1503                immlo: u2,
 1504                op: Op = .adrp,
 1505            };
 1506
 1507            pub const Op = enum(u1) {
 1508                adr = 0b0,
 1509                adrp = 0b1,
 1510            };
 1511
 1512            pub const Decoded = union(enum) {
 1513                adr: Adr,
 1514                adrp: Adrp,
 1515            };
 1516            pub fn decode(inst: @This()) @This().Decoded {
 1517                return switch (inst.group.op) {
 1518                    .adr => .{ .adr = inst.adr },
 1519                    .adrp => .{ .adrp = inst.adrp },
 1520                };
 1521            }
 1522        };
 1523
 1524        /// Add/subtract (immediate)
 1525        pub const AddSubtractImmediate = packed union {
 1526            group: @This().Group,
 1527            add: Add,
 1528            adds: Adds,
 1529            sub: Sub,
 1530            subs: Subs,
 1531
 1532            pub const Group = packed struct {
 1533                Rd: Register.Encoded,
 1534                Rn: Register.Encoded,
 1535                imm12: u12,
 1536                sh: Shift,
 1537                decoded23: u6 = 0b100010,
 1538                S: bool,
 1539                op: AddSubtractOp,
 1540                sf: Register.GeneralSize,
 1541            };
 1542
 1543            /// C6.2.4 ADD (immediate)
 1544            pub const Add = packed struct {
 1545                Rd: Register.Encoded,
 1546                Rn: Register.Encoded,
 1547                imm12: u12,
 1548                sh: Shift,
 1549                decoded23: u6 = 0b100010,
 1550                S: bool = false,
 1551                op: AddSubtractOp = .add,
 1552                sf: Register.GeneralSize,
 1553            };
 1554
 1555            /// C6.2.8 ADDS (immediate)
 1556            pub const Adds = packed struct {
 1557                Rd: Register.Encoded,
 1558                Rn: Register.Encoded,
 1559                imm12: u12,
 1560                sh: Shift,
 1561                decoded23: u6 = 0b100010,
 1562                S: bool = true,
 1563                op: AddSubtractOp = .add,
 1564                sf: Register.GeneralSize,
 1565            };
 1566
 1567            /// C6.2.357 SUB (immediate)
 1568            pub const Sub = packed struct {
 1569                Rd: Register.Encoded,
 1570                Rn: Register.Encoded,
 1571                imm12: u12,
 1572                sh: Shift,
 1573                decoded23: u6 = 0b100010,
 1574                S: bool = false,
 1575                op: AddSubtractOp = .sub,
 1576                sf: Register.GeneralSize,
 1577            };
 1578
 1579            /// C6.2.363 SUBS (immediate)
 1580            pub const Subs = packed struct {
 1581                Rd: Register.Encoded,
 1582                Rn: Register.Encoded,
 1583                imm12: u12,
 1584                sh: Shift,
 1585                decoded23: u6 = 0b100010,
 1586                S: bool = true,
 1587                op: AddSubtractOp = .sub,
 1588                sf: Register.GeneralSize,
 1589            };
 1590
 1591            pub const Shift = enum(u1) {
 1592                @"0" = 0b0,
 1593                @"12" = 0b1,
 1594            };
 1595
 1596            pub const Decoded = union(enum) {
 1597                add: Add,
 1598                adds: Adds,
 1599                sub: Sub,
 1600                subs: Subs,
 1601            };
 1602            pub fn decode(inst: @This()) @This().Decaded {
 1603                return switch (inst.group.op) {
 1604                    .add => switch (inst.group.S) {
 1605                        false => .{ .add = inst.add },
 1606                        true => .{ .addc = inst.addc },
 1607                    },
 1608                    .sub => switch (inst.group.S) {
 1609                        false => .{ .sub = inst.sub },
 1610                        true => .{ .subc = inst.subc },
 1611                    },
 1612                };
 1613            }
 1614        };
 1615
 1616        /// Add/subtract (immediate, with tags)
 1617        pub const AddSubtractImmediateWithTags = packed union {
 1618            group: @This().Group,
 1619            addg: Addg,
 1620            subg: Subg,
 1621
 1622            pub const Group = packed struct {
 1623                Rd: Register.Encoded,
 1624                Rn: Register.Encoded,
 1625                uimm4: u4,
 1626                op3: u2,
 1627                uimm6: u6,
 1628                o2: u1,
 1629                decoded23: u6 = 0b100011,
 1630                S: bool,
 1631                op: AddSubtractOp,
 1632                sf: Register.GeneralSize,
 1633            };
 1634
 1635            /// C6.2.6 ADDG
 1636            pub const Addg = packed struct {
 1637                Xd: Register.Encoded,
 1638                Xn: Register.Encoded,
 1639                uimm4: u4,
 1640                op3: u2 = 0b00,
 1641                uimm6: u6,
 1642                o2: u1 = 0b0,
 1643                decoded23: u6 = 0b100011,
 1644                S: bool = false,
 1645                op: AddSubtractOp = .add,
 1646                sf: Register.GeneralSize = .doubleword,
 1647            };
 1648
 1649            /// C6.2.359 SUBG
 1650            pub const Subg = packed struct {
 1651                Xd: Register.Encoded,
 1652                Xn: Register.Encoded,
 1653                uimm4: u4,
 1654                op3: u2 = 0b00,
 1655                uimm6: u6,
 1656                o2: u1 = 0b0,
 1657                decoded23: u6 = 0b100011,
 1658                S: bool = false,
 1659                op: AddSubtractOp = .sub,
 1660                sf: Register.GeneralSize = .doubleword,
 1661            };
 1662
 1663            pub const Decoded = union(enum) {
 1664                unallocated,
 1665                addg: Addg,
 1666                subg: Subg,
 1667            };
 1668            pub fn decode(inst: @This()) @This().Decoded {
 1669                return switch (inst.group.o2) {
 1670                    0b1 => .unallocated,
 1671                    0b0 => switch (inst.group.sf) {
 1672                        .word => .unallocated,
 1673                        .doubleword => switch (inst.group.S) {
 1674                            true => .unallocated,
 1675                            false => switch (inst.group.op) {
 1676                                .add => .{ .addg = inst.addg },
 1677                                .sub => .{ .subg = inst.subg },
 1678                            },
 1679                        },
 1680                    },
 1681                };
 1682            }
 1683        };
 1684
 1685        /// Logical (immediate)
 1686        pub const LogicalImmediate = packed union {
 1687            group: @This().Group,
 1688            @"and": And,
 1689            orr: Orr,
 1690            eor: Eor,
 1691            ands: Ands,
 1692
 1693            pub const Group = packed struct {
 1694                Rd: Register.Encoded,
 1695                Rn: Register.Encoded,
 1696                imm: Bitmask,
 1697                decoded23: u6 = 0b100100,
 1698                opc: LogicalOpc,
 1699                sf: Register.GeneralSize,
 1700            };
 1701
 1702            /// C6.2.12 AND (immediate)
 1703            pub const And = packed struct {
 1704                Rd: Register.Encoded,
 1705                Rn: Register.Encoded,
 1706                imm: Bitmask,
 1707                decoded23: u6 = 0b100100,
 1708                opc: LogicalOpc = .@"and",
 1709                sf: Register.GeneralSize,
 1710            };
 1711
 1712            /// C6.2.240 ORR (immediate)
 1713            pub const Orr = packed struct {
 1714                Rd: Register.Encoded,
 1715                Rn: Register.Encoded,
 1716                imm: Bitmask,
 1717                decoded23: u6 = 0b100100,
 1718                opc: LogicalOpc = .orr,
 1719                sf: Register.GeneralSize,
 1720            };
 1721
 1722            /// C6.2.119 EOR (immediate)
 1723            pub const Eor = packed struct {
 1724                Rd: Register.Encoded,
 1725                Rn: Register.Encoded,
 1726                imm: Bitmask,
 1727                decoded23: u6 = 0b100100,
 1728                opc: LogicalOpc = .eor,
 1729                sf: Register.GeneralSize,
 1730            };
 1731
 1732            /// C6.2.14 ANDS (immediate)
 1733            pub const Ands = packed struct {
 1734                Rd: Register.Encoded,
 1735                Rn: Register.Encoded,
 1736                imm: Bitmask,
 1737                decoded23: u6 = 0b100100,
 1738                opc: LogicalOpc = .ands,
 1739                sf: Register.GeneralSize,
 1740            };
 1741
 1742            pub const Decoded = union(enum) {
 1743                unallocated,
 1744                @"and": And,
 1745                orr: Orr,
 1746                eor: Eor,
 1747                ands: Ands,
 1748            };
 1749            pub fn decode(inst: @This()) @This().Decoded {
 1750                return if (!inst.group.imm.validImmediate(inst.group.sf))
 1751                    .unallocated
 1752                else switch (inst.group.opc) {
 1753                    .@"and" => .{ .@"and" = inst.@"and" },
 1754                    .orr => .{ .orr = inst.orr },
 1755                    .eor => .{ .eor = inst.eor },
 1756                    .ands => .{ .ands = inst.ands },
 1757                };
 1758            }
 1759        };
 1760
 1761        /// Move wide (immediate)
 1762        pub const MoveWideImmediate = packed union {
 1763            group: @This().Group,
 1764            movn: Movn,
 1765            movz: Movz,
 1766            movk: Movk,
 1767
 1768            pub const Group = packed struct {
 1769                Rd: Register.Encoded,
 1770                imm16: u16,
 1771                hw: Hw,
 1772                decoded23: u6 = 0b100101,
 1773                opc: Opc,
 1774                sf: Register.GeneralSize,
 1775            };
 1776
 1777            /// C6.2.226 MOVN
 1778            pub const Movn = packed struct {
 1779                Rd: Register.Encoded,
 1780                imm16: u16,
 1781                hw: Hw,
 1782                decoded23: u6 = 0b100101,
 1783                opc: Opc = .movn,
 1784                sf: Register.GeneralSize,
 1785            };
 1786
 1787            /// C6.2.227 MOVZ
 1788            pub const Movz = packed struct {
 1789                Rd: Register.Encoded,
 1790                imm16: u16,
 1791                hw: Hw,
 1792                decoded23: u6 = 0b100101,
 1793                opc: Opc = .movz,
 1794                sf: Register.GeneralSize,
 1795            };
 1796
 1797            /// C6.2.225 MOVK
 1798            pub const Movk = packed struct {
 1799                Rd: Register.Encoded,
 1800                imm16: u16,
 1801                hw: Hw,
 1802                decoded23: u6 = 0b100101,
 1803                opc: Opc = .movk,
 1804                sf: Register.GeneralSize,
 1805            };
 1806
 1807            pub const Hw = enum(u2) {
 1808                @"0" = 0b00,
 1809                @"16" = 0b01,
 1810                @"32" = 0b10,
 1811                @"48" = 0b11,
 1812
 1813                pub fn int(hw: Hw) u6 {
 1814                    return switch (hw) {
 1815                        .@"0" => 0,
 1816                        .@"16" => 16,
 1817                        .@"32" => 32,
 1818                        .@"48" => 48,
 1819                    };
 1820                }
 1821
 1822                pub fn sf(hw: Hw) Register.GeneralSize {
 1823                    return switch (hw) {
 1824                        .@"0", .@"16" => .word,
 1825                        .@"32", .@"48" => .doubleword,
 1826                    };
 1827                }
 1828            };
 1829
 1830            pub const Opc = enum(u2) {
 1831                movn = 0b00,
 1832                movz = 0b10,
 1833                movk = 0b11,
 1834                _,
 1835            };
 1836
 1837            pub const Decoded = union(enum) {
 1838                unallocated,
 1839                movn: Movn,
 1840                movz: Movz,
 1841                movk: Movk,
 1842            };
 1843            pub fn decode(inst: @This()) @This().Decoded {
 1844                return if (inst.group.sf == .word and inst.group.hw.sf() == .doubleword)
 1845                    .unallocated
 1846                else switch (inst.group.opc) {
 1847                    _ => .unallocated,
 1848                    .movn => .{ .movn = inst.movn },
 1849                    .movz => .{ .movz = inst.movz },
 1850                    .movk => .{ .movk = inst.movk },
 1851                };
 1852            }
 1853        };
 1854
 1855        /// Bitfield
 1856        pub const Bitfield = packed union {
 1857            group: @This().Group,
 1858            sbfm: Sbfm,
 1859            bfm: Bfm,
 1860            ubfm: Ubfm,
 1861
 1862            pub const Group = packed struct {
 1863                Rd: Register.Encoded,
 1864                Rn: Register.Encoded,
 1865                imm: Bitmask,
 1866                decoded23: u6 = 0b100110,
 1867                opc: Opc,
 1868                sf: Register.GeneralSize,
 1869            };
 1870
 1871            pub const Sbfm = packed struct {
 1872                Rd: Register.Encoded,
 1873                Rn: Register.Encoded,
 1874                imm: Bitmask,
 1875                decoded23: u6 = 0b100110,
 1876                opc: Opc = .sbfm,
 1877                sf: Register.GeneralSize,
 1878            };
 1879
 1880            pub const Bfm = packed struct {
 1881                Rd: Register.Encoded,
 1882                Rn: Register.Encoded,
 1883                imm: Bitmask,
 1884                decoded23: u6 = 0b100110,
 1885                opc: Opc = .bfm,
 1886                sf: Register.GeneralSize,
 1887            };
 1888
 1889            pub const Ubfm = packed struct {
 1890                Rd: Register.Encoded,
 1891                Rn: Register.Encoded,
 1892                imm: Bitmask,
 1893                decoded23: u6 = 0b100110,
 1894                opc: Opc = .ubfm,
 1895                sf: Register.GeneralSize,
 1896            };
 1897
 1898            pub const Opc = enum(u2) {
 1899                sbfm = 0b00,
 1900                bfm = 0b01,
 1901                ubfm = 0b10,
 1902                _,
 1903            };
 1904
 1905            pub const Decoded = union(enum) {
 1906                unallocated,
 1907                sbfm: Sbfm,
 1908                bfm: Bfm,
 1909                ubfm: Ubfm,
 1910            };
 1911            pub fn decode(inst: @This()) @This().Decoded {
 1912                return if (!inst.group.imm.validBitfield(inst.group.sf))
 1913                    .unallocated
 1914                else switch (inst.group.opc) {
 1915                    _ => .unallocated,
 1916                    .sbfm => .{ .sbfm = inst.sbfm },
 1917                    .bfm => .{ .bfm = inst.bfm },
 1918                    .ubfm => .{ .ubfm = inst.ubfm },
 1919                };
 1920            }
 1921        };
 1922
 1923        /// Extract
 1924        pub const Extract = packed union {
 1925            group: @This().Group,
 1926            extr: Extr,
 1927
 1928            pub const Group = packed struct {
 1929                Rd: Register.Encoded,
 1930                Rn: Register.Encoded,
 1931                imms: u6,
 1932                Rm: Register.Encoded,
 1933                o0: u1,
 1934                N: Register.GeneralSize,
 1935                decoded23: u6 = 0b100111,
 1936                op21: u2,
 1937                sf: Register.GeneralSize,
 1938            };
 1939
 1940            pub const Extr = packed struct {
 1941                Rd: Register.Encoded,
 1942                Rn: Register.Encoded,
 1943                imms: u6,
 1944                Rm: Register.Encoded,
 1945                o0: u1 = 0b0,
 1946                N: Register.GeneralSize,
 1947                decoded23: u6 = 0b100111,
 1948                op21: u2 = 0b00,
 1949                sf: Register.GeneralSize,
 1950            };
 1951
 1952            pub const Decoded = union(enum) {
 1953                unallocated,
 1954                extr: Extr,
 1955            };
 1956            pub fn decode(inst: @This()) @This().Decoded {
 1957                return switch (inst.group.op21) {
 1958                    0b01, 0b10...0b11 => .unallocated,
 1959                    0b00 => switch (inst.group.o0) {
 1960                        0b1 => .unallocated,
 1961                        0b0 => if ((inst.group.sf == .word and @as(u1, @truncate(inst.group.imms >> 5)) == 0b1) or
 1962                            inst.group.sf != inst.group.N)
 1963                            .unallocated
 1964                        else
 1965                            .{ .extr = inst.extr },
 1966                    },
 1967                };
 1968            }
 1969        };
 1970
 1971        pub const Bitmask = packed struct {
 1972            imms: u6,
 1973            immr: u6,
 1974            N: Register.GeneralSize,
 1975
 1976            fn lenHsb(bitmask: Bitmask) u7 {
 1977                return @bitCast(packed struct {
 1978                    not_imms: u6,
 1979                    N: Register.GeneralSize,
 1980                }{ .not_imms = ~bitmask.imms, .N = bitmask.N });
 1981            }
 1982
 1983            fn validImmediate(bitmask: Bitmask, sf: Register.GeneralSize) bool {
 1984                if (sf == .word and bitmask.N == .doubleword) return false;
 1985                const len_hsb = bitmask.lenHsb();
 1986                return (len_hsb -% 1) & len_hsb != 0b0_000000;
 1987            }
 1988
 1989            fn validBitfield(bitmask: Bitmask, sf: Register.GeneralSize) bool {
 1990                if (sf != bitmask.N) return false;
 1991                if (sf == .word and (@as(u1, @truncate(bitmask.immr >> 5)) != 0b0 or
 1992                    @as(u1, @truncate(bitmask.imms >> 5)) != 0b0)) return false;
 1993                const len_hsb = bitmask.lenHsb();
 1994                return len_hsb >= 0b0_000010;
 1995            }
 1996
 1997            fn decode(bitmask: Bitmask, sf: Register.GeneralSize) struct { u64, u64 } {
 1998                const esize = @as(u7, 1 << 6) >> @clz(bitmask.lenHsb());
 1999                const levels: u6 = @intCast(esize - 1);
 2000                const s = bitmask.imms & levels;
 2001                const r = bitmask.immr & levels;
 2002                const d = (s -% r) & levels;
 2003                const welem = @as(u64, std.math.maxInt(u64)) >> (63 - s);
 2004                const telem = @as(u64, std.math.maxInt(u64)) >> (63 - d);
 2005                const emask = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - esize);
 2006                const rmask = @divExact(std.math.maxInt(u64), emask);
 2007                const wmask = std.math.rotr(u64, welem * rmask, r);
 2008                const tmask = telem * rmask;
 2009                return switch (sf) {
 2010                    .word => .{ @as(u32, @truncate(wmask)), @as(u32, @truncate(tmask)) },
 2011                    .doubleword => .{ wmask, tmask },
 2012                };
 2013            }
 2014
 2015            pub fn decodeImmediate(bitmask: Bitmask, sf: Register.GeneralSize) u64 {
 2016                assert(bitmask.validImmediate(sf));
 2017                const imm, _ = bitmask.decode(sf);
 2018                return imm;
 2019            }
 2020
 2021            pub fn decodeBitfield(bitmask: Bitmask, sf: Register.GeneralSize) struct { u64, u64 } {
 2022                assert(bitmask.validBitfield(sf));
 2023                return bitmask.decode(sf);
 2024            }
 2025
 2026            pub fn moveWidePreferred(bitmask: Bitmask, sf: Register.GeneralSize) bool {
 2027                const s = bitmask.imms;
 2028                const r = bitmask.immr;
 2029                const width: u7 = switch (sf) {
 2030                    .word => 32,
 2031                    .doubleword => 64,
 2032                };
 2033                if (sf != bitmask.N) return false;
 2034                if (sf == .word and @as(u1, @truncate(s >> 5)) != 0b0) return false;
 2035                if (s < 16) return (-%r % 16) <= (15 - s);
 2036                if (s >= width - 15) return (r % 16) <= (s - (width - 15));
 2037                return false;
 2038            }
 2039        };
 2040
 2041        pub const Decoded = union(enum) {
 2042            unallocated,
 2043            pc_relative_addressing: PcRelativeAddressing,
 2044            add_subtract_immediate: AddSubtractImmediate,
 2045            add_subtract_immediate_with_tags: AddSubtractImmediateWithTags,
 2046            logical_immediate: LogicalImmediate,
 2047            move_wide_immediate: MoveWideImmediate,
 2048            bitfield: Bitfield,
 2049            extract: Extract,
 2050        };
 2051        pub fn decode(inst: @This()) @This().Decoded {
 2052            return switch (inst.group.op0) {
 2053                0b000, 0b001 => .{ .pc_relative_addressing = inst.pc_relative_addressing },
 2054                0b010 => .{ .add_subtract_immediate = inst.add_subtract_immediate },
 2055                0b011 => .{ .add_subtract_immediate_with_tags = inst.add_subtract_immediate_with_tags },
 2056                0b100 => .{ .logical_immediate = inst.logical_immediate },
 2057                0b101 => .{ .move_wide_immediate = inst.move_wide_immediate },
 2058                0b110 => .{ .bitfield = inst.bitfield },
 2059                0b111 => .{ .extract = inst.extract },
 2060            };
 2061        }
 2062    };
 2063
 2064    /// C4.1.87 Branches, Exception Generating and System instructions
 2065    pub const BranchExceptionGeneratingSystem = packed union {
 2066        group: @This().Group,
 2067        conditional_branch_immediate: ConditionalBranchImmediate,
 2068        exception_generating: ExceptionGenerating,
 2069        system_register_argument: SystemRegisterArgument,
 2070        hints: Hints,
 2071        barriers: Barriers,
 2072        pstate: Pstate,
 2073        system_result: SystemResult,
 2074        system: System,
 2075        system_register_move: SystemRegisterMove,
 2076        unconditional_branch_register: UnconditionalBranchRegister,
 2077        unconditional_branch_immediate: UnconditionalBranchImmediate,
 2078        compare_branch_immediate: CompareBranchImmediate,
 2079        test_branch_immediate: TestBranchImmediate,
 2080
 2081        /// Table C4-88 Encoding table for the Branches, Exception Generating and System instructions group
 2082        pub const Group = packed struct {
 2083            op2: u5,
 2084            encoded5: u7,
 2085            op1: u14,
 2086            decoded26: u3 = 0b101,
 2087            op0: u3,
 2088        };
 2089
 2090        /// Conditional branch (immediate)
 2091        pub const ConditionalBranchImmediate = packed union {
 2092            group: @This().Group,
 2093            b: B,
 2094            bc: Bc,
 2095
 2096            pub const Group = packed struct {
 2097                cond: ConditionCode,
 2098                o0: u1,
 2099                imm19: i19,
 2100                o1: u1,
 2101                decoded25: u7 = 0b0101010,
 2102            };
 2103
 2104            /// C6.2.26 B.cond
 2105            pub const B = packed struct {
 2106                cond: ConditionCode,
 2107                o0: u1 = 0b0,
 2108                imm19: i19,
 2109                o1: u1 = 0b0,
 2110                decoded25: u7 = 0b0101010,
 2111            };
 2112
 2113            /// C6.2.27 BC.cond
 2114            pub const Bc = packed struct {
 2115                cond: ConditionCode,
 2116                o0: u1 = 0b1,
 2117                imm19: i19,
 2118                o1: u1 = 0b0,
 2119                decoded25: u7 = 0b0101010,
 2120            };
 2121
 2122            pub const Decoded = union(enum) {
 2123                unallocated,
 2124                b: B,
 2125                bc: Bc,
 2126            };
 2127            pub fn decode(inst: @This()) @This().Decoded {
 2128                return switch (inst.group.o1) {
 2129                    0b0 => switch (inst.group.o0) {
 2130                        0b0 => .{ .b = inst.b },
 2131                        0b1 => .{ .bc = inst.bc },
 2132                    },
 2133                    0b1 => .unallocated,
 2134                };
 2135            }
 2136        };
 2137
 2138        /// Exception generating
 2139        pub const ExceptionGenerating = packed union {
 2140            group: @This().Group,
 2141            svc: Svc,
 2142            hvc: Hvc,
 2143            smc: Smc,
 2144            brk: Brk,
 2145            hlt: Hlt,
 2146            tcancel: Tcancel,
 2147            dcps1: Dcps1,
 2148            dcps2: Dcps2,
 2149            dcps3: Dcps3,
 2150
 2151            pub const Group = packed struct {
 2152                LL: u2,
 2153                op2: u3,
 2154                imm16: u16,
 2155                opc: u3,
 2156                decoded24: u8 = 0b11010100,
 2157            };
 2158
 2159            /// C6.2.365 SVC
 2160            pub const Svc = packed struct {
 2161                decoded0: u2 = 0b01,
 2162                decoded2: u3 = 0b000,
 2163                imm16: u16,
 2164                decoded21: u3 = 0b000,
 2165                decoded24: u8 = 0b11010100,
 2166            };
 2167
 2168            /// C6.2.128 HVC
 2169            pub const Hvc = packed struct {
 2170                decoded0: u2 = 0b10,
 2171                decoded2: u3 = 0b000,
 2172                imm16: u16,
 2173                decoded21: u3 = 0b000,
 2174                decoded24: u8 = 0b11010100,
 2175            };
 2176
 2177            /// C6.2.283 SMC
 2178            pub const Smc = packed struct {
 2179                decoded0: u2 = 0b11,
 2180                decoded2: u3 = 0b000,
 2181                imm16: u16,
 2182                decoded21: u3 = 0b000,
 2183                decoded24: u8 = 0b11010100,
 2184            };
 2185
 2186            /// C6.2.40 BRK
 2187            pub const Brk = packed struct {
 2188                decoded0: u2 = 0b00,
 2189                decoded2: u3 = 0b000,
 2190                imm16: u16,
 2191                decoded21: u3 = 0b001,
 2192                decoded24: u8 = 0b11010100,
 2193            };
 2194
 2195            /// C6.2.127 HLT
 2196            pub const Hlt = packed struct {
 2197                decoded0: u2 = 0b00,
 2198                decoded2: u3 = 0b000,
 2199                imm16: u16,
 2200                decoded21: u3 = 0b010,
 2201                decoded24: u8 = 0b11010100,
 2202            };
 2203
 2204            /// C6.2.376 TCANCEL
 2205            pub const Tcancel = packed struct {
 2206                decoded0: u2 = 0b00,
 2207                decoded2: u3 = 0b000,
 2208                imm16: u16,
 2209                decoded21: u3 = 0b011,
 2210                decoded24: u8 = 0b11010100,
 2211            };
 2212
 2213            /// C6.2.110 DCPS1
 2214            pub const Dcps1 = packed struct {
 2215                LL: u2 = 0b01,
 2216                decoded2: u3 = 0b000,
 2217                imm16: u16,
 2218                decoded21: u3 = 0b101,
 2219                decoded24: u8 = 0b11010100,
 2220            };
 2221
 2222            /// C6.2.110 DCPS2
 2223            pub const Dcps2 = packed struct {
 2224                LL: u2 = 0b10,
 2225                decoded2: u3 = 0b000,
 2226                imm16: u16,
 2227                decoded21: u3 = 0b101,
 2228                decoded24: u8 = 0b11010100,
 2229            };
 2230
 2231            /// C6.2.110 DCPS3
 2232            pub const Dcps3 = packed struct {
 2233                LL: u2 = 0b11,
 2234                decoded2: u3 = 0b000,
 2235                imm16: u16,
 2236                decoded21: u3 = 0b101,
 2237                decoded24: u8 = 0b11010100,
 2238            };
 2239
 2240            pub const Decoded = union(enum) {
 2241                unallocated,
 2242                svc: Svc,
 2243                hvc: Hvc,
 2244                smc: Smc,
 2245                brk: Brk,
 2246                hlt: Hlt,
 2247                tcancel: Tcancel,
 2248                dcps1: Dcps1,
 2249                dcps2: Dcps2,
 2250                dcps3: Dcps3,
 2251            };
 2252            pub fn decode(inst: @This()) @This().Decoded {
 2253                return switch (inst.group.op2) {
 2254                    0b001 => .unallocated,
 2255                    0b010...0b011 => .unallocated,
 2256                    0b100...0b111 => .unallocated,
 2257                    0b000 => switch (inst.group.opc) {
 2258                        0b000 => switch (inst.group.LL) {
 2259                            0b00 => .unallocated,
 2260                            0b01 => .{ .svc = inst.svc },
 2261                            0b10 => .{ .hvc = inst.hvc },
 2262                            0b11 => .{ .smc = inst.smc },
 2263                        },
 2264                        0b001 => switch (inst.group.LL) {
 2265                            0b01 => .unallocated,
 2266                            0b00 => .{ .brk = inst.brk },
 2267                            0b10...0b11 => .unallocated,
 2268                        },
 2269                        0b010 => switch (inst.group.LL) {
 2270                            0b01 => .unallocated,
 2271                            0b00 => .{ .hlt = inst.hlt },
 2272                            0b10...0b11 => .unallocated,
 2273                        },
 2274                        0b011 => switch (inst.group.LL) {
 2275                            0b00 => .{ .tcancel = inst.tcancel },
 2276                            0b01 => .unallocated,
 2277                            0b10...0b11 => .unallocated,
 2278                        },
 2279                        0b100 => .unallocated,
 2280                        0b101 => switch (inst.group.LL) {
 2281                            0b00 => .unallocated,
 2282                            0b01 => .{ .dcps1 = inst.dcps1 },
 2283                            0b10 => .{ .dcps2 = inst.dcps2 },
 2284                            0b11 => .{ .dcps3 = inst.dcps3 },
 2285                        },
 2286                        0b110 => .unallocated,
 2287                        0b111 => .unallocated,
 2288                    },
 2289                };
 2290            }
 2291        };
 2292
 2293        /// System instructions with register argument
 2294        pub const SystemRegisterArgument = packed struct {
 2295            Rt: Register.Encoded,
 2296            op2: u3,
 2297            CRm: u4,
 2298            decoded12: u20 = 0b11010101000000110001,
 2299        };
 2300
 2301        /// Hints
 2302        pub const Hints = packed union {
 2303            group: @This().Group,
 2304            hint: Hint,
 2305            nop: Nop,
 2306            yield: Yield,
 2307            wfe: Wfe,
 2308            wfi: Wfi,
 2309            sev: Sev,
 2310            sevl: Sevl,
 2311
 2312            pub const Group = packed struct {
 2313                decoded0: u5 = 0b11111,
 2314                op2: u3,
 2315                CRm: u4,
 2316                decoded12: u20 = 0b11010101000000110010,
 2317            };
 2318
 2319            /// C6.2.126 HINT
 2320            pub const Hint = packed struct {
 2321                decoded0: u5 = 0b11111,
 2322                op2: u3,
 2323                CRm: u4,
 2324                decoded12: u4 = 0b0010,
 2325                decoded16: u3 = 0b011,
 2326                decoded19: u2 = 0b00,
 2327                decoded21: u1 = 0b0,
 2328                decoded22: u10 = 0b1101010100,
 2329            };
 2330
 2331            /// C6.2.238 NOP
 2332            pub const Nop = packed struct {
 2333                decoded0: u5 = 0b11111,
 2334                op2: u3 = 0b000,
 2335                CRm: u4 = 0b0000,
 2336                decoded12: u4 = 0b0010,
 2337                decoded16: u3 = 0b011,
 2338                decoded19: u2 = 0b00,
 2339                decoded21: u1 = 0b0,
 2340                decoded22: u10 = 0b1101010100,
 2341            };
 2342
 2343            /// C6.2.402 YIELD
 2344            pub const Yield = packed struct {
 2345                decoded0: u5 = 0b11111,
 2346                op2: u3 = 0b001,
 2347                CRm: u4 = 0b0000,
 2348                decoded12: u4 = 0b0010,
 2349                decoded16: u3 = 0b011,
 2350                decoded19: u2 = 0b00,
 2351                decoded21: u1 = 0b0,
 2352                decoded22: u10 = 0b1101010100,
 2353            };
 2354
 2355            /// C6.2.396 WFE
 2356            pub const Wfe = packed struct {
 2357                decoded0: u5 = 0b11111,
 2358                op2: u3 = 0b010,
 2359                CRm: u4 = 0b0000,
 2360                decoded12: u4 = 0b0010,
 2361                decoded16: u3 = 0b011,
 2362                decoded19: u2 = 0b00,
 2363                decoded21: u1 = 0b0,
 2364                decoded22: u10 = 0b1101010100,
 2365            };
 2366
 2367            /// C6.2.398 WFI
 2368            pub const Wfi = packed struct {
 2369                decoded0: u5 = 0b11111,
 2370                op2: u3 = 0b011,
 2371                CRm: u4 = 0b0000,
 2372                decoded12: u4 = 0b0010,
 2373                decoded16: u3 = 0b011,
 2374                decoded19: u2 = 0b00,
 2375                decoded21: u1 = 0b0,
 2376                decoded22: u10 = 0b1101010100,
 2377            };
 2378
 2379            /// C6.2.280 SEV
 2380            pub const Sev = packed struct {
 2381                decoded0: u5 = 0b11111,
 2382                op2: u3 = 0b100,
 2383                CRm: u4 = 0b0000,
 2384                decoded12: u4 = 0b0010,
 2385                decoded16: u3 = 0b011,
 2386                decoded19: u2 = 0b00,
 2387                decoded21: u1 = 0b0,
 2388                decoded22: u10 = 0b1101010100,
 2389            };
 2390
 2391            /// C6.2.280 SEVL
 2392            pub const Sevl = packed struct {
 2393                decoded0: u5 = 0b11111,
 2394                op2: u3 = 0b101,
 2395                CRm: u4 = 0b0000,
 2396                decoded12: u4 = 0b0010,
 2397                decoded16: u3 = 0b011,
 2398                decoded19: u2 = 0b00,
 2399                decoded21: u1 = 0b0,
 2400                decoded22: u10 = 0b1101010100,
 2401            };
 2402
 2403            pub const Decoded = union(enum) {
 2404                hint: Hint,
 2405                nop: Nop,
 2406                yield: Yield,
 2407                wfe: Wfe,
 2408                wfi: Wfi,
 2409                sev: Sev,
 2410                sevl: Sevl,
 2411            };
 2412            pub fn decode(inst: @This()) @This().Decoded {
 2413                return switch (inst.group.CRm) {
 2414                    else => .{ .hint = inst.hint },
 2415                    0b0000 => switch (inst.group.op2) {
 2416                        else => .{ .hint = inst.hint },
 2417                        0b000 => .{ .nop = inst.nop },
 2418                        0b001 => .{ .yield = inst.yield },
 2419                        0b010 => .{ .wfe = inst.wfe },
 2420                        0b011 => .{ .wfi = inst.wfi },
 2421                        0b100 => .{ .sev = inst.sev },
 2422                        0b101 => .{ .sevl = inst.sevl },
 2423                    },
 2424                };
 2425            }
 2426        };
 2427
 2428        /// Barriers
 2429        pub const Barriers = packed union {
 2430            group: @This().Group,
 2431            clrex: Clrex,
 2432            dsb: Dsb,
 2433            dmb: Dmb,
 2434            isb: Isb,
 2435            sb: Sb,
 2436
 2437            pub const Group = packed struct {
 2438                Rt: Register.Encoded,
 2439                op2: u3,
 2440                CRm: u4,
 2441                decoded12: u4 = 0b0011,
 2442                decoded16: u3 = 0b011,
 2443                decoded19: u2 = 0b00,
 2444                decoded21: u1 = 0b0,
 2445                decoded22: u10 = 0b1101010100,
 2446            };
 2447
 2448            /// C6.2.56 CLREX
 2449            pub const Clrex = packed struct {
 2450                Rt: Register.Encoded = no_reg,
 2451                op2: u3 = 0b010,
 2452                CRm: u4,
 2453                decoded12: u4 = 0b0011,
 2454                decoded16: u3 = 0b011,
 2455                decoded19: u2 = 0b00,
 2456                decoded21: u1 = 0b0,
 2457                decoded22: u10 = 0b1101010100,
 2458            };
 2459
 2460            /// C6.2.116 DSB
 2461            pub const Dsb = packed struct {
 2462                Rt: Register.Encoded = no_reg,
 2463                opc: u2 = 0b00,
 2464                decoded7: u1 = 0b1,
 2465                CRm: Option,
 2466                decoded12: u4 = 0b0011,
 2467                decoded16: u3 = 0b011,
 2468                decoded19: u2 = 0b00,
 2469                decoded21: u1 = 0b0,
 2470                decoded22: u10 = 0b1101010100,
 2471            };
 2472
 2473            /// C6.2.114 DMB
 2474            pub const Dmb = packed struct {
 2475                Rt: Register.Encoded = no_reg,
 2476                opc: u2 = 0b01,
 2477                decoded7: u1 = 0b1,
 2478                CRm: Option,
 2479                decoded12: u4 = 0b0011,
 2480                decoded16: u3 = 0b011,
 2481                decoded19: u2 = 0b00,
 2482                decoded21: u1 = 0b0,
 2483                decoded22: u10 = 0b1101010100,
 2484            };
 2485
 2486            /// C6.2.131 ISB
 2487            pub const Isb = packed struct {
 2488                Rt: Register.Encoded = no_reg,
 2489                opc: u2 = 0b10,
 2490                decoded7: u1 = 0b1,
 2491                CRm: Option,
 2492                decoded12: u4 = 0b0011,
 2493                decoded16: u3 = 0b011,
 2494                decoded19: u2 = 0b00,
 2495                decoded21: u1 = 0b0,
 2496                decoded22: u10 = 0b1101010100,
 2497            };
 2498
 2499            /// C6.2.264 SB
 2500            pub const Sb = packed struct {
 2501                Rt: Register.Encoded = no_reg,
 2502                opc: u2 = 0b11,
 2503                decoded7: u1 = 0b1,
 2504                CRm: u4 = 0b0000,
 2505                decoded12: u4 = 0b0011,
 2506                decoded16: u3 = 0b011,
 2507                decoded19: u2 = 0b00,
 2508                decoded21: u1 = 0b0,
 2509                decoded22: u10 = 0b1101010100,
 2510            };
 2511
 2512            pub const Option = enum(u4) {
 2513                oshld = 0b0001,
 2514                oshst = 0b0010,
 2515                osh = 0b0011,
 2516                nshld = 0b0101,
 2517                nshst = 0b0110,
 2518                nsh = 0b0111,
 2519                ishld = 0b1001,
 2520                ishst = 0b1010,
 2521                ish = 0b1011,
 2522                ld = 0b1101,
 2523                st = 0b1110,
 2524                sy = 0b1111,
 2525                _,
 2526            };
 2527
 2528            pub const Decoded = union(enum) {
 2529                unallocated,
 2530                clrex: Clrex,
 2531                dsb: Dsb,
 2532                dmb: Dmb,
 2533                isb: Isb,
 2534                sb: Sb,
 2535            };
 2536            pub fn decode(inst: @This()) @This().Decoded {
 2537                return switch (inst.group.op2) {
 2538                    0b000, 0b001 => .unallocated,
 2539                    0b010 => switch (inst.group.Rt) {
 2540                        no_reg => .{ .clrex = inst.clrex },
 2541                        else => .unallocated,
 2542                    },
 2543                    0b100 => switch (inst.group.Rt) {
 2544                        no_reg => .{ .dsb = inst.dsb },
 2545                        else => .unallocated,
 2546                    },
 2547                    0b101 => switch (inst.group.Rt) {
 2548                        no_reg => .{ .dmb = inst.dmb },
 2549                        else => .unallocated,
 2550                    },
 2551                    0b110 => switch (inst.group.Rt) {
 2552                        no_reg => .{ .isb = inst.isb },
 2553                        else => .unallocated,
 2554                    },
 2555                    0b111 => switch (inst.group.Rt) {
 2556                        no_reg => .{ .sb = inst.sb },
 2557                        else => .unallocated,
 2558                    },
 2559                };
 2560            }
 2561        };
 2562
 2563        /// PSTATE
 2564        pub const Pstate = packed union {
 2565            group: @This().Group,
 2566            msr: Msr,
 2567            cfinv: Cfinv,
 2568            xaflag: Xaflag,
 2569            axflag: Axflag,
 2570
 2571            pub const Group = packed struct {
 2572                Rt: Register.Encoded,
 2573                op2: u3,
 2574                CRm: u4,
 2575                decoded12: u4 = 0b0100,
 2576                op1: u3,
 2577                decoded19: u13 = 0b1101010100000,
 2578            };
 2579
 2580            /// C6.2.229 MSR (immediate)
 2581            pub const Msr = packed struct {
 2582                Rt: Register.Encoded = no_reg,
 2583                op2: u3,
 2584                CRm: u4,
 2585                decoded12: u4 = 0b0100,
 2586                op1: u3,
 2587                decoded19: u13 = 0b1101010100000,
 2588            };
 2589
 2590            /// C6.2.52 CFINV
 2591            pub const Cfinv = packed struct {
 2592                Rt: Register.Encoded = no_reg,
 2593                op2: u3 = 0b000,
 2594                CRm: u4 = 0b0000,
 2595                decoded12: u4 = 0b0100,
 2596                op1: u3 = 0b000,
 2597                decoded19: u13 = 0b1101010100000,
 2598            };
 2599
 2600            /// C6.2.400 XAFLAG
 2601            pub const Xaflag = packed struct {
 2602                Rt: Register.Encoded = no_reg,
 2603                op2: u3 = 0b001,
 2604                CRm: u4 = 0b0000,
 2605                decoded12: u4 = 0b0100,
 2606                op1: u3 = 0b000,
 2607                decoded19: u13 = 0b1101010100000,
 2608            };
 2609
 2610            /// C6.2.24 AXFLAG
 2611            pub const Axflag = packed struct {
 2612                Rt: Register.Encoded = no_reg,
 2613                op2: u3 = 0b010,
 2614                CRm: u4 = 0b0000,
 2615                decoded12: u4 = 0b0100,
 2616                op1: u3 = 0b000,
 2617                decoded19: u13 = 0b1101010100000,
 2618            };
 2619
 2620            pub const Decoded = union(enum) {
 2621                unallocated,
 2622                msr: Msr,
 2623                cfinv: Cfinv,
 2624                xaflag: Xaflag,
 2625                axflag: Axflag,
 2626            };
 2627            pub fn decode(inst: @This()) @This().Decoded {
 2628                return switch (inst.group.Rt) {
 2629                    else => .unallocated,
 2630                    no_reg => switch (inst.group.op1) {
 2631                        else => .{ .msr = inst.msr },
 2632                        0b000 => switch (inst.group.op2) {
 2633                            else => .{ .msr = inst.msr },
 2634                            0b000 => .{ .cfinv = inst.cfinv },
 2635                            0b001 => .{ .xaflag = inst.xaflag },
 2636                            0b010 => .{ .axflag = inst.axflag },
 2637                        },
 2638                    },
 2639                };
 2640            }
 2641        };
 2642
 2643        /// System with result
 2644        pub const SystemResult = packed struct {
 2645            Rt: Register.Encoded,
 2646            op2: u3,
 2647            CRm: u4,
 2648            CRn: u4,
 2649            op1: u3,
 2650            decoded19: u13 = 0b1101010100100,
 2651        };
 2652
 2653        /// System instructions
 2654        pub const System = packed union {
 2655            group: @This().Group,
 2656            sys: Sys,
 2657            sysl: Sysl,
 2658
 2659            pub const Group = packed struct {
 2660                Rt: Register.Encoded,
 2661                op2: u3,
 2662                CRm: u4,
 2663                CRn: u4,
 2664                op1: u3,
 2665                decoded19: u2 = 0b01,
 2666                L: L,
 2667                decoded22: u10 = 0b1101010100,
 2668            };
 2669
 2670            /// C6.2.372 SYS
 2671            pub const Sys = packed struct {
 2672                Rt: Register.Encoded,
 2673                op2: u3,
 2674                CRm: u4,
 2675                CRn: u4,
 2676                op1: u3,
 2677                decoded19: u2 = 0b01,
 2678                L: L = .sys,
 2679                decoded22: u10 = 0b1101010100,
 2680            };
 2681
 2682            /// C6.2.373 SYSL
 2683            pub const Sysl = packed struct {
 2684                Rt: Register.Encoded,
 2685                op2: u3,
 2686                CRm: u4,
 2687                CRn: u4,
 2688                op1: u3,
 2689                decoded19: u2 = 0b01,
 2690                L: L = .sysl,
 2691                decoded22: u10 = 0b1101010100,
 2692            };
 2693
 2694            const L = enum(u1) {
 2695                sys = 0b0,
 2696                sysl = 0b1,
 2697            };
 2698
 2699            pub const Decoded = union(enum) {
 2700                sys: Sys,
 2701                sysl: Sysl,
 2702            };
 2703            pub fn decode(inst: @This()) @This().Decoded {
 2704                return switch (inst.group.L) {
 2705                    .sys => .{ .sys = inst.sys },
 2706                    .sysl => .{ .sysl = inst.sysl },
 2707                };
 2708            }
 2709        };
 2710
 2711        /// System register move
 2712        pub const SystemRegisterMove = packed union {
 2713            group: @This().Group,
 2714            msr: Msr,
 2715            mrs: Mrs,
 2716
 2717            pub const Group = packed struct {
 2718                Rt: Register.Encoded,
 2719                systemreg: Register.System,
 2720                L: L,
 2721                decoded22: u10 = 0b1101010100,
 2722            };
 2723
 2724            /// C6.2.230 MSR (register)
 2725            pub const Msr = packed struct {
 2726                Rt: Register.Encoded,
 2727                systemreg: Register.System,
 2728                L: L = .msr,
 2729                decoded22: u10 = 0b1101010100,
 2730            };
 2731
 2732            /// C6.2.228 MRS
 2733            pub const Mrs = packed struct {
 2734                Rt: Register.Encoded,
 2735                systemreg: Register.System,
 2736                L: L = .mrs,
 2737                decoded22: u10 = 0b1101010100,
 2738            };
 2739
 2740            pub const L = enum(u1) {
 2741                msr = 0b0,
 2742                mrs = 0b1,
 2743            };
 2744
 2745            pub const Decoded = union(enum) {
 2746                msr: Msr,
 2747                mrs: Mrs,
 2748            };
 2749            pub fn decode(inst: @This()) @This().Decoded {
 2750                return switch (inst.group.L) {
 2751                    .msr => .{ .msr = inst.msr },
 2752                    .mrs => .{ .mrs = inst.mrs },
 2753                };
 2754            }
 2755        };
 2756
 2757        /// Unconditional branch (register)
 2758        pub const UnconditionalBranchRegister = packed union {
 2759            group: @This().Group,
 2760            br: Br,
 2761            blr: Blr,
 2762            ret: Ret,
 2763
 2764            pub const Group = packed struct {
 2765                op4: u5,
 2766                Rn: Register.Encoded,
 2767                op3: u6,
 2768                op2: u5,
 2769                opc: u4,
 2770                decoded25: u7 = 0b1101011,
 2771            };
 2772
 2773            /// C6.2.37 BR
 2774            pub const Br = packed struct {
 2775                Rm: Register.Encoded = @enumFromInt(0),
 2776                Rn: Register.Encoded,
 2777                M: bool = false,
 2778                A: bool = false,
 2779                decoded12: u4 = 0b0000,
 2780                decoded16: u5 = 0b11111,
 2781                op: u2 = 0b00,
 2782                decoded23: u1 = 0b0,
 2783                Z: bool = false,
 2784                decoded25: u7 = 0b1101011,
 2785            };
 2786
 2787            /// C6.2.35 BLR
 2788            pub const Blr = packed struct {
 2789                Rm: Register.Encoded = @enumFromInt(0),
 2790                Rn: Register.Encoded,
 2791                M: bool = false,
 2792                A: bool = false,
 2793                decoded12: u4 = 0b0000,
 2794                decoded16: u5 = 0b11111,
 2795                op: u2 = 0b01,
 2796                decoded23: u1 = 0b0,
 2797                Z: bool = false,
 2798                decoded25: u7 = 0b1101011,
 2799            };
 2800
 2801            /// C6.2.254 RET
 2802            pub const Ret = packed struct {
 2803                Rm: Register.Encoded = @enumFromInt(0),
 2804                Rn: Register.Encoded,
 2805                M: bool = false,
 2806                A: bool = false,
 2807                decoded12: u4 = 0b0000,
 2808                decoded16: u5 = 0b11111,
 2809                op: u2 = 0b10,
 2810                decoded23: u1 = 0b0,
 2811                Z: bool = false,
 2812                decoded25: u7 = 0b1101011,
 2813            };
 2814
 2815            pub const Decoded = union(enum) {
 2816                unallocated,
 2817                br: Br,
 2818                blr: Blr,
 2819                ret: Ret,
 2820            };
 2821            pub fn decode(inst: @This()) @This().Decoded {
 2822                return switch (inst.group.op2) {
 2823                    else => .unallocated,
 2824                    0b11111 => switch (inst.group.opc) {
 2825                        0b0000 => switch (inst.group.op4) {
 2826                            else => .unallocated,
 2827                            0b00000 => .{ .br = inst.br },
 2828                        },
 2829                        0b0001 => switch (inst.group.op4) {
 2830                            else => .unallocated,
 2831                            0b00000 => .{ .blr = inst.blr },
 2832                        },
 2833                        0b0010 => switch (inst.group.op4) {
 2834                            else => .unallocated,
 2835                            0b00000 => .{ .ret = inst.ret },
 2836                        },
 2837                        else => .unallocated,
 2838                    },
 2839                };
 2840            }
 2841        };
 2842
 2843        /// Unconditional branch (immediate)
 2844        pub const UnconditionalBranchImmediate = packed union {
 2845            group: @This().Group,
 2846            b: B,
 2847            bl: Bl,
 2848
 2849            pub const Group = packed struct {
 2850                imm26: i26,
 2851                decoded26: u5 = 0b00101,
 2852                op: Op,
 2853            };
 2854
 2855            /// C6.2.25 B
 2856            pub const B = packed struct {
 2857                imm26: i26,
 2858                decoded26: u5 = 0b00101,
 2859                op: Op = .b,
 2860            };
 2861
 2862            /// C6.2.34 BL
 2863            pub const Bl = packed struct {
 2864                imm26: i26,
 2865                decoded26: u5 = 0b00101,
 2866                op: Op = .bl,
 2867            };
 2868
 2869            pub const Op = enum(u1) {
 2870                b = 0b0,
 2871                bl = 0b1,
 2872            };
 2873
 2874            pub const Decoded = union(enum) {
 2875                b: B,
 2876                bl: Bl,
 2877            };
 2878            pub fn decode(inst: @This()) @This().Decoded {
 2879                return switch (inst.group.op) {
 2880                    .b => .{ .b = inst.b },
 2881                    .bl => .{ .bl = inst.bl },
 2882                };
 2883            }
 2884        };
 2885
 2886        /// Compare and branch (immediate)
 2887        pub const CompareBranchImmediate = packed union {
 2888            group: @This().Group,
 2889            cbz: Cbz,
 2890            cbnz: Cbnz,
 2891
 2892            pub const Group = packed struct {
 2893                Rt: Register.Encoded,
 2894                imm19: i19,
 2895                op: Op,
 2896                decoded25: u6 = 0b011010,
 2897                sf: Register.GeneralSize,
 2898            };
 2899
 2900            /// C6.2.47 CBZ
 2901            pub const Cbz = packed struct {
 2902                Rt: Register.Encoded,
 2903                imm19: i19,
 2904                op: Op = .cbz,
 2905                decoded25: u6 = 0b011010,
 2906                sf: Register.GeneralSize,
 2907            };
 2908
 2909            /// C6.2.46 CBNZ
 2910            pub const Cbnz = packed struct {
 2911                Rt: Register.Encoded,
 2912                imm19: i19,
 2913                op: Op = .cbnz,
 2914                decoded25: u6 = 0b011010,
 2915                sf: Register.GeneralSize,
 2916            };
 2917
 2918            pub const Op = enum(u1) {
 2919                cbz = 0b0,
 2920                cbnz = 0b1,
 2921            };
 2922
 2923            pub const Decoded = union(enum) {
 2924                cbz: Cbz,
 2925                cbnz: Cbnz,
 2926            };
 2927            pub fn decode(inst: @This()) @This().Decoded {
 2928                return switch (inst.group.op) {
 2929                    .cbz => .{ .cbz = inst.cbz },
 2930                    .cbnz => .{ .cbnz = inst.cbnz },
 2931                };
 2932            }
 2933        };
 2934
 2935        /// Test and branch (immediate)
 2936        pub const TestBranchImmediate = packed union {
 2937            group: @This().Group,
 2938            tbz: Tbz,
 2939            tbnz: Tbnz,
 2940
 2941            pub const Group = packed struct {
 2942                Rt: Register.Encoded,
 2943                imm14: i14,
 2944                b40: u5,
 2945                op: Op,
 2946                decoded25: u6 = 0b011011,
 2947                b5: u1,
 2948            };
 2949
 2950            /// C6.2.375 TBZ
 2951            pub const Tbz = packed struct {
 2952                Rt: Register.Encoded,
 2953                imm14: i14,
 2954                b40: u5,
 2955                op: Op = .tbz,
 2956                decoded25: u6 = 0b011011,
 2957                b5: u1,
 2958            };
 2959
 2960            /// C6.2.374 TBNZ
 2961            pub const Tbnz = packed struct {
 2962                Rt: Register.Encoded,
 2963                imm14: i14,
 2964                b40: u5,
 2965                op: Op = .tbnz,
 2966                decoded25: u6 = 0b011011,
 2967                b5: u1,
 2968            };
 2969
 2970            pub const Op = enum(u1) {
 2971                tbz = 0b0,
 2972                tbnz = 0b1,
 2973            };
 2974
 2975            pub const Decoded = union(enum) {
 2976                tbz: Tbz,
 2977                tbnz: Tbnz,
 2978            };
 2979            pub fn decode(inst: @This()) @This().Decoded {
 2980                return switch (inst.group.op) {
 2981                    .tbz => .{ .tbz = inst.tbz },
 2982                    .tbnz => .{ .tbnz = inst.tbnz },
 2983                };
 2984            }
 2985        };
 2986
 2987        pub const no_reg: Register.Encoded = Register.Alias.zr.encode(.{});
 2988
 2989        pub const Decoded = union(enum) {
 2990            unallocated,
 2991            conditional_branch_immediate: ConditionalBranchImmediate,
 2992            exception_generating: ExceptionGenerating,
 2993            system_register_argument: SystemRegisterArgument,
 2994            hints: Hints,
 2995            barriers: Barriers,
 2996            pstate: Pstate,
 2997            system_result: SystemResult,
 2998            system: System,
 2999            system_register_move: SystemRegisterMove,
 3000            unconditional_branch_register: UnconditionalBranchRegister,
 3001            unconditional_branch_immediate: UnconditionalBranchImmediate,
 3002            compare_branch_immediate: CompareBranchImmediate,
 3003            test_branch_immediate: TestBranchImmediate,
 3004        };
 3005        pub fn decode(inst: @This()) @This().Decoded {
 3006            return switch (inst.group.op0) {
 3007                0b010 => switch (inst.group.op1) {
 3008                    0b000000000000000...0b01111111111111 => .{ .conditional_branch_immediate = inst.conditional_branch_immediate },
 3009                    else => .unallocated,
 3010                },
 3011                0b110 => switch (inst.group.op1) {
 3012                    0b00000000000000...0b00111111111111 => .{ .exception_generating = inst.exception_generating },
 3013                    0b01000000110001 => .{ .system_register_argument = inst.system_register_argument },
 3014                    0b01000000110010 => switch (inst.group.op2) {
 3015                        0b11111 => .{ .hints = inst.hints },
 3016                        else => .unallocated,
 3017                    },
 3018                    0b01000000110011 => .{ .barriers = inst.barriers },
 3019                    0b01000000000100,
 3020                    0b01000000010100,
 3021                    0b01000000100100,
 3022                    0b01000000110100,
 3023                    0b01000001000100,
 3024                    0b01000001010100,
 3025                    0b01000001100100,
 3026                    0b01000001110100,
 3027                    => .{ .pstate = inst.pstate },
 3028                    0b01001000000000...0b01001001111111 => .{ .system_result = inst.system_result },
 3029                    0b01000010000000...0b01000011111111, 0b01001010000000...0b01001011111111 => .{ .system = inst.system },
 3030                    0b01000100000000...0b01000111111111, 0b01001100000000...0b01001111111111 => .{ .system_register_move = inst.system_register_move },
 3031                    0b10000000000000...0b11111111111111 => .{ .unconditional_branch_register = inst.unconditional_branch_register },
 3032                    else => .unallocated,
 3033                },
 3034                0b000, 0b100 => .{ .unconditional_branch_immediate = inst.unconditional_branch_immediate },
 3035                0b001, 0b101 => switch (inst.group.op1) {
 3036                    0b00000000000000...0b01111111111111 => .{ .compare_branch_immediate = inst.compare_branch_immediate },
 3037                    0b10000000000000...0b11111111111111 => .{ .test_branch_immediate = inst.test_branch_immediate },
 3038                },
 3039                else => .unallocated,
 3040            };
 3041        }
 3042    };
 3043
 3044    /// C4.1.88 Loads and Stores
 3045    pub const LoadStore = packed union {
 3046        group: @This().Group,
 3047        register_literal: RegisterLiteral,
 3048        memory: Memory,
 3049        no_allocate_pair_offset: NoAllocatePairOffset,
 3050        register_pair_post_indexed: RegisterPairPostIndexed,
 3051        register_pair_offset: RegisterPairOffset,
 3052        register_pair_pre_indexed: RegisterPairPreIndexed,
 3053        register_unscaled_immediate: RegisterUnscaledImmediate,
 3054        register_immediate_post_indexed: RegisterImmediatePostIndexed,
 3055        register_unprivileged: RegisterUnprivileged,
 3056        register_immediate_pre_indexed: RegisterImmediatePreIndexed,
 3057        register_register_offset: RegisterRegisterOffset,
 3058        register_unsigned_immediate: RegisterUnsignedImmediate,
 3059
 3060        /// Table C4-89 Encoding table for the Loads and Stores group
 3061        pub const Group = packed struct {
 3062            encoded0: u10,
 3063            op4: u2,
 3064            encoded12: u4,
 3065            op3: u6,
 3066            encoded22: u1,
 3067            op2: u2,
 3068            decoded25: u1 = 0b0,
 3069            op1: bool,
 3070            decoded27: u1 = 0b1,
 3071            op0: u4,
 3072        };
 3073
 3074        /// Load register (literal)
 3075        pub const RegisterLiteral = packed union {
 3076            group: @This().Group,
 3077            integer: Integer,
 3078            vector: Vector,
 3079
 3080            pub const Group = packed struct {
 3081                Rt: Register.Encoded,
 3082                imm19: i19,
 3083                decoded24: u2 = 0b00,
 3084                V: bool,
 3085                decoded27: u3 = 0b011,
 3086                opc: u2,
 3087            };
 3088
 3089            pub const Integer = packed union {
 3090                group: @This().Group,
 3091                ldr: Ldr,
 3092                ldrsw: Ldrsw,
 3093                prfm: Prfm,
 3094
 3095                pub const Group = packed struct {
 3096                    Rt: Register.Encoded,
 3097                    imm19: i19,
 3098                    decoded24: u2 = 0b00,
 3099                    V: bool = false,
 3100                    decoded27: u3 = 0b011,
 3101                    opc: u2,
 3102                };
 3103
 3104                /// C6.2.167 LDR (literal)
 3105                pub const Ldr = packed struct {
 3106                    Rt: Register.Encoded,
 3107                    imm19: i19,
 3108                    decoded24: u2 = 0b00,
 3109                    V: bool = false,
 3110                    decoded27: u3 = 0b011,
 3111                    sf: Register.GeneralSize,
 3112                    opc1: u1 = 0b0,
 3113                };
 3114
 3115                /// C6.2.179 LDRSW (literal)
 3116                pub const Ldrsw = packed struct {
 3117                    Rt: Register.Encoded,
 3118                    imm19: i19,
 3119                    decoded24: u2 = 0b00,
 3120                    V: bool = false,
 3121                    decoded27: u3 = 0b011,
 3122                    opc: u2 = 0b10,
 3123                };
 3124
 3125                /// C6.2.248 PRFM (literal)
 3126                pub const Prfm = packed struct {
 3127                    prfop: PrfOp,
 3128                    imm19: i19,
 3129                    decoded24: u2 = 0b00,
 3130                    V: bool = false,
 3131                    decoded27: u3 = 0b011,
 3132                    opc: u2 = 0b11,
 3133                };
 3134            };
 3135
 3136            pub const Vector = packed union {
 3137                group: @This().Group,
 3138                ldr: Ldr,
 3139
 3140                pub const Group = packed struct {
 3141                    Rt: Register.Encoded,
 3142                    imm19: i19,
 3143                    decoded24: u2 = 0b00,
 3144                    V: bool = true,
 3145                    decoded27: u3 = 0b011,
 3146                    opc: VectorSize,
 3147                };
 3148
 3149                /// C7.2.192 LDR (literal, SIMD&FP)
 3150                pub const Ldr = packed struct {
 3151                    Rt: Register.Encoded,
 3152                    imm19: i19,
 3153                    decoded24: u2 = 0b00,
 3154                    V: bool = true,
 3155                    decoded27: u3 = 0b011,
 3156                    opc: VectorSize,
 3157                };
 3158            };
 3159
 3160            pub const Decoded = union(enum) {
 3161                integer: Integer,
 3162                vector: Vector,
 3163            };
 3164            pub fn decode(inst: @This()) @This().Decoded {
 3165                return switch (inst.group.V) {
 3166                    false => .{ .integer = inst.integer },
 3167                    true => .{ .vector = inst.vector },
 3168                };
 3169            }
 3170        };
 3171
 3172        /// Memory Copy and Memory Set
 3173        pub const Memory = packed struct {
 3174            Rd: Register.Encoded,
 3175            Rn: Register.Encoded,
 3176            decoded10: u2 = 0b01,
 3177            op2: u4,
 3178            Rs: Register.Encoded,
 3179            decoded21: u1 = 0b0,
 3180            op1: u2,
 3181            decoded24: u2 = 0b01,
 3182            o0: u1,
 3183            decoded27: u3 = 0b011,
 3184            size: Size,
 3185        };
 3186
 3187        /// Load/store no-allocate pair (offset)
 3188        pub const NoAllocatePairOffset = packed struct {
 3189            Rt: Register.Encoded,
 3190            Rn: Register.Encoded,
 3191            Rt2: Register.Encoded,
 3192            imm7: i7,
 3193            L: L,
 3194            decoded23: u3 = 0b000,
 3195            V: bool,
 3196            decoded27: u3 = 0b101,
 3197            opc: u2,
 3198        };
 3199
 3200        /// Load/store register pair (post-indexed)
 3201        pub const RegisterPairPostIndexed = packed union {
 3202            group: @This().Group,
 3203            integer: Integer,
 3204            vector: Vector,
 3205
 3206            pub const Group = packed struct {
 3207                Rt: Register.Encoded,
 3208                Rn: Register.Encoded,
 3209                Rt2: Register.Encoded,
 3210                imm7: i7,
 3211                L: L,
 3212                decoded23: u3 = 0b001,
 3213                V: bool,
 3214                decoded27: u3 = 0b101,
 3215                opc: u2,
 3216            };
 3217
 3218            pub const Integer = packed union {
 3219                group: @This().Group,
 3220                stp: Stp,
 3221                ldp: Ldp,
 3222                ldpsw: Ldpsw,
 3223
 3224                pub const Group = packed struct {
 3225                    Rt: Register.Encoded,
 3226                    Rn: Register.Encoded,
 3227                    Rt2: Register.Encoded,
 3228                    imm7: i7,
 3229                    L: L,
 3230                    decoded23: u3 = 0b001,
 3231                    V: bool = false,
 3232                    decoded27: u3 = 0b101,
 3233                    opc: u2,
 3234                };
 3235
 3236                /// C6.2.321 STP
 3237                pub const Stp = packed struct {
 3238                    Rt: Register.Encoded,
 3239                    Rn: Register.Encoded,
 3240                    Rt2: Register.Encoded,
 3241                    imm7: i7,
 3242                    L: L = .store,
 3243                    decoded23: u3 = 0b001,
 3244                    V: bool = false,
 3245                    decoded27: u3 = 0b101,
 3246                    opc0: u1 = 0b0,
 3247                    sf: Register.GeneralSize,
 3248                };
 3249
 3250                /// C6.2.164 LDP
 3251                pub const Ldp = packed struct {
 3252                    Rt: Register.Encoded,
 3253                    Rn: Register.Encoded,
 3254                    Rt2: Register.Encoded,
 3255                    imm7: i7,
 3256                    L: L = .load,
 3257                    decoded23: u3 = 0b001,
 3258                    V: bool = false,
 3259                    decoded27: u3 = 0b101,
 3260                    opc0: u1 = 0b0,
 3261                    sf: Register.GeneralSize,
 3262                };
 3263
 3264                /// C6.2.165 LDPSW
 3265                pub const Ldpsw = packed struct {
 3266                    Rt: Register.Encoded,
 3267                    Rn: Register.Encoded,
 3268                    Rt2: Register.Encoded,
 3269                    imm7: i7,
 3270                    L: L = .load,
 3271                    decoded23: u3 = 0b001,
 3272                    V: bool = false,
 3273                    decoded27: u3 = 0b101,
 3274                    opc: u2 = 0b01,
 3275                };
 3276
 3277                pub const Decoded = union(enum) {
 3278                    unallocated,
 3279                    stp: Stp,
 3280                    ldp: Ldp,
 3281                    ldpsw: Ldpsw,
 3282                };
 3283                pub fn decode(inst: @This()) @This().Decoded {
 3284                    return switch (inst.group.opc) {
 3285                        0b00, 0b10 => switch (inst.group.L) {
 3286                            .store => .{ .stp = inst.stp },
 3287                            .load => .{ .ldp = inst.ldp },
 3288                        },
 3289                        0b01 => switch (inst.group.L) {
 3290                            else => .unallocated,
 3291                            .load => .{ .ldpsw = inst.ldpsw },
 3292                        },
 3293                        else => .unallocated,
 3294                    };
 3295                }
 3296            };
 3297
 3298            pub const Vector = packed union {
 3299                group: @This().Group,
 3300                stp: Stp,
 3301                ldp: Ldp,
 3302
 3303                pub const Group = packed struct {
 3304                    Rt: Register.Encoded,
 3305                    Rn: Register.Encoded,
 3306                    Rt2: Register.Encoded,
 3307                    imm7: i7,
 3308                    L: L,
 3309                    decoded23: u3 = 0b001,
 3310                    V: bool = true,
 3311                    decoded27: u3 = 0b101,
 3312                    opc: VectorSize,
 3313                };
 3314
 3315                /// C7.2.330 STP (SIMD&FP)
 3316                pub const Stp = packed struct {
 3317                    Rt: Register.Encoded,
 3318                    Rn: Register.Encoded,
 3319                    Rt2: Register.Encoded,
 3320                    imm7: i7,
 3321                    L: L = .store,
 3322                    decoded23: u3 = 0b001,
 3323                    V: bool = true,
 3324                    decoded27: u3 = 0b101,
 3325                    opc: VectorSize,
 3326                };
 3327
 3328                /// C7.2.190 LDP (SIMD&FP)
 3329                pub const Ldp = packed struct {
 3330                    Rt: Register.Encoded,
 3331                    Rn: Register.Encoded,
 3332                    Rt2: Register.Encoded,
 3333                    imm7: i7,
 3334                    L: L = .load,
 3335                    decoded23: u3 = 0b001,
 3336                    V: bool = true,
 3337                    decoded27: u3 = 0b101,
 3338                    opc: VectorSize,
 3339                };
 3340
 3341                pub const Decoded = union(enum) {
 3342                    unallocated,
 3343                    stp: Stp,
 3344                    ldp: Ldp,
 3345                };
 3346                pub fn decode(inst: @This()) @This().Decoded {
 3347                    return switch (inst.group.opc) {
 3348                        .single, .double, .quad => switch (inst.group.L) {
 3349                            .store => .{ .stp = inst.stp },
 3350                            .load => .{ .ldp = inst.ldp },
 3351                        },
 3352                        _ => .unallocated,
 3353                    };
 3354                }
 3355            };
 3356
 3357            pub const Decoded = union(enum) {
 3358                integer: Integer,
 3359                vector: Vector,
 3360            };
 3361            pub fn decode(inst: @This()) @This().Decoded {
 3362                return switch (inst.group.V) {
 3363                    false => .{ .integer = inst.integer },
 3364                    true => .{ .vector = inst.vector },
 3365                };
 3366            }
 3367        };
 3368
 3369        /// Load/store register pair (offset)
 3370        pub const RegisterPairOffset = packed union {
 3371            group: @This().Group,
 3372            integer: Integer,
 3373            vector: Vector,
 3374
 3375            pub const Group = packed struct {
 3376                Rt: Register.Encoded,
 3377                Rn: Register.Encoded,
 3378                Rt2: Register.Encoded,
 3379                imm7: i7,
 3380                L: L,
 3381                decoded23: u3 = 0b010,
 3382                V: bool,
 3383                decoded27: u3 = 0b101,
 3384                opc: u2,
 3385            };
 3386
 3387            pub const Integer = packed union {
 3388                group: @This().Group,
 3389                stp: Stp,
 3390                ldp: Ldp,
 3391                ldpsw: Ldpsw,
 3392
 3393                pub const Group = packed struct {
 3394                    Rt: Register.Encoded,
 3395                    Rn: Register.Encoded,
 3396                    Rt2: Register.Encoded,
 3397                    imm7: i7,
 3398                    L: L,
 3399                    decoded23: u3 = 0b010,
 3400                    V: bool = false,
 3401                    decoded27: u3 = 0b101,
 3402                    opc: u2,
 3403                };
 3404
 3405                /// C6.2.321 STP
 3406                pub const Stp = packed struct {
 3407                    Rt: Register.Encoded,
 3408                    Rn: Register.Encoded,
 3409                    Rt2: Register.Encoded,
 3410                    imm7: i7,
 3411                    L: L = .store,
 3412                    decoded23: u3 = 0b010,
 3413                    V: bool = false,
 3414                    decoded27: u3 = 0b101,
 3415                    opc0: u1 = 0b0,
 3416                    sf: Register.GeneralSize,
 3417                };
 3418
 3419                /// C6.2.164 LDP
 3420                pub const Ldp = packed struct {
 3421                    Rt: Register.Encoded,
 3422                    Rn: Register.Encoded,
 3423                    Rt2: Register.Encoded,
 3424                    imm7: i7,
 3425                    L: L = .load,
 3426                    decoded23: u3 = 0b010,
 3427                    V: bool = false,
 3428                    decoded27: u3 = 0b101,
 3429                    opc0: u1 = 0b0,
 3430                    sf: Register.GeneralSize,
 3431                };
 3432
 3433                /// C6.2.165 LDPSW
 3434                pub const Ldpsw = packed struct {
 3435                    Rt: Register.Encoded,
 3436                    Rn: Register.Encoded,
 3437                    Rt2: Register.Encoded,
 3438                    imm7: i7,
 3439                    L: L = .load,
 3440                    decoded23: u3 = 0b010,
 3441                    V: bool = false,
 3442                    decoded27: u3 = 0b101,
 3443                    opc: u2 = 0b01,
 3444                };
 3445
 3446                pub const Decoded = union(enum) {
 3447                    unallocated,
 3448                    stp: Stp,
 3449                    ldp: Ldp,
 3450                    ldpsw: Ldpsw,
 3451                };
 3452                pub fn decode(inst: @This()) @This().Decoded {
 3453                    return switch (inst.group.opc) {
 3454                        0b00, 0b10 => switch (inst.group.L) {
 3455                            .store => .{ .stp = inst.stp },
 3456                            .load => .{ .ldp = inst.ldp },
 3457                        },
 3458                        0b01 => switch (inst.group.L) {
 3459                            else => .unallocated,
 3460                            .load => .{ .ldpsw = inst.ldpsw },
 3461                        },
 3462                        else => .unallocated,
 3463                    };
 3464                }
 3465            };
 3466
 3467            pub const Vector = packed union {
 3468                group: @This().Group,
 3469                stp: Stp,
 3470                ldp: Ldp,
 3471
 3472                pub const Group = packed struct {
 3473                    Rt: Register.Encoded,
 3474                    Rn: Register.Encoded,
 3475                    Rt2: Register.Encoded,
 3476                    imm7: i7,
 3477                    L: L,
 3478                    decoded23: u3 = 0b010,
 3479                    V: bool = true,
 3480                    decoded27: u3 = 0b101,
 3481                    opc: VectorSize,
 3482                };
 3483
 3484                /// C7.2.330 STP (SIMD&FP)
 3485                pub const Stp = packed struct {
 3486                    Rt: Register.Encoded,
 3487                    Rn: Register.Encoded,
 3488                    Rt2: Register.Encoded,
 3489                    imm7: i7,
 3490                    L: L = .store,
 3491                    decoded23: u3 = 0b010,
 3492                    V: bool = true,
 3493                    decoded27: u3 = 0b101,
 3494                    opc: VectorSize,
 3495                };
 3496
 3497                /// C7.2.190 LDP (SIMD&FP)
 3498                pub const Ldp = packed struct {
 3499                    Rt: Register.Encoded,
 3500                    Rn: Register.Encoded,
 3501                    Rt2: Register.Encoded,
 3502                    imm7: i7,
 3503                    L: L = .load,
 3504                    decoded23: u3 = 0b010,
 3505                    V: bool = true,
 3506                    decoded27: u3 = 0b101,
 3507                    opc: VectorSize,
 3508                };
 3509
 3510                pub const Decoded = union(enum) {
 3511                    unallocated,
 3512                    stp: Stp,
 3513                    ldp: Ldp,
 3514                };
 3515                pub fn decode(inst: @This()) @This().Decoded {
 3516                    return switch (inst.group.opc) {
 3517                        .single, .double, .quad => switch (inst.group.L) {
 3518                            .store => .{ .stp = inst.stp },
 3519                            .load => .{ .ldp = inst.ldp },
 3520                        },
 3521                        _ => .unallocated,
 3522                    };
 3523                }
 3524            };
 3525
 3526            pub const Decoded = union(enum) {
 3527                integer: Integer,
 3528                vector: Vector,
 3529            };
 3530            pub fn decode(inst: @This()) @This().Decoded {
 3531                return switch (inst.group.V) {
 3532                    false => .{ .integer = inst.integer },
 3533                    true => .{ .vector = inst.vector },
 3534                };
 3535            }
 3536        };
 3537
 3538        /// Load/store register pair (pre-indexed)
 3539        pub const RegisterPairPreIndexed = packed union {
 3540            group: @This().Group,
 3541            integer: Integer,
 3542            vector: Vector,
 3543
 3544            pub const Group = packed struct {
 3545                Rt: Register.Encoded,
 3546                Rn: Register.Encoded,
 3547                Rt2: Register.Encoded,
 3548                imm7: i7,
 3549                L: L,
 3550                decoded23: u3 = 0b011,
 3551                V: bool,
 3552                decoded27: u3 = 0b101,
 3553                opc: u2,
 3554            };
 3555
 3556            pub const Integer = packed union {
 3557                group: @This().Group,
 3558                stp: Stp,
 3559                ldp: Ldp,
 3560                ldpsw: Ldpsw,
 3561
 3562                pub const Group = packed struct {
 3563                    Rt: Register.Encoded,
 3564                    Rn: Register.Encoded,
 3565                    Rt2: Register.Encoded,
 3566                    imm7: i7,
 3567                    L: L,
 3568                    decoded23: u3 = 0b011,
 3569                    V: bool = false,
 3570                    decoded27: u3 = 0b101,
 3571                    opc: u2,
 3572                };
 3573
 3574                /// C6.2.321 STP
 3575                pub const Stp = packed struct {
 3576                    Rt: Register.Encoded,
 3577                    Rn: Register.Encoded,
 3578                    Rt2: Register.Encoded,
 3579                    imm7: i7,
 3580                    L: L = .store,
 3581                    decoded23: u3 = 0b011,
 3582                    V: bool = false,
 3583                    decoded27: u3 = 0b101,
 3584                    opc0: u1 = 0b0,
 3585                    sf: Register.GeneralSize,
 3586                };
 3587
 3588                /// C6.2.164 LDP
 3589                pub const Ldp = packed struct {
 3590                    Rt: Register.Encoded,
 3591                    Rn: Register.Encoded,
 3592                    Rt2: Register.Encoded,
 3593                    imm7: i7,
 3594                    L: L = .load,
 3595                    decoded23: u3 = 0b011,
 3596                    V: bool = false,
 3597                    decoded27: u3 = 0b101,
 3598                    opc0: u1 = 0b0,
 3599                    sf: Register.GeneralSize,
 3600                };
 3601
 3602                /// C6.2.165 LDPSW
 3603                pub const Ldpsw = packed struct {
 3604                    Rt: Register.Encoded,
 3605                    Rn: Register.Encoded,
 3606                    Rt2: Register.Encoded,
 3607                    imm7: i7,
 3608                    L: L = .load,
 3609                    decoded23: u3 = 0b011,
 3610                    V: bool = false,
 3611                    decoded27: u3 = 0b101,
 3612                    opc0: u2 = 0b01,
 3613                };
 3614
 3615                pub const Decoded = union(enum) {
 3616                    unallocated,
 3617                    stp: Stp,
 3618                    ldp: Ldp,
 3619                    ldpsw: Ldpsw,
 3620                };
 3621                pub fn decode(inst: @This()) @This().Decoded {
 3622                    return switch (inst.group.opc) {
 3623                        0b00, 0b10 => switch (inst.group.L) {
 3624                            .store => .{ .stp = inst.stp },
 3625                            .load => .{ .ldp = inst.ldp },
 3626                        },
 3627                        0b01 => switch (inst.group.L) {
 3628                            else => .unallocated,
 3629                            .load => .{ .ldpsw = inst.ldpsw },
 3630                        },
 3631                        else => .unallocated,
 3632                    };
 3633                }
 3634            };
 3635
 3636            pub const Vector = packed union {
 3637                group: @This().Group,
 3638                stp: Stp,
 3639                ldp: Ldp,
 3640
 3641                pub const Group = packed struct {
 3642                    Rt: Register.Encoded,
 3643                    Rn: Register.Encoded,
 3644                    Rt2: Register.Encoded,
 3645                    imm7: i7,
 3646                    L: L,
 3647                    decoded23: u3 = 0b011,
 3648                    V: bool = true,
 3649                    decoded27: u3 = 0b101,
 3650                    opc: VectorSize,
 3651                };
 3652
 3653                /// C7.2.330 STP (SIMD&FP)
 3654                pub const Stp = packed struct {
 3655                    Rt: Register.Encoded,
 3656                    Rn: Register.Encoded,
 3657                    Rt2: Register.Encoded,
 3658                    imm7: i7,
 3659                    L: L = .store,
 3660                    decoded23: u3 = 0b011,
 3661                    V: bool = true,
 3662                    decoded27: u3 = 0b101,
 3663                    opc: VectorSize,
 3664                };
 3665
 3666                /// C7.2.190 LDP (SIMD&FP)
 3667                pub const Ldp = packed struct {
 3668                    Rt: Register.Encoded,
 3669                    Rn: Register.Encoded,
 3670                    Rt2: Register.Encoded,
 3671                    imm7: i7,
 3672                    L: L = .load,
 3673                    decoded23: u3 = 0b011,
 3674                    V: bool = true,
 3675                    decoded27: u3 = 0b101,
 3676                    opc: VectorSize,
 3677                };
 3678
 3679                pub const Decoded = union(enum) {
 3680                    unallocated,
 3681                    stp: Stp,
 3682                    ldp: Ldp,
 3683                };
 3684                pub fn decode(inst: @This()) @This().Decoded {
 3685                    return switch (inst.group.opc) {
 3686                        .single, .double, .quad => switch (inst.group.L) {
 3687                            .store => .{ .stp = inst.stp },
 3688                            .load => .{ .ldp = inst.ldp },
 3689                        },
 3690                        _ => .unallocated,
 3691                    };
 3692                }
 3693            };
 3694
 3695            pub const Decoded = union(enum) {
 3696                integer: Integer,
 3697                vector: Vector,
 3698            };
 3699            pub fn decode(inst: @This()) @This().Decoded {
 3700                return switch (inst.group.V) {
 3701                    false => .{ .integer = inst.integer },
 3702                    true => .{ .vector = inst.vector },
 3703                };
 3704            }
 3705        };
 3706
 3707        /// Load/store register (unscaled immediate)
 3708        pub const RegisterUnscaledImmediate = packed union {
 3709            group: @This().Group,
 3710            integer: Integer,
 3711            vector: Vector,
 3712
 3713            pub const Group = packed struct {
 3714                Rt: Register.Encoded,
 3715                Rn: Register.Encoded,
 3716                decoded10: u2 = 0b00,
 3717                imm9: i9,
 3718                decoded21: u1 = 0b0,
 3719                opc: u2,
 3720                decoded24: u2 = 0b00,
 3721                V: bool,
 3722                decoded27: u3 = 0b111,
 3723                size: u2,
 3724            };
 3725
 3726            pub const Integer = packed union {
 3727                group: @This().Group,
 3728                sturb: Sturb,
 3729                ldurb: Ldurb,
 3730                ldursb: Ldursb,
 3731                sturh: Sturh,
 3732                ldurh: Ldurh,
 3733                ldursh: Ldursh,
 3734                stur: Stur,
 3735                ldur: Ldur,
 3736                ldursw: Ldursw,
 3737                prfum: Prfum,
 3738
 3739                pub const Group = packed struct {
 3740                    Rt: Register.Encoded,
 3741                    Rn: Register.Encoded,
 3742                    decoded10: u2 = 0b00,
 3743                    imm9: i9,
 3744                    decoded21: u1 = 0b0,
 3745                    opc: u2,
 3746                    decoded24: u2 = 0b00,
 3747                    V: bool = false,
 3748                    decoded27: u3 = 0b111,
 3749                    size: Size,
 3750                };
 3751
 3752                /// C6.2.347 STURB
 3753                pub const Sturb = packed struct {
 3754                    Rt: Register.Encoded,
 3755                    Rn: Register.Encoded,
 3756                    decoded10: u2 = 0b00,
 3757                    imm9: i9,
 3758                    decoded21: u1 = 0b0,
 3759                    opc: u2 = 0b00,
 3760                    decoded24: u2 = 0b00,
 3761                    V: bool = false,
 3762                    decoded27: u3 = 0b111,
 3763                    size: Size = .byte,
 3764                };
 3765
 3766                /// C6.2.203 LDURB
 3767                pub const Ldurb = packed struct {
 3768                    Rt: Register.Encoded,
 3769                    Rn: Register.Encoded,
 3770                    decoded10: u2 = 0b00,
 3771                    imm9: i9,
 3772                    decoded21: u1 = 0b0,
 3773                    opc: u2 = 0b01,
 3774                    decoded24: u2 = 0b00,
 3775                    V: bool = false,
 3776                    decoded27: u3 = 0b111,
 3777                    size: Size = .byte,
 3778                };
 3779
 3780                /// C6.2.205 LDURSB
 3781                pub const Ldursb = packed struct {
 3782                    Rt: Register.Encoded,
 3783                    Rn: Register.Encoded,
 3784                    decoded10: u2 = 0b00,
 3785                    imm9: i9,
 3786                    decoded21: u1 = 0b0,
 3787                    opc0: u1,
 3788                    opc1: u1 = 0b1,
 3789                    decoded24: u2 = 0b00,
 3790                    V: bool = false,
 3791                    decoded27: u3 = 0b111,
 3792                    size: Size = .byte,
 3793                };
 3794
 3795                /// C6.2.348 STURH
 3796                pub const Sturh = packed struct {
 3797                    Rt: Register.Encoded,
 3798                    Rn: Register.Encoded,
 3799                    decoded10: u2 = 0b00,
 3800                    imm9: i9,
 3801                    decoded21: u1 = 0b0,
 3802                    opc: u2 = 0b00,
 3803                    decoded24: u2 = 0b00,
 3804                    V: bool = false,
 3805                    decoded27: u3 = 0b111,
 3806                    size: Size = .halfword,
 3807                };
 3808
 3809                /// C6.2.204 LDURH
 3810                pub const Ldurh = packed struct {
 3811                    Rt: Register.Encoded,
 3812                    Rn: Register.Encoded,
 3813                    decoded10: u2 = 0b00,
 3814                    imm9: i9,
 3815                    decoded21: u1 = 0b0,
 3816                    opc: u2 = 0b01,
 3817                    decoded24: u2 = 0b00,
 3818                    V: bool = false,
 3819                    decoded27: u3 = 0b111,
 3820                    size: Size = .halfword,
 3821                };
 3822
 3823                /// C6.2.206 LDURSH
 3824                pub const Ldursh = packed struct {
 3825                    Rt: Register.Encoded,
 3826                    Rn: Register.Encoded,
 3827                    decoded10: u2 = 0b00,
 3828                    imm9: i9,
 3829                    decoded21: u1 = 0b0,
 3830                    opc0: u1,
 3831                    opc1: u1 = 0b1,
 3832                    decoded24: u2 = 0b00,
 3833                    V: bool = false,
 3834                    decoded27: u3 = 0b111,
 3835                    size: Size = .halfword,
 3836                };
 3837
 3838                /// C6.2.346 STUR
 3839                pub const Stur = packed struct {
 3840                    Rt: Register.Encoded,
 3841                    Rn: Register.Encoded,
 3842                    decoded10: u2 = 0b00,
 3843                    imm9: i9,
 3844                    decoded21: u1 = 0b0,
 3845                    opc: u2 = 0b00,
 3846                    decoded24: u2 = 0b00,
 3847                    V: bool = false,
 3848                    decoded27: u3 = 0b111,
 3849                    sf: Register.GeneralSize,
 3850                    size1: u1 = 0b1,
 3851                };
 3852
 3853                /// C6.2.202 LDUR
 3854                pub const Ldur = packed struct {
 3855                    Rt: Register.Encoded,
 3856                    Rn: Register.Encoded,
 3857                    decoded10: u2 = 0b00,
 3858                    imm9: i9,
 3859                    decoded21: u1 = 0b0,
 3860                    opc: u2 = 0b01,
 3861                    decoded24: u2 = 0b00,
 3862                    V: bool = false,
 3863                    decoded27: u3 = 0b111,
 3864                    sf: Register.GeneralSize,
 3865                    size1: u1 = 0b1,
 3866                };
 3867
 3868                /// C6.2.207 LDURSW
 3869                pub const Ldursw = packed struct {
 3870                    Rt: Register.Encoded,
 3871                    Rn: Register.Encoded,
 3872                    decoded10: u2 = 0b00,
 3873                    imm9: i9,
 3874                    decoded21: u1 = 0b0,
 3875                    opc: u2 = 0b10,
 3876                    decoded24: u2 = 0b00,
 3877                    V: bool = false,
 3878                    decoded27: u3 = 0b111,
 3879                    size: Size = .word,
 3880                };
 3881
 3882                /// C6.2.250 PRFUM
 3883                pub const Prfum = packed struct {
 3884                    prfop: PrfOp,
 3885                    Rn: Register.Encoded,
 3886                    decoded10: u2 = 0b00,
 3887                    imm9: i9,
 3888                    decoded21: u1 = 0b0,
 3889                    opc: u2 = 0b10,
 3890                    decoded24: u2 = 0b00,
 3891                    V: bool = false,
 3892                    decoded27: u3 = 0b111,
 3893                    size: Size = .doubleword,
 3894                };
 3895
 3896                pub const Decoded = union(enum) {
 3897                    unallocated,
 3898                    sturb: Sturb,
 3899                    ldurb: Ldurb,
 3900                    ldursb: Ldursb,
 3901                    sturh: Sturh,
 3902                    ldurh: Ldurh,
 3903                    ldursh: Ldursh,
 3904                    stur: Stur,
 3905                    ldur: Ldur,
 3906                    ldursw: Ldursw,
 3907                    prfum: Prfum,
 3908                };
 3909                pub fn decode(inst: @This()) @This().Decoded {
 3910                    return switch (inst.group.size) {
 3911                        .byte => switch (inst.group.V) {
 3912                            false => switch (inst.group.opc) {
 3913                                0b00 => .{ .sturb = inst.sturb },
 3914                                0b01 => .{ .ldurb = inst.ldurb },
 3915                                0b10, 0b11 => .{ .ldursb = inst.ldursb },
 3916                            },
 3917                            true => .unallocated,
 3918                        },
 3919                        .halfword => switch (inst.group.V) {
 3920                            false => switch (inst.group.opc) {
 3921                                0b00 => .{ .sturh = inst.sturh },
 3922                                0b01 => .{ .ldurh = inst.ldurh },
 3923                                0b10, 0b11 => .{ .ldursh = inst.ldursh },
 3924                            },
 3925                            true => .unallocated,
 3926                        },
 3927                        .word => switch (inst.group.V) {
 3928                            false => switch (inst.group.opc) {
 3929                                0b00 => .{ .stur = inst.stur },
 3930                                0b01 => .{ .ldur = inst.ldur },
 3931                                0b10 => .{ .ldursw = inst.ldursw },
 3932                                0b11 => .unallocated,
 3933                            },
 3934                            true => .unallocated,
 3935                        },
 3936                        .doubleword => switch (inst.group.V) {
 3937                            false => switch (inst.group.opc) {
 3938                                0b00 => .{ .stur = inst.stur },
 3939                                0b01 => .{ .ldur = inst.ldur },
 3940                                0b10 => .{ .prfum = inst.prfum },
 3941                                0b11 => .unallocated,
 3942                            },
 3943                            true => .unallocated,
 3944                        },
 3945                    };
 3946                }
 3947            };
 3948
 3949            pub const Vector = packed union {
 3950                group: @This().Group,
 3951                stur: Stur,
 3952                ldur: Ldur,
 3953
 3954                pub const Group = packed struct {
 3955                    Rt: Register.Encoded,
 3956                    Rn: Register.Encoded,
 3957                    decoded10: u2 = 0b00,
 3958                    imm9: i9,
 3959                    decoded21: u1 = 0b0,
 3960                    opc0: L,
 3961                    opc1: Opc1,
 3962                    decoded24: u2 = 0b00,
 3963                    V: bool = true,
 3964                    decoded27: u3 = 0b111,
 3965                    size: Vector.Size,
 3966                };
 3967
 3968                /// C7.2.333 STUR (SIMD&FP)
 3969                pub const Stur = packed struct {
 3970                    Rt: Register.Encoded,
 3971                    Rn: Register.Encoded,
 3972                    decoded10: u2 = 0b00,
 3973                    imm9: i9,
 3974                    decoded21: u1 = 0b0,
 3975                    opc0: L = .store,
 3976                    opc1: Opc1,
 3977                    decoded24: u2 = 0b00,
 3978                    V: bool = true,
 3979                    decoded27: u3 = 0b111,
 3980                    size: Vector.Size,
 3981                };
 3982
 3983                /// C7.2.194 LDUR (SIMD&FP)
 3984                pub const Ldur = packed struct {
 3985                    Rt: Register.Encoded,
 3986                    Rn: Register.Encoded,
 3987                    decoded10: u2 = 0b00,
 3988                    imm9: i9,
 3989                    decoded21: u1 = 0b0,
 3990                    opc0: L = .load,
 3991                    opc1: Opc1,
 3992                    decoded24: u2 = 0b00,
 3993                    V: bool = true,
 3994                    decoded27: u3 = 0b111,
 3995                    size: Vector.Size,
 3996                };
 3997
 3998                pub const Opc1 = packed struct {
 3999                    encoded: u1,
 4000
 4001                    pub fn encode(ss: Register.ScalarSize) Opc1 {
 4002                        return .{ .encoded = switch (ss) {
 4003                            .byte, .half, .single, .double => 0b0,
 4004                            .quad => 0b1,
 4005                        } };
 4006                    }
 4007
 4008                    pub fn decode(enc_opc1: Opc1, enc_size: Vector.Size) Register.ScalarSize {
 4009                        return switch (enc_size.encoded) {
 4010                            0b00 => switch (enc_opc1.encoded) {
 4011                                0b0 => .byte,
 4012                                0b1 => .quad,
 4013                            },
 4014                            0b01 => switch (enc_opc1.encoded) {
 4015                                0b0 => .half,
 4016                                0b1 => unreachable,
 4017                            },
 4018                            0b10 => switch (enc_opc1.encoded) {
 4019                                0b0 => .single,
 4020                                0b1 => unreachable,
 4021                            },
 4022                            0b11 => switch (enc_opc1.encoded) {
 4023                                0b0 => .double,
 4024                                0b1 => unreachable,
 4025                            },
 4026                        };
 4027                    }
 4028                };
 4029
 4030                pub const Size = packed struct {
 4031                    encoded: u2,
 4032
 4033                    pub fn encode(ss: Register.ScalarSize) Vector.Size {
 4034                        return .{ .encoded = switch (ss) {
 4035                            .byte, .quad => 0b00,
 4036                            .half => 0b01,
 4037                            .single => 0b10,
 4038                            .double => 0b11,
 4039                        } };
 4040                    }
 4041                };
 4042
 4043                pub const Decoded = union(enum) {
 4044                    unallocated,
 4045                    stur: Stur,
 4046                    ldur: Ldur,
 4047                };
 4048                pub fn decode(inst: @This()) @This().Decoded {
 4049                    return switch (inst.group.size.encoded) {
 4050                        0b00 => switch (inst.group.opc0) {
 4051                            .store => .{ .stur = inst.stur },
 4052                            .load => .{ .ldur = inst.ldur },
 4053                        },
 4054                        0b01, 0b10, 0b11 => switch (inst.group.opc1.encoded) {
 4055                            0b0 => switch (inst.group.opc0) {
 4056                                .store => .{ .stur = inst.stur },
 4057                                .load => .{ .ldur = inst.ldur },
 4058                            },
 4059                            0b1 => .unallocated,
 4060                        },
 4061                    };
 4062                }
 4063            };
 4064
 4065            pub const Decoded = union(enum) {
 4066                integer: Integer,
 4067                vector: Vector,
 4068            };
 4069            pub fn decode(inst: @This()) @This().Decoded {
 4070                return switch (inst.group.V) {
 4071                    false => .{ .integer = inst.integer },
 4072                    true => .{ .vector = inst.vector },
 4073                };
 4074            }
 4075        };
 4076
 4077        /// Load/store register (immediate post-indexed)
 4078        pub const RegisterImmediatePostIndexed = packed union {
 4079            group: @This().Group,
 4080            integer: Integer,
 4081            vector: Vector,
 4082
 4083            pub const Group = packed struct {
 4084                Rt: Register.Encoded,
 4085                Rn: Register.Encoded,
 4086                decoded10: u2 = 0b01,
 4087                imm9: i9,
 4088                decoded21: u1 = 0b0,
 4089                opc: u2,
 4090                decoded24: u2 = 0b00,
 4091                V: bool,
 4092                decoded27: u3 = 0b111,
 4093                size: u2,
 4094            };
 4095
 4096            pub const Integer = packed union {
 4097                group: @This().Group,
 4098                strb: Strb,
 4099                ldrb: Ldrb,
 4100                ldrsb: Ldrsb,
 4101                strh: Strh,
 4102                ldrh: Ldrh,
 4103                ldrsh: Ldrsh,
 4104                str: Str,
 4105                ldr: Ldr,
 4106                ldrsw: Ldrsw,
 4107
 4108                pub const Group = packed struct {
 4109                    Rt: Register.Encoded,
 4110                    Rn: Register.Encoded,
 4111                    decoded10: u2 = 0b01,
 4112                    imm9: i9,
 4113                    decoded21: u1 = 0b0,
 4114                    opc: u2,
 4115                    decoded24: u2 = 0b00,
 4116                    V: bool = false,
 4117                    decoded27: u3 = 0b111,
 4118                    size: Size,
 4119                };
 4120
 4121                /// C6.2.324 STRB (immediate)
 4122                pub const Strb = packed struct {
 4123                    Rt: Register.Encoded,
 4124                    Rn: Register.Encoded,
 4125                    decoded10: u2 = 0b01,
 4126                    imm9: i9,
 4127                    decoded21: u1 = 0b0,
 4128                    opc: u2 = 0b00,
 4129                    decoded24: u2 = 0b00,
 4130                    V: bool = false,
 4131                    decoded27: u3 = 0b111,
 4132                    size: Size = .byte,
 4133                };
 4134
 4135                /// C6.2.170 LDRB (immediate)
 4136                pub const Ldrb = packed struct {
 4137                    Rt: Register.Encoded,
 4138                    Rn: Register.Encoded,
 4139                    decoded10: u2 = 0b01,
 4140                    imm9: i9,
 4141                    decoded21: u1 = 0b0,
 4142                    opc: u2 = 0b01,
 4143                    decoded24: u2 = 0b00,
 4144                    V: bool = false,
 4145                    decoded27: u3 = 0b111,
 4146                    size: Size = .byte,
 4147                };
 4148
 4149                /// C6.2.174 LDRSB (immediate)
 4150                pub const Ldrsb = packed struct {
 4151                    Rt: Register.Encoded,
 4152                    Rn: Register.Encoded,
 4153                    decoded10: u2 = 0b01,
 4154                    imm9: i9,
 4155                    decoded21: u1 = 0b0,
 4156                    opc0: u1,
 4157                    opc1: u1 = 0b1,
 4158                    decoded24: u2 = 0b00,
 4159                    V: bool = false,
 4160                    decoded27: u3 = 0b111,
 4161                    size: Size = .byte,
 4162                };
 4163
 4164                /// C6.2.326 STRH (immediate)
 4165                pub const Strh = packed struct {
 4166                    Rt: Register.Encoded,
 4167                    Rn: Register.Encoded,
 4168                    decoded10: u2 = 0b01,
 4169                    imm9: i9,
 4170                    decoded21: u1 = 0b0,
 4171                    opc: u2 = 0b00,
 4172                    decoded24: u2 = 0b00,
 4173                    V: bool = false,
 4174                    decoded27: u3 = 0b111,
 4175                    size: Size = .halfword,
 4176                };
 4177
 4178                /// C6.2.172 LDRH (immediate)
 4179                pub const Ldrh = packed struct {
 4180                    Rt: Register.Encoded,
 4181                    Rn: Register.Encoded,
 4182                    decoded10: u2 = 0b01,
 4183                    imm9: i9,
 4184                    decoded21: u1 = 0b0,
 4185                    opc: u2 = 0b01,
 4186                    decoded24: u2 = 0b00,
 4187                    V: bool = false,
 4188                    decoded27: u3 = 0b111,
 4189                    size: Size = .halfword,
 4190                };
 4191
 4192                /// C6.2.176 LDRSH (immediate)
 4193                pub const Ldrsh = packed struct {
 4194                    Rt: Register.Encoded,
 4195                    Rn: Register.Encoded,
 4196                    decoded10: u2 = 0b01,
 4197                    imm9: i9,
 4198                    decoded21: u1 = 0b0,
 4199                    opc0: u1,
 4200                    opc1: u1 = 0b1,
 4201                    decoded24: u2 = 0b00,
 4202                    V: bool = false,
 4203                    decoded27: u3 = 0b111,
 4204                    size: Size = .halfword,
 4205                };
 4206
 4207                /// C6.2.322 STR (immediate)
 4208                pub const Str = packed struct {
 4209                    Rt: Register.Encoded,
 4210                    Rn: Register.Encoded,
 4211                    decoded10: u2 = 0b01,
 4212                    imm9: i9,
 4213                    decoded21: u1 = 0b0,
 4214                    opc: u2 = 0b00,
 4215                    decoded24: u2 = 0b00,
 4216                    V: bool = false,
 4217                    decoded27: u3 = 0b111,
 4218                    sf: Register.GeneralSize,
 4219                    size1: u1 = 0b1,
 4220                };
 4221
 4222                /// C6.2.166 LDR (immediate)
 4223                pub const Ldr = packed struct {
 4224                    Rt: Register.Encoded,
 4225                    Rn: Register.Encoded,
 4226                    decoded10: u2 = 0b01,
 4227                    imm9: i9,
 4228                    decoded21: u1 = 0b0,
 4229                    opc: u2 = 0b01,
 4230                    decoded24: u2 = 0b00,
 4231                    V: bool = false,
 4232                    decoded27: u3 = 0b111,
 4233                    sf: Register.GeneralSize,
 4234                    size1: u1 = 0b1,
 4235                };
 4236
 4237                /// C6.2.178 LDRSW (immediate)
 4238                pub const Ldrsw = packed struct {
 4239                    Rt: Register.Encoded,
 4240                    Rn: Register.Encoded,
 4241                    decoded10: u2 = 0b01,
 4242                    imm9: i9,
 4243                    decoded21: u1 = 0b0,
 4244                    opc: u2 = 0b10,
 4245                    decoded24: u2 = 0b00,
 4246                    V: bool = false,
 4247                    decoded27: u3 = 0b111,
 4248                    size: Size = .word,
 4249                };
 4250
 4251                pub const Decoded = union(enum) {
 4252                    unallocated,
 4253                    strb: Strb,
 4254                    ldrb: Ldrb,
 4255                    ldrsb: Ldrsb,
 4256                    strh: Strh,
 4257                    ldrh: Ldrh,
 4258                    ldrsh: Ldrsh,
 4259                    str: Str,
 4260                    ldr: Ldr,
 4261                    ldrsw: Ldrsw,
 4262                };
 4263                pub fn decode(inst: @This()) @This().Decoded {
 4264                    return switch (inst.group.size) {
 4265                        .byte => switch (inst.group.V) {
 4266                            false => switch (inst.group.opc) {
 4267                                0b00 => .{ .strb = inst.strb },
 4268                                0b01 => .{ .ldrb = inst.ldrb },
 4269                                0b10, 0b11 => .{ .ldrsb = inst.ldrsb },
 4270                            },
 4271                            true => .unallocated,
 4272                        },
 4273                        .halfword => switch (inst.group.V) {
 4274                            false => switch (inst.group.opc) {
 4275                                0b00 => .{ .strh = inst.strh },
 4276                                0b01 => .{ .ldrh = inst.ldrh },
 4277                                0b10, 0b11 => .{ .ldrsh = inst.ldrsh },
 4278                            },
 4279                            true => .unallocated,
 4280                        },
 4281                        .word => switch (inst.group.V) {
 4282                            false => switch (inst.group.opc) {
 4283                                0b00 => .{ .str = inst.str },
 4284                                0b01 => .{ .ldr = inst.ldr },
 4285                                0b10 => .{ .ldrsw = inst.ldrsw },
 4286                                0b11 => .unallocated,
 4287                            },
 4288                            true => .unallocated,
 4289                        },
 4290                        .doubleword => switch (inst.group.V) {
 4291                            false => switch (inst.group.opc) {
 4292                                0b00 => .{ .str = inst.str },
 4293                                0b01 => .{ .ldr = inst.ldr },
 4294                                0b10, 0b11 => .unallocated,
 4295                            },
 4296                            true => .unallocated,
 4297                        },
 4298                    };
 4299                }
 4300            };
 4301
 4302            pub const Vector = packed union {
 4303                group: @This().Group,
 4304                str: Str,
 4305                ldr: Ldr,
 4306
 4307                pub const Group = packed struct {
 4308                    Rt: Register.Encoded,
 4309                    Rn: Register.Encoded,
 4310                    decoded10: u2 = 0b01,
 4311                    imm9: i9,
 4312                    decoded21: u1 = 0b0,
 4313                    opc0: L,
 4314                    opc1: Opc1,
 4315                    decoded24: u2 = 0b00,
 4316                    V: bool = true,
 4317                    decoded27: u3 = 0b111,
 4318                    size: Vector.Size,
 4319                };
 4320
 4321                /// C7.2.331 STR (immediate, SIMD&FP)
 4322                pub const Str = packed struct {
 4323                    Rt: Register.Encoded,
 4324                    Rn: Register.Encoded,
 4325                    decoded10: u2 = 0b01,
 4326                    imm9: i9,
 4327                    decoded21: u1 = 0b0,
 4328                    opc0: L = .store,
 4329                    opc1: Opc1,
 4330                    decoded24: u2 = 0b00,
 4331                    V: bool = true,
 4332                    decoded27: u3 = 0b111,
 4333                    size: Vector.Size,
 4334                };
 4335
 4336                /// C7.2.191 LDR (immediate, SIMD&FP)
 4337                pub const Ldr = packed struct {
 4338                    Rt: Register.Encoded,
 4339                    Rn: Register.Encoded,
 4340                    decoded10: u2 = 0b01,
 4341                    imm9: i9,
 4342                    decoded21: u1 = 0b0,
 4343                    opc0: L = .load,
 4344                    opc1: Opc1,
 4345                    decoded24: u2 = 0b00,
 4346                    V: bool = true,
 4347                    decoded27: u3 = 0b111,
 4348                    size: Vector.Size,
 4349                };
 4350
 4351                pub const Opc1 = packed struct {
 4352                    encoded: u1,
 4353
 4354                    pub fn encode(ss: Register.ScalarSize) Opc1 {
 4355                        return .{ .encoded = switch (ss) {
 4356                            .byte, .half, .single, .double => 0b0,
 4357                            .quad => 0b1,
 4358                        } };
 4359                    }
 4360
 4361                    pub fn decode(enc_opc1: Opc1, enc_size: Vector.Size) Register.ScalarSize {
 4362                        return switch (enc_size.encoded) {
 4363                            0b00 => switch (enc_opc1.encoded) {
 4364                                0b0 => .byte,
 4365                                0b1 => .quad,
 4366                            },
 4367                            0b01 => switch (enc_opc1.encoded) {
 4368                                0b0 => .half,
 4369                                0b1 => unreachable,
 4370                            },
 4371                            0b10 => switch (enc_opc1.encoded) {
 4372                                0b0 => .single,
 4373                                0b1 => unreachable,
 4374                            },
 4375                            0b11 => switch (enc_opc1.encoded) {
 4376                                0b0 => .double,
 4377                                0b1 => unreachable,
 4378                            },
 4379                        };
 4380                    }
 4381                };
 4382
 4383                pub const Size = packed struct {
 4384                    encoded: u2,
 4385
 4386                    pub fn encode(ss: Register.ScalarSize) Vector.Size {
 4387                        return .{ .encoded = switch (ss) {
 4388                            .byte, .quad => 0b00,
 4389                            .half => 0b01,
 4390                            .single => 0b10,
 4391                            .double => 0b11,
 4392                        } };
 4393                    }
 4394                };
 4395
 4396                pub const Decoded = union(enum) {
 4397                    unallocated,
 4398                    str: Str,
 4399                    ldr: Ldr,
 4400                };
 4401                pub fn decode(inst: @This()) @This().Decoded {
 4402                    return switch (inst.group.size.encoded) {
 4403                        0b00 => switch (inst.group.opc0) {
 4404                            .store => .{ .str = inst.str },
 4405                            .load => .{ .ldr = inst.ldr },
 4406                        },
 4407                        0b01, 0b10, 0b11 => switch (inst.group.opc1.encoded) {
 4408                            0b0 => switch (inst.group.opc0) {
 4409                                .store => .{ .str = inst.str },
 4410                                .load => .{ .ldr = inst.ldr },
 4411                            },
 4412                            0b1 => .unallocated,
 4413                        },
 4414                    };
 4415                }
 4416            };
 4417
 4418            pub const Decoded = union(enum) {
 4419                integer: Integer,
 4420                vector: Vector,
 4421            };
 4422            pub fn decode(inst: @This()) @This().Decoded {
 4423                return switch (inst.group.V) {
 4424                    false => .{ .integer = inst.integer },
 4425                    true => .{ .vector = inst.vector },
 4426                };
 4427            }
 4428        };
 4429
 4430        /// Load/store register (unprivileged)
 4431        pub const RegisterUnprivileged = packed struct {
 4432            Rt: Register.Encoded,
 4433            Rn: Register.Encoded,
 4434            decoded10: u2 = 0b10,
 4435            imm9: i9,
 4436            decoded21: u1 = 0b0,
 4437            opc: u2,
 4438            decoded24: u2 = 0b00,
 4439            V: bool,
 4440            decoded27: u3 = 0b111,
 4441            size: Size,
 4442        };
 4443
 4444        /// Load/store register (immediate pre-indexed)
 4445        pub const RegisterImmediatePreIndexed = packed union {
 4446            group: @This().Group,
 4447            integer: Integer,
 4448            vector: Vector,
 4449
 4450            pub const Group = packed struct {
 4451                Rt: Register.Encoded,
 4452                Rn: Register.Encoded,
 4453                decoded10: u2 = 0b11,
 4454                imm9: i9,
 4455                decoded21: u1 = 0b0,
 4456                opc: u2,
 4457                decoded24: u2 = 0b00,
 4458                V: bool,
 4459                decoded27: u3 = 0b111,
 4460                size: u2,
 4461            };
 4462
 4463            pub const Integer = packed union {
 4464                group: @This().Group,
 4465                strb: Strb,
 4466                ldrb: Ldrb,
 4467                ldrsb: Ldrsb,
 4468                strh: Strh,
 4469                ldrh: Ldrh,
 4470                ldrsh: Ldrsh,
 4471                str: Str,
 4472                ldr: Ldr,
 4473                ldrsw: Ldrsw,
 4474
 4475                pub const Group = packed struct {
 4476                    Rt: Register.Encoded,
 4477                    Rn: Register.Encoded,
 4478                    decoded10: u2 = 0b11,
 4479                    imm9: i9,
 4480                    decoded21: u1 = 0b0,
 4481                    opc: u2,
 4482                    decoded24: u2 = 0b00,
 4483                    V: bool = false,
 4484                    decoded27: u3 = 0b111,
 4485                    size: Size,
 4486                };
 4487
 4488                /// C6.2.324 STRB (immediate)
 4489                pub const Strb = packed struct {
 4490                    Rt: Register.Encoded,
 4491                    Rn: Register.Encoded,
 4492                    decoded10: u2 = 0b11,
 4493                    imm9: i9,
 4494                    decoded21: u1 = 0b0,
 4495                    opc: u2 = 0b00,
 4496                    decoded24: u2 = 0b00,
 4497                    V: bool = false,
 4498                    decoded27: u3 = 0b111,
 4499                    size: Size = .byte,
 4500                };
 4501
 4502                /// C6.2.170 LDRB (immediate)
 4503                pub const Ldrb = packed struct {
 4504                    Rt: Register.Encoded,
 4505                    Rn: Register.Encoded,
 4506                    decoded10: u2 = 0b11,
 4507                    imm9: i9,
 4508                    decoded21: u1 = 0b0,
 4509                    opc: u2 = 0b01,
 4510                    decoded24: u2 = 0b00,
 4511                    V: bool = false,
 4512                    decoded27: u3 = 0b111,
 4513                    size: Size = .byte,
 4514                };
 4515
 4516                /// C6.2.174 LDRSB (immediate)
 4517                pub const Ldrsb = packed struct {
 4518                    Rt: Register.Encoded,
 4519                    Rn: Register.Encoded,
 4520                    decoded10: u2 = 0b11,
 4521                    imm9: i9,
 4522                    decoded21: u1 = 0b0,
 4523                    opc0: u1,
 4524                    opc1: u1 = 0b1,
 4525                    decoded24: u2 = 0b00,
 4526                    V: bool = false,
 4527                    decoded27: u3 = 0b111,
 4528                    size: Size = .byte,
 4529                };
 4530
 4531                /// C6.2.326 STRH (immediate)
 4532                pub const Strh = packed struct {
 4533                    Rt: Register.Encoded,
 4534                    Rn: Register.Encoded,
 4535                    decoded10: u2 = 0b11,
 4536                    imm9: i9,
 4537                    decoded21: u1 = 0b0,
 4538                    opc: u2 = 0b00,
 4539                    decoded24: u2 = 0b00,
 4540                    V: bool = false,
 4541                    decoded27: u3 = 0b111,
 4542                    size: Size = .halfword,
 4543                };
 4544
 4545                /// C6.2.172 LDRH (immediate)
 4546                pub const Ldrh = packed struct {
 4547                    Rt: Register.Encoded,
 4548                    Rn: Register.Encoded,
 4549                    decoded10: u2 = 0b11,
 4550                    imm9: i9,
 4551                    decoded21: u1 = 0b0,
 4552                    opc: u2 = 0b01,
 4553                    decoded24: u2 = 0b00,
 4554                    V: bool = false,
 4555                    decoded27: u3 = 0b111,
 4556                    size: Size = .halfword,
 4557                };
 4558
 4559                /// C6.2.176 LDRSH (immediate)
 4560                pub const Ldrsh = packed struct {
 4561                    Rt: Register.Encoded,
 4562                    Rn: Register.Encoded,
 4563                    decoded10: u2 = 0b11,
 4564                    imm9: i9,
 4565                    decoded21: u1 = 0b0,
 4566                    opc0: u1,
 4567                    opc1: u1 = 0b1,
 4568                    decoded24: u2 = 0b00,
 4569                    V: bool = false,
 4570                    decoded27: u3 = 0b111,
 4571                    size: Size = .halfword,
 4572                };
 4573
 4574                /// C6.2.322 STR (immediate)
 4575                pub const Str = packed struct {
 4576                    Rt: Register.Encoded,
 4577                    Rn: Register.Encoded,
 4578                    decoded10: u2 = 0b11,
 4579                    imm9: i9,
 4580                    decoded21: u1 = 0b0,
 4581                    opc: u2 = 0b00,
 4582                    decoded24: u2 = 0b00,
 4583                    V: bool = false,
 4584                    decoded27: u3 = 0b111,
 4585                    sf: Register.GeneralSize,
 4586                    size1: u1 = 0b1,
 4587                };
 4588
 4589                /// C6.2.166 LDR (immediate)
 4590                pub const Ldr = packed struct {
 4591                    Rt: Register.Encoded,
 4592                    Rn: Register.Encoded,
 4593                    decoded10: u2 = 0b11,
 4594                    imm9: i9,
 4595                    decoded21: u1 = 0b0,
 4596                    opc: u2 = 0b01,
 4597                    decoded24: u2 = 0b00,
 4598                    V: bool = false,
 4599                    decoded27: u3 = 0b111,
 4600                    sf: Register.GeneralSize,
 4601                    size1: u1 = 0b1,
 4602                };
 4603
 4604                /// C6.2.178 LDRSW (immediate)
 4605                pub const Ldrsw = packed struct {
 4606                    Rt: Register.Encoded,
 4607                    Rn: Register.Encoded,
 4608                    decoded10: u2 = 0b11,
 4609                    imm9: i9,
 4610                    decoded21: u1 = 0b0,
 4611                    opc: u2 = 0b10,
 4612                    decoded24: u2 = 0b00,
 4613                    V: bool = false,
 4614                    decoded27: u3 = 0b111,
 4615                    size: Size = .word,
 4616                };
 4617
 4618                pub const Decoded = union(enum) {
 4619                    unallocated,
 4620                    strb: Strb,
 4621                    ldrb: Ldrb,
 4622                    ldrsb: Ldrsb,
 4623                    strh: Strh,
 4624                    ldrh: Ldrh,
 4625                    ldrsh: Ldrsh,
 4626                    str: Str,
 4627                    ldr: Ldr,
 4628                    ldrsw: Ldrsw,
 4629                };
 4630                pub fn decode(inst: @This()) @This().Decoded {
 4631                    return switch (inst.group.size) {
 4632                        .byte => switch (inst.group.opc) {
 4633                            0b00 => .{ .strb = inst.strb },
 4634                            0b01 => .{ .ldrb = inst.ldrb },
 4635                            0b10, 0b11 => .{ .ldrsb = inst.ldrsb },
 4636                        },
 4637                        .halfword => switch (inst.group.opc) {
 4638                            0b00 => .{ .strh = inst.strh },
 4639                            0b01 => .{ .ldrh = inst.ldrh },
 4640                            0b10, 0b11 => .{ .ldrsh = inst.ldrsh },
 4641                        },
 4642                        .word => switch (inst.group.opc) {
 4643                            0b00 => .{ .str = inst.str },
 4644                            0b01 => .{ .ldr = inst.ldr },
 4645                            0b10 => .{ .ldrsw = inst.ldrsw },
 4646                            0b11 => .unallocated,
 4647                        },
 4648                        .doubleword => switch (inst.group.opc) {
 4649                            0b00 => .{ .str = inst.str },
 4650                            0b01 => .{ .ldr = inst.ldr },
 4651                            0b10, 0b11 => .unallocated,
 4652                        },
 4653                    };
 4654                }
 4655            };
 4656
 4657            pub const Vector = packed union {
 4658                group: @This().Group,
 4659                str: Str,
 4660                ldr: Ldr,
 4661
 4662                pub const Group = packed struct {
 4663                    Rt: Register.Encoded,
 4664                    Rn: Register.Encoded,
 4665                    decoded10: u2 = 0b11,
 4666                    imm9: i9,
 4667                    decoded21: u1 = 0b0,
 4668                    opc0: L,
 4669                    opc1: Opc1,
 4670                    decoded24: u2 = 0b00,
 4671                    V: bool = true,
 4672                    decoded27: u3 = 0b111,
 4673                    size: Vector.Size,
 4674                };
 4675
 4676                /// C7.2.331 STR (immediate, SIMD&FP)
 4677                pub const Str = packed struct {
 4678                    Rt: Register.Encoded,
 4679                    Rn: Register.Encoded,
 4680                    decoded10: u2 = 0b11,
 4681                    imm9: i9,
 4682                    decoded21: u1 = 0b0,
 4683                    opc0: L = .store,
 4684                    opc1: Opc1,
 4685                    decoded24: u2 = 0b00,
 4686                    V: bool = true,
 4687                    decoded27: u3 = 0b111,
 4688                    size: Vector.Size,
 4689                };
 4690
 4691                /// C7.2.191 LDR (immediate, SIMD&FP)
 4692                pub const Ldr = packed struct {
 4693                    Rt: Register.Encoded,
 4694                    Rn: Register.Encoded,
 4695                    decoded10: u2 = 0b11,
 4696                    imm9: i9,
 4697                    decoded21: u1 = 0b0,
 4698                    opc0: L = .load,
 4699                    opc1: Opc1,
 4700                    decoded24: u2 = 0b00,
 4701                    V: bool = true,
 4702                    decoded27: u3 = 0b111,
 4703                    size: Vector.Size,
 4704                };
 4705
 4706                pub const Opc1 = packed struct {
 4707                    encoded: u1,
 4708
 4709                    pub fn encode(ss: Register.ScalarSize) Opc1 {
 4710                        return .{ .encoded = switch (ss) {
 4711                            .byte, .half, .single, .double => 0b0,
 4712                            .quad => 0b1,
 4713                        } };
 4714                    }
 4715
 4716                    pub fn decode(enc_opc1: Opc1, enc_size: Vector.Size) Register.ScalarSize {
 4717                        return switch (enc_size.encoded) {
 4718                            0b00 => switch (enc_opc1.encoded) {
 4719                                0b0 => .byte,
 4720                                0b1 => .quad,
 4721                            },
 4722                            0b01 => switch (enc_opc1.encoded) {
 4723                                0b0 => .half,
 4724                                0b1 => unreachable,
 4725                            },
 4726                            0b10 => switch (enc_opc1.encoded) {
 4727                                0b0 => .single,
 4728                                0b1 => unreachable,
 4729                            },
 4730                            0b11 => switch (enc_opc1.encoded) {
 4731                                0b0 => .double,
 4732                                0b1 => unreachable,
 4733                            },
 4734                        };
 4735                    }
 4736                };
 4737
 4738                pub const Size = packed struct {
 4739                    encoded: u2,
 4740
 4741                    pub fn encode(ss: Register.ScalarSize) Vector.Size {
 4742                        return .{ .encoded = switch (ss) {
 4743                            .byte, .quad => 0b00,
 4744                            .half => 0b01,
 4745                            .single => 0b10,
 4746                            .double => 0b11,
 4747                        } };
 4748                    }
 4749                };
 4750
 4751                pub const Decoded = union(enum) {
 4752                    unallocated,
 4753                    str: Str,
 4754                    ldr: Ldr,
 4755                };
 4756                pub fn decode(inst: @This()) @This().Decoded {
 4757                    return switch (inst.group.size.encoded) {
 4758                        0b00 => switch (inst.group.opc0) {
 4759                            .store => .{ .str = inst.str },
 4760                            .load => .{ .ldr = inst.ldr },
 4761                        },
 4762                        0b01, 0b10, 0b11 => switch (inst.group.opc1.encoded) {
 4763                            0b0 => switch (inst.group.opc0) {
 4764                                .store => .{ .str = inst.str },
 4765                                .load => .{ .ldr = inst.ldr },
 4766                            },
 4767                            0b1 => .unallocated,
 4768                        },
 4769                    };
 4770                }
 4771            };
 4772
 4773            pub const Decoded = union(enum) {
 4774                integer: Integer,
 4775                vector: Vector,
 4776            };
 4777            pub fn decode(inst: @This()) @This().Decoded {
 4778                return switch (inst.group.V) {
 4779                    false => .{ .integer = inst.integer },
 4780                    true => .{ .vector = inst.vector },
 4781                };
 4782            }
 4783        };
 4784
 4785        /// Load/store register (register offset)
 4786        pub const RegisterRegisterOffset = packed union {
 4787            group: @This().Group,
 4788            integer: Integer,
 4789            vector: Vector,
 4790
 4791            pub const Group = packed struct {
 4792                Rt: Register.Encoded,
 4793                Rn: Register.Encoded,
 4794                decoded10: u2 = 0b10,
 4795                S: bool,
 4796                option: Option,
 4797                Rm: Register.Encoded,
 4798                decoded21: u1 = 0b1,
 4799                opc: u2,
 4800                decoded24: u2 = 0b00,
 4801                V: bool,
 4802                decoded27: u3 = 0b111,
 4803                size: u2,
 4804            };
 4805
 4806            pub const Integer = packed union {
 4807                group: @This().Group,
 4808                strb: Strb,
 4809                ldrb: Ldrb,
 4810                ldrsb: Ldrsb,
 4811                strh: Strh,
 4812                ldrh: Ldrh,
 4813                ldrsh: Ldrsh,
 4814                str: Str,
 4815                ldr: Ldr,
 4816                ldrsw: Ldrsw,
 4817                prfm: Prfm,
 4818
 4819                pub const Group = packed struct {
 4820                    Rt: Register.Encoded,
 4821                    Rn: Register.Encoded,
 4822                    decoded10: u2 = 0b10,
 4823                    S: bool,
 4824                    option: Option,
 4825                    Rm: Register.Encoded,
 4826                    decoded21: u1 = 0b1,
 4827                    opc: u2,
 4828                    decoded24: u2 = 0b00,
 4829                    V: bool = false,
 4830                    decoded27: u3 = 0b111,
 4831                    size: Size,
 4832                };
 4833
 4834                /// C6.2.325 STRB (register)
 4835                pub const Strb = packed struct {
 4836                    Rt: Register.Encoded,
 4837                    Rn: Register.Encoded,
 4838                    decoded10: u2 = 0b10,
 4839                    S: bool,
 4840                    option: Option,
 4841                    Rm: Register.Encoded,
 4842                    decoded21: u1 = 0b1,
 4843                    opc: u2 = 0b00,
 4844                    decoded24: u2 = 0b00,
 4845                    V: bool = false,
 4846                    decoded27: u3 = 0b111,
 4847                    size: Size = .byte,
 4848                };
 4849
 4850                /// C6.2.171 LDRB (register)
 4851                pub const Ldrb = packed struct {
 4852                    Rt: Register.Encoded,
 4853                    Rn: Register.Encoded,
 4854                    decoded10: u2 = 0b10,
 4855                    S: bool,
 4856                    option: Option,
 4857                    Rm: Register.Encoded,
 4858                    decoded21: u1 = 0b1,
 4859                    opc: u2 = 0b01,
 4860                    decoded24: u2 = 0b00,
 4861                    V: bool = false,
 4862                    decoded27: u3 = 0b111,
 4863                    size: Size = .byte,
 4864                };
 4865
 4866                /// C6.2.175 LDRSB (register)
 4867                pub const Ldrsb = packed struct {
 4868                    Rt: Register.Encoded,
 4869                    Rn: Register.Encoded,
 4870                    decoded10: u2 = 0b10,
 4871                    S: bool,
 4872                    option: Option,
 4873                    Rm: Register.Encoded,
 4874                    decoded21: u1 = 0b1,
 4875                    opc0: u1,
 4876                    opc1: u1 = 0b1,
 4877                    decoded24: u2 = 0b00,
 4878                    V: bool = false,
 4879                    decoded27: u3 = 0b111,
 4880                    size: Size = .byte,
 4881                };
 4882
 4883                /// C6.2.327 STRH (register)
 4884                pub const Strh = packed struct {
 4885                    Rt: Register.Encoded,
 4886                    Rn: Register.Encoded,
 4887                    decoded10: u2 = 0b10,
 4888                    S: bool,
 4889                    option: Option,
 4890                    Rm: Register.Encoded,
 4891                    decoded21: u1 = 0b1,
 4892                    opc: u2 = 0b00,
 4893                    decoded24: u2 = 0b00,
 4894                    V: bool = false,
 4895                    decoded27: u3 = 0b111,
 4896                    size: Size = .halfword,
 4897                };
 4898
 4899                /// C6.2.173 LDRH (register)
 4900                pub const Ldrh = packed struct {
 4901                    Rt: Register.Encoded,
 4902                    Rn: Register.Encoded,
 4903                    decoded10: u2 = 0b10,
 4904                    S: bool,
 4905                    option: Option,
 4906                    Rm: Register.Encoded,
 4907                    decoded21: u1 = 0b1,
 4908                    opc: u2 = 0b01,
 4909                    decoded24: u2 = 0b00,
 4910                    V: bool = false,
 4911                    decoded27: u3 = 0b111,
 4912                    size: Size = .halfword,
 4913                };
 4914
 4915                /// C6.2.177 LDRSH (register)
 4916                pub const Ldrsh = packed struct {
 4917                    Rt: Register.Encoded,
 4918                    Rn: Register.Encoded,
 4919                    decoded10: u2 = 0b10,
 4920                    S: bool,
 4921                    option: Option,
 4922                    Rm: Register.Encoded,
 4923                    decoded21: u1 = 0b1,
 4924                    opc0: u1,
 4925                    opc1: u1 = 0b1,
 4926                    decoded24: u2 = 0b00,
 4927                    V: bool = false,
 4928                    decoded27: u3 = 0b111,
 4929                    size: Size = .halfword,
 4930                };
 4931
 4932                /// C6.2.323 STR (register)
 4933                pub const Str = packed struct {
 4934                    Rt: Register.Encoded,
 4935                    Rn: Register.Encoded,
 4936                    decoded10: u2 = 0b10,
 4937                    S: bool,
 4938                    option: Option,
 4939                    Rm: Register.Encoded,
 4940                    decoded21: u1 = 0b1,
 4941                    opc: u2 = 0b00,
 4942                    decoded24: u2 = 0b00,
 4943                    V: bool = false,
 4944                    decoded27: u3 = 0b111,
 4945                    sf: Register.GeneralSize,
 4946                    size1: u1 = 0b1,
 4947                };
 4948
 4949                /// C6.2.168 LDR (register)
 4950                pub const Ldr = packed struct {
 4951                    Rt: Register.Encoded,
 4952                    Rn: Register.Encoded,
 4953                    decoded10: u2 = 0b10,
 4954                    S: bool,
 4955                    option: Option,
 4956                    Rm: Register.Encoded,
 4957                    decoded21: u1 = 0b1,
 4958                    opc: u2 = 0b01,
 4959                    decoded24: u2 = 0b00,
 4960                    V: bool = false,
 4961                    decoded27: u3 = 0b111,
 4962                    sf: Register.GeneralSize,
 4963                    size1: u1 = 0b1,
 4964                };
 4965
 4966                /// C6.2.180 LDRSW (register)
 4967                pub const Ldrsw = packed struct {
 4968                    Rt: Register.Encoded,
 4969                    Rn: Register.Encoded,
 4970                    decoded10: u2 = 0b10,
 4971                    S: bool,
 4972                    option: Option,
 4973                    Rm: Register.Encoded,
 4974                    decoded21: u1 = 0b1,
 4975                    opc: u2 = 0b10,
 4976                    decoded24: u2 = 0b00,
 4977                    V: bool = false,
 4978                    decoded27: u3 = 0b111,
 4979                    size: Size = .word,
 4980                };
 4981
 4982                /// C6.2.249 PRFM (register)
 4983                pub const Prfm = packed struct {
 4984                    prfop: PrfOp,
 4985                    Rn: Register.Encoded,
 4986                    decoded10: u2 = 0b10,
 4987                    S: bool,
 4988                    option: Option,
 4989                    Rm: Register.Encoded,
 4990                    decoded21: u1 = 0b1,
 4991                    opc: u2 = 0b10,
 4992                    decoded24: u2 = 0b00,
 4993                    V: bool = false,
 4994                    decoded27: u3 = 0b111,
 4995                    size: Size = .doubleword,
 4996                };
 4997
 4998                pub const Decoded = union(enum) {
 4999                    unallocated,
 5000                    strb: Strb,
 5001                    ldrb: Ldrb,
 5002                    ldrsb: Ldrsb,
 5003                    strh: Strh,
 5004                    ldrh: Ldrh,
 5005                    ldrsh: Ldrsh,
 5006                    str: Str,
 5007                    ldr: Ldr,
 5008                    ldrsw: Ldrsw,
 5009                    prfm: Prfm,
 5010                };
 5011                pub fn decode(inst: @This()) @This().Decoded {
 5012                    return switch (inst.group.size) {
 5013                        .byte => switch (inst.group.V) {
 5014                            false => switch (inst.group.opc) {
 5015                                0b00 => .{ .strb = inst.strb },
 5016                                0b01 => .{ .ldrb = inst.ldrb },
 5017                                0b10, 0b11 => .{ .ldrsb = inst.ldrsb },
 5018                            },
 5019                            true => .unallocated,
 5020                        },
 5021                        .halfword => switch (inst.group.V) {
 5022                            false => switch (inst.group.opc) {
 5023                                0b00 => .{ .strh = inst.strh },
 5024                                0b01 => .{ .ldrh = inst.ldrh },
 5025                                0b10, 0b11 => .{ .ldrsh = inst.ldrsh },
 5026                            },
 5027                            true => .unallocated,
 5028                        },
 5029                        .word => switch (inst.group.V) {
 5030                            false => switch (inst.group.opc) {
 5031                                0b00 => .{ .str = inst.str },
 5032                                0b01 => .{ .ldr = inst.ldr },
 5033                                0b10 => .{ .ldrsw = inst.ldrsw },
 5034                                0b11 => .unallocated,
 5035                            },
 5036                            true => .unallocated,
 5037                        },
 5038                        .doubleword => switch (inst.group.V) {
 5039                            false => switch (inst.group.opc) {
 5040                                0b00 => .{ .str = inst.str },
 5041                                0b01 => .{ .ldr = inst.ldr },
 5042                                0b10 => .{ .prfm = inst.prfm },
 5043                                0b11 => .unallocated,
 5044                            },
 5045                            true => .unallocated,
 5046                        },
 5047                    };
 5048                }
 5049            };
 5050
 5051            pub const Vector = packed union {
 5052                group: @This().Group,
 5053                str: Str,
 5054                ldr: Ldr,
 5055
 5056                pub const Group = packed struct {
 5057                    Rt: Register.Encoded,
 5058                    Rn: Register.Encoded,
 5059                    decoded10: u2 = 0b10,
 5060                    S: bool,
 5061                    option: Option,
 5062                    Rm: Register.Encoded,
 5063                    decoded21: u1 = 0b1,
 5064                    opc: u2,
 5065                    decoded24: u2 = 0b00,
 5066                    V: bool = true,
 5067                    decoded27: u3 = 0b111,
 5068                    size: Vector.Size,
 5069                };
 5070
 5071                /// C7.2.332 STR (register, SIMD&FP)
 5072                pub const Str = packed struct {
 5073                    Rt: Register.Encoded,
 5074                    Rn: Register.Encoded,
 5075                    decoded10: u2 = 0b10,
 5076                    S: bool,
 5077                    option: Option,
 5078                    Rm: Register.Encoded,
 5079                    decoded21: u1 = 0b1,
 5080                    opc0: L = .store,
 5081                    opc1: Opc1,
 5082                    decoded24: u2 = 0b00,
 5083                    V: bool = true,
 5084                    decoded27: u3 = 0b111,
 5085                    size: Vector.Size,
 5086                };
 5087
 5088                /// C7.2.193 LDR (register, SIMD&FP)
 5089                pub const Ldr = packed struct {
 5090                    Rt: Register.Encoded,
 5091                    Rn: Register.Encoded,
 5092                    decoded10: u2 = 0b10,
 5093                    S: bool,
 5094                    option: Option,
 5095                    Rm: Register.Encoded,
 5096                    decoded21: u1 = 0b1,
 5097                    opc0: L = .load,
 5098                    opc1: Opc1,
 5099                    decoded24: u2 = 0b00,
 5100                    V: bool = true,
 5101                    decoded27: u3 = 0b111,
 5102                    size: Vector.Size,
 5103                };
 5104
 5105                pub const Opc1 = packed struct {
 5106                    encoded: u1,
 5107
 5108                    pub fn encode(ss: Register.ScalarSize) Opc1 {
 5109                        return .{ .encoded = switch (ss) {
 5110                            .byte, .half, .single, .double => 0b0,
 5111                            .quad => 0b1,
 5112                        } };
 5113                    }
 5114
 5115                    pub fn decode(enc_opc1: Opc1, enc_size: Vector.Size) Register.ScalarSize {
 5116                        return switch (enc_size.encoded) {
 5117                            0b00 => switch (enc_opc1.encoded) {
 5118                                0b0 => .byte,
 5119                                0b1 => .quad,
 5120                            },
 5121                            0b01 => switch (enc_opc1.encoded) {
 5122                                0b0 => .half,
 5123                                0b1 => unreachable,
 5124                            },
 5125                            0b10 => switch (enc_opc1.encoded) {
 5126                                0b0 => .single,
 5127                                0b1 => unreachable,
 5128                            },
 5129                            0b11 => switch (enc_opc1.encoded) {
 5130                                0b0 => .double,
 5131                                0b1 => unreachable,
 5132                            },
 5133                        };
 5134                    }
 5135                };
 5136
 5137                pub const Size = packed struct {
 5138                    encoded: u2,
 5139
 5140                    pub fn encode(ss: Register.ScalarSize) Vector.Size {
 5141                        return .{ .encoded = switch (ss) {
 5142                            .byte, .quad => 0b00,
 5143                            .half => 0b01,
 5144                            .single => 0b10,
 5145                            .double => 0b11,
 5146                        } };
 5147                    }
 5148                };
 5149            };
 5150
 5151            pub const Option = enum(u3) {
 5152                uxtw = 0b010,
 5153                lsl = 0b011,
 5154                sxtw = 0b110,
 5155                sxtx = 0b111,
 5156                _,
 5157
 5158                pub fn sf(option: Option) Register.GeneralSize {
 5159                    return switch (option) {
 5160                        .uxtw, .sxtw => .word,
 5161                        .lsl, .sxtx => .doubleword,
 5162                        _ => unreachable,
 5163                    };
 5164                }
 5165            };
 5166
 5167            pub const Extend = union(Option) {
 5168                uxtw: Amount,
 5169                lsl: Amount,
 5170                sxtw: Amount,
 5171                sxtx: Amount,
 5172
 5173                pub const Amount = u3;
 5174            };
 5175
 5176            pub const Decoded = union(enum) {
 5177                integer: Integer,
 5178                vector: Vector,
 5179            };
 5180            pub fn decode(inst: @This()) @This().Decoded {
 5181                return switch (inst.group.V) {
 5182                    false => .{ .integer = inst.integer },
 5183                    true => .{ .vector = inst.vector },
 5184                };
 5185            }
 5186        };
 5187
 5188        /// Load/store register (unsigned immediate)
 5189        pub const RegisterUnsignedImmediate = packed union {
 5190            group: @This().Group,
 5191            integer: Integer,
 5192            vector: Vector,
 5193
 5194            pub const Group = packed struct {
 5195                Rt: Register.Encoded,
 5196                Rn: Register.Encoded,
 5197                imm12: u12,
 5198                opc: u2,
 5199                decoded24: u2 = 0b01,
 5200                V: bool,
 5201                decoded27: u3 = 0b111,
 5202                size: u2,
 5203            };
 5204
 5205            pub const Integer = packed union {
 5206                group: @This().Group,
 5207                strb: Strb,
 5208                ldrb: Ldrb,
 5209                ldrsb: Ldrsb,
 5210                strh: Strh,
 5211                ldrh: Ldrh,
 5212                ldrsh: Ldrsh,
 5213                str: Str,
 5214                ldr: Ldr,
 5215                ldrsw: Ldrsw,
 5216                prfm: Prfm,
 5217
 5218                pub const Group = packed struct {
 5219                    Rt: Register.Encoded,
 5220                    Rn: Register.Encoded,
 5221                    imm12: u12,
 5222                    opc: u2,
 5223                    decoded24: u2 = 0b01,
 5224                    V: bool = false,
 5225                    decoded27: u3 = 0b111,
 5226                    size: Size,
 5227                };
 5228
 5229                /// C6.2.324 STRB (immediate)
 5230                pub const Strb = packed struct {
 5231                    Rt: Register.Encoded,
 5232                    Rn: Register.Encoded,
 5233                    imm12: u12,
 5234                    opc: u2 = 0b00,
 5235                    decoded24: u2 = 0b01,
 5236                    V: bool = false,
 5237                    decoded27: u3 = 0b111,
 5238                    size: Size = .byte,
 5239                };
 5240
 5241                /// C6.2.170 LDRB (immediate)
 5242                pub const Ldrb = packed struct {
 5243                    Rt: Register.Encoded,
 5244                    Rn: Register.Encoded,
 5245                    imm12: u12,
 5246                    opc: u2 = 0b01,
 5247                    decoded24: u2 = 0b01,
 5248                    V: bool = false,
 5249                    decoded27: u3 = 0b111,
 5250                    size: Size = .byte,
 5251                };
 5252
 5253                /// C6.2.174 LDRSB (immediate)
 5254                pub const Ldrsb = packed struct {
 5255                    Rt: Register.Encoded,
 5256                    Rn: Register.Encoded,
 5257                    imm12: u12,
 5258                    opc0: u1,
 5259                    opc1: u1 = 0b1,
 5260                    decoded24: u2 = 0b01,
 5261                    V: bool = false,
 5262                    decoded27: u3 = 0b111,
 5263                    size: Size = .byte,
 5264                };
 5265
 5266                /// C6.2.326 STRH (immediate)
 5267                pub const Strh = packed struct {
 5268                    Rt: Register.Encoded,
 5269                    Rn: Register.Encoded,
 5270                    imm12: u12,
 5271                    opc: u2 = 0b00,
 5272                    decoded24: u2 = 0b01,
 5273                    V: bool = false,
 5274                    decoded27: u3 = 0b111,
 5275                    size: Size = .halfword,
 5276                };
 5277
 5278                /// C6.2.172 LDRH (immediate)
 5279                pub const Ldrh = packed struct {
 5280                    Rt: Register.Encoded,
 5281                    Rn: Register.Encoded,
 5282                    imm12: u12,
 5283                    opc: u2 = 0b01,
 5284                    decoded24: u2 = 0b01,
 5285                    V: bool = false,
 5286                    decoded27: u3 = 0b111,
 5287                    size: Size = .halfword,
 5288                };
 5289
 5290                /// C6.2.176 LDRSH (immediate)
 5291                pub const Ldrsh = packed struct {
 5292                    Rt: Register.Encoded,
 5293                    Rn: Register.Encoded,
 5294                    imm12: u12,
 5295                    opc0: u1,
 5296                    opc1: u1 = 0b1,
 5297                    decoded24: u2 = 0b01,
 5298                    V: bool = false,
 5299                    decoded27: u3 = 0b111,
 5300                    size: Size = .halfword,
 5301                };
 5302
 5303                /// C6.2.322 STR (immediate)
 5304                pub const Str = packed struct {
 5305                    Rt: Register.Encoded,
 5306                    Rn: Register.Encoded,
 5307                    imm12: u12,
 5308                    opc: u2 = 0b00,
 5309                    decoded24: u2 = 0b01,
 5310                    V: bool = false,
 5311                    decoded27: u3 = 0b111,
 5312                    sf: Register.GeneralSize,
 5313                    size1: u1 = 0b1,
 5314                };
 5315
 5316                /// C6.2.166 LDR (immediate)
 5317                pub const Ldr = packed struct {
 5318                    Rt: Register.Encoded,
 5319                    Rn: Register.Encoded,
 5320                    imm12: u12,
 5321                    opc: u2 = 0b01,
 5322                    decoded24: u2 = 0b01,
 5323                    V: bool = false,
 5324                    decoded27: u3 = 0b111,
 5325                    sf: Register.GeneralSize,
 5326                    size1: u1 = 0b1,
 5327                };
 5328
 5329                /// C6.2.178 LDRSW (immediate)
 5330                pub const Ldrsw = packed struct {
 5331                    Rt: Register.Encoded,
 5332                    Rn: Register.Encoded,
 5333                    imm12: u12,
 5334                    opc: u2 = 0b10,
 5335                    decoded24: u2 = 0b01,
 5336                    V: bool = false,
 5337                    decoded27: u3 = 0b111,
 5338                    size: Size = .word,
 5339                };
 5340
 5341                /// C6.2.247 PRFM (immediate)
 5342                pub const Prfm = packed struct {
 5343                    prfop: PrfOp,
 5344                    Rn: Register.Encoded,
 5345                    imm12: u12,
 5346                    opc: u2 = 0b10,
 5347                    decoded24: u2 = 0b01,
 5348                    V: bool = false,
 5349                    decoded27: u3 = 0b111,
 5350                    size: Size = .doubleword,
 5351                };
 5352
 5353                pub const Decoded = union(enum) {
 5354                    unallocated,
 5355                    strb: Strb,
 5356                    ldrb: Ldrb,
 5357                    ldrsb: Ldrsb,
 5358                    strh: Strh,
 5359                    ldrh: Ldrh,
 5360                    ldrsh: Ldrsh,
 5361                    str: Str,
 5362                    ldr: Ldr,
 5363                    ldrsw: Ldrsw,
 5364                    prfm: Prfm,
 5365                };
 5366                pub fn decode(inst: @This()) @This().Decoded {
 5367                    return switch (inst.group.size) {
 5368                        .byte => switch (inst.group.V) {
 5369                            false => switch (inst.group.opc) {
 5370                                0b00 => .{ .strb = inst.strb },
 5371                                0b01 => .{ .ldrb = inst.ldrb },
 5372                                0b10, 0b11 => .{ .ldrsb = inst.ldrsb },
 5373                            },
 5374                            true => .unallocated,
 5375                        },
 5376                        .halfword => switch (inst.group.V) {
 5377                            false => switch (inst.group.opc) {
 5378                                0b00 => .{ .strh = inst.strh },
 5379                                0b01 => .{ .ldrh = inst.ldrh },
 5380                                0b10, 0b11 => .{ .ldrsh = inst.ldrsh },
 5381                            },
 5382                            true => .unallocated,
 5383                        },
 5384                        .word => switch (inst.group.V) {
 5385                            false => switch (inst.group.opc) {
 5386                                0b00 => .{ .str = inst.str },
 5387                                0b01 => .{ .ldr = inst.ldr },
 5388                                0b10 => .{ .ldrsw = inst.ldrsw },
 5389                                0b11 => .unallocated,
 5390                            },
 5391                            true => .unallocated,
 5392                        },
 5393                        .doubleword => switch (inst.group.V) {
 5394                            false => switch (inst.group.opc) {
 5395                                0b00 => .{ .str = inst.str },
 5396                                0b01 => .{ .ldr = inst.ldr },
 5397                                0b10 => .{ .prfm = inst.prfm },
 5398                                0b11 => .unallocated,
 5399                            },
 5400                            true => .unallocated,
 5401                        },
 5402                    };
 5403                }
 5404            };
 5405
 5406            pub const Vector = packed union {
 5407                group: @This().Group,
 5408                str: Str,
 5409                ldr: Ldr,
 5410
 5411                pub const Group = packed struct {
 5412                    Rt: Register.Encoded,
 5413                    Rn: Register.Encoded,
 5414                    imm12: u12,
 5415                    opc0: L,
 5416                    opc1: Opc1,
 5417                    decoded24: u2 = 0b01,
 5418                    V: bool = true,
 5419                    decoded27: u3 = 0b111,
 5420                    size: Vector.Size,
 5421                };
 5422
 5423                /// C7.2.331 STR (immediate, SIMD&FP)
 5424                pub const Str = packed struct {
 5425                    Rt: Register.Encoded,
 5426                    Rn: Register.Encoded,
 5427                    imm12: u12,
 5428                    opc0: L = .store,
 5429                    opc1: Opc1,
 5430                    decoded24: u2 = 0b01,
 5431                    V: bool = true,
 5432                    decoded27: u3 = 0b111,
 5433                    size: Vector.Size,
 5434                };
 5435
 5436                /// C7.2.191 LDR (immediate, SIMD&FP)
 5437                pub const Ldr = packed struct {
 5438                    Rt: Register.Encoded,
 5439                    Rn: Register.Encoded,
 5440                    imm12: u12,
 5441                    opc0: L = .load,
 5442                    opc1: Opc1,
 5443                    decoded24: u2 = 0b01,
 5444                    V: bool = true,
 5445                    decoded27: u3 = 0b111,
 5446                    size: Vector.Size,
 5447                };
 5448
 5449                pub const Opc1 = packed struct {
 5450                    encoded: u1,
 5451
 5452                    pub fn encode(ss: Register.ScalarSize) Opc1 {
 5453                        return .{ .encoded = switch (ss) {
 5454                            .byte, .half, .single, .double => 0b0,
 5455                            .quad => 0b1,
 5456                        } };
 5457                    }
 5458
 5459                    pub fn decode(enc_opc1: Opc1, enc_size: Vector.Size) Register.ScalarSize {
 5460                        return switch (enc_size.encoded) {
 5461                            0b00 => switch (enc_opc1.encoded) {
 5462                                0b0 => .byte,
 5463                                0b1 => .quad,
 5464                            },
 5465                            0b01 => switch (enc_opc1.encoded) {
 5466                                0b0 => .half,
 5467                                0b1 => unreachable,
 5468                            },
 5469                            0b10 => switch (enc_opc1.encoded) {
 5470                                0b0 => .single,
 5471                                0b1 => unreachable,
 5472                            },
 5473                            0b11 => switch (enc_opc1.encoded) {
 5474                                0b0 => .double,
 5475                                0b1 => unreachable,
 5476                            },
 5477                        };
 5478                    }
 5479                };
 5480
 5481                pub const Size = packed struct {
 5482                    encoded: u2,
 5483
 5484                    pub fn encode(ss: Register.ScalarSize) Vector.Size {
 5485                        return .{ .encoded = switch (ss) {
 5486                            .byte, .quad => 0b00,
 5487                            .half => 0b01,
 5488                            .single => 0b10,
 5489                            .double => 0b11,
 5490                        } };
 5491                    }
 5492                };
 5493
 5494                pub const Decoded = union(enum) {
 5495                    unallocated,
 5496                    str: Str,
 5497                    ldr: Ldr,
 5498                };
 5499                pub fn decode(inst: @This()) @This().Decoded {
 5500                    return switch (inst.group.size.encoded) {
 5501                        0b00 => switch (inst.group.opc0) {
 5502                            .store => .{ .str = inst.str },
 5503                            .load => .{ .ldr = inst.ldr },
 5504                        },
 5505                        0b01, 0b10, 0b11 => switch (inst.group.opc1.encoded) {
 5506                            0b0 => switch (inst.group.opc0) {
 5507                                .store => .{ .str = inst.str },
 5508                                .load => .{ .ldr = inst.ldr },
 5509                            },
 5510                            0b1 => .unallocated,
 5511                        },
 5512                    };
 5513                }
 5514            };
 5515
 5516            pub const Decoded = union(enum) {
 5517                integer: Integer,
 5518                vector: Vector,
 5519            };
 5520            pub fn decode(inst: @This()) @This().Decoded {
 5521                return switch (inst.group.V) {
 5522                    false => .{ .integer = inst.integer },
 5523                    true => .{ .vector = inst.vector },
 5524                };
 5525            }
 5526        };
 5527
 5528        pub const L = enum(u1) {
 5529            store = 0b0,
 5530            load = 0b1,
 5531        };
 5532
 5533        pub const Size = enum(u2) {
 5534            byte = 0b00,
 5535            halfword = 0b01,
 5536            word = 0b10,
 5537            doubleword = 0b11,
 5538        };
 5539
 5540        pub const VectorSize = enum(u2) {
 5541            single = 0b00,
 5542            double = 0b01,
 5543            quad = 0b10,
 5544            _,
 5545
 5546            pub fn decode(vs: VectorSize) Register.ScalarSize {
 5547                return switch (vs) {
 5548                    .single => .single,
 5549                    .double => .double,
 5550                    .quad => .quad,
 5551                    _ => unreachable,
 5552                };
 5553            }
 5554
 5555            pub fn encode(ss: Register.ScalarSize) VectorSize {
 5556                return switch (ss) {
 5557                    else => unreachable,
 5558                    .single => .single,
 5559                    .double => .double,
 5560                    .quad => .quad,
 5561                };
 5562            }
 5563        };
 5564
 5565        pub const PrfOp = packed struct {
 5566            policy: Policy,
 5567            target: Target,
 5568            type: Type,
 5569
 5570            pub const Policy = enum(u1) {
 5571                keep = 0b0,
 5572                strm = 0b1,
 5573            };
 5574
 5575            pub const Target = enum(u2) {
 5576                l1 = 0b00,
 5577                l2 = 0b01,
 5578                l3 = 0b10,
 5579                _,
 5580            };
 5581
 5582            pub const Type = enum(u2) {
 5583                pld = 0b00,
 5584                pli = 0b01,
 5585                pst = 0b10,
 5586                _,
 5587            };
 5588
 5589            pub const pldl1keep: PrfOp = .{ .type = .pld, .target = .l1, .policy = .keep };
 5590            pub const pldl1strm: PrfOp = .{ .type = .pld, .target = .l1, .policy = .strm };
 5591            pub const pldl2keep: PrfOp = .{ .type = .pld, .target = .l2, .policy = .keep };
 5592            pub const pldl2strm: PrfOp = .{ .type = .pld, .target = .l2, .policy = .strm };
 5593            pub const pldl3keep: PrfOp = .{ .type = .pld, .target = .l3, .policy = .keep };
 5594            pub const pldl3strm: PrfOp = .{ .type = .pld, .target = .l3, .policy = .strm };
 5595            pub const plil1keep: PrfOp = .{ .type = .pli, .target = .l1, .policy = .keep };
 5596            pub const plil1strm: PrfOp = .{ .type = .pli, .target = .l1, .policy = .strm };
 5597            pub const plil2keep: PrfOp = .{ .type = .pli, .target = .l2, .policy = .keep };
 5598            pub const plil2strm: PrfOp = .{ .type = .pli, .target = .l2, .policy = .strm };
 5599            pub const plil3keep: PrfOp = .{ .type = .pli, .target = .l3, .policy = .keep };
 5600            pub const plil3strm: PrfOp = .{ .type = .pli, .target = .l3, .policy = .strm };
 5601            pub const pstl1keep: PrfOp = .{ .type = .pst, .target = .l1, .policy = .keep };
 5602            pub const pstl1strm: PrfOp = .{ .type = .pst, .target = .l1, .policy = .strm };
 5603            pub const pstl2keep: PrfOp = .{ .type = .pst, .target = .l2, .policy = .keep };
 5604            pub const pstl2strm: PrfOp = .{ .type = .pst, .target = .l2, .policy = .strm };
 5605            pub const pstl3keep: PrfOp = .{ .type = .pst, .target = .l3, .policy = .keep };
 5606            pub const pstl3strm: PrfOp = .{ .type = .pst, .target = .l3, .policy = .strm_ };
 5607        };
 5608
 5609        pub const Decoded = union(enum) {
 5610            unallocated,
 5611            register_literal: RegisterLiteral,
 5612            memory: Memory,
 5613            no_allocate_pair_offset: NoAllocatePairOffset,
 5614            register_pair_post_indexed: RegisterPairPostIndexed,
 5615            register_pair_offset: RegisterPairOffset,
 5616            register_pair_pre_indexed: RegisterPairPreIndexed,
 5617            register_unscaled_immediate: RegisterUnscaledImmediate,
 5618            register_immediate_post_indexed: RegisterImmediatePostIndexed,
 5619            register_unprivileged: RegisterUnprivileged,
 5620            register_immediate_pre_indexed: RegisterImmediatePreIndexed,
 5621            register_register_offset: RegisterRegisterOffset,
 5622            register_unsigned_immediate: RegisterUnsignedImmediate,
 5623        };
 5624        pub fn decode(inst: @This()) @This().Decoded {
 5625            return switch (inst.group.op0) {
 5626                else => .unallocated,
 5627                0b0010, 0b0110, 0b1010, 0b1110 => switch (inst.group.op2) {
 5628                    0b00 => .{ .no_allocate_pair_offset = inst.no_allocate_pair_offset },
 5629                    0b01 => .{ .register_pair_post_indexed = inst.register_pair_post_indexed },
 5630                    0b10 => .{ .register_pair_offset = inst.register_pair_offset },
 5631                    0b11 => .{ .register_pair_pre_indexed = inst.register_pair_pre_indexed },
 5632                },
 5633                0b0011, 0b0111, 0b1011, 0b1111 => switch (inst.group.op2) {
 5634                    0b00...0b01 => switch (inst.group.op3) {
 5635                        0b000000...0b011111 => switch (inst.group.op4) {
 5636                            0b00 => .{ .register_unscaled_immediate = inst.register_unscaled_immediate },
 5637                            0b01 => .{ .register_immediate_post_indexed = inst.register_immediate_post_indexed },
 5638                            0b10 => .{ .register_unprivileged = inst.register_unprivileged },
 5639                            0b11 => .{ .register_immediate_pre_indexed = inst.register_immediate_pre_indexed },
 5640                        },
 5641                        0b100000...0b111111 => switch (inst.group.op4) {
 5642                            0b00 => .unallocated,
 5643                            0b10 => .{ .register_register_offset = inst.register_register_offset },
 5644                            0b01, 0b11 => .unallocated,
 5645                        },
 5646                    },
 5647                    0b10...0b11 => .{ .register_unsigned_immediate = inst.register_unsigned_immediate },
 5648                },
 5649            };
 5650        }
 5651    };
 5652
 5653    /// C4.1.89 Data Processing -- Register
 5654    pub const DataProcessingRegister = packed union {
 5655        group: @This().Group,
 5656        data_processing_two_source: DataProcessingTwoSource,
 5657        data_processing_one_source: DataProcessingOneSource,
 5658        logical_shifted_register: LogicalShiftedRegister,
 5659        add_subtract_shifted_register: AddSubtractShiftedRegister,
 5660        add_subtract_extended_register: AddSubtractExtendedRegister,
 5661        add_subtract_with_carry: AddSubtractWithCarry,
 5662        rotate_right_into_flags: RotateRightIntoFlags,
 5663        evaluate_into_flags: EvaluateIntoFlags,
 5664        conditional_compare_register: ConditionalCompareRegister,
 5665        conditional_compare_immediate: ConditionalCompareImmediate,
 5666        conditional_select: ConditionalSelect,
 5667        data_processing_three_source: DataProcessingThreeSource,
 5668
 5669        /// Table C4-90 Encoding table for the Data Processing -- Register group
 5670        pub const Group = packed struct {
 5671            encoded0: u10,
 5672            op3: u6,
 5673            encoded16: u5,
 5674            op2: u4,
 5675            decoded25: u3 = 0b101,
 5676            op1: u1,
 5677            encoded29: u1,
 5678            op0: u1,
 5679            encoded31: u1,
 5680        };
 5681
 5682        /// Data-processing (2 source)
 5683        pub const DataProcessingTwoSource = packed union {
 5684            group: @This().Group,
 5685            udiv: Udiv,
 5686            sdiv: Sdiv,
 5687            lslv: Lslv,
 5688            lsrv: Lsrv,
 5689            asrv: Asrv,
 5690            rorv: Rorv,
 5691
 5692            pub const Group = packed struct {
 5693                Rd: Register.Encoded,
 5694                Rn: Register.Encoded,
 5695                opcode: u6,
 5696                Rm: Register.Encoded,
 5697                decoded21: u8 = 0b11010110,
 5698                S: bool,
 5699                decoded30: u1 = 0b0,
 5700                sf: Register.GeneralSize,
 5701            };
 5702
 5703            /// C6.2.388 UDIV
 5704            pub const Udiv = packed struct {
 5705                Rd: Register.Encoded,
 5706                Rn: Register.Encoded,
 5707                o1: DivOp = .udiv,
 5708                decoded11: u5 = 0b00001,
 5709                Rm: Register.Encoded,
 5710                decoded21: u8 = 0b11010110,
 5711                S: bool = false,
 5712                decoded30: u1 = 0b0,
 5713                sf: Register.GeneralSize,
 5714            };
 5715
 5716            /// C6.2.270 SDIV
 5717            pub const Sdiv = packed struct {
 5718                Rd: Register.Encoded,
 5719                Rn: Register.Encoded,
 5720                o1: DivOp = .sdiv,
 5721                decoded11: u5 = 0b00001,
 5722                Rm: Register.Encoded,
 5723                decoded21: u8 = 0b11010110,
 5724                S: bool = false,
 5725                decoded30: u1 = 0b0,
 5726                sf: Register.GeneralSize,
 5727            };
 5728
 5729            /// C6.2.214 LSLV
 5730            pub const Lslv = packed struct {
 5731                Rd: Register.Encoded,
 5732                Rn: Register.Encoded,
 5733                op2: ShiftOp = .lslv,
 5734                decoded12: u4 = 0b0010,
 5735                Rm: Register.Encoded,
 5736                decoded21: u8 = 0b11010110,
 5737                S: bool = false,
 5738                decoded30: u1 = 0b0,
 5739                sf: Register.GeneralSize,
 5740            };
 5741
 5742            /// C6.2.217 LSRV
 5743            pub const Lsrv = packed struct {
 5744                Rd: Register.Encoded,
 5745                Rn: Register.Encoded,
 5746                op2: ShiftOp = .lsrv,
 5747                decoded12: u4 = 0b0010,
 5748                Rm: Register.Encoded,
 5749                decoded21: u8 = 0b11010110,
 5750                S: bool = false,
 5751                decoded30: u1 = 0b0,
 5752                sf: Register.GeneralSize,
 5753            };
 5754
 5755            /// C6.2.18 ASRV
 5756            pub const Asrv = packed struct {
 5757                Rd: Register.Encoded,
 5758                Rn: Register.Encoded,
 5759                op2: ShiftOp = .asrv,
 5760                decoded12: u4 = 0b0010,
 5761                Rm: Register.Encoded,
 5762                decoded21: u8 = 0b11010110,
 5763                S: bool = false,
 5764                decoded30: u1 = 0b0,
 5765                sf: Register.GeneralSize,
 5766            };
 5767
 5768            /// C6.2.263 RORV
 5769            pub const Rorv = packed struct {
 5770                Rd: Register.Encoded,
 5771                Rn: Register.Encoded,
 5772                op2: ShiftOp = .rorv,
 5773                decoded12: u4 = 0b0010,
 5774                Rm: Register.Encoded,
 5775                decoded21: u8 = 0b11010110,
 5776                S: bool = false,
 5777                decoded30: u1 = 0b0,
 5778                sf: Register.GeneralSize,
 5779            };
 5780
 5781            pub const DivOp = enum(u1) {
 5782                udiv = 0b0,
 5783                sdiv = 0b1,
 5784            };
 5785
 5786            pub const ShiftOp = enum(u2) {
 5787                lslv = 0b00,
 5788                lsrv = 0b01,
 5789                asrv = 0b10,
 5790                rorv = 0b11,
 5791            };
 5792
 5793            pub const Decoded = union(enum) {
 5794                unallocated,
 5795                udiv: Udiv,
 5796                sdiv: Sdiv,
 5797                lslv: Lslv,
 5798                lsrv: Lsrv,
 5799                asrv: Asrv,
 5800                rorv: Rorv,
 5801            };
 5802            pub fn decode(inst: @This()) @This().Decoded {
 5803                return switch (inst.group.S) {
 5804                    false => switch (inst.group.opcode) {
 5805                        else => .unallocated,
 5806                        0b000010 => .{ .udiv = inst.udiv },
 5807                        0b000011 => .{ .sdiv = inst.sdiv },
 5808                        0b001000 => .{ .lslv = inst.lslv },
 5809                        0b001001 => .{ .lsrv = inst.lsrv },
 5810                        0b001010 => .{ .asrv = inst.asrv },
 5811                        0b001011 => .{ .rorv = inst.rorv },
 5812                    },
 5813                    true => .unallocated,
 5814                };
 5815            }
 5816        };
 5817
 5818        /// Data-processing (1 source)
 5819        pub const DataProcessingOneSource = packed union {
 5820            group: @This().Group,
 5821            rbit: Rbit,
 5822            rev16: Rev16,
 5823            rev32: Rev32,
 5824            rev: Rev,
 5825            clz: Clz,
 5826            cls: Cls,
 5827
 5828            pub const Group = packed struct {
 5829                Rd: Register.Encoded,
 5830                Rn: Register.Encoded,
 5831                opcode: u6,
 5832                opcode2: u5,
 5833                decoded21: u8 = 0b11010110,
 5834                S: bool,
 5835                decoded30: u1 = 0b1,
 5836                sf: Register.GeneralSize,
 5837            };
 5838
 5839            /// C6.2.253 RBIT
 5840            pub const Rbit = packed struct {
 5841                Rd: Register.Encoded,
 5842                Rn: Register.Encoded,
 5843                decoded10: u2 = 0b00,
 5844                decoded12: u4 = 0b0000,
 5845                decoded16: u5 = 0b00000,
 5846                decoded21: u8 = 0b11010110,
 5847                S: bool = false,
 5848                decoded30: u1 = 0b1,
 5849                sf: Register.GeneralSize,
 5850            };
 5851
 5852            /// C6.2.257 REV16
 5853            pub const Rev16 = packed struct {
 5854                Rd: Register.Encoded,
 5855                Rn: Register.Encoded,
 5856                opc: u2 = 0b01,
 5857                decoded12: u4 = 0b0000,
 5858                decoded16: u5 = 0b00000,
 5859                decoded21: u8 = 0b11010110,
 5860                S: bool = false,
 5861                decoded30: u1 = 0b1,
 5862                sf: Register.GeneralSize,
 5863            };
 5864
 5865            /// C6.2.258 REV32
 5866            pub const Rev32 = packed struct {
 5867                Rd: Register.Encoded,
 5868                Rn: Register.Encoded,
 5869                opc: u2 = 0b10,
 5870                decoded12: u4 = 0b0000,
 5871                decoded16: u5 = 0b00000,
 5872                decoded21: u8 = 0b11010110,
 5873                S: bool = false,
 5874                decoded30: u1 = 0b1,
 5875                sf: Register.GeneralSize = .doubleword,
 5876            };
 5877
 5878            /// C6.2.256 REV
 5879            pub const Rev = packed struct {
 5880                Rd: Register.Encoded,
 5881                Rn: Register.Encoded,
 5882                opc0: Register.GeneralSize,
 5883                opc1: u1 = 0b1,
 5884                decoded12: u4 = 0b0000,
 5885                decoded16: u5 = 0b00000,
 5886                decoded21: u8 = 0b11010110,
 5887                S: bool = false,
 5888                decoded30: u1 = 0b1,
 5889                sf: Register.GeneralSize,
 5890            };
 5891
 5892            /// C6.2.58 CLZ
 5893            pub const Clz = packed struct {
 5894                Rd: Register.Encoded,
 5895                Rn: Register.Encoded,
 5896                op: u1 = 0b0,
 5897                decoded11: u5 = 0b00010,
 5898                decoded16: u5 = 0b00000,
 5899                decoded21: u8 = 0b11010110,
 5900                S: bool = false,
 5901                decoded30: u1 = 0b1,
 5902                sf: Register.GeneralSize,
 5903            };
 5904
 5905            /// C6.2.57 CLS
 5906            pub const Cls = packed struct {
 5907                Rd: Register.Encoded,
 5908                Rn: Register.Encoded,
 5909                op: u1 = 0b1,
 5910                decoded11: u5 = 0b00010,
 5911                decoded16: u5 = 0b00000,
 5912                decoded21: u8 = 0b11010110,
 5913                S: bool = false,
 5914                decoded30: u1 = 0b1,
 5915                sf: Register.GeneralSize,
 5916            };
 5917
 5918            pub const Decoded = union(enum) {
 5919                unallocated,
 5920                rbit: Rbit,
 5921                rev16: Rev16,
 5922                rev32: Rev32,
 5923                rev: Rev,
 5924                clz: Clz,
 5925                cls: Cls,
 5926            };
 5927            pub fn decode(inst: @This()) @This().Decoded {
 5928                return switch (inst.group.S) {
 5929                    true => .unallocated,
 5930                    false => switch (inst.group.opcode2) {
 5931                        else => .unallocated,
 5932                        0b00000 => switch (inst.group.opcode) {
 5933                            else => .unallocated,
 5934                            0b000000 => .{ .rbit = inst.rbit },
 5935                            0b000001 => .{ .rev16 = inst.rev16 },
 5936                            0b000010 => switch (inst.group.sf) {
 5937                                .word => .{ .rev = inst.rev },
 5938                                .doubleword => .{ .rev32 = inst.rev32 },
 5939                            },
 5940                            0b000011 => switch (inst.group.sf) {
 5941                                .word => .unallocated,
 5942                                .doubleword => .{ .rev = inst.rev },
 5943                            },
 5944                            0b000100 => .{ .clz = inst.clz },
 5945                            0b000101 => .{ .cls = inst.cls },
 5946                        },
 5947                    },
 5948                };
 5949            }
 5950        };
 5951
 5952        /// Logical (shifted register)
 5953        pub const LogicalShiftedRegister = packed union {
 5954            group: @This().Group,
 5955            @"and": And,
 5956            bic: Bic,
 5957            orr: Orr,
 5958            orn: Orn,
 5959            eor: Eor,
 5960            eon: Eon,
 5961            ands: Ands,
 5962            bics: Bics,
 5963
 5964            pub const Group = packed struct {
 5965                Rd: Register.Encoded,
 5966                Rn: Register.Encoded,
 5967                imm6: Shift.Amount,
 5968                Rm: Register.Encoded,
 5969                N: bool,
 5970                shift: Shift.Op,
 5971                decoded24: u5 = 0b01010,
 5972                opc: LogicalOpc,
 5973                sf: Register.GeneralSize,
 5974            };
 5975
 5976            /// C6.2.13 AND (shifted register)
 5977            pub const And = packed struct {
 5978                Rd: Register.Encoded,
 5979                Rn: Register.Encoded,
 5980                imm6: Shift.Amount,
 5981                Rm: Register.Encoded,
 5982                N: bool = false,
 5983                shift: Shift.Op,
 5984                decoded24: u5 = 0b01010,
 5985                opc: LogicalOpc = .@"and",
 5986                sf: Register.GeneralSize,
 5987            };
 5988
 5989            /// C6.2.32 BIC (shifted register)
 5990            pub const Bic = packed struct {
 5991                Rd: Register.Encoded,
 5992                Rn: Register.Encoded,
 5993                imm6: Shift.Amount,
 5994                Rm: Register.Encoded,
 5995                N: bool = true,
 5996                shift: Shift.Op,
 5997                decoded24: u5 = 0b01010,
 5998                opc: LogicalOpc = .@"and",
 5999                sf: Register.GeneralSize,
 6000            };
 6001
 6002            /// C6.2.241 ORR (shifted register)
 6003            pub const Orr = packed struct {
 6004                Rd: Register.Encoded,
 6005                Rn: Register.Encoded,
 6006                imm6: Shift.Amount,
 6007                Rm: Register.Encoded,
 6008                N: bool = false,
 6009                shift: Shift.Op,
 6010                decoded24: u5 = 0b01010,
 6011                opc: LogicalOpc = .orr,
 6012                sf: Register.GeneralSize,
 6013            };
 6014
 6015            /// C6.2.239 ORN (shifted register)
 6016            pub const Orn = packed struct {
 6017                Rd: Register.Encoded,
 6018                Rn: Register.Encoded,
 6019                imm6: Shift.Amount,
 6020                Rm: Register.Encoded,
 6021                N: bool = true,
 6022                shift: Shift.Op,
 6023                decoded24: u5 = 0b01010,
 6024                opc: LogicalOpc = .orr,
 6025                sf: Register.GeneralSize,
 6026            };
 6027
 6028            /// C6.2.120 EOR (shifted register)
 6029            pub const Eor = packed struct {
 6030                Rd: Register.Encoded,
 6031                Rn: Register.Encoded,
 6032                imm6: Shift.Amount,
 6033                Rm: Register.Encoded,
 6034                N: bool = false,
 6035                shift: Shift.Op,
 6036                decoded24: u5 = 0b01010,
 6037                opc: LogicalOpc = .eor,
 6038                sf: Register.GeneralSize,
 6039            };
 6040
 6041            /// C6.2.118 EON (shifted register)
 6042            pub const Eon = packed struct {
 6043                Rd: Register.Encoded,
 6044                Rn: Register.Encoded,
 6045                imm6: Shift.Amount,
 6046                Rm: Register.Encoded,
 6047                N: bool = true,
 6048                shift: Shift.Op,
 6049                decoded24: u5 = 0b01010,
 6050                opc: LogicalOpc = .eor,
 6051                sf: Register.GeneralSize,
 6052            };
 6053
 6054            /// C6.2.15 ANDS (shifted register)
 6055            pub const Ands = packed struct {
 6056                Rd: Register.Encoded,
 6057                Rn: Register.Encoded,
 6058                imm6: Shift.Amount,
 6059                Rm: Register.Encoded,
 6060                N: bool = false,
 6061                shift: Shift.Op,
 6062                decoded24: u5 = 0b01010,
 6063                opc: LogicalOpc = .ands,
 6064                sf: Register.GeneralSize,
 6065            };
 6066
 6067            /// C6.2.33 BICS (shifted register)
 6068            pub const Bics = packed struct {
 6069                Rd: Register.Encoded,
 6070                Rn: Register.Encoded,
 6071                imm6: Shift.Amount,
 6072                Rm: Register.Encoded,
 6073                N: bool = true,
 6074                shift: Shift.Op,
 6075                decoded24: u5 = 0b01010,
 6076                opc: LogicalOpc = .ands,
 6077                sf: Register.GeneralSize,
 6078            };
 6079
 6080            pub const Decoded = union(enum) {
 6081                unallocated,
 6082                @"and": And,
 6083                bic: Bic,
 6084                orr: Orr,
 6085                orn: Orn,
 6086                eor: Eor,
 6087                eon: Eon,
 6088                ands: Ands,
 6089                bics: Bics,
 6090            };
 6091            pub fn decode(inst: @This()) @This().Decoded {
 6092                return if (inst.group.sf == .word and @as(u1, @truncate(inst.group.imm6 >> 5)) == 0b1)
 6093                    .unallocated
 6094                else switch (inst.group.opc) {
 6095                    .@"and" => switch (inst.group.N) {
 6096                        false => .{ .@"and" = inst.@"and" },
 6097                        true => .{ .bic = inst.bic },
 6098                    },
 6099                    .orr => switch (inst.group.N) {
 6100                        false => .{ .orr = inst.orr },
 6101                        true => .{ .orn = inst.orn },
 6102                    },
 6103                    .eor => switch (inst.group.N) {
 6104                        false => .{ .eor = inst.eor },
 6105                        true => .{ .eon = inst.eon },
 6106                    },
 6107                    .ands => switch (inst.group.N) {
 6108                        false => .{ .ands = inst.ands },
 6109                        true => .{ .bics = inst.bics },
 6110                    },
 6111                };
 6112            }
 6113        };
 6114
 6115        /// Add/subtract (shifted register)
 6116        pub const AddSubtractShiftedRegister = packed union {
 6117            group: @This().Group,
 6118            add: Add,
 6119            adds: Adds,
 6120            sub: Sub,
 6121            subs: Subs,
 6122
 6123            pub const Group = packed struct {
 6124                Rd: Register.Encoded,
 6125                Rn: Register.Encoded,
 6126                imm6: Shift.Amount,
 6127                Rm: Register.Encoded,
 6128                decoded21: u1 = 0b0,
 6129                shift: Shift.Op,
 6130                decoded24: u5 = 0b01011,
 6131                S: bool,
 6132                op: AddSubtractOp,
 6133                sf: Register.GeneralSize,
 6134            };
 6135
 6136            /// C6.2.5 ADD (shifted register)
 6137            pub const Add = packed struct {
 6138                Rd: Register.Encoded,
 6139                Rn: Register.Encoded,
 6140                imm6: Shift.Amount,
 6141                Rm: Register.Encoded,
 6142                decoded21: u1 = 0b0,
 6143                shift: Shift.Op,
 6144                decoded24: u5 = 0b01011,
 6145                S: bool = false,
 6146                op: AddSubtractOp = .add,
 6147                sf: Register.GeneralSize,
 6148            };
 6149
 6150            /// C6.2.9 ADDS (shifted register)
 6151            pub const Adds = packed struct {
 6152                Rd: Register.Encoded,
 6153                Rn: Register.Encoded,
 6154                imm6: Shift.Amount,
 6155                Rm: Register.Encoded,
 6156                decoded21: u1 = 0b0,
 6157                shift: Shift.Op,
 6158                decoded24: u5 = 0b01011,
 6159                S: bool = true,
 6160                op: AddSubtractOp = .add,
 6161                sf: Register.GeneralSize,
 6162            };
 6163
 6164            /// C6.2.5 SUB (shifted register)
 6165            pub const Sub = packed struct {
 6166                Rd: Register.Encoded,
 6167                Rn: Register.Encoded,
 6168                imm6: Shift.Amount,
 6169                Rm: Register.Encoded,
 6170                decoded21: u1 = 0b0,
 6171                shift: Shift.Op,
 6172                decoded24: u5 = 0b01011,
 6173                S: bool = false,
 6174                op: AddSubtractOp = .sub,
 6175                sf: Register.GeneralSize,
 6176            };
 6177
 6178            /// C6.2.9 SUBS (shifted register)
 6179            pub const Subs = packed struct {
 6180                Rd: Register.Encoded,
 6181                Rn: Register.Encoded,
 6182                imm6: Shift.Amount,
 6183                Rm: Register.Encoded,
 6184                decoded21: u1 = 0b0,
 6185                shift: Shift.Op,
 6186                decoded24: u5 = 0b01011,
 6187                S: bool = true,
 6188                op: AddSubtractOp = .sub,
 6189                sf: Register.GeneralSize,
 6190            };
 6191
 6192            pub const Decoded = union(enum) {
 6193                unallocated,
 6194                add: Add,
 6195                adds: Adds,
 6196                sub: Sub,
 6197                subs: Subs,
 6198            };
 6199            pub fn decode(inst: @This()) @This().Decoded {
 6200                return switch (inst.group.shift) {
 6201                    .ror => .unallocated,
 6202                    .lsl, .lsr, .asr => if (inst.group.sf == .word and @as(u1, @truncate(inst.group.imm6 >> 5)) == 0b1)
 6203                        .unallocated
 6204                    else switch (inst.group.op) {
 6205                        .add => switch (inst.group.S) {
 6206                            false => .{ .add = inst.add },
 6207                            true => .{ .adds = inst.adds },
 6208                        },
 6209                        .sub => switch (inst.group.S) {
 6210                            false => .{ .sub = inst.sub },
 6211                            true => .{ .subs = inst.subs },
 6212                        },
 6213                    },
 6214                };
 6215            }
 6216        };
 6217
 6218        /// Add/subtract (extended register)
 6219        pub const AddSubtractExtendedRegister = packed union {
 6220            group: @This().Group,
 6221            add: Add,
 6222            adds: Adds,
 6223            sub: Sub,
 6224            subs: Subs,
 6225
 6226            pub const Group = packed struct {
 6227                Rd: Register.Encoded,
 6228                Rn: Register.Encoded,
 6229                imm3: Extend.Amount,
 6230                option: Option,
 6231                Rm: Register.Encoded,
 6232                decoded21: u1 = 0b1,
 6233                opt: u2,
 6234                decoded24: u5 = 0b01011,
 6235                S: bool,
 6236                op: AddSubtractOp,
 6237                sf: Register.GeneralSize,
 6238            };
 6239
 6240            /// C6.2.3 ADD (extended register)
 6241            pub const Add = packed struct {
 6242                Rd: Register.Encoded,
 6243                Rn: Register.Encoded,
 6244                imm3: Extend.Amount,
 6245                option: Option,
 6246                Rm: Register.Encoded,
 6247                decoded21: u1 = 0b1,
 6248                opt: u2 = 0b00,
 6249                decoded24: u5 = 0b01011,
 6250                S: bool = false,
 6251                op: AddSubtractOp = .add,
 6252                sf: Register.GeneralSize,
 6253            };
 6254
 6255            /// C6.2.7 ADDS (extended register)
 6256            pub const Adds = packed struct {
 6257                Rd: Register.Encoded,
 6258                Rn: Register.Encoded,
 6259                imm3: Extend.Amount,
 6260                option: Option,
 6261                Rm: Register.Encoded,
 6262                decoded21: u1 = 0b1,
 6263                opt: u2 = 0b00,
 6264                decoded24: u5 = 0b01011,
 6265                S: bool = true,
 6266                op: AddSubtractOp = .add,
 6267                sf: Register.GeneralSize,
 6268            };
 6269
 6270            /// C6.2.356 SUB (extended register)
 6271            pub const Sub = packed struct {
 6272                Rd: Register.Encoded,
 6273                Rn: Register.Encoded,
 6274                imm3: Extend.Amount,
 6275                option: Option,
 6276                Rm: Register.Encoded,
 6277                decoded21: u1 = 0b1,
 6278                opt: u2 = 0b00,
 6279                decoded24: u5 = 0b01011,
 6280                S: bool = false,
 6281                op: AddSubtractOp = .sub,
 6282                sf: Register.GeneralSize,
 6283            };
 6284
 6285            /// C6.2.362 SUBS (extended register)
 6286            pub const Subs = packed struct {
 6287                Rd: Register.Encoded,
 6288                Rn: Register.Encoded,
 6289                imm3: Extend.Amount,
 6290                option: Option,
 6291                Rm: Register.Encoded,
 6292                decoded21: u1 = 0b1,
 6293                opt: u2 = 0b00,
 6294                decoded24: u5 = 0b01011,
 6295                S: bool = true,
 6296                op: AddSubtractOp = .sub,
 6297                sf: Register.GeneralSize,
 6298            };
 6299
 6300            pub const Option = enum(u3) {
 6301                uxtb = 0b000,
 6302                uxth = 0b001,
 6303                uxtw = 0b010,
 6304                uxtx = 0b011,
 6305                sxtb = 0b100,
 6306                sxth = 0b101,
 6307                sxtw = 0b110,
 6308                sxtx = 0b111,
 6309
 6310                pub fn sf(option: Option) Register.GeneralSize {
 6311                    return switch (option) {
 6312                        .uxtb, .uxth, .uxtw, .sxtb, .sxth, .sxtw => .word,
 6313                        .uxtx, .sxtx => .doubleword,
 6314                    };
 6315                }
 6316            };
 6317
 6318            pub const Extend = union(Option) {
 6319                uxtb: Amount,
 6320                uxth: Amount,
 6321                uxtw: Amount,
 6322                uxtx: Amount,
 6323                sxtb: Amount,
 6324                sxth: Amount,
 6325                sxtw: Amount,
 6326                sxtx: Amount,
 6327
 6328                pub const Amount = u3;
 6329            };
 6330
 6331            pub const Decoded = union(enum) {
 6332                unallocated,
 6333                add: Add,
 6334                adds: Adds,
 6335                sub: Sub,
 6336                subs: Subs,
 6337            };
 6338            pub fn decode(inst: @This()) @This().Decoded {
 6339                return switch (inst.group.imm3) {
 6340                    0b101 => .unallocated,
 6341                    0b110...0b111 => .unallocated,
 6342                    0b000...0b100 => switch (inst.group.opt) {
 6343                        0b01 => .unallocated,
 6344                        0b10...0b11 => .unallocated,
 6345                        0b00 => switch (inst.group.op) {
 6346                            .add => switch (inst.group.S) {
 6347                                false => .{ .add = inst.add },
 6348                                true => .{ .adds = inst.adds },
 6349                            },
 6350                            .sub => switch (inst.group.S) {
 6351                                false => .{ .sub = inst.sub },
 6352                                true => .{ .subs = inst.subs },
 6353                            },
 6354                        },
 6355                    },
 6356                };
 6357            }
 6358        };
 6359
 6360        /// Add/subtract (with carry)
 6361        pub const AddSubtractWithCarry = packed union {
 6362            group: @This().Group,
 6363            adc: Adc,
 6364            adcs: Adcs,
 6365            sbc: Sbc,
 6366            sbcs: Sbcs,
 6367
 6368            pub const Group = packed struct {
 6369                Rd: Register.Encoded,
 6370                Rn: Register.Encoded,
 6371                decoded10: u6 = 0b000000,
 6372                Rm: Register.Encoded,
 6373                decoded21: u8 = 0b11010000,
 6374                S: bool,
 6375                op: Op,
 6376                sf: Register.GeneralSize,
 6377            };
 6378
 6379            /// C6.2.1 ADC
 6380            pub const Adc = packed struct {
 6381                Rd: Register.Encoded,
 6382                Rn: Register.Encoded,
 6383                decoded10: u6 = 0b000000,
 6384                Rm: Register.Encoded,
 6385                decoded21: u8 = 0b11010000,
 6386                S: bool = false,
 6387                op: Op = .adc,
 6388                sf: Register.GeneralSize,
 6389            };
 6390
 6391            /// C6.2.2 ADCS
 6392            pub const Adcs = packed struct {
 6393                Rd: Register.Encoded,
 6394                Rn: Register.Encoded,
 6395                decoded10: u6 = 0b000000,
 6396                Rm: Register.Encoded,
 6397                decoded21: u8 = 0b11010000,
 6398                S: bool = true,
 6399                op: Op = .adc,
 6400                sf: Register.GeneralSize,
 6401            };
 6402
 6403            /// C6.2.265 SBC
 6404            pub const Sbc = packed struct {
 6405                Rd: Register.Encoded,
 6406                Rn: Register.Encoded,
 6407                decoded10: u6 = 0b000000,
 6408                Rm: Register.Encoded,
 6409                decoded21: u8 = 0b11010000,
 6410                S: bool = false,
 6411                op: Op = .sbc,
 6412                sf: Register.GeneralSize,
 6413            };
 6414
 6415            /// C6.2.266 SBCS
 6416            pub const Sbcs = packed struct {
 6417                Rd: Register.Encoded,
 6418                Rn: Register.Encoded,
 6419                decoded10: u6 = 0b000000,
 6420                Rm: Register.Encoded,
 6421                decoded21: u8 = 0b11010000,
 6422                S: bool = true,
 6423                op: Op = .sbc,
 6424                sf: Register.GeneralSize,
 6425            };
 6426
 6427            pub const Op = enum(u1) {
 6428                adc = 0b0,
 6429                sbc = 0b1,
 6430            };
 6431
 6432            pub const Decoded = union(enum) {
 6433                adc: Adc,
 6434                adcs: Adcs,
 6435                sbc: Sbc,
 6436                sbcs: Sbcs,
 6437            };
 6438            pub fn decode(inst: @This()) @This().Decoded {
 6439                return switch (inst.group.op) {
 6440                    .adc => switch (inst.group.S) {
 6441                        false => .{ .adc = inst.adc },
 6442                        true => .{ .adcs = inst.adcs },
 6443                    },
 6444                    .sbc => switch (inst.group.S) {
 6445                        false => .{ .sbc = inst.sbc },
 6446                        true => .{ .sbcs = inst.sbcs },
 6447                    },
 6448                };
 6449            }
 6450        };
 6451
 6452        /// Rotate right into flags
 6453        pub const RotateRightIntoFlags = packed union {
 6454            group: @This().Group,
 6455
 6456            pub const Group = packed struct {
 6457                mask: Nzcv,
 6458                o2: u1,
 6459                Rn: Register.Encoded,
 6460                decoded10: u5 = 0b0001,
 6461                imm6: u6,
 6462                decoded21: u8 = 0b11010000,
 6463                S: bool,
 6464                op: u1,
 6465                sf: Register.GeneralSize,
 6466            };
 6467        };
 6468
 6469        /// Evaluate into flags
 6470        pub const EvaluateIntoFlags = packed union {
 6471            group: @This().Group,
 6472
 6473            pub const Group = packed struct {
 6474                mask: Nzcv,
 6475                o3: u1,
 6476                Rn: Register.Encoded,
 6477                decoded10: u4 = 0b0010,
 6478                sz: enum(u1) {
 6479                    byte = 0b0,
 6480                    word = 0b1,
 6481                },
 6482                opcode2: u6,
 6483                decoded21: u8 = 0b11010000,
 6484                S: bool,
 6485                op: u1,
 6486                sf: Register.GeneralSize,
 6487            };
 6488        };
 6489
 6490        /// Conditional compare (register)
 6491        pub const ConditionalCompareRegister = packed union {
 6492            group: @This().Group,
 6493            ccmn: Ccmn,
 6494            ccmp: Ccmp,
 6495
 6496            pub const Group = packed struct {
 6497                nzcv: Nzcv,
 6498                o3: u1,
 6499                Rn: Register.Encoded,
 6500                o2: u1,
 6501                decoded11: u1 = 0b0,
 6502                cond: ConditionCode,
 6503                Rm: Register.Encoded,
 6504                decoded21: u8 = 0b11010010,
 6505                S: bool,
 6506                op: Op,
 6507                sf: Register.GeneralSize,
 6508            };
 6509
 6510            /// C6.2.49 CCMN (register)
 6511            pub const Ccmn = packed struct {
 6512                nzcv: Nzcv,
 6513                o3: u1 = 0b0,
 6514                Rn: Register.Encoded,
 6515                o2: u1 = 0b0,
 6516                decoded11: u1 = 0b0,
 6517                cond: ConditionCode,
 6518                Rm: Register.Encoded,
 6519                decoded21: u8 = 0b11010010,
 6520                S: bool = true,
 6521                op: Op = .ccmn,
 6522                sf: Register.GeneralSize,
 6523            };
 6524
 6525            /// C6.2.51 CCMP (register)
 6526            pub const Ccmp = packed struct {
 6527                nzcv: Nzcv,
 6528                o3: u1 = 0b0,
 6529                Rn: Register.Encoded,
 6530                o2: u1 = 0b0,
 6531                decoded11: u1 = 0b0,
 6532                cond: ConditionCode,
 6533                Rm: Register.Encoded,
 6534                decoded21: u8 = 0b11010010,
 6535                S: bool = true,
 6536                op: Op = .ccmp,
 6537                sf: Register.GeneralSize,
 6538            };
 6539
 6540            pub const Op = enum(u1) {
 6541                ccmn = 0b0,
 6542                ccmp = 0b1,
 6543            };
 6544        };
 6545
 6546        /// Conditional compare (immediate)
 6547        pub const ConditionalCompareImmediate = packed union {
 6548            group: @This().Group,
 6549            ccmn: Ccmn,
 6550            ccmp: Ccmp,
 6551
 6552            pub const Group = packed struct {
 6553                nzcv: Nzcv,
 6554                o3: u1,
 6555                Rn: Register.Encoded,
 6556                o2: u1,
 6557                decoded11: u1 = 0b1,
 6558                cond: ConditionCode,
 6559                imm5: u5,
 6560                decoded21: u8 = 0b11010010,
 6561                S: bool,
 6562                op: Op,
 6563                sf: Register.GeneralSize,
 6564            };
 6565
 6566            /// C6.2.48 CCMN (immediate)
 6567            pub const Ccmn = packed struct {
 6568                nzcv: Nzcv,
 6569                o3: u1 = 0b0,
 6570                Rn: Register.Encoded,
 6571                o2: u1 = 0b0,
 6572                decoded11: u1 = 0b1,
 6573                cond: ConditionCode,
 6574                imm5: u5,
 6575                decoded21: u8 = 0b11010010,
 6576                S: bool = true,
 6577                op: Op = .ccmn,
 6578                sf: Register.GeneralSize,
 6579            };
 6580
 6581            /// C6.2.50 CCMP (immediate)
 6582            pub const Ccmp = packed struct {
 6583                nzcv: Nzcv,
 6584                o3: u1 = 0b0,
 6585                Rn: Register.Encoded,
 6586                o2: u1 = 0b0,
 6587                decoded11: u1 = 0b1,
 6588                cond: ConditionCode,
 6589                imm5: u5,
 6590                decoded21: u8 = 0b11010010,
 6591                S: bool = true,
 6592                op: Op = .ccmp,
 6593                sf: Register.GeneralSize,
 6594            };
 6595
 6596            pub const Op = enum(u1) {
 6597                ccmn = 0b0,
 6598                ccmp = 0b1,
 6599            };
 6600        };
 6601
 6602        /// Conditional select
 6603        pub const ConditionalSelect = packed union {
 6604            group: @This().Group,
 6605            csel: Csel,
 6606            csinc: Csinc,
 6607            csinv: Csinv,
 6608            csneg: Csneg,
 6609
 6610            pub const Group = packed struct {
 6611                Rd: Register.Encoded,
 6612                Rn: Register.Encoded,
 6613                op2: u2,
 6614                cond: ConditionCode,
 6615                Rm: Register.Encoded,
 6616                decoded21: u8 = 0b11010100,
 6617                S: bool,
 6618                op: u1,
 6619                sf: Register.GeneralSize,
 6620            };
 6621
 6622            /// C6.2.103 CSEL
 6623            pub const Csel = packed struct {
 6624                Rd: Register.Encoded,
 6625                Rn: Register.Encoded,
 6626                op2: u2 = 0b00,
 6627                cond: ConditionCode,
 6628                Rm: Register.Encoded,
 6629                decoded21: u8 = 0b11010100,
 6630                S: bool = false,
 6631                op: u1 = 0b0,
 6632                sf: Register.GeneralSize,
 6633            };
 6634
 6635            /// C6.2.106 CSINC
 6636            pub const Csinc = packed struct {
 6637                Rd: Register.Encoded,
 6638                Rn: Register.Encoded,
 6639                op2: u2 = 0b01,
 6640                cond: ConditionCode,
 6641                Rm: Register.Encoded,
 6642                decoded21: u8 = 0b11010100,
 6643                S: bool = false,
 6644                op: u1 = 0b0,
 6645                sf: Register.GeneralSize,
 6646            };
 6647
 6648            /// C6.2.107 CSINV
 6649            pub const Csinv = packed struct {
 6650                Rd: Register.Encoded,
 6651                Rn: Register.Encoded,
 6652                op2: u2 = 0b00,
 6653                cond: ConditionCode,
 6654                Rm: Register.Encoded,
 6655                decoded21: u8 = 0b11010100,
 6656                S: bool = false,
 6657                op: u1 = 0b1,
 6658                sf: Register.GeneralSize,
 6659            };
 6660
 6661            /// C6.2.108 CSNEG
 6662            pub const Csneg = packed struct {
 6663                Rd: Register.Encoded,
 6664                Rn: Register.Encoded,
 6665                op2: u2 = 0b01,
 6666                cond: ConditionCode,
 6667                Rm: Register.Encoded,
 6668                decoded21: u8 = 0b11010100,
 6669                S: bool = false,
 6670                op: u1 = 0b1,
 6671                sf: Register.GeneralSize,
 6672            };
 6673
 6674            pub const Decoded = union(enum) {
 6675                unallocated,
 6676                csel: Csel,
 6677                csinc: Csinc,
 6678                csinv: Csinv,
 6679                csneg: Csneg,
 6680            };
 6681            pub fn decode(inst: @This()) @This().Decoded {
 6682                return switch (inst.group.S) {
 6683                    true => .unallocated,
 6684                    false => switch (inst.group.op) {
 6685                        0b0 => switch (inst.group.op2) {
 6686                            0b10...0b11 => .unallocated,
 6687                            0b00 => .{ .csel = inst.csel },
 6688                            0b01 => .{ .csinc = inst.csinc },
 6689                        },
 6690                        0b1 => switch (inst.group.op2) {
 6691                            0b10...0b11 => .unallocated,
 6692                            0b00 => .{ .csinv = inst.csinv },
 6693                            0b01 => .{ .csneg = inst.csneg },
 6694                        },
 6695                    },
 6696                };
 6697            }
 6698        };
 6699
 6700        /// Data-processing (3 source)
 6701        pub const DataProcessingThreeSource = packed union {
 6702            group: @This().Group,
 6703            madd: Madd,
 6704            msub: Msub,
 6705            smaddl: Smaddl,
 6706            smsubl: Smsubl,
 6707            smulh: Smulh,
 6708            umaddl: Umaddl,
 6709            umsubl: Umsubl,
 6710            umulh: Umulh,
 6711
 6712            pub const Group = packed struct {
 6713                Rd: Register.Encoded,
 6714                Rn: Register.Encoded,
 6715                Ra: Register.Encoded,
 6716                o0: AddSubtractOp,
 6717                Rm: Register.Encoded,
 6718                op31: u3,
 6719                decoded24: u5 = 0b11011,
 6720                op54: u2,
 6721                sf: Register.GeneralSize,
 6722            };
 6723
 6724            /// C6.2.218 MADD
 6725            pub const Madd = packed struct {
 6726                Rd: Register.Encoded,
 6727                Rn: Register.Encoded,
 6728                Ra: Register.Encoded,
 6729                o0: AddSubtractOp = .add,
 6730                Rm: Register.Encoded,
 6731                op31: u3 = 0b000,
 6732                decoded24: u5 = 0b11011,
 6733                op54: u2 = 0b00,
 6734                sf: Register.GeneralSize,
 6735            };
 6736
 6737            /// C6.2.231 MSUB
 6738            pub const Msub = packed struct {
 6739                Rd: Register.Encoded,
 6740                Rn: Register.Encoded,
 6741                Ra: Register.Encoded,
 6742                o0: AddSubtractOp = .sub,
 6743                Rm: Register.Encoded,
 6744                op31: u3 = 0b000,
 6745                decoded24: u5 = 0b11011,
 6746                op54: u2 = 0b00,
 6747                sf: Register.GeneralSize,
 6748            };
 6749
 6750            /// C6.2.282 SMADDL
 6751            pub const Smaddl = packed struct {
 6752                Rd: Register.Encoded,
 6753                Rn: Register.Encoded,
 6754                Ra: Register.Encoded,
 6755                o0: AddSubtractOp = .add,
 6756                Rm: Register.Encoded,
 6757                op21: u2 = 0b01,
 6758                U: std.builtin.Signedness = .signed,
 6759                decoded24: u5 = 0b11011,
 6760                op54: u2 = 0b00,
 6761                sf: Register.GeneralSize = .doubleword,
 6762            };
 6763
 6764            /// C6.2.287 SMSUBL
 6765            pub const Smsubl = packed struct {
 6766                Rd: Register.Encoded,
 6767                Rn: Register.Encoded,
 6768                Ra: Register.Encoded,
 6769                o0: AddSubtractOp = .sub,
 6770                Rm: Register.Encoded,
 6771                op21: u2 = 0b01,
 6772                U: std.builtin.Signedness = .signed,
 6773                decoded24: u5 = 0b11011,
 6774                op54: u2 = 0b00,
 6775                sf: Register.GeneralSize = .doubleword,
 6776            };
 6777
 6778            /// C6.2.288 SMULH
 6779            pub const Smulh = packed struct {
 6780                Rd: Register.Encoded,
 6781                Rn: Register.Encoded,
 6782                Ra: Register.Encoded = Register.Alias.zr.encode(.{}),
 6783                o0: AddSubtractOp = .add,
 6784                Rm: Register.Encoded,
 6785                op21: u2 = 0b10,
 6786                U: std.builtin.Signedness = .signed,
 6787                decoded24: u5 = 0b11011,
 6788                op54: u2 = 0b00,
 6789                sf: Register.GeneralSize = .doubleword,
 6790            };
 6791
 6792            /// C6.2.389 UMADDL
 6793            pub const Umaddl = packed struct {
 6794                Rd: Register.Encoded,
 6795                Rn: Register.Encoded,
 6796                Ra: Register.Encoded,
 6797                o0: AddSubtractOp = .add,
 6798                Rm: Register.Encoded,
 6799                op21: u2 = 0b01,
 6800                U: std.builtin.Signedness = .unsigned,
 6801                decoded24: u5 = 0b11011,
 6802                op54: u2 = 0b00,
 6803                sf: Register.GeneralSize = .doubleword,
 6804            };
 6805
 6806            /// C6.2.391 UMSUBL
 6807            pub const Umsubl = packed struct {
 6808                Rd: Register.Encoded,
 6809                Rn: Register.Encoded,
 6810                Ra: Register.Encoded,
 6811                o0: AddSubtractOp = .sub,
 6812                Rm: Register.Encoded,
 6813                op21: u2 = 0b01,
 6814                U: std.builtin.Signedness = .unsigned,
 6815                decoded24: u5 = 0b11011,
 6816                op54: u2 = 0b00,
 6817                sf: Register.GeneralSize = .doubleword,
 6818            };
 6819
 6820            /// C6.2.392 UMULH
 6821            pub const Umulh = packed struct {
 6822                Rd: Register.Encoded,
 6823                Rn: Register.Encoded,
 6824                Ra: Register.Encoded = Register.Alias.zr.encode(.{}),
 6825                o0: AddSubtractOp = .add,
 6826                Rm: Register.Encoded,
 6827                op21: u2 = 0b10,
 6828                U: std.builtin.Signedness = .unsigned,
 6829                decoded24: u5 = 0b11011,
 6830                op54: u2 = 0b00,
 6831                sf: Register.GeneralSize = .doubleword,
 6832            };
 6833
 6834            pub const Decoded = union(enum) {
 6835                unallocated,
 6836                madd: Madd,
 6837                msub: Msub,
 6838                smaddl: Smaddl,
 6839                smsubl: Smsubl,
 6840                smulh: Smulh,
 6841                umaddl: Umaddl,
 6842                umsubl: Umsubl,
 6843                umulh: Umulh,
 6844            };
 6845            pub fn decode(inst: @This()) @This().Decoded {
 6846                return switch (inst.group.op54) {
 6847                    0b01, 0b10...0b11 => .unallocated,
 6848                    0b00 => switch (inst.group.op31) {
 6849                        0b011, 0b100, 0b111 => .unallocated,
 6850                        0b000 => switch (inst.group.o0) {
 6851                            .add => .{ .madd = inst.madd },
 6852                            .sub => .{ .msub = inst.msub },
 6853                        },
 6854                        0b001 => switch (inst.group.sf) {
 6855                            .word => .unallocated,
 6856                            .doubleword => switch (inst.group.o0) {
 6857                                .add => .{ .smaddl = inst.smaddl },
 6858                                .sub => .{ .smsubl = inst.smsubl },
 6859                            },
 6860                        },
 6861                        0b010 => switch (inst.group.sf) {
 6862                            .word => .unallocated,
 6863                            .doubleword => switch (inst.group.o0) {
 6864                                .add => .{ .smulh = inst.smulh },
 6865                                .sub => .unallocated,
 6866                            },
 6867                        },
 6868                        0b101 => switch (inst.group.sf) {
 6869                            .word => .unallocated,
 6870                            .doubleword => switch (inst.group.o0) {
 6871                                .add => .{ .umaddl = inst.umaddl },
 6872                                .sub => .{ .umsubl = inst.umsubl },
 6873                            },
 6874                        },
 6875                        0b110 => switch (inst.group.sf) {
 6876                            .word => .unallocated,
 6877                            .doubleword => switch (inst.group.o0) {
 6878                                .add => .{ .umulh = inst.umulh },
 6879                                .sub => .unallocated,
 6880                            },
 6881                        },
 6882                    },
 6883                };
 6884            }
 6885        };
 6886
 6887        pub const Shift = union(enum(u2)) {
 6888            lsl: Amount = 0b00,
 6889            lsr: Amount = 0b01,
 6890            asr: Amount = 0b10,
 6891            ror: Amount = 0b11,
 6892
 6893            pub const Op = @typeInfo(Shift).@"union".tag_type.?;
 6894            pub const Amount = u6;
 6895            pub const none: Shift = .{ .lsl = 0 };
 6896        };
 6897
 6898        pub const Decoded = union(enum) {
 6899            unallocated,
 6900            data_processing_two_source: DataProcessingTwoSource,
 6901            data_processing_one_source: DataProcessingOneSource,
 6902            logical_shifted_register: LogicalShiftedRegister,
 6903            add_subtract_shifted_register: AddSubtractShiftedRegister,
 6904            add_subtract_extended_register: AddSubtractExtendedRegister,
 6905            add_subtract_with_carry: AddSubtractWithCarry,
 6906            rotate_right_into_flags: RotateRightIntoFlags,
 6907            evaluate_into_flags: EvaluateIntoFlags,
 6908            conditional_compare_register: ConditionalCompareRegister,
 6909            conditional_compare_immediate: ConditionalCompareImmediate,
 6910            conditional_select: ConditionalSelect,
 6911            data_processing_three_source: DataProcessingThreeSource,
 6912        };
 6913        pub fn decode(inst: @This()) @This().Decoded {
 6914            return switch (inst.group.op1) {
 6915                0b0 => switch (@as(u1, @truncate(inst.group.op2 >> 3))) {
 6916                    0b0 => .{ .logical_shifted_register = inst.logical_shifted_register },
 6917                    0b1 => switch (@as(u1, @truncate(inst.group.op2 >> 0))) {
 6918                        0b0 => .{ .add_subtract_shifted_register = inst.add_subtract_shifted_register },
 6919                        0b1 => .{ .add_subtract_extended_register = inst.add_subtract_extended_register },
 6920                    },
 6921                },
 6922                0b1 => switch (inst.group.op2) {
 6923                    0b0000 => switch (inst.group.op3) {
 6924                        0b000000 => .{ .add_subtract_with_carry = inst.add_subtract_with_carry },
 6925                        0b000001, 0b100001 => .{ .rotate_right_into_flags = inst.rotate_right_into_flags },
 6926                        0b000010, 0b010010, 0b100010, 0b110010 => .{ .evaluate_into_flags = inst.evaluate_into_flags },
 6927                        else => .unallocated,
 6928                    },
 6929                    0b0010 => switch (@as(u1, @truncate(inst.group.op3 >> 1))) {
 6930                        0b0 => .{ .conditional_compare_register = inst.conditional_compare_register },
 6931                        0b1 => .{ .conditional_compare_immediate = inst.conditional_compare_immediate },
 6932                    },
 6933                    0b0100 => .{ .conditional_select = inst.conditional_select },
 6934                    0b0110 => switch (inst.group.op0) {
 6935                        0b0 => .{ .data_processing_two_source = inst.data_processing_two_source },
 6936                        0b1 => .{ .data_processing_one_source = inst.data_processing_one_source },
 6937                    },
 6938                    0b1000...0b1111 => .{ .data_processing_three_source = inst.data_processing_three_source },
 6939                    else => .unallocated,
 6940                },
 6941            };
 6942        }
 6943    };
 6944
 6945    /// C4.1.90 Data Processing -- Scalar Floating-Point and Advanced SIMD
 6946    pub const DataProcessingVector = packed union {
 6947        group: @This().Group,
 6948        simd_scalar_copy: SimdScalarCopy,
 6949        simd_scalar_two_register_miscellaneous_fp16: SimdScalarTwoRegisterMiscellaneousFp16,
 6950        simd_scalar_two_register_miscellaneous: SimdScalarTwoRegisterMiscellaneous,
 6951        simd_scalar_pairwise: SimdScalarPairwise,
 6952        simd_copy: SimdCopy,
 6953        simd_two_register_miscellaneous_fp16: SimdTwoRegisterMiscellaneousFp16,
 6954        simd_two_register_miscellaneous: SimdTwoRegisterMiscellaneous,
 6955        simd_across_lanes: SimdAcrossLanes,
 6956        simd_three_same: SimdThreeSame,
 6957        simd_modified_immediate: SimdModifiedImmediate,
 6958        convert_float_fixed: ConvertFloatFixed,
 6959        convert_float_integer: ConvertFloatInteger,
 6960        float_data_processing_one_source: FloatDataProcessingOneSource,
 6961        float_compare: FloatCompare,
 6962        float_immediate: FloatImmediate,
 6963        float_conditional_compare: FloatConditionalCompare,
 6964        float_data_processing_two_source: FloatDataProcessingTwoSource,
 6965        float_conditional_select: FloatConditionalSelect,
 6966        float_data_processing_three_source: FloatDataProcessingThreeSource,
 6967
 6968        /// Table C4-91 Encoding table for the Data Processing -- Scalar Floating-Point and Advanced SIMD group
 6969        pub const Group = packed struct {
 6970            encoded0: u10,
 6971            op3: u9,
 6972            op2: u4,
 6973            op1: u2,
 6974            decoded25: u3 = 0b111,
 6975            op0: u4,
 6976        };
 6977
 6978        /// Advanced SIMD scalar copy
 6979        pub const SimdScalarCopy = packed union {
 6980            group: @This().Group,
 6981            dup: Dup,
 6982
 6983            pub const Group = packed struct {
 6984                Rd: Register.Encoded,
 6985                Rn: Register.Encoded,
 6986                decoded10: u1 = 0b1,
 6987                imm4: u4,
 6988                decoded15: u1 = 0b0,
 6989                imm5: u5,
 6990                decoded21: u8 = 0b11110000,
 6991                op: u1,
 6992                decoded30: u2 = 0b01,
 6993            };
 6994
 6995            /// C7.2.39 DUP (element)
 6996            pub const Dup = packed struct {
 6997                Rd: Register.Encoded,
 6998                Rn: Register.Encoded,
 6999                decoded10: u1 = 0b1,
 7000                imm4: u4 = 0b0000,
 7001                decoded15: u1 = 0b0,
 7002                imm5: u5,
 7003                decoded21: u8 = 0b11110000,
 7004                op: u1 = 0b0,
 7005                decoded30: u2 = 0b01,
 7006            };
 7007
 7008            pub const Decoded = union(enum) {
 7009                unallocated,
 7010                dup: Dup,
 7011            };
 7012            pub fn decode(inst: @This()) @This().Decoded {
 7013                return switch (inst.group.op) {
 7014                    0b0 => switch (inst.group.imm4) {
 7015                        else => .unallocated,
 7016                        0b0000 => .{ .dup = inst.dup },
 7017                    },
 7018                    0b1 => .unallocated,
 7019                };
 7020            }
 7021        };
 7022
 7023        /// Advanced SIMD scalar two-register miscellaneous FP16
 7024        pub const SimdScalarTwoRegisterMiscellaneousFp16 = packed union {
 7025            group: @This().Group,
 7026            fcvtns: Fcvtns,
 7027            fcvtms: Fcvtms,
 7028            fcvtas: Fcvtas,
 7029            scvtf: Scvtf,
 7030            fcmgt: Fcmgt,
 7031            fcmeq: Fcmeq,
 7032            fcmlt: Fcmlt,
 7033            fcvtps: Fcvtps,
 7034            fcvtzs: Fcvtzs,
 7035            frecpe: Frecpe,
 7036            frecpx: Frecpx,
 7037            fcvtnu: Fcvtnu,
 7038            fcvtmu: Fcvtmu,
 7039            fcvtau: Fcvtau,
 7040            ucvtf: Ucvtf,
 7041            fcmge: Fcmge,
 7042            fcmle: Fcmle,
 7043            fcvtpu: Fcvtpu,
 7044            fcvtzu: Fcvtzu,
 7045            frsqrte: Frsqrte,
 7046
 7047            pub const Group = packed struct {
 7048                Rd: Register.Encoded,
 7049                Rn: Register.Encoded,
 7050                decoded10: u2 = 0b10,
 7051                opcode: u5,
 7052                decoded17: u6 = 0b111100,
 7053                a: u1,
 7054                decoded24: u5 = 0b11110,
 7055                U: std.builtin.Signedness,
 7056                decoded30: u2 = 0b01,
 7057            };
 7058
 7059            /// C7.2.80 FCVTNS (vector)
 7060            pub const Fcvtns = packed struct {
 7061                Rd: Register.Encoded,
 7062                Rn: Register.Encoded,
 7063                decoded10: u2 = 0b10,
 7064                opcode: u5 = 0b11010,
 7065                decoded17: u6 = 0b111100,
 7066                o2: u1 = 0b0,
 7067                decoded24: u5 = 0b11110,
 7068                U: std.builtin.Signedness = .signed,
 7069                decoded30: u2 = 0b01,
 7070            };
 7071
 7072            /// C7.2.75 FCVTMS (vector)
 7073            pub const Fcvtms = packed struct {
 7074                Rd: Register.Encoded,
 7075                Rn: Register.Encoded,
 7076                decoded10: u2 = 0b10,
 7077                opcode: u5 = 0b11011,
 7078                decoded17: u6 = 0b111100,
 7079                o2: u1 = 0b0,
 7080                decoded24: u5 = 0b11110,
 7081                U: std.builtin.Signedness = .signed,
 7082                decoded30: u2 = 0b01,
 7083            };
 7084
 7085            /// C7.2.70 FCVTAS (vector)
 7086            pub const Fcvtas = packed struct {
 7087                Rd: Register.Encoded,
 7088                Rn: Register.Encoded,
 7089                decoded10: u2 = 0b10,
 7090                opcode: u5 = 0b11100,
 7091                decoded17: u6 = 0b111100,
 7092                o2: u1 = 0b0,
 7093                decoded24: u5 = 0b11110,
 7094                U: std.builtin.Signedness = .signed,
 7095                decoded30: u2 = 0b01,
 7096            };
 7097
 7098            /// C7.2.234 SCVTF (vector, integer)
 7099            pub const Scvtf = packed struct {
 7100                Rd: Register.Encoded,
 7101                Rn: Register.Encoded,
 7102                decoded10: u2 = 0b10,
 7103                opcode: u5 = 0b11101,
 7104                decoded17: u6 = 0b111100,
 7105                o2: u1 = 0b0,
 7106                decoded24: u5 = 0b11110,
 7107                U: std.builtin.Signedness = .signed,
 7108                decoded30: u2 = 0b01,
 7109            };
 7110
 7111            /// C7.2.61 FCMGT (zero)
 7112            pub const Fcmgt = packed struct {
 7113                Rd: Register.Encoded,
 7114                Rn: Register.Encoded,
 7115                decoded10: u2 = 0b10,
 7116                opcode: u5 = 0b01100,
 7117                decoded17: u6 = 0b111100,
 7118                o2: u1 = 0b1,
 7119                decoded24: u5 = 0b11110,
 7120                U: std.builtin.Signedness = .signed,
 7121                decoded30: u2 = 0b01,
 7122            };
 7123
 7124            /// C7.2.57 FCMEQ (zero)
 7125            pub const Fcmeq = packed struct {
 7126                Rd: Register.Encoded,
 7127                Rn: Register.Encoded,
 7128                decoded10: u2 = 0b10,
 7129                opcode: u5 = 0b01101,
 7130                decoded17: u6 = 0b111100,
 7131                o2: u1 = 0b1,
 7132                decoded24: u5 = 0b11110,
 7133                U: std.builtin.Signedness = .signed,
 7134                decoded30: u2 = 0b01,
 7135            };
 7136
 7137            /// C7.2.65 FCMLT (zero)
 7138            pub const Fcmlt = packed struct {
 7139                Rd: Register.Encoded,
 7140                Rn: Register.Encoded,
 7141                decoded10: u2 = 0b10,
 7142                opcode: u5 = 0b01110,
 7143                decoded17: u6 = 0b111100,
 7144                o2: u1 = 0b1,
 7145                decoded24: u5 = 0b11110,
 7146                U: std.builtin.Signedness = .signed,
 7147                decoded30: u2 = 0b01,
 7148            };
 7149
 7150            /// C7.2.84 FCVTPS (vector)
 7151            pub const Fcvtps = packed struct {
 7152                Rd: Register.Encoded,
 7153                Rn: Register.Encoded,
 7154                decoded10: u2 = 0b10,
 7155                opcode: u5 = 0b11010,
 7156                decoded17: u6 = 0b111100,
 7157                o2: u1 = 0b1,
 7158                decoded24: u5 = 0b11110,
 7159                U: std.builtin.Signedness = .signed,
 7160                decoded30: u2 = 0b01,
 7161            };
 7162
 7163            /// C7.2.90 FCVTZS (vector, integer)
 7164            pub const Fcvtzs = packed struct {
 7165                Rd: Register.Encoded,
 7166                Rn: Register.Encoded,
 7167                decoded10: u2 = 0b10,
 7168                opcode: u5 = 0b11011,
 7169                decoded17: u6 = 0b111100,
 7170                o2: u1 = 0b1,
 7171                decoded24: u5 = 0b11110,
 7172                U: std.builtin.Signedness = .signed,
 7173                decoded30: u2 = 0b01,
 7174            };
 7175
 7176            /// C7.2.144 FRECPE
 7177            pub const Frecpe = packed struct {
 7178                Rd: Register.Encoded,
 7179                Rn: Register.Encoded,
 7180                decoded10: u2 = 0b10,
 7181                opcode: u5 = 0b11101,
 7182                decoded17: u6 = 0b111100,
 7183                o2: u1 = 0b1,
 7184                decoded24: u5 = 0b11110,
 7185                U: std.builtin.Signedness = .signed,
 7186                decoded30: u2 = 0b01,
 7187            };
 7188
 7189            /// C7.2.146 FRECPX
 7190            pub const Frecpx = packed struct {
 7191                Rd: Register.Encoded,
 7192                Rn: Register.Encoded,
 7193                decoded10: u2 = 0b10,
 7194                opcode: u5 = 0b11111,
 7195                decoded17: u6 = 0b111100,
 7196                o2: u1 = 0b1,
 7197                decoded24: u5 = 0b11110,
 7198                U: std.builtin.Signedness = .signed,
 7199                decoded30: u2 = 0b01,
 7200            };
 7201
 7202            /// C7.2.82 FCVTNU (vector)
 7203            pub const Fcvtnu = packed struct {
 7204                Rd: Register.Encoded,
 7205                Rn: Register.Encoded,
 7206                decoded10: u2 = 0b10,
 7207                opcode: u5 = 0b11010,
 7208                decoded17: u6 = 0b111100,
 7209                o2: u1 = 0b0,
 7210                decoded24: u5 = 0b11110,
 7211                U: std.builtin.Signedness = .unsigned,
 7212                decoded30: u2 = 0b01,
 7213            };
 7214
 7215            /// C7.2.77 FCVTMU (vector)
 7216            pub const Fcvtmu = packed struct {
 7217                Rd: Register.Encoded,
 7218                Rn: Register.Encoded,
 7219                decoded10: u2 = 0b10,
 7220                opcode: u5 = 0b11011,
 7221                decoded17: u6 = 0b111100,
 7222                o2: u1 = 0b0,
 7223                decoded24: u5 = 0b11110,
 7224                U: std.builtin.Signedness = .unsigned,
 7225                decoded30: u2 = 0b01,
 7226            };
 7227
 7228            /// C7.2.72 FCVTAU (vector)
 7229            pub const Fcvtau = packed struct {
 7230                Rd: Register.Encoded,
 7231                Rn: Register.Encoded,
 7232                decoded10: u2 = 0b10,
 7233                opcode: u5 = 0b11100,
 7234                decoded17: u6 = 0b111100,
 7235                o2: u1 = 0b0,
 7236                decoded24: u5 = 0b11110,
 7237                U: std.builtin.Signedness = .unsigned,
 7238                decoded30: u2 = 0b01,
 7239            };
 7240
 7241            /// C7.2.353 UCVTF (vector, integer)
 7242            pub const Ucvtf = packed struct {
 7243                Rd: Register.Encoded,
 7244                Rn: Register.Encoded,
 7245                decoded10: u2 = 0b10,
 7246                opcode: u5 = 0b11101,
 7247                decoded17: u6 = 0b111100,
 7248                o2: u1 = 0b0,
 7249                decoded24: u5 = 0b11110,
 7250                U: std.builtin.Signedness = .unsigned,
 7251                decoded30: u2 = 0b01,
 7252            };
 7253
 7254            /// C7.2.59 FCMGE (zero)
 7255            pub const Fcmge = packed struct {
 7256                Rd: Register.Encoded,
 7257                Rn: Register.Encoded,
 7258                decoded10: u2 = 0b10,
 7259                opcode: u5 = 0b01100,
 7260                decoded17: u6 = 0b111100,
 7261                o2: u1 = 0b1,
 7262                decoded24: u5 = 0b11110,
 7263                U: std.builtin.Signedness = .unsigned,
 7264                decoded30: u2 = 0b01,
 7265            };
 7266
 7267            /// C7.2.64 FCMLE (zero)
 7268            pub const Fcmle = packed struct {
 7269                Rd: Register.Encoded,
 7270                Rn: Register.Encoded,
 7271                decoded10: u2 = 0b10,
 7272                opcode: u5 = 0b01101,
 7273                decoded17: u6 = 0b111100,
 7274                o2: u1 = 0b1,
 7275                decoded24: u5 = 0b11110,
 7276                U: std.builtin.Signedness = .unsigned,
 7277                decoded30: u2 = 0b01,
 7278            };
 7279
 7280            /// C7.2.86 FCVTPU (vector)
 7281            pub const Fcvtpu = packed struct {
 7282                Rd: Register.Encoded,
 7283                Rn: Register.Encoded,
 7284                decoded10: u2 = 0b10,
 7285                opcode: u5 = 0b11010,
 7286                decoded17: u6 = 0b111100,
 7287                o2: u1 = 0b1,
 7288                decoded24: u5 = 0b11110,
 7289                U: std.builtin.Signedness = .unsigned,
 7290                decoded30: u2 = 0b01,
 7291            };
 7292
 7293            /// C7.2.94 FCVTZU (vector, integer)
 7294            pub const Fcvtzu = packed struct {
 7295                Rd: Register.Encoded,
 7296                Rn: Register.Encoded,
 7297                decoded10: u2 = 0b10,
 7298                opcode: u5 = 0b11011,
 7299                decoded17: u6 = 0b111100,
 7300                o2: u1 = 0b1,
 7301                decoded24: u5 = 0b11110,
 7302                U: std.builtin.Signedness = .unsigned,
 7303                decoded30: u2 = 0b01,
 7304            };
 7305
 7306            /// C7.2.169 FRSQRTE
 7307            pub const Frsqrte = packed struct {
 7308                Rd: Register.Encoded,
 7309                Rn: Register.Encoded,
 7310                decoded10: u2 = 0b10,
 7311                opcode: u5 = 0b11101,
 7312                decoded17: u6 = 0b111100,
 7313                o2: u1 = 0b1,
 7314                decoded24: u5 = 0b11110,
 7315                U: std.builtin.Signedness = .unsigned,
 7316                decoded30: u2 = 0b01,
 7317            };
 7318
 7319            pub const Decoded = union(enum) {
 7320                unallocated,
 7321                fcvtns: Fcvtns,
 7322                fcvtms: Fcvtms,
 7323                fcvtas: Fcvtas,
 7324                scvtf: Scvtf,
 7325                fcmgt: Fcmgt,
 7326                fcmeq: Fcmeq,
 7327                fcmlt: Fcmlt,
 7328                fcvtps: Fcvtps,
 7329                fcvtzs: Fcvtzs,
 7330                frecpe: Frecpe,
 7331                frecpx: Frecpx,
 7332                fcvtnu: Fcvtnu,
 7333                fcvtmu: Fcvtmu,
 7334                fcvtau: Fcvtau,
 7335                ucvtf: Ucvtf,
 7336                fcmge: Fcmge,
 7337                fcmle: Fcmle,
 7338                fcvtpu: Fcvtpu,
 7339                fcvtzu: Fcvtzu,
 7340                frsqrte: Frsqrte,
 7341            };
 7342            pub fn decode(inst: @This()) @This().Decoded {
 7343                return switch (inst.group.U) {
 7344                    .signed => switch (inst.group.a) {
 7345                        0b0 => switch (inst.group.opcode) {
 7346                            else => .unallocated,
 7347                            0b11010 => .{ .fcvtns = inst.fcvtns },
 7348                            0b11011 => .{ .fcvtms = inst.fcvtms },
 7349                            0b11100 => .{ .fcvtas = inst.fcvtas },
 7350                            0b11101 => .{ .scvtf = inst.scvtf },
 7351                        },
 7352                        0b1 => switch (inst.group.opcode) {
 7353                            else => .unallocated,
 7354                            0b01100 => .{ .fcmgt = inst.fcmgt },
 7355                            0b01101 => .{ .fcmeq = inst.fcmeq },
 7356                            0b01110 => .{ .fcmlt = inst.fcmlt },
 7357                            0b11010 => .{ .fcvtps = inst.fcvtps },
 7358                            0b11011 => .{ .fcvtzs = inst.fcvtzs },
 7359                            0b11101 => .{ .frecpe = inst.frecpe },
 7360                            0b11111 => .{ .frecpx = inst.frecpx },
 7361                        },
 7362                    },
 7363                    .unsigned => switch (inst.group.a) {
 7364                        0b0 => switch (inst.group.opcode) {
 7365                            else => .unallocated,
 7366                            0b11010 => .{ .fcvtnu = inst.fcvtnu },
 7367                            0b11011 => .{ .fcvtmu = inst.fcvtmu },
 7368                            0b11100 => .{ .fcvtau = inst.fcvtau },
 7369                            0b11101 => .{ .ucvtf = inst.ucvtf },
 7370                        },
 7371                        0b1 => switch (inst.group.opcode) {
 7372                            else => .unallocated,
 7373                            0b01100 => .{ .fcmge = inst.fcmge },
 7374                            0b01101 => .{ .fcmle = inst.fcmle },
 7375                            0b11010 => .{ .fcvtpu = inst.fcvtpu },
 7376                            0b11011 => .{ .fcvtzu = inst.fcvtzu },
 7377                            0b11101 => .{ .frsqrte = inst.frsqrte },
 7378                        },
 7379                    },
 7380                };
 7381            }
 7382        };
 7383
 7384        /// Advanced SIMD scalar two-register miscellaneous
 7385        pub const SimdScalarTwoRegisterMiscellaneous = packed union {
 7386            group: @This().Group,
 7387            suqadd: Suqadd,
 7388            sqabs: Sqabs,
 7389            cmgt: Cmgt,
 7390            cmeq: Cmeq,
 7391            cmlt: Cmlt,
 7392            abs: Abs,
 7393            sqxtn: Sqxtn,
 7394            fcvtns: Fcvtns,
 7395            fcvtms: Fcvtms,
 7396            fcvtas: Fcvtas,
 7397            scvtf: Scvtf,
 7398            fcmgt: Fcmgt,
 7399            fcmeq: Fcmeq,
 7400            fcmlt: Fcmlt,
 7401            fcvtps: Fcvtps,
 7402            fcvtzs: Fcvtzs,
 7403            frecpe: Frecpe,
 7404            frecpx: Frecpx,
 7405            usqadd: Usqadd,
 7406            sqneg: Sqneg,
 7407            cmge: Cmge,
 7408            cmle: Cmle,
 7409            neg: Neg,
 7410            sqxtun: Sqxtun,
 7411            uqxtn: Uqxtn,
 7412            fcvtxn: Fcvtxn,
 7413            fcvtnu: Fcvtnu,
 7414            fcvtmu: Fcvtmu,
 7415            fcvtau: Fcvtau,
 7416            ucvtf: Ucvtf,
 7417            fcmge: Fcmge,
 7418            fcmle: Fcmle,
 7419            fcvtpu: Fcvtpu,
 7420            fcvtzu: Fcvtzu,
 7421            frsqrte: Frsqrte,
 7422
 7423            pub const Group = packed struct {
 7424                Rd: Register.Encoded,
 7425                Rn: Register.Encoded,
 7426                decoded10: u2 = 0b10,
 7427                opcode: u5,
 7428                decoded17: u5 = 0b10000,
 7429                size: Size,
 7430                decoded24: u5 = 0b11110,
 7431                U: std.builtin.Signedness,
 7432                decoded30: u2 = 0b01,
 7433            };
 7434
 7435            /// C7.2.337 SUQADD
 7436            pub const Suqadd = packed struct {
 7437                Rd: Register.Encoded,
 7438                Rn: Register.Encoded,
 7439                decoded10: u2 = 0b10,
 7440                opcode: u5 = 0b00011,
 7441                decoded17: u5 = 0b10000,
 7442                size: Size,
 7443                decoded24: u5 = 0b11110,
 7444                U: std.builtin.Signedness = .signed,
 7445                decoded30: u2 = 0b01,
 7446            };
 7447
 7448            /// C7.2.282 SQABS
 7449            pub const Sqabs = packed struct {
 7450                Rd: Register.Encoded,
 7451                Rn: Register.Encoded,
 7452                decoded10: u2 = 0b10,
 7453                opcode: u5 = 0b00111,
 7454                decoded17: u5 = 0b10000,
 7455                size: Size,
 7456                decoded24: u5 = 0b11110,
 7457                U: std.builtin.Signedness = .signed,
 7458                decoded30: u2 = 0b01,
 7459            };
 7460
 7461            /// C7.2.32 CMGT (zero)
 7462            pub const Cmgt = packed struct {
 7463                Rd: Register.Encoded,
 7464                Rn: Register.Encoded,
 7465                decoded10: u2 = 0b10,
 7466                opcode: u5 = 0b01000,
 7467                decoded17: u5 = 0b10000,
 7468                size: Size,
 7469                decoded24: u5 = 0b11110,
 7470                U: std.builtin.Signedness = .signed,
 7471                decoded30: u2 = 0b01,
 7472            };
 7473
 7474            /// C7.2.28 CMEQ (zero)
 7475            pub const Cmeq = packed struct {
 7476                Rd: Register.Encoded,
 7477                Rn: Register.Encoded,
 7478                decoded10: u2 = 0b10,
 7479                opcode: u5 = 0b01001,
 7480                decoded17: u5 = 0b10000,
 7481                size: Size,
 7482                decoded24: u5 = 0b11110,
 7483                U: std.builtin.Signedness = .signed,
 7484                decoded30: u2 = 0b01,
 7485            };
 7486
 7487            /// C7.2.36 CMLT (zero)
 7488            pub const Cmlt = packed struct {
 7489                Rd: Register.Encoded,
 7490                Rn: Register.Encoded,
 7491                decoded10: u2 = 0b10,
 7492                opcode: u5 = 0b01010,
 7493                decoded17: u5 = 0b10000,
 7494                size: Size,
 7495                decoded24: u5 = 0b11110,
 7496                U: std.builtin.Signedness = .signed,
 7497                decoded30: u2 = 0b01,
 7498            };
 7499
 7500            /// C7.2.1 ABS
 7501            pub const Abs = packed struct {
 7502                Rd: Register.Encoded,
 7503                Rn: Register.Encoded,
 7504                decoded10: u2 = 0b10,
 7505                opcode: u5 = 0b01011,
 7506                decoded17: u5 = 0b10000,
 7507                size: Size,
 7508                decoded24: u5 = 0b11110,
 7509                U: std.builtin.Signedness = .signed,
 7510                decoded30: u2 = 0b01,
 7511            };
 7512
 7513            /// C7.2.308 SQXTN
 7514            pub const Sqxtn = packed struct {
 7515                Rd: Register.Encoded,
 7516                Rn: Register.Encoded,
 7517                decoded10: u2 = 0b10,
 7518                opcode: u5 = 0b10100,
 7519                decoded17: u5 = 0b10000,
 7520                size: Size,
 7521                decoded24: u5 = 0b11110,
 7522                U: std.builtin.Signedness = .signed,
 7523                decoded30: u2 = 0b01,
 7524            };
 7525
 7526            /// C7.2.80 FCVTNS (vector)
 7527            pub const Fcvtns = packed struct {
 7528                Rd: Register.Encoded,
 7529                Rn: Register.Encoded,
 7530                decoded10: u2 = 0b10,
 7531                opcode: u5 = 0b11010,
 7532                decoded17: u5 = 0b10000,
 7533                sz: Sz,
 7534                o2: u1 = 0b0,
 7535                decoded24: u5 = 0b11110,
 7536                U: std.builtin.Signedness = .signed,
 7537                decoded30: u2 = 0b01,
 7538            };
 7539
 7540            /// C7.2.75 FCVTMS (vector)
 7541            pub const Fcvtms = packed struct {
 7542                Rd: Register.Encoded,
 7543                Rn: Register.Encoded,
 7544                decoded10: u2 = 0b10,
 7545                opcode: u5 = 0b11011,
 7546                decoded17: u5 = 0b10000,
 7547                sz: Sz,
 7548                o2: u1 = 0b0,
 7549                decoded24: u5 = 0b11110,
 7550                U: std.builtin.Signedness = .signed,
 7551                decoded30: u2 = 0b01,
 7552            };
 7553
 7554            /// C7.2.70 FCVTAS (vector)
 7555            pub const Fcvtas = packed struct {
 7556                Rd: Register.Encoded,
 7557                Rn: Register.Encoded,
 7558                decoded10: u2 = 0b10,
 7559                opcode: u5 = 0b11100,
 7560                decoded17: u5 = 0b10000,
 7561                sz: Sz,
 7562                o2: u1 = 0b0,
 7563                decoded24: u5 = 0b11110,
 7564                U: std.builtin.Signedness = .signed,
 7565                decoded30: u2 = 0b01,
 7566            };
 7567
 7568            /// C7.2.234 SCVTF (vector, integer)
 7569            pub const Scvtf = packed struct {
 7570                Rd: Register.Encoded,
 7571                Rn: Register.Encoded,
 7572                decoded10: u2 = 0b10,
 7573                opcode: u5 = 0b11101,
 7574                decoded17: u5 = 0b10000,
 7575                sz: Sz,
 7576                o2: u1 = 0b0,
 7577                decoded24: u5 = 0b11110,
 7578                U: std.builtin.Signedness = .signed,
 7579                decoded30: u2 = 0b01,
 7580            };
 7581
 7582            /// C7.2.61 FCMGT (zero)
 7583            pub const Fcmgt = packed struct {
 7584                Rd: Register.Encoded,
 7585                Rn: Register.Encoded,
 7586                decoded10: u2 = 0b10,
 7587                opcode: u5 = 0b01100,
 7588                decoded17: u5 = 0b10000,
 7589                sz: Sz,
 7590                o2: u1 = 0b1,
 7591                decoded24: u5 = 0b11110,
 7592                U: std.builtin.Signedness = .signed,
 7593                decoded30: u2 = 0b01,
 7594            };
 7595
 7596            /// C7.2.57 FCMEQ (zero)
 7597            pub const Fcmeq = packed struct {
 7598                Rd: Register.Encoded,
 7599                Rn: Register.Encoded,
 7600                decoded10: u2 = 0b10,
 7601                opcode: u5 = 0b01101,
 7602                decoded17: u5 = 0b10000,
 7603                sz: Sz,
 7604                o2: u1 = 0b1,
 7605                decoded24: u5 = 0b11110,
 7606                U: std.builtin.Signedness = .signed,
 7607                decoded30: u2 = 0b01,
 7608            };
 7609
 7610            /// C7.2.65 FCMLT (zero)
 7611            pub const Fcmlt = packed struct {
 7612                Rd: Register.Encoded,
 7613                Rn: Register.Encoded,
 7614                decoded10: u2 = 0b10,
 7615                opcode: u5 = 0b01110,
 7616                decoded17: u5 = 0b10000,
 7617                sz: Sz,
 7618                o2: u1 = 0b1,
 7619                decoded24: u5 = 0b11110,
 7620                U: std.builtin.Signedness = .signed,
 7621                decoded30: u2 = 0b01,
 7622            };
 7623
 7624            /// C7.2.84 FCVTPS (vector)
 7625            pub const Fcvtps = packed struct {
 7626                Rd: Register.Encoded,
 7627                Rn: Register.Encoded,
 7628                decoded10: u2 = 0b10,
 7629                opcode: u5 = 0b11010,
 7630                decoded17: u5 = 0b10000,
 7631                sz: Sz,
 7632                o2: u1 = 0b1,
 7633                decoded24: u5 = 0b11110,
 7634                U: std.builtin.Signedness = .signed,
 7635                decoded30: u2 = 0b01,
 7636            };
 7637
 7638            /// C7.2.90 FCVTZS (vector, integer)
 7639            pub const Fcvtzs = packed struct {
 7640                Rd: Register.Encoded,
 7641                Rn: Register.Encoded,
 7642                decoded10: u2 = 0b10,
 7643                opcode: u5 = 0b11011,
 7644                decoded17: u5 = 0b10000,
 7645                sz: Sz,
 7646                o2: u1 = 0b1,
 7647                decoded24: u5 = 0b11110,
 7648                U: std.builtin.Signedness = .signed,
 7649                decoded30: u2 = 0b01,
 7650            };
 7651
 7652            /// C7.2.144 FRECPE
 7653            pub const Frecpe = packed struct {
 7654                Rd: Register.Encoded,
 7655                Rn: Register.Encoded,
 7656                decoded10: u2 = 0b10,
 7657                opcode: u5 = 0b11101,
 7658                decoded17: u5 = 0b10000,
 7659                sz: Sz,
 7660                o2: u1 = 0b1,
 7661                decoded24: u5 = 0b11110,
 7662                U: std.builtin.Signedness = .signed,
 7663                decoded30: u2 = 0b01,
 7664            };
 7665
 7666            /// C7.2.146 FRECPX
 7667            pub const Frecpx = packed struct {
 7668                Rd: Register.Encoded,
 7669                Rn: Register.Encoded,
 7670                decoded10: u2 = 0b10,
 7671                opcode: u5 = 0b11111,
 7672                decoded17: u5 = 0b10000,
 7673                sz: Sz,
 7674                o2: u1 = 0b1,
 7675                decoded24: u5 = 0b11110,
 7676                U: std.builtin.Signedness = .signed,
 7677                decoded30: u2 = 0b01,
 7678            };
 7679
 7680            /// C7.2.394 USQADD
 7681            pub const Usqadd = packed struct {
 7682                Rd: Register.Encoded,
 7683                Rn: Register.Encoded,
 7684                decoded10: u2 = 0b10,
 7685                opcode: u5 = 0b00011,
 7686                decoded17: u5 = 0b10000,
 7687                size: Size,
 7688                decoded24: u5 = 0b11110,
 7689                U: std.builtin.Signedness = .unsigned,
 7690                decoded30: u2 = 0b01,
 7691            };
 7692
 7693            /// C7.2.292 SQNEG
 7694            pub const Sqneg = packed struct {
 7695                Rd: Register.Encoded,
 7696                Rn: Register.Encoded,
 7697                decoded10: u2 = 0b10,
 7698                opcode: u5 = 0b00111,
 7699                decoded17: u5 = 0b10000,
 7700                size: Size,
 7701                decoded24: u5 = 0b11110,
 7702                U: std.builtin.Signedness = .unsigned,
 7703                decoded30: u2 = 0b01,
 7704            };
 7705
 7706            /// C7.2.30 CMGE (zero)
 7707            pub const Cmge = packed struct {
 7708                Rd: Register.Encoded,
 7709                Rn: Register.Encoded,
 7710                decoded10: u2 = 0b10,
 7711                opcode: u5 = 0b01000,
 7712                decoded17: u5 = 0b10000,
 7713                size: Size,
 7714                decoded24: u5 = 0b11110,
 7715                U: std.builtin.Signedness = .unsigned,
 7716                decoded30: u2 = 0b01,
 7717            };
 7718
 7719            /// C7.2.35 CMLE (zero)
 7720            pub const Cmle = packed struct {
 7721                Rd: Register.Encoded,
 7722                Rn: Register.Encoded,
 7723                decoded10: u2 = 0b10,
 7724                opcode: u5 = 0b01001,
 7725                decoded17: u5 = 0b10000,
 7726                size: Size,
 7727                decoded24: u5 = 0b11110,
 7728                U: std.builtin.Signedness = .unsigned,
 7729                decoded30: u2 = 0b01,
 7730            };
 7731
 7732            /// C7.2.209 NEG (vector)
 7733            pub const Neg = packed struct {
 7734                Rd: Register.Encoded,
 7735                Rn: Register.Encoded,
 7736                decoded10: u2 = 0b10,
 7737                opcode: u5 = 0b01011,
 7738                decoded17: u5 = 0b10000,
 7739                size: Size,
 7740                decoded24: u5 = 0b11110,
 7741                U: std.builtin.Signedness = .unsigned,
 7742                decoded30: u2 = 0b01,
 7743            };
 7744
 7745            /// C7.2.309 SQXTUN
 7746            pub const Sqxtun = packed struct {
 7747                Rd: Register.Encoded,
 7748                Rn: Register.Encoded,
 7749                decoded10: u2 = 0b10,
 7750                opcode: u5 = 0b10010,
 7751                decoded17: u5 = 0b10000,
 7752                size: Size,
 7753                decoded24: u5 = 0b11110,
 7754                U: std.builtin.Signedness = .unsigned,
 7755                decoded30: u2 = 0b01,
 7756            };
 7757
 7758            /// C7.2.381 UQXTN
 7759            pub const Uqxtn = packed struct {
 7760                Rd: Register.Encoded,
 7761                Rn: Register.Encoded,
 7762                decoded10: u2 = 0b10,
 7763                opcode: u5 = 0b10100,
 7764                decoded17: u5 = 0b10000,
 7765                size: Size,
 7766                decoded24: u5 = 0b11110,
 7767                U: std.builtin.Signedness = .unsigned,
 7768                decoded30: u2 = 0b01,
 7769            };
 7770
 7771            /// C7.2.88 FCVTXN
 7772            pub const Fcvtxn = packed struct {
 7773                Rd: Register.Encoded,
 7774                Rn: Register.Encoded,
 7775                decoded10: u2 = 0b10,
 7776                opcode: u5 = 0b10110,
 7777                decoded17: u5 = 0b10000,
 7778                sz: Sz,
 7779                o2: u1 = 0b0,
 7780                decoded24: u5 = 0b11110,
 7781                U: std.builtin.Signedness = .unsigned,
 7782                decoded30: u2 = 0b01,
 7783            };
 7784
 7785            /// C7.2.82 FCVTNU (vector)
 7786            pub const Fcvtnu = packed struct {
 7787                Rd: Register.Encoded,
 7788                Rn: Register.Encoded,
 7789                decoded10: u2 = 0b10,
 7790                opcode: u5 = 0b11010,
 7791                decoded17: u5 = 0b10000,
 7792                sz: Sz,
 7793                o2: u1 = 0b0,
 7794                decoded24: u5 = 0b11110,
 7795                U: std.builtin.Signedness = .unsigned,
 7796                decoded30: u2 = 0b01,
 7797            };
 7798
 7799            /// C7.2.77 FCVTMU (vector)
 7800            pub const Fcvtmu = packed struct {
 7801                Rd: Register.Encoded,
 7802                Rn: Register.Encoded,
 7803                decoded10: u2 = 0b10,
 7804                opcode: u5 = 0b11011,
 7805                decoded17: u5 = 0b10000,
 7806                sz: Sz,
 7807                o2: u1 = 0b0,
 7808                decoded24: u5 = 0b11110,
 7809                U: std.builtin.Signedness = .unsigned,
 7810                decoded30: u2 = 0b01,
 7811            };
 7812
 7813            /// C7.2.72 FCVTAU (vector)
 7814            pub const Fcvtau = packed struct {
 7815                Rd: Register.Encoded,
 7816                Rn: Register.Encoded,
 7817                decoded10: u2 = 0b10,
 7818                opcode: u5 = 0b11100,
 7819                decoded17: u5 = 0b10000,
 7820                sz: Sz,
 7821                o2: u1 = 0b0,
 7822                decoded24: u5 = 0b11110,
 7823                U: std.builtin.Signedness = .unsigned,
 7824                decoded30: u2 = 0b01,
 7825            };
 7826
 7827            /// C7.2.353 UCVTF (vector, integer)
 7828            pub const Ucvtf = packed struct {
 7829                Rd: Register.Encoded,
 7830                Rn: Register.Encoded,
 7831                decoded10: u2 = 0b10,
 7832                opcode: u5 = 0b11101,
 7833                decoded17: u5 = 0b10000,
 7834                sz: Sz,
 7835                o2: u1 = 0b0,
 7836                decoded24: u5 = 0b11110,
 7837                U: std.builtin.Signedness = .unsigned,
 7838                decoded30: u2 = 0b01,
 7839            };
 7840
 7841            /// C7.2.59 FCMGE (zero)
 7842            pub const Fcmge = packed struct {
 7843                Rd: Register.Encoded,
 7844                Rn: Register.Encoded,
 7845                decoded10: u2 = 0b10,
 7846                opcode: u5 = 0b01100,
 7847                decoded17: u5 = 0b10000,
 7848                sz: Sz,
 7849                o2: u1 = 0b1,
 7850                decoded24: u5 = 0b11110,
 7851                U: std.builtin.Signedness = .unsigned,
 7852                decoded30: u2 = 0b01,
 7853            };
 7854
 7855            /// C7.2.64 FCMLE (zero)
 7856            pub const Fcmle = packed struct {
 7857                Rd: Register.Encoded,
 7858                Rn: Register.Encoded,
 7859                decoded10: u2 = 0b10,
 7860                opcode: u5 = 0b01101,
 7861                decoded17: u5 = 0b10000,
 7862                sz: Sz,
 7863                o2: u1 = 0b1,
 7864                decoded24: u5 = 0b11110,
 7865                U: std.builtin.Signedness = .unsigned,
 7866                decoded30: u2 = 0b01,
 7867            };
 7868
 7869            /// C7.2.86 FCVTPU (vector)
 7870            pub const Fcvtpu = packed struct {
 7871                Rd: Register.Encoded,
 7872                Rn: Register.Encoded,
 7873                decoded10: u2 = 0b10,
 7874                opcode: u5 = 0b11010,
 7875                decoded17: u5 = 0b10000,
 7876                sz: Sz,
 7877                o2: u1 = 0b1,
 7878                decoded24: u5 = 0b11110,
 7879                U: std.builtin.Signedness = .unsigned,
 7880                decoded30: u2 = 0b01,
 7881            };
 7882
 7883            /// C7.2.94 FCVTZU (vector, integer)
 7884            pub const Fcvtzu = packed struct {
 7885                Rd: Register.Encoded,
 7886                Rn: Register.Encoded,
 7887                decoded10: u2 = 0b10,
 7888                opcode: u5 = 0b11011,
 7889                decoded17: u5 = 0b10000,
 7890                sz: Sz,
 7891                o2: u1 = 0b1,
 7892                decoded24: u5 = 0b11110,
 7893                U: std.builtin.Signedness = .unsigned,
 7894                decoded30: u2 = 0b01,
 7895            };
 7896
 7897            /// C7.2.169 FRSQRTE
 7898            pub const Frsqrte = packed struct {
 7899                Rd: Register.Encoded,
 7900                Rn: Register.Encoded,
 7901                decoded10: u2 = 0b10,
 7902                opcode: u5 = 0b11101,
 7903                decoded17: u5 = 0b10000,
 7904                sz: Sz,
 7905                o2: u1 = 0b1,
 7906                decoded24: u5 = 0b11110,
 7907                U: std.builtin.Signedness = .unsigned,
 7908                decoded30: u2 = 0b01,
 7909            };
 7910
 7911            pub const Decoded = union(enum) {
 7912                unallocated,
 7913                suqadd: Suqadd,
 7914                sqabs: Sqabs,
 7915                cmgt: Cmgt,
 7916                cmeq: Cmeq,
 7917                cmlt: Cmlt,
 7918                abs: Abs,
 7919                sqxtn: Sqxtn,
 7920                fcvtns: Fcvtns,
 7921                fcvtms: Fcvtms,
 7922                fcvtas: Fcvtas,
 7923                scvtf: Scvtf,
 7924                fcmgt: Fcmgt,
 7925                fcmeq: Fcmeq,
 7926                fcmlt: Fcmlt,
 7927                fcvtps: Fcvtps,
 7928                fcvtzs: Fcvtzs,
 7929                frecpe: Frecpe,
 7930                frecpx: Frecpx,
 7931                usqadd: Usqadd,
 7932                sqneg: Sqneg,
 7933                cmge: Cmge,
 7934                cmle: Cmle,
 7935                neg: Neg,
 7936                sqxtun: Sqxtun,
 7937                uqxtn: Uqxtn,
 7938                fcvtxn: Fcvtxn,
 7939                fcvtnu: Fcvtnu,
 7940                fcvtmu: Fcvtmu,
 7941                fcvtau: Fcvtau,
 7942                ucvtf: Ucvtf,
 7943                fcmge: Fcmge,
 7944                fcmle: Fcmle,
 7945                fcvtpu: Fcvtpu,
 7946                fcvtzu: Fcvtzu,
 7947                frsqrte: Frsqrte,
 7948            };
 7949            pub fn decode(inst: @This()) @This().Decoded {
 7950                return switch (inst.group.U) {
 7951                    .signed => switch (inst.group.opcode) {
 7952                        else => .unallocated,
 7953                        0b00011 => .{ .suqadd = inst.suqadd },
 7954                        0b00111 => .{ .sqabs = inst.sqabs },
 7955                        0b01000 => .{ .cmgt = inst.cmgt },
 7956                        0b01001 => .{ .cmeq = inst.cmeq },
 7957                        0b01010 => .{ .cmlt = inst.cmlt },
 7958                        0b01011 => .{ .abs = inst.abs },
 7959                        0b10100 => .{ .sqxtn = inst.sqxtn },
 7960                        0b11010 => switch (inst.group.size) {
 7961                            .byte, .half => .{ .fcvtns = inst.fcvtns },
 7962                            .single, .double => .{ .fcvtps = inst.fcvtps },
 7963                        },
 7964                        0b11011 => switch (inst.group.size) {
 7965                            .byte, .half => .{ .fcvtms = inst.fcvtms },
 7966                            .single, .double => .{ .fcvtzs = inst.fcvtzs },
 7967                        },
 7968                        0b11100 => switch (inst.group.size) {
 7969                            .byte, .half => .{ .fcvtas = inst.fcvtas },
 7970                            .single, .double => .unallocated,
 7971                        },
 7972                        0b11101 => switch (inst.group.size) {
 7973                            .byte, .half => .{ .scvtf = inst.scvtf },
 7974                            .single, .double => .{ .frecpe = inst.frecpe },
 7975                        },
 7976                        0b01100 => switch (inst.group.size) {
 7977                            .byte, .half => .unallocated,
 7978                            .single, .double => .{ .fcmgt = inst.fcmgt },
 7979                        },
 7980                        0b01101 => switch (inst.group.size) {
 7981                            .byte, .half => .unallocated,
 7982                            .single, .double => .{ .fcmeq = inst.fcmeq },
 7983                        },
 7984                        0b01110 => switch (inst.group.size) {
 7985                            .byte, .half => .unallocated,
 7986                            .single, .double => .{ .fcmlt = inst.fcmlt },
 7987                        },
 7988                        0b11111 => switch (inst.group.size) {
 7989                            .byte, .half => .unallocated,
 7990                            .single, .double => .{ .frecpx = inst.frecpx },
 7991                        },
 7992                    },
 7993                    .unsigned => switch (inst.group.opcode) {
 7994                        else => .unallocated,
 7995                        0b00011 => .{ .usqadd = inst.usqadd },
 7996                        0b00111 => .{ .sqneg = inst.sqneg },
 7997                        0b01000 => .{ .cmge = inst.cmge },
 7998                        0b01001 => .{ .cmle = inst.cmle },
 7999                        0b01011 => .{ .neg = inst.neg },
 8000                        0b10010 => .{ .sqxtun = inst.sqxtun },
 8001                        0b10100 => .{ .uqxtn = inst.uqxtn },
 8002                        0b10110 => switch (inst.group.size) {
 8003                            .byte, .half => .{ .fcvtxn = inst.fcvtxn },
 8004                            .single, .double => .unallocated,
 8005                        },
 8006                        0b11010 => switch (inst.group.size) {
 8007                            .byte, .half => .{ .fcvtnu = inst.fcvtnu },
 8008                            .single, .double => .{ .fcvtpu = inst.fcvtpu },
 8009                        },
 8010                        0b11011 => switch (inst.group.size) {
 8011                            .byte, .half => .{ .fcvtmu = inst.fcvtmu },
 8012                            .single, .double => .{ .fcvtzu = inst.fcvtzu },
 8013                        },
 8014                        0b11100 => switch (inst.group.size) {
 8015                            .byte, .half => .{ .fcvtau = inst.fcvtau },
 8016                            .single, .double => .unallocated,
 8017                        },
 8018                        0b11101 => switch (inst.group.size) {
 8019                            .byte, .half => .{ .ucvtf = inst.ucvtf },
 8020                            .single, .double => .{ .frsqrte = inst.frsqrte },
 8021                        },
 8022                        0b01100 => switch (inst.group.size) {
 8023                            .byte, .half => .unallocated,
 8024                            .single, .double => .{ .fcmge = inst.fcmge },
 8025                        },
 8026                        0b01101 => switch (inst.group.size) {
 8027                            .byte, .half => .unallocated,
 8028                            .single, .double => .{ .fcmle = inst.fcmle },
 8029                        },
 8030                    },
 8031                };
 8032            }
 8033        };
 8034
 8035        /// Advanced SIMD scalar pairwise
 8036        pub const SimdScalarPairwise = packed union {
 8037            group: @This().Group,
 8038            addp: Addp,
 8039
 8040            pub const Group = packed struct {
 8041                Rd: Register.Encoded,
 8042                Rn: Register.Encoded,
 8043                decoded10: u2 = 0b10,
 8044                opcode: u5,
 8045                decoded17: u5 = 0b11000,
 8046                size: Size,
 8047                decoded24: u5 = 0b11110,
 8048                U: std.builtin.Signedness,
 8049                decoded30: u2 = 0b01,
 8050            };
 8051
 8052            /// C7.2.4 ADDP (scalar)
 8053            pub const Addp = packed struct {
 8054                Rd: Register.Encoded,
 8055                Rn: Register.Encoded,
 8056                decoded10: u2 = 0b10,
 8057                opcode: u5 = 0b11011,
 8058                decoded17: u5 = 0b11000,
 8059                size: Size,
 8060                decoded24: u5 = 0b11110,
 8061                U: std.builtin.Signedness = .signed,
 8062                decoded30: u2 = 0b01,
 8063            };
 8064
 8065            pub const Decoded = union(enum) {
 8066                unallocated,
 8067                addp: Addp,
 8068            };
 8069            pub fn decode(inst: @This()) @This().Decoded {
 8070                return switch (inst.group.U) {
 8071                    .signed => switch (inst.group.opcode) {
 8072                        else => .unallocated,
 8073                        0b11011 => .{ .addp = inst.addp },
 8074                    },
 8075                    .unsigned => .unallocated,
 8076                };
 8077            }
 8078        };
 8079
 8080        /// Advanced SIMD copy
 8081        pub const SimdCopy = packed union {
 8082            group: @This().Group,
 8083            dup: Dup,
 8084            smov: Smov,
 8085            umov: Umov,
 8086            ins: Ins,
 8087
 8088            pub const Group = packed struct {
 8089                Rd: Register.Encoded,
 8090                Rn: Register.Encoded,
 8091                decoded10: u1 = 0b1,
 8092                imm4: u4,
 8093                decoded15: u1 = 0b0,
 8094                imm5: u5,
 8095                decoded21: u8 = 0b01110000,
 8096                op: u1,
 8097                Q: u1,
 8098                decoded31: u1 = 0b0,
 8099            };
 8100
 8101            /// C7.2.39 DUP (element)
 8102            /// C7.2.40 DUP (general)
 8103            pub const Dup = packed struct {
 8104                Rd: Register.Encoded,
 8105                Rn: Register.Encoded,
 8106                decoded10: u1 = 0b1,
 8107                imm4: Imm4,
 8108                decoded15: u1 = 0b0,
 8109                imm5: u5,
 8110                decoded21: u8 = 0b01110000,
 8111                op: u1 = 0b0,
 8112                Q: Q,
 8113                decoded31: u1 = 0b0,
 8114
 8115                pub const Imm4 = enum(u4) {
 8116                    element = 0b0000,
 8117                    general = 0b0001,
 8118                    _,
 8119                };
 8120            };
 8121
 8122            /// C7.2.279 SMOV
 8123            pub const Smov = packed struct {
 8124                Rd: Register.Encoded,
 8125                Rn: Register.Encoded,
 8126                decoded10: u1 = 0b1,
 8127                imm4: u4 = 0b0101,
 8128                decoded15: u1 = 0b0,
 8129                imm5: u5,
 8130                decoded21: u8 = 0b01110000,
 8131                op: u1 = 0b0,
 8132                Q: Register.GeneralSize,
 8133                decoded31: u1 = 0b0,
 8134            };
 8135
 8136            /// C7.2.371 UMOV
 8137            pub const Umov = packed struct {
 8138                Rd: Register.Encoded,
 8139                Rn: Register.Encoded,
 8140                decoded10: u1 = 0b1,
 8141                imm4: u4 = 0b0111,
 8142                decoded15: u1 = 0b0,
 8143                imm5: u5,
 8144                decoded21: u8 = 0b01110000,
 8145                op: u1 = 0b0,
 8146                Q: Register.GeneralSize,
 8147                decoded31: u1 = 0b0,
 8148            };
 8149
 8150            /// C7.2.175 INS (element)
 8151            /// C7.2.176 INS (general)
 8152            pub const Ins = packed struct {
 8153                Rd: Register.Encoded,
 8154                Rn: Register.Encoded,
 8155                decoded10: u1 = 0b1,
 8156                imm4: Imm4,
 8157                decoded15: u1 = 0b0,
 8158                imm5: u5,
 8159                decoded21: u8 = 0b01110000,
 8160                op: Op,
 8161                Q: u1 = 0b1,
 8162                decoded31: u1 = 0b0,
 8163
 8164                pub const Imm4 = packed union {
 8165                    element: u4,
 8166                    general: General,
 8167
 8168                    pub const General = enum(u4) {
 8169                        general = 0b0011,
 8170                        _,
 8171                    };
 8172                };
 8173
 8174                pub const Op = enum(u1) {
 8175                    general = 0b0,
 8176                    element = 0b1,
 8177                };
 8178            };
 8179
 8180            pub const Decoded = union(enum) {
 8181                unallocated,
 8182                dup: Dup,
 8183                smov: Smov,
 8184                umov: Umov,
 8185                ins: Ins,
 8186            };
 8187            pub fn decode(inst: @This()) @This().Decoded {
 8188                return switch (inst.group.op) {
 8189                    0b0 => switch (inst.group.imm4) {
 8190                        0b0000, 0b0001 => .{ .dup = inst.dup },
 8191                        else => .unallocated,
 8192                        0b0101 => switch (@ctz(inst.group.imm5)) {
 8193                            0, 1 => .{ .smov = inst.smov },
 8194                            2 => switch (inst.group.Q) {
 8195                                0b1 => .{ .smov = inst.smov },
 8196                                0b0 => .unallocated,
 8197                            },
 8198                            else => .unallocated,
 8199                        },
 8200                        0b0111 => switch (@ctz(inst.group.imm5)) {
 8201                            0, 1, 2 => switch (inst.group.Q) {
 8202                                0b0 => .{ .umov = inst.umov },
 8203                                0b1 => .unallocated,
 8204                            },
 8205                            3 => switch (inst.group.Q) {
 8206                                0b1 => .{ .umov = inst.umov },
 8207                                0b0 => .unallocated,
 8208                            },
 8209                            else => .unallocated,
 8210                        },
 8211                        0b0011 => switch (inst.group.Q) {
 8212                            0b0 => .unallocated,
 8213                            0b1 => .{ .ins = inst.ins },
 8214                        },
 8215                    },
 8216                    0b1 => switch (inst.group.Q) {
 8217                        0b0 => .unallocated,
 8218                        0b1 => .{ .ins = inst.ins },
 8219                    },
 8220                };
 8221            }
 8222        };
 8223
 8224        /// Advanced SIMD two-register miscellaneous (FP16)
 8225        pub const SimdTwoRegisterMiscellaneousFp16 = packed union {
 8226            group: @This().Group,
 8227            frintn: Frintn,
 8228            frintm: Frintm,
 8229            fcvtns: Fcvtns,
 8230            fcvtms: Fcvtms,
 8231            fcvtas: Fcvtas,
 8232            scvtf: Scvtf,
 8233            fcmgt: Fcmgt,
 8234            fcmeq: Fcmeq,
 8235            fcmlt: Fcmlt,
 8236            fabs: Fabs,
 8237            frintp: Frintp,
 8238            frintz: Frintz,
 8239            fcvtps: Fcvtps,
 8240            fcvtzs: Fcvtzs,
 8241            frecpe: Frecpe,
 8242            frinta: Frinta,
 8243            frintx: Frintx,
 8244            fcvtnu: Fcvtnu,
 8245            fcvtmu: Fcvtmu,
 8246            fcvtau: Fcvtau,
 8247            ucvtf: Ucvtf,
 8248            fcmge: Fcmge,
 8249            fcmle: Fcmle,
 8250            fneg: Fneg,
 8251            frinti: Frinti,
 8252            fcvtpu: Fcvtpu,
 8253            fcvtzu: Fcvtzu,
 8254            frsqrte: Frsqrte,
 8255            fsqrt: Fsqrt,
 8256
 8257            pub const Group = packed struct {
 8258                Rd: Register.Encoded,
 8259                Rn: Register.Encoded,
 8260                decoded10: u2 = 0b10,
 8261                opcode: u5,
 8262                decoded17: u6 = 0b111100,
 8263                a: u1,
 8264                decoded24: u5 = 0b01110,
 8265                U: std.builtin.Signedness,
 8266                Q: Q,
 8267                decoded31: u1 = 0b0,
 8268            };
 8269
 8270            /// C7.2.161 FRINTN (vector)
 8271            pub const Frintn = packed struct {
 8272                Rd: Register.Encoded,
 8273                Rn: Register.Encoded,
 8274                decoded10: u2 = 0b10,
 8275                opcode: u5 = 0b11000,
 8276                decoded17: u6 = 0b111100,
 8277                o2: u1 = 0b0,
 8278                decoded24: u5 = 0b01110,
 8279                U: std.builtin.Signedness = .signed,
 8280                Q: Q,
 8281                decoded31: u1 = 0b0,
 8282            };
 8283
 8284            /// C7.2.159 FRINTM (vector)
 8285            pub const Frintm = packed struct {
 8286                Rd: Register.Encoded,
 8287                Rn: Register.Encoded,
 8288                decoded10: u2 = 0b10,
 8289                opcode: u5 = 0b11001,
 8290                decoded17: u6 = 0b111100,
 8291                o2: u1 = 0b0,
 8292                decoded24: u5 = 0b01110,
 8293                U: std.builtin.Signedness = .signed,
 8294                Q: Q,
 8295                decoded31: u1 = 0b0,
 8296            };
 8297
 8298            /// C7.2.80 FCVTNS (vector)
 8299            pub const Fcvtns = packed struct {
 8300                Rd: Register.Encoded,
 8301                Rn: Register.Encoded,
 8302                decoded10: u2 = 0b10,
 8303                opcode: u5 = 0b11010,
 8304                decoded17: u6 = 0b111100,
 8305                o2: u1 = 0b0,
 8306                decoded24: u5 = 0b01110,
 8307                U: std.builtin.Signedness = .signed,
 8308                Q: Q,
 8309                decoded31: u1 = 0b0,
 8310            };
 8311
 8312            /// C7.2.75 FCVTMS (vector)
 8313            pub const Fcvtms = packed struct {
 8314                Rd: Register.Encoded,
 8315                Rn: Register.Encoded,
 8316                decoded10: u2 = 0b10,
 8317                opcode: u5 = 0b11011,
 8318                decoded17: u6 = 0b111100,
 8319                o2: u1 = 0b0,
 8320                decoded24: u5 = 0b01110,
 8321                U: std.builtin.Signedness = .signed,
 8322                Q: Q,
 8323                decoded31: u1 = 0b0,
 8324            };
 8325
 8326            /// C7.2.70 FCVTAS (vector)
 8327            pub const Fcvtas = packed struct {
 8328                Rd: Register.Encoded,
 8329                Rn: Register.Encoded,
 8330                decoded10: u2 = 0b10,
 8331                opcode: u5 = 0b11100,
 8332                decoded17: u6 = 0b111100,
 8333                o2: u1 = 0b0,
 8334                decoded24: u5 = 0b01110,
 8335                U: std.builtin.Signedness = .signed,
 8336                Q: Q,
 8337                decoded31: u1 = 0b0,
 8338            };
 8339
 8340            /// C7.2.234 SCVTF (vector, integer)
 8341            pub const Scvtf = packed struct {
 8342                Rd: Register.Encoded,
 8343                Rn: Register.Encoded,
 8344                decoded10: u2 = 0b10,
 8345                opcode: u5 = 0b11101,
 8346                decoded17: u6 = 0b111100,
 8347                o2: u1 = 0b0,
 8348                decoded24: u5 = 0b01110,
 8349                U: std.builtin.Signedness = .signed,
 8350                Q: Q,
 8351                decoded31: u1 = 0b0,
 8352            };
 8353
 8354            /// C7.2.61 FCMGT (zero)
 8355            pub const Fcmgt = packed struct {
 8356                Rd: Register.Encoded,
 8357                Rn: Register.Encoded,
 8358                decoded10: u2 = 0b10,
 8359                opcode: u5 = 0b01100,
 8360                decoded17: u6 = 0b111100,
 8361                o2: u1 = 0b1,
 8362                decoded24: u5 = 0b01110,
 8363                U: std.builtin.Signedness = .signed,
 8364                Q: Q,
 8365                decoded31: u1 = 0b0,
 8366            };
 8367
 8368            /// C7.2.57 FCMEQ (zero)
 8369            pub const Fcmeq = packed struct {
 8370                Rd: Register.Encoded,
 8371                Rn: Register.Encoded,
 8372                decoded10: u2 = 0b10,
 8373                opcode: u5 = 0b01101,
 8374                decoded17: u6 = 0b111100,
 8375                o2: u1 = 0b1,
 8376                decoded24: u5 = 0b01110,
 8377                U: std.builtin.Signedness = .signed,
 8378                Q: Q,
 8379                decoded31: u1 = 0b0,
 8380            };
 8381
 8382            /// C7.2.65 FCMLT (zero)
 8383            pub const Fcmlt = packed struct {
 8384                Rd: Register.Encoded,
 8385                Rn: Register.Encoded,
 8386                decoded10: u2 = 0b10,
 8387                opcode: u5 = 0b01110,
 8388                decoded17: u6 = 0b111100,
 8389                o2: u1 = 0b1,
 8390                decoded24: u5 = 0b01110,
 8391                U: std.builtin.Signedness = .signed,
 8392                Q: Q,
 8393                decoded31: u1 = 0b0,
 8394            };
 8395
 8396            /// C7.2.45 FABS (vector)
 8397            pub const Fabs = packed struct {
 8398                Rd: Register.Encoded,
 8399                Rn: Register.Encoded,
 8400                decoded10: u2 = 0b10,
 8401                opcode: u5 = 0b01111,
 8402                decoded17: u6 = 0b111100,
 8403                o2: u1 = 0b1,
 8404                decoded24: u5 = 0b01110,
 8405                U: std.builtin.Signedness = .signed,
 8406                Q: Q,
 8407                decoded31: u1 = 0b0,
 8408            };
 8409
 8410            /// C7.2.163 FRINTP (vector)
 8411            pub const Frintp = packed struct {
 8412                Rd: Register.Encoded,
 8413                Rn: Register.Encoded,
 8414                decoded10: u2 = 0b10,
 8415                opcode: u5 = 0b11000,
 8416                decoded17: u6 = 0b111100,
 8417                o2: u1 = 0b1,
 8418                decoded24: u5 = 0b01110,
 8419                U: std.builtin.Signedness = .signed,
 8420                Q: Q,
 8421                decoded31: u1 = 0b0,
 8422            };
 8423
 8424            /// C7.2.167 FRINTZ (vector)
 8425            pub const Frintz = packed struct {
 8426                Rd: Register.Encoded,
 8427                Rn: Register.Encoded,
 8428                decoded10: u2 = 0b10,
 8429                opcode: u5 = 0b11001,
 8430                decoded17: u6 = 0b111100,
 8431                o2: u1 = 0b1,
 8432                decoded24: u5 = 0b01110,
 8433                U: std.builtin.Signedness = .signed,
 8434                Q: Q,
 8435                decoded31: u1 = 0b0,
 8436            };
 8437
 8438            /// C7.2.84 FCVTPS (vector)
 8439            pub const Fcvtps = packed struct {
 8440                Rd: Register.Encoded,
 8441                Rn: Register.Encoded,
 8442                decoded10: u2 = 0b10,
 8443                opcode: u5 = 0b11010,
 8444                decoded17: u6 = 0b111100,
 8445                o2: u1 = 0b1,
 8446                decoded24: u5 = 0b01110,
 8447                U: std.builtin.Signedness = .signed,
 8448                Q: Q,
 8449                decoded31: u1 = 0b0,
 8450            };
 8451
 8452            /// C7.2.90 FCVTZS (vector, integer)
 8453            pub const Fcvtzs = packed struct {
 8454                Rd: Register.Encoded,
 8455                Rn: Register.Encoded,
 8456                decoded10: u2 = 0b10,
 8457                opcode: u5 = 0b11011,
 8458                decoded17: u6 = 0b111100,
 8459                o2: u1 = 0b1,
 8460                decoded24: u5 = 0b01110,
 8461                U: std.builtin.Signedness = .signed,
 8462                Q: Q,
 8463                decoded31: u1 = 0b0,
 8464            };
 8465
 8466            /// C7.2.144 FRECPE
 8467            pub const Frecpe = packed struct {
 8468                Rd: Register.Encoded,
 8469                Rn: Register.Encoded,
 8470                decoded10: u2 = 0b10,
 8471                opcode: u5 = 0b11101,
 8472                decoded17: u6 = 0b111100,
 8473                o2: u1 = 0b1,
 8474                decoded24: u5 = 0b01110,
 8475                U: std.builtin.Signedness = .signed,
 8476                Q: Q,
 8477                decoded31: u1 = 0b0,
 8478            };
 8479
 8480            /// C7.2.155 FRINTA (vector)
 8481            pub const Frinta = packed struct {
 8482                Rd: Register.Encoded,
 8483                Rn: Register.Encoded,
 8484                decoded10: u2 = 0b10,
 8485                opcode: u5 = 0b11000,
 8486                decoded17: u6 = 0b111100,
 8487                o2: u1 = 0b0,
 8488                decoded24: u5 = 0b01110,
 8489                U: std.builtin.Signedness = .unsigned,
 8490                Q: Q,
 8491                decoded31: u1 = 0b0,
 8492            };
 8493
 8494            /// C7.2.159 FRINTX (vector)
 8495            pub const Frintx = packed struct {
 8496                Rd: Register.Encoded,
 8497                Rn: Register.Encoded,
 8498                decoded10: u2 = 0b10,
 8499                opcode: u5 = 0b11001,
 8500                decoded17: u6 = 0b111100,
 8501                o2: u1 = 0b0,
 8502                decoded24: u5 = 0b01110,
 8503                U: std.builtin.Signedness = .unsigned,
 8504                Q: Q,
 8505                decoded31: u1 = 0b0,
 8506            };
 8507
 8508            /// C7.2.82 FCVTNU (vector)
 8509            pub const Fcvtnu = packed struct {
 8510                Rd: Register.Encoded,
 8511                Rn: Register.Encoded,
 8512                decoded10: u2 = 0b10,
 8513                opcode: u5 = 0b11010,
 8514                decoded17: u6 = 0b111100,
 8515                o2: u1 = 0b0,
 8516                decoded24: u5 = 0b01110,
 8517                U: std.builtin.Signedness = .unsigned,
 8518                Q: Q,
 8519                decoded31: u1 = 0b0,
 8520            };
 8521
 8522            /// C7.2.77 FCVTMU (vector)
 8523            pub const Fcvtmu = packed struct {
 8524                Rd: Register.Encoded,
 8525                Rn: Register.Encoded,
 8526                decoded10: u2 = 0b10,
 8527                opcode: u5 = 0b11011,
 8528                decoded17: u6 = 0b111100,
 8529                o2: u1 = 0b0,
 8530                decoded24: u5 = 0b01110,
 8531                U: std.builtin.Signedness = .unsigned,
 8532                Q: Q,
 8533                decoded31: u1 = 0b0,
 8534            };
 8535
 8536            /// C7.2.72 FCVTAU (vector)
 8537            pub const Fcvtau = packed struct {
 8538                Rd: Register.Encoded,
 8539                Rn: Register.Encoded,
 8540                decoded10: u2 = 0b10,
 8541                opcode: u5 = 0b11100,
 8542                decoded17: u6 = 0b111100,
 8543                o2: u1 = 0b0,
 8544                decoded24: u5 = 0b01110,
 8545                U: std.builtin.Signedness = .unsigned,
 8546                Q: Q,
 8547                decoded31: u1 = 0b0,
 8548            };
 8549
 8550            /// C7.2.353 UCVTF (vector, integer)
 8551            pub const Ucvtf = packed struct {
 8552                Rd: Register.Encoded,
 8553                Rn: Register.Encoded,
 8554                decoded10: u2 = 0b10,
 8555                opcode: u5 = 0b11101,
 8556                decoded17: u6 = 0b111100,
 8557                o2: u1 = 0b0,
 8558                decoded24: u5 = 0b01110,
 8559                U: std.builtin.Signedness = .unsigned,
 8560                Q: Q,
 8561                decoded31: u1 = 0b0,
 8562            };
 8563
 8564            /// C7.2.59 FCMGE (zero)
 8565            pub const Fcmge = packed struct {
 8566                Rd: Register.Encoded,
 8567                Rn: Register.Encoded,
 8568                decoded10: u2 = 0b10,
 8569                opcode: u5 = 0b01100,
 8570                decoded17: u6 = 0b111100,
 8571                o2: u1 = 0b1,
 8572                decoded24: u5 = 0b01110,
 8573                U: std.builtin.Signedness = .unsigned,
 8574                Q: Q,
 8575                decoded31: u1 = 0b0,
 8576            };
 8577
 8578            /// C7.2.64 FCMLE (zero)
 8579            pub const Fcmle = packed struct {
 8580                Rd: Register.Encoded,
 8581                Rn: Register.Encoded,
 8582                decoded10: u2 = 0b10,
 8583                opcode: u5 = 0b01101,
 8584                decoded17: u6 = 0b111100,
 8585                o2: u1 = 0b1,
 8586                decoded24: u5 = 0b01110,
 8587                U: std.builtin.Signedness = .unsigned,
 8588                Q: Q,
 8589                decoded31: u1 = 0b0,
 8590            };
 8591
 8592            /// C7.2.139 FNEG (vector)
 8593            pub const Fneg = packed struct {
 8594                Rd: Register.Encoded,
 8595                Rn: Register.Encoded,
 8596                decoded10: u2 = 0b10,
 8597                opcode: u5 = 0b01111,
 8598                decoded17: u6 = 0b111100,
 8599                o2: u1 = 0b1,
 8600                decoded24: u5 = 0b01110,
 8601                U: std.builtin.Signedness = .unsigned,
 8602                Q: Q,
 8603                decoded31: u1 = 0b0,
 8604            };
 8605
 8606            /// C7.2.157 FRINTI (vector)
 8607            pub const Frinti = packed struct {
 8608                Rd: Register.Encoded,
 8609                Rn: Register.Encoded,
 8610                decoded10: u2 = 0b10,
 8611                opcode: u5 = 0b11001,
 8612                decoded17: u6 = 0b111100,
 8613                o2: u1 = 0b1,
 8614                decoded24: u5 = 0b01110,
 8615                U: std.builtin.Signedness = .unsigned,
 8616                Q: Q,
 8617                decoded31: u1 = 0b0,
 8618            };
 8619
 8620            /// C7.2.86 FCVTPU (vector)
 8621            pub const Fcvtpu = packed struct {
 8622                Rd: Register.Encoded,
 8623                Rn: Register.Encoded,
 8624                decoded10: u2 = 0b10,
 8625                opcode: u5 = 0b11010,
 8626                decoded17: u6 = 0b111100,
 8627                o2: u1 = 0b1,
 8628                decoded24: u5 = 0b01110,
 8629                U: std.builtin.Signedness = .unsigned,
 8630                Q: Q,
 8631                decoded31: u1 = 0b0,
 8632            };
 8633
 8634            /// C7.2.94 FCVTZU (vector, integer)
 8635            pub const Fcvtzu = packed struct {
 8636                Rd: Register.Encoded,
 8637                Rn: Register.Encoded,
 8638                decoded10: u2 = 0b10,
 8639                opcode: u5 = 0b11011,
 8640                decoded17: u6 = 0b111100,
 8641                o2: u1 = 0b1,
 8642                decoded24: u5 = 0b01110,
 8643                U: std.builtin.Signedness = .unsigned,
 8644                Q: Q,
 8645                decoded31: u1 = 0b0,
 8646            };
 8647
 8648            /// C7.2.169 FRSQRTE
 8649            pub const Frsqrte = packed struct {
 8650                Rd: Register.Encoded,
 8651                Rn: Register.Encoded,
 8652                decoded10: u2 = 0b10,
 8653                opcode: u5 = 0b11101,
 8654                decoded17: u6 = 0b111100,
 8655                o2: u1 = 0b1,
 8656                decoded24: u5 = 0b01110,
 8657                U: std.builtin.Signedness = .unsigned,
 8658                Q: Q,
 8659                decoded31: u1 = 0b0,
 8660            };
 8661
 8662            /// C7.2.171 FSQRT
 8663            pub const Fsqrt = packed struct {
 8664                Rd: Register.Encoded,
 8665                Rn: Register.Encoded,
 8666                decoded10: u2 = 0b10,
 8667                opcode: u5 = 0b11111,
 8668                decoded17: u6 = 0b111100,
 8669                o2: u1 = 0b1,
 8670                decoded24: u5 = 0b01110,
 8671                U: std.builtin.Signedness = .unsigned,
 8672                Q: Q,
 8673                decoded31: u1 = 0b0,
 8674            };
 8675
 8676            pub const Decoded = union(enum) {
 8677                unallocated,
 8678                frintn: Frintn,
 8679                frintm: Frintm,
 8680                fcvtns: Fcvtns,
 8681                fcvtms: Fcvtms,
 8682                fcvtas: Fcvtas,
 8683                scvtf: Scvtf,
 8684                fcmgt: Fcmgt,
 8685                fcmeq: Fcmeq,
 8686                fcmlt: Fcmlt,
 8687                fabs: Fabs,
 8688                frintp: Frintp,
 8689                frintz: Frintz,
 8690                fcvtps: Fcvtps,
 8691                fcvtzs: Fcvtzs,
 8692                frecpe: Frecpe,
 8693                frinta: Frinta,
 8694                frintx: Frintx,
 8695                fcvtnu: Fcvtnu,
 8696                fcvtmu: Fcvtmu,
 8697                fcvtau: Fcvtau,
 8698                ucvtf: Ucvtf,
 8699                fcmge: Fcmge,
 8700                fcmle: Fcmle,
 8701                fneg: Fneg,
 8702                frinti: Frinti,
 8703                fcvtpu: Fcvtpu,
 8704                fcvtzu: Fcvtzu,
 8705                frsqrte: Frsqrte,
 8706                fsqrt: Fsqrt,
 8707            };
 8708            pub fn decode(inst: @This()) @This().Decoded {
 8709                return switch (inst.group.U) {
 8710                    .signed => switch (inst.group.a) {
 8711                        0b0 => switch (inst.group.opcode) {
 8712                            else => .unallocated,
 8713                            0b11000 => .{ .frintn = inst.frintn },
 8714                            0b11001 => .{ .frintm = inst.frintm },
 8715                            0b11010 => .{ .fcvtns = inst.fcvtns },
 8716                            0b11011 => .{ .fcvtms = inst.fcvtms },
 8717                            0b11100 => .{ .fcvtas = inst.fcvtas },
 8718                            0b11101 => .{ .scvtf = inst.scvtf },
 8719                        },
 8720                        0b1 => switch (inst.group.opcode) {
 8721                            else => .unallocated,
 8722                            0b01100 => .{ .fcmgt = inst.fcmgt },
 8723                            0b01101 => .{ .fcmeq = inst.fcmeq },
 8724                            0b01110 => .{ .fcmlt = inst.fcmlt },
 8725                            0b01111 => .{ .fabs = inst.fabs },
 8726                            0b11000 => .{ .frintp = inst.frintp },
 8727                            0b11001 => .{ .frintz = inst.frintz },
 8728                            0b11010 => .{ .fcvtps = inst.fcvtps },
 8729                            0b11011 => .{ .fcvtzs = inst.fcvtzs },
 8730                            0b11101 => .{ .frecpe = inst.frecpe },
 8731                        },
 8732                    },
 8733                    .unsigned => switch (inst.group.a) {
 8734                        0b0 => switch (inst.group.opcode) {
 8735                            else => .unallocated,
 8736                            0b11000 => .{ .frinta = inst.frinta },
 8737                            0b11001 => .{ .frintx = inst.frintx },
 8738                            0b11010 => .{ .fcvtnu = inst.fcvtnu },
 8739                            0b11011 => .{ .fcvtmu = inst.fcvtmu },
 8740                            0b11100 => .{ .fcvtau = inst.fcvtau },
 8741                            0b11101 => .{ .ucvtf = inst.ucvtf },
 8742                        },
 8743                        0b1 => switch (inst.group.opcode) {
 8744                            else => .unallocated,
 8745                            0b01100 => .{ .fcmge = inst.fcmge },
 8746                            0b01101 => .{ .fcmle = inst.fcmle },
 8747                            0b01111 => .{ .fneg = inst.fneg },
 8748                            0b11001 => .{ .frinti = inst.frinti },
 8749                            0b11010 => .{ .fcvtpu = inst.fcvtpu },
 8750                            0b11011 => .{ .fcvtzu = inst.fcvtzu },
 8751                            0b11101 => .{ .frsqrte = inst.frsqrte },
 8752                            0b11111 => .{ .fsqrt = inst.fsqrt },
 8753                        },
 8754                    },
 8755                };
 8756            }
 8757        };
 8758
 8759        /// Advanced SIMD two-register miscellaneous
 8760        pub const SimdTwoRegisterMiscellaneous = packed union {
 8761            group: @This().Group,
 8762            suqadd: Suqadd,
 8763            cnt: Cnt,
 8764            sqabs: Sqabs,
 8765            cmgt: Cmgt,
 8766            cmeq: Cmeq,
 8767            cmlt: Cmlt,
 8768            abs: Abs,
 8769            sqxtn: Sqxtn,
 8770            frintn: Frintn,
 8771            frintm: Frintm,
 8772            fcvtns: Fcvtns,
 8773            fcvtms: Fcvtms,
 8774            fcvtas: Fcvtas,
 8775            scvtf: Scvtf,
 8776            fcmgt: Fcmgt,
 8777            fcmeq: Fcmeq,
 8778            fcmlt: Fcmlt,
 8779            fabs: Fabs,
 8780            frintp: Frintp,
 8781            frintz: Frintz,
 8782            fcvtps: Fcvtps,
 8783            fcvtzs: Fcvtzs,
 8784            frecpe: Frecpe,
 8785            usqadd: Usqadd,
 8786            sqneg: Sqneg,
 8787            cmge: Cmge,
 8788            cmle: Cmle,
 8789            neg: Neg,
 8790            sqxtun: Sqxtun,
 8791            uqxtn: Uqxtn,
 8792            fcvtxn: Fcvtxn,
 8793            frinta: Frinta,
 8794            frintx: Frintx,
 8795            fcvtnu: Fcvtnu,
 8796            fcvtmu: Fcvtmu,
 8797            fcvtau: Fcvtau,
 8798            ucvtf: Ucvtf,
 8799            not: Not,
 8800            fcmge: Fcmge,
 8801            fcmle: Fcmle,
 8802            fneg: Fneg,
 8803            frinti: Frinti,
 8804            fcvtpu: Fcvtpu,
 8805            fcvtzu: Fcvtzu,
 8806            frsqrte: Frsqrte,
 8807            fsqrt: Fsqrt,
 8808
 8809            pub const Group = packed struct {
 8810                Rd: Register.Encoded,
 8811                Rn: Register.Encoded,
 8812                decoded10: u2 = 0b10,
 8813                opcode: u5,
 8814                decoded17: u5 = 0b10000,
 8815                size: Size,
 8816                decoded24: u5 = 0b01110,
 8817                U: std.builtin.Signedness,
 8818                Q: Q,
 8819                decoded31: u1 = 0b0,
 8820            };
 8821
 8822            /// C7.2.337 SUQADD
 8823            pub const Suqadd = packed struct {
 8824                Rd: Register.Encoded,
 8825                Rn: Register.Encoded,
 8826                decoded10: u2 = 0b10,
 8827                opcode: u5 = 0b00011,
 8828                decoded17: u5 = 0b10000,
 8829                size: Size,
 8830                decoded24: u5 = 0b01110,
 8831                U: std.builtin.Signedness = .signed,
 8832                Q: Q,
 8833                decoded31: u1 = 0b0,
 8834            };
 8835
 8836            /// C7.2.38 CNT
 8837            pub const Cnt = packed struct {
 8838                Rd: Register.Encoded,
 8839                Rn: Register.Encoded,
 8840                decoded10: u2 = 0b10,
 8841                opcode: u5 = 0b00101,
 8842                decoded17: u5 = 0b10000,
 8843                size: Size,
 8844                decoded24: u5 = 0b01110,
 8845                U: std.builtin.Signedness = .signed,
 8846                Q: Q,
 8847                decoded31: u1 = 0b0,
 8848            };
 8849
 8850            /// C7.2.282 SQABS
 8851            pub const Sqabs = packed struct {
 8852                Rd: Register.Encoded,
 8853                Rn: Register.Encoded,
 8854                decoded10: u2 = 0b10,
 8855                opcode: u5 = 0b00111,
 8856                decoded17: u5 = 0b10000,
 8857                size: Size,
 8858                decoded24: u5 = 0b01110,
 8859                U: std.builtin.Signedness = .signed,
 8860                Q: Q,
 8861                decoded31: u1 = 0b0,
 8862            };
 8863
 8864            /// C7.2.32 CMGT (zero)
 8865            pub const Cmgt = packed struct {
 8866                Rd: Register.Encoded,
 8867                Rn: Register.Encoded,
 8868                decoded10: u2 = 0b10,
 8869                opcode: u5 = 0b01000,
 8870                decoded17: u5 = 0b10000,
 8871                size: Size,
 8872                decoded24: u5 = 0b01110,
 8873                U: std.builtin.Signedness = .signed,
 8874                Q: Q,
 8875                decoded31: u1 = 0b0,
 8876            };
 8877
 8878            /// C7.2.28 CMEQ (zero)
 8879            pub const Cmeq = packed struct {
 8880                Rd: Register.Encoded,
 8881                Rn: Register.Encoded,
 8882                decoded10: u2 = 0b10,
 8883                opcode: u5 = 0b01001,
 8884                decoded17: u5 = 0b10000,
 8885                size: Size,
 8886                decoded24: u5 = 0b01110,
 8887                U: std.builtin.Signedness = .signed,
 8888                Q: Q,
 8889                decoded31: u1 = 0b0,
 8890            };
 8891
 8892            /// C7.2.36 CMLT (zero)
 8893            pub const Cmlt = packed struct {
 8894                Rd: Register.Encoded,
 8895                Rn: Register.Encoded,
 8896                decoded10: u2 = 0b10,
 8897                opcode: u5 = 0b01010,
 8898                decoded17: u5 = 0b10000,
 8899                size: Size,
 8900                decoded24: u5 = 0b01110,
 8901                U: std.builtin.Signedness = .signed,
 8902                Q: Q,
 8903                decoded31: u1 = 0b0,
 8904            };
 8905
 8906            /// C7.2.1 ABS
 8907            pub const Abs = packed struct {
 8908                Rd: Register.Encoded,
 8909                Rn: Register.Encoded,
 8910                decoded10: u2 = 0b10,
 8911                opcode: u5 = 0b01011,
 8912                decoded17: u5 = 0b10000,
 8913                size: Size,
 8914                decoded24: u5 = 0b01110,
 8915                U: std.builtin.Signedness = .signed,
 8916                Q: Q,
 8917                decoded31: u1 = 0b0,
 8918            };
 8919
 8920            /// C7.2.308 SQXTN, SQXTN2
 8921            pub const Sqxtn = packed struct {
 8922                Rd: Register.Encoded,
 8923                Rn: Register.Encoded,
 8924                decoded10: u2 = 0b10,
 8925                opcode: u5 = 0b10100,
 8926                decoded17: u5 = 0b10000,
 8927                size: Size,
 8928                decoded24: u5 = 0b01110,
 8929                U: std.builtin.Signedness = .signed,
 8930                Q: Q,
 8931                decoded31: u1 = 0b0,
 8932            };
 8933
 8934            /// C7.2.161 FRINTN (vector)
 8935            pub const Frintn = packed struct {
 8936                Rd: Register.Encoded,
 8937                Rn: Register.Encoded,
 8938                decoded10: u2 = 0b10,
 8939                opcode: u5 = 0b11000,
 8940                decoded17: u5 = 0b10000,
 8941                sz: Sz,
 8942                o2: u1 = 0b0,
 8943                decoded24: u5 = 0b01110,
 8944                U: std.builtin.Signedness = .signed,
 8945                Q: Q,
 8946                decoded31: u1 = 0b0,
 8947            };
 8948
 8949            /// C7.2.159 FRINTM (vector)
 8950            pub const Frintm = packed struct {
 8951                Rd: Register.Encoded,
 8952                Rn: Register.Encoded,
 8953                decoded10: u2 = 0b10,
 8954                opcode: u5 = 0b11001,
 8955                decoded17: u5 = 0b10000,
 8956                sz: Sz,
 8957                o2: u1 = 0b0,
 8958                decoded24: u5 = 0b01110,
 8959                U: std.builtin.Signedness = .signed,
 8960                Q: Q,
 8961                decoded31: u1 = 0b0,
 8962            };
 8963
 8964            /// C7.2.80 FCVTNS (vector)
 8965            pub const Fcvtns = packed struct {
 8966                Rd: Register.Encoded,
 8967                Rn: Register.Encoded,
 8968                decoded10: u2 = 0b10,
 8969                opcode: u5 = 0b11010,
 8970                decoded17: u5 = 0b10000,
 8971                sz: Sz,
 8972                o2: u1 = 0b0,
 8973                decoded24: u5 = 0b01110,
 8974                U: std.builtin.Signedness = .signed,
 8975                Q: Q,
 8976                decoded31: u1 = 0b0,
 8977            };
 8978
 8979            /// C7.2.75 FCVTMS (vector)
 8980            pub const Fcvtms = packed struct {
 8981                Rd: Register.Encoded,
 8982                Rn: Register.Encoded,
 8983                decoded10: u2 = 0b10,
 8984                opcode: u5 = 0b11011,
 8985                decoded17: u5 = 0b10000,
 8986                sz: Sz,
 8987                o2: u1 = 0b0,
 8988                decoded24: u5 = 0b01110,
 8989                U: std.builtin.Signedness = .signed,
 8990                Q: Q,
 8991                decoded31: u1 = 0b0,
 8992            };
 8993
 8994            /// C7.2.70 FCVTAS (vector)
 8995            pub const Fcvtas = packed struct {
 8996                Rd: Register.Encoded,
 8997                Rn: Register.Encoded,
 8998                decoded10: u2 = 0b10,
 8999                opcode: u5 = 0b11100,
 9000                decoded17: u5 = 0b10000,
 9001                sz: Sz,
 9002                o2: u1 = 0b0,
 9003                decoded24: u5 = 0b01110,
 9004                U: std.builtin.Signedness = .signed,
 9005                Q: Q,
 9006                decoded31: u1 = 0b0,
 9007            };
 9008
 9009            /// C7.2.234 SCVTF (vector, integer)
 9010            pub const Scvtf = packed struct {
 9011                Rd: Register.Encoded,
 9012                Rn: Register.Encoded,
 9013                decoded10: u2 = 0b10,
 9014                opcode: u5 = 0b11101,
 9015                decoded17: u5 = 0b10000,
 9016                sz: Sz,
 9017                o2: u1 = 0b0,
 9018                decoded24: u5 = 0b01110,
 9019                U: std.builtin.Signedness = .signed,
 9020                Q: Q,
 9021                decoded31: u1 = 0b0,
 9022            };
 9023
 9024            /// C7.2.61 FCMGT (zero)
 9025            pub const Fcmgt = packed struct {
 9026                Rd: Register.Encoded,
 9027                Rn: Register.Encoded,
 9028                decoded10: u2 = 0b10,
 9029                opcode: u5 = 0b01100,
 9030                decoded17: u5 = 0b10000,
 9031                sz: Sz,
 9032                o2: u1 = 0b1,
 9033                decoded24: u5 = 0b01110,
 9034                U: std.builtin.Signedness = .signed,
 9035                Q: Q,
 9036                decoded31: u1 = 0b0,
 9037            };
 9038
 9039            /// C7.2.57 FCMEQ (zero)
 9040            pub const Fcmeq = packed struct {
 9041                Rd: Register.Encoded,
 9042                Rn: Register.Encoded,
 9043                decoded10: u2 = 0b10,
 9044                opcode: u5 = 0b01101,
 9045                decoded17: u5 = 0b10000,
 9046                sz: Sz,
 9047                o2: u1 = 0b1,
 9048                decoded24: u5 = 0b01110,
 9049                U: std.builtin.Signedness = .signed,
 9050                Q: Q,
 9051                decoded31: u1 = 0b0,
 9052            };
 9053
 9054            /// C7.2.65 FCMLT (zero)
 9055            pub const Fcmlt = packed struct {
 9056                Rd: Register.Encoded,
 9057                Rn: Register.Encoded,
 9058                decoded10: u2 = 0b10,
 9059                opcode: u5 = 0b01110,
 9060                decoded17: u5 = 0b10000,
 9061                sz: Sz,
 9062                o2: u1 = 0b1,
 9063                decoded24: u5 = 0b01110,
 9064                U: std.builtin.Signedness = .signed,
 9065                Q: Q,
 9066                decoded31: u1 = 0b0,
 9067            };
 9068
 9069            /// C7.2.45 FABS (vector)
 9070            pub const Fabs = packed struct {
 9071                Rd: Register.Encoded,
 9072                Rn: Register.Encoded,
 9073                decoded10: u2 = 0b10,
 9074                opcode: u5 = 0b01111,
 9075                decoded17: u5 = 0b10000,
 9076                sz: Sz,
 9077                o2: u1 = 0b1,
 9078                decoded24: u5 = 0b01110,
 9079                U: std.builtin.Signedness = .signed,
 9080                Q: Q,
 9081                decoded31: u1 = 0b0,
 9082            };
 9083
 9084            /// C7.2.163 FRINTP (vector)
 9085            pub const Frintp = packed struct {
 9086                Rd: Register.Encoded,
 9087                Rn: Register.Encoded,
 9088                decoded10: u2 = 0b10,
 9089                opcode: u5 = 0b11000,
 9090                decoded17: u5 = 0b10000,
 9091                sz: Sz,
 9092                o2: u1 = 0b1,
 9093                decoded24: u5 = 0b01110,
 9094                U: std.builtin.Signedness = .signed,
 9095                Q: Q,
 9096                decoded31: u1 = 0b0,
 9097            };
 9098
 9099            /// C7.2.167 FRINTZ (vector)
 9100            pub const Frintz = packed struct {
 9101                Rd: Register.Encoded,
 9102                Rn: Register.Encoded,
 9103                decoded10: u2 = 0b10,
 9104                opcode: u5 = 0b11001,
 9105                decoded17: u5 = 0b10000,
 9106                sz: Sz,
 9107                o2: u1 = 0b1,
 9108                decoded24: u5 = 0b01110,
 9109                U: std.builtin.Signedness = .signed,
 9110                Q: Q,
 9111                decoded31: u1 = 0b0,
 9112            };
 9113
 9114            /// C7.2.84 FCVTPS (vector)
 9115            pub const Fcvtps = packed struct {
 9116                Rd: Register.Encoded,
 9117                Rn: Register.Encoded,
 9118                decoded10: u2 = 0b10,
 9119                opcode: u5 = 0b11010,
 9120                decoded17: u5 = 0b10000,
 9121                sz: Sz,
 9122                o2: u1 = 0b1,
 9123                decoded24: u5 = 0b01110,
 9124                U: std.builtin.Signedness = .signed,
 9125                Q: Q,
 9126                decoded31: u1 = 0b0,
 9127            };
 9128
 9129            /// C7.2.90 FCVTZS (vector, integer)
 9130            pub const Fcvtzs = packed struct {
 9131                Rd: Register.Encoded,
 9132                Rn: Register.Encoded,
 9133                decoded10: u2 = 0b10,
 9134                opcode: u5 = 0b11011,
 9135                decoded17: u5 = 0b10000,
 9136                sz: Sz,
 9137                o2: u1 = 0b1,
 9138                decoded24: u5 = 0b01110,
 9139                U: std.builtin.Signedness = .signed,
 9140                Q: Q,
 9141                decoded31: u1 = 0b0,
 9142            };
 9143
 9144            /// C7.2.144 FRECPE
 9145            pub const Frecpe = packed struct {
 9146                Rd: Register.Encoded,
 9147                Rn: Register.Encoded,
 9148                decoded10: u2 = 0b10,
 9149                opcode: u5 = 0b11101,
 9150                decoded17: u5 = 0b10000,
 9151                sz: Sz,
 9152                o2: u1 = 0b1,
 9153                decoded24: u5 = 0b01110,
 9154                U: std.builtin.Signedness = .signed,
 9155                Q: Q,
 9156                decoded31: u1 = 0b0,
 9157            };
 9158
 9159            /// C7.2.394 USQADD
 9160            pub const Usqadd = packed struct {
 9161                Rd: Register.Encoded,
 9162                Rn: Register.Encoded,
 9163                decoded10: u2 = 0b10,
 9164                opcode: u5 = 0b00011,
 9165                decoded17: u5 = 0b10000,
 9166                size: Size,
 9167                decoded24: u5 = 0b01110,
 9168                U: std.builtin.Signedness = .unsigned,
 9169                Q: Q,
 9170                decoded31: u1 = 0b0,
 9171            };
 9172
 9173            /// C7.2.292 SQNEG
 9174            pub const Sqneg = packed struct {
 9175                Rd: Register.Encoded,
 9176                Rn: Register.Encoded,
 9177                decoded10: u2 = 0b10,
 9178                opcode: u5 = 0b00111,
 9179                decoded17: u5 = 0b10000,
 9180                size: Size,
 9181                decoded24: u5 = 0b01110,
 9182                U: std.builtin.Signedness = .unsigned,
 9183                Q: Q,
 9184                decoded31: u1 = 0b0,
 9185            };
 9186
 9187            /// C7.2.30 CMGE (zero)
 9188            pub const Cmge = packed struct {
 9189                Rd: Register.Encoded,
 9190                Rn: Register.Encoded,
 9191                decoded10: u2 = 0b10,
 9192                opcode: u5 = 0b01000,
 9193                decoded17: u5 = 0b10000,
 9194                size: Size,
 9195                decoded24: u5 = 0b01110,
 9196                U: std.builtin.Signedness = .unsigned,
 9197                Q: Q,
 9198                decoded31: u1 = 0b0,
 9199            };
 9200
 9201            /// C7.2.35 CMLE (zero)
 9202            pub const Cmle = packed struct {
 9203                Rd: Register.Encoded,
 9204                Rn: Register.Encoded,
 9205                decoded10: u2 = 0b10,
 9206                opcode: u5 = 0b01001,
 9207                decoded17: u5 = 0b10000,
 9208                size: Size,
 9209                decoded24: u5 = 0b01110,
 9210                U: std.builtin.Signedness = .unsigned,
 9211                Q: Q,
 9212                decoded31: u1 = 0b0,
 9213            };
 9214
 9215            /// C7.2.209 NEG (vector)
 9216            pub const Neg = packed struct {
 9217                Rd: Register.Encoded,
 9218                Rn: Register.Encoded,
 9219                decoded10: u2 = 0b10,
 9220                opcode: u5 = 0b01011,
 9221                decoded17: u5 = 0b10000,
 9222                size: Size,
 9223                decoded24: u5 = 0b01110,
 9224                U: std.builtin.Signedness = .unsigned,
 9225                Q: Q,
 9226                decoded31: u1 = 0b0,
 9227            };
 9228
 9229            /// C7.2.309 SQXTUN
 9230            pub const Sqxtun = packed struct {
 9231                Rd: Register.Encoded,
 9232                Rn: Register.Encoded,
 9233                decoded10: u2 = 0b10,
 9234                opcode: u5 = 0b10010,
 9235                decoded17: u5 = 0b10000,
 9236                size: Size,
 9237                decoded24: u5 = 0b01110,
 9238                U: std.builtin.Signedness = .unsigned,
 9239                Q: Q,
 9240                decoded31: u1 = 0b0,
 9241            };
 9242
 9243            /// C7.2.381 UQXTN
 9244            pub const Uqxtn = packed struct {
 9245                Rd: Register.Encoded,
 9246                Rn: Register.Encoded,
 9247                decoded10: u2 = 0b10,
 9248                opcode: u5 = 0b10100,
 9249                decoded17: u5 = 0b10000,
 9250                size: Size,
 9251                decoded24: u5 = 0b01110,
 9252                U: std.builtin.Signedness = .unsigned,
 9253                Q: Q,
 9254                decoded31: u1 = 0b0,
 9255            };
 9256
 9257            /// C7.2.88 FCVTXN
 9258            pub const Fcvtxn = packed struct {
 9259                Rd: Register.Encoded,
 9260                Rn: Register.Encoded,
 9261                decoded10: u2 = 0b10,
 9262                opcode: u5 = 0b10110,
 9263                decoded17: u5 = 0b10000,
 9264                sz: Sz,
 9265                o2: u1 = 0b0,
 9266                decoded24: u5 = 0b01110,
 9267                U: std.builtin.Signedness = .unsigned,
 9268                Q: Q,
 9269                decoded31: u1 = 0b0,
 9270            };
 9271
 9272            /// C7.2.155 FRINTA (vector)
 9273            pub const Frinta = packed struct {
 9274                Rd: Register.Encoded,
 9275                Rn: Register.Encoded,
 9276                decoded10: u2 = 0b10,
 9277                opcode: u5 = 0b11000,
 9278                decoded17: u5 = 0b10000,
 9279                sz: Sz,
 9280                o2: u1 = 0b0,
 9281                decoded24: u5 = 0b01110,
 9282                U: std.builtin.Signedness = .unsigned,
 9283                Q: Q,
 9284                decoded31: u1 = 0b0,
 9285            };
 9286
 9287            /// C7.2.165 FRINTX (vector)
 9288            pub const Frintx = packed struct {
 9289                Rd: Register.Encoded,
 9290                Rn: Register.Encoded,
 9291                decoded10: u2 = 0b10,
 9292                opcode: u5 = 0b11001,
 9293                decoded17: u5 = 0b10000,
 9294                sz: Sz,
 9295                o2: u1 = 0b0,
 9296                decoded24: u5 = 0b01110,
 9297                U: std.builtin.Signedness = .unsigned,
 9298                Q: Q,
 9299                decoded31: u1 = 0b0,
 9300            };
 9301
 9302            /// C7.2.82 FCVTNU (vector)
 9303            pub const Fcvtnu = packed struct {
 9304                Rd: Register.Encoded,
 9305                Rn: Register.Encoded,
 9306                decoded10: u2 = 0b10,
 9307                opcode: u5 = 0b11010,
 9308                decoded17: u5 = 0b10000,
 9309                sz: Sz,
 9310                o2: u1 = 0b0,
 9311                decoded24: u5 = 0b01110,
 9312                U: std.builtin.Signedness = .unsigned,
 9313                Q: Q,
 9314                decoded31: u1 = 0b0,
 9315            };
 9316
 9317            /// C7.2.77 FCVTMU (vector)
 9318            pub const Fcvtmu = packed struct {
 9319                Rd: Register.Encoded,
 9320                Rn: Register.Encoded,
 9321                decoded10: u2 = 0b10,
 9322                opcode: u5 = 0b11011,
 9323                decoded17: u5 = 0b10000,
 9324                sz: Sz,
 9325                o2: u1 = 0b0,
 9326                decoded24: u5 = 0b01110,
 9327                U: std.builtin.Signedness = .unsigned,
 9328                Q: Q,
 9329                decoded31: u1 = 0b0,
 9330            };
 9331
 9332            /// C7.2.72 FCVTAU (vector)
 9333            pub const Fcvtau = packed struct {
 9334                Rd: Register.Encoded,
 9335                Rn: Register.Encoded,
 9336                decoded10: u2 = 0b10,
 9337                opcode: u5 = 0b11100,
 9338                decoded17: u5 = 0b10000,
 9339                sz: Sz,
 9340                o2: u1 = 0b0,
 9341                decoded24: u5 = 0b01110,
 9342                U: std.builtin.Signedness = .unsigned,
 9343                Q: Q,
 9344                decoded31: u1 = 0b0,
 9345            };
 9346
 9347            /// C7.2.353 UCVTF (vector, integer)
 9348            pub const Ucvtf = packed struct {
 9349                Rd: Register.Encoded,
 9350                Rn: Register.Encoded,
 9351                decoded10: u2 = 0b10,
 9352                opcode: u5 = 0b11101,
 9353                decoded17: u5 = 0b10000,
 9354                sz: Sz,
 9355                o2: u1 = 0b0,
 9356                decoded24: u5 = 0b01110,
 9357                U: std.builtin.Signedness = .unsigned,
 9358                Q: Q,
 9359                decoded31: u1 = 0b0,
 9360            };
 9361
 9362            /// C7.2.210 NOT
 9363            pub const Not = packed struct {
 9364                Rd: Register.Encoded,
 9365                Rn: Register.Encoded,
 9366                decoded10: u2 = 0b10,
 9367                opcode: u5 = 0b00101,
 9368                decoded17: u5 = 0b10000,
 9369                size: Size = .byte,
 9370                decoded24: u5 = 0b01110,
 9371                U: std.builtin.Signedness = .unsigned,
 9372                Q: Q,
 9373                decoded31: u1 = 0b0,
 9374            };
 9375
 9376            /// C7.2.59 FCMGE (zero)
 9377            pub const Fcmge = packed struct {
 9378                Rd: Register.Encoded,
 9379                Rn: Register.Encoded,
 9380                decoded10: u2 = 0b10,
 9381                opcode: u5 = 0b01100,
 9382                decoded17: u5 = 0b10000,
 9383                sz: Sz,
 9384                o2: u1 = 0b1,
 9385                decoded24: u5 = 0b01110,
 9386                U: std.builtin.Signedness = .unsigned,
 9387                Q: Q,
 9388                decoded31: u1 = 0b0,
 9389            };
 9390
 9391            /// C7.2.64 FCMLE (zero)
 9392            pub const Fcmle = packed struct {
 9393                Rd: Register.Encoded,
 9394                Rn: Register.Encoded,
 9395                decoded10: u2 = 0b10,
 9396                opcode: u5 = 0b01101,
 9397                decoded17: u5 = 0b10000,
 9398                sz: Sz,
 9399                o2: u1 = 0b1,
 9400                decoded24: u5 = 0b01110,
 9401                U: std.builtin.Signedness = .unsigned,
 9402                Q: Q,
 9403                decoded31: u1 = 0b0,
 9404            };
 9405
 9406            /// C7.2.139 FNEG (vector)
 9407            pub const Fneg = packed struct {
 9408                Rd: Register.Encoded,
 9409                Rn: Register.Encoded,
 9410                decoded10: u2 = 0b10,
 9411                opcode: u5 = 0b01111,
 9412                decoded17: u5 = 0b10000,
 9413                sz: Sz,
 9414                o2: u1 = 0b1,
 9415                decoded24: u5 = 0b01110,
 9416                U: std.builtin.Signedness = .unsigned,
 9417                Q: Q,
 9418                decoded31: u1 = 0b0,
 9419            };
 9420
 9421            /// C7.2.157 FRINTI (vector)
 9422            pub const Frinti = packed struct {
 9423                Rd: Register.Encoded,
 9424                Rn: Register.Encoded,
 9425                decoded10: u2 = 0b10,
 9426                opcode: u5 = 0b11001,
 9427                decoded17: u5 = 0b10000,
 9428                sz: Sz,
 9429                o2: u1 = 0b1,
 9430                decoded24: u5 = 0b01110,
 9431                U: std.builtin.Signedness = .unsigned,
 9432                Q: Q,
 9433                decoded31: u1 = 0b0,
 9434            };
 9435
 9436            /// C7.2.86 FCVTPU (vector)
 9437            pub const Fcvtpu = packed struct {
 9438                Rd: Register.Encoded,
 9439                Rn: Register.Encoded,
 9440                decoded10: u2 = 0b10,
 9441                opcode: u5 = 0b11010,
 9442                decoded17: u5 = 0b10000,
 9443                sz: Sz,
 9444                o2: u1 = 0b1,
 9445                decoded24: u5 = 0b01110,
 9446                U: std.builtin.Signedness = .unsigned,
 9447                Q: Q,
 9448                decoded31: u1 = 0b0,
 9449            };
 9450
 9451            /// C7.2.94 FCVTZU (vector, integer)
 9452            pub const Fcvtzu = packed struct {
 9453                Rd: Register.Encoded,
 9454                Rn: Register.Encoded,
 9455                decoded10: u2 = 0b10,
 9456                opcode: u5 = 0b11011,
 9457                decoded17: u5 = 0b10000,
 9458                sz: Sz,
 9459                o2: u1 = 0b1,
 9460                decoded24: u5 = 0b01110,
 9461                U: std.builtin.Signedness = .unsigned,
 9462                Q: Q,
 9463                decoded31: u1 = 0b0,
 9464            };
 9465
 9466            /// C7.2.169 FRSQRTE
 9467            pub const Frsqrte = packed struct {
 9468                Rd: Register.Encoded,
 9469                Rn: Register.Encoded,
 9470                decoded10: u2 = 0b10,
 9471                opcode: u5 = 0b11101,
 9472                decoded17: u5 = 0b10000,
 9473                sz: Sz,
 9474                o2: u1 = 0b1,
 9475                decoded24: u5 = 0b01110,
 9476                U: std.builtin.Signedness = .unsigned,
 9477                Q: Q,
 9478                decoded31: u1 = 0b0,
 9479            };
 9480
 9481            /// C7.2.171 FSQRT (vector)
 9482            pub const Fsqrt = packed struct {
 9483                Rd: Register.Encoded,
 9484                Rn: Register.Encoded,
 9485                decoded10: u2 = 0b10,
 9486                opcode: u5 = 0b11111,
 9487                decoded17: u5 = 0b10000,
 9488                sz: Sz,
 9489                o2: u1 = 0b1,
 9490                decoded24: u5 = 0b01110,
 9491                U: std.builtin.Signedness = .unsigned,
 9492                Q: Q,
 9493                decoded31: u1 = 0b0,
 9494            };
 9495
 9496            pub const Decoded = union(enum) {
 9497                unallocated,
 9498                suqadd: Suqadd,
 9499                cnt: Cnt,
 9500                sqabs: Sqabs,
 9501                cmgt: Cmgt,
 9502                cmeq: Cmeq,
 9503                cmlt: Cmlt,
 9504                abs: Abs,
 9505                sqxtn: Sqxtn,
 9506                frintn: Frintn,
 9507                frintm: Frintm,
 9508                fcvtns: Fcvtns,
 9509                fcvtms: Fcvtms,
 9510                fcvtas: Fcvtas,
 9511                scvtf: Scvtf,
 9512                fcmgt: Fcmgt,
 9513                fcmeq: Fcmeq,
 9514                fcmlt: Fcmlt,
 9515                fabs: Fabs,
 9516                frintp: Frintp,
 9517                frintz: Frintz,
 9518                fcvtps: Fcvtps,
 9519                fcvtzs: Fcvtzs,
 9520                frecpe: Frecpe,
 9521                usqadd: Usqadd,
 9522                sqneg: Sqneg,
 9523                cmge: Cmge,
 9524                cmle: Cmle,
 9525                neg: Neg,
 9526                sqxtun: Sqxtun,
 9527                uqxtn: Uqxtn,
 9528                fcvtxn: Fcvtxn,
 9529                frinta: Frinta,
 9530                frintx: Frintx,
 9531                fcvtnu: Fcvtnu,
 9532                fcvtmu: Fcvtmu,
 9533                fcvtau: Fcvtau,
 9534                ucvtf: Ucvtf,
 9535                not: Not,
 9536                fcmge: Fcmge,
 9537                fcmle: Fcmle,
 9538                fneg: Fneg,
 9539                frinti: Frinti,
 9540                fcvtpu: Fcvtpu,
 9541                fcvtzu: Fcvtzu,
 9542                frsqrte: Frsqrte,
 9543                fsqrt: Fsqrt,
 9544            };
 9545            pub fn decode(inst: @This()) @This().Decoded {
 9546                return switch (inst.group.U) {
 9547                    .signed => switch (inst.group.opcode) {
 9548                        else => .unallocated,
 9549                        0b00011 => .{ .suqadd = inst.suqadd },
 9550                        0b00101 => .{ .cnt = inst.cnt },
 9551                        0b00111 => .{ .sqabs = inst.sqabs },
 9552                        0b01000 => .{ .cmgt = inst.cmgt },
 9553                        0b01001 => .{ .cmeq = inst.cmeq },
 9554                        0b01010 => .{ .cmlt = inst.cmlt },
 9555                        0b01011 => .{ .abs = inst.abs },
 9556                        0b10100 => .{ .sqxtn = inst.sqxtn },
 9557                        0b11000 => switch (inst.group.size) {
 9558                            .byte, .half => .{ .frintn = inst.frintn },
 9559                            .single, .double => .{ .frintp = inst.frintp },
 9560                        },
 9561                        0b11001 => switch (inst.group.size) {
 9562                            .byte, .half => .{ .frintm = inst.frintm },
 9563                            .single, .double => .{ .frintz = inst.frintz },
 9564                        },
 9565                        0b11010 => switch (inst.group.size) {
 9566                            .byte, .half => .{ .fcvtns = inst.fcvtns },
 9567                            .single, .double => .{ .fcvtps = inst.fcvtps },
 9568                        },
 9569                        0b11011 => switch (inst.group.size) {
 9570                            .byte, .half => .{ .fcvtms = inst.fcvtms },
 9571                            .single, .double => .{ .fcvtzs = inst.fcvtzs },
 9572                        },
 9573                        0b11100 => switch (inst.group.size) {
 9574                            .byte, .half => .{ .fcvtas = inst.fcvtas },
 9575                            .single, .double => .unallocated,
 9576                        },
 9577                        0b11101 => switch (inst.group.size) {
 9578                            .byte, .half => .{ .scvtf = inst.scvtf },
 9579                            .single, .double => .{ .frecpe = inst.frecpe },
 9580                        },
 9581                        0b01100 => switch (inst.group.size) {
 9582                            .byte, .half => .unallocated,
 9583                            .single, .double => .{ .fcmgt = inst.fcmgt },
 9584                        },
 9585                        0b01101 => switch (inst.group.size) {
 9586                            .byte, .half => .unallocated,
 9587                            .single, .double => .{ .fcmeq = inst.fcmeq },
 9588                        },
 9589                        0b01110 => switch (inst.group.size) {
 9590                            .byte, .half => .unallocated,
 9591                            .single, .double => .{ .fcmlt = inst.fcmlt },
 9592                        },
 9593                        0b01111 => switch (inst.group.size) {
 9594                            .byte, .half => .unallocated,
 9595                            .single, .double => .{ .fabs = inst.fabs },
 9596                        },
 9597                    },
 9598                    .unsigned => switch (inst.group.opcode) {
 9599                        else => .unallocated,
 9600                        0b00011 => .{ .usqadd = inst.usqadd },
 9601                        0b00111 => .{ .sqneg = inst.sqneg },
 9602                        0b01000 => .{ .cmge = inst.cmge },
 9603                        0b01001 => .{ .cmle = inst.cmle },
 9604                        0b01011 => .{ .neg = inst.neg },
 9605                        0b10010 => .{ .sqxtun = inst.sqxtun },
 9606                        0b10100 => .{ .uqxtn = inst.uqxtn },
 9607                        0b10110 => switch (inst.group.size) {
 9608                            .byte, .half => .{ .fcvtxn = inst.fcvtxn },
 9609                            .single, .double => .unallocated,
 9610                        },
 9611                        0b11000 => switch (inst.group.size) {
 9612                            .byte, .half => .{ .frinta = inst.frinta },
 9613                            .single, .double => .unallocated,
 9614                        },
 9615                        0b11001 => switch (inst.group.size) {
 9616                            .byte, .half => .{ .frintx = inst.frintx },
 9617                            .single, .double => .{ .frinti = inst.frinti },
 9618                        },
 9619                        0b11010 => switch (inst.group.size) {
 9620                            .byte, .half => .{ .fcvtnu = inst.fcvtnu },
 9621                            .single, .double => .{ .fcvtpu = inst.fcvtpu },
 9622                        },
 9623                        0b11011 => switch (inst.group.size) {
 9624                            .byte, .half => .{ .fcvtmu = inst.fcvtmu },
 9625                            .single, .double => .{ .fcvtzu = inst.fcvtzu },
 9626                        },
 9627                        0b11100 => switch (inst.group.size) {
 9628                            .byte, .half => .{ .fcvtau = inst.fcvtau },
 9629                            .single, .double => .unallocated,
 9630                        },
 9631                        0b11101 => switch (inst.group.size) {
 9632                            .byte, .half => .{ .ucvtf = inst.ucvtf },
 9633                            .single, .double => .{ .frsqrte = inst.frsqrte },
 9634                        },
 9635                        0b00101 => switch (inst.group.size) {
 9636                            .byte => .{ .not = inst.not },
 9637                            .half, .single, .double => .unallocated,
 9638                        },
 9639                        0b01100 => switch (inst.group.size) {
 9640                            .byte, .half => .unallocated,
 9641                            .single, .double => .{ .fcmge = inst.fcmge },
 9642                        },
 9643                        0b01101 => switch (inst.group.size) {
 9644                            .byte, .half => .unallocated,
 9645                            .single, .double => .{ .fcmle = inst.fcmle },
 9646                        },
 9647                        0b01111 => switch (inst.group.size) {
 9648                            .byte, .half => .unallocated,
 9649                            .single, .double => .{ .fneg = inst.fneg },
 9650                        },
 9651                        0b11111 => switch (inst.group.size) {
 9652                            .byte, .half => .unallocated,
 9653                            .single, .double => .{ .fsqrt = inst.fsqrt },
 9654                        },
 9655                    },
 9656                };
 9657            }
 9658        };
 9659
 9660        /// Advanced SIMD across lanes
 9661        pub const SimdAcrossLanes = packed union {
 9662            group: @This().Group,
 9663            addv: Addv,
 9664
 9665            pub const Group = packed struct {
 9666                Rd: Register.Encoded,
 9667                Rn: Register.Encoded,
 9668                decoded10: u2 = 0b10,
 9669                opcode: u5,
 9670                decoded17: u5 = 0b11000,
 9671                size: Size,
 9672                decoded24: u5 = 0b01110,
 9673                U: std.builtin.Signedness,
 9674                Q: Q,
 9675                decoded31: u1 = 0b0,
 9676            };
 9677
 9678            /// C7.2.6 ADDV
 9679            pub const Addv = packed struct {
 9680                Rd: Register.Encoded,
 9681                Rn: Register.Encoded,
 9682                decoded10: u2 = 0b10,
 9683                opcode: u5 = 0b11011,
 9684                decoded17: u5 = 0b11000,
 9685                size: Size,
 9686                decoded24: u5 = 0b01110,
 9687                U: std.builtin.Signedness = .signed,
 9688                Q: Q,
 9689                decoded31: u1 = 0b0,
 9690            };
 9691
 9692            pub const Decoded = union(enum) {
 9693                unallocated,
 9694                addv: Addv,
 9695            };
 9696            pub fn decode(inst: @This()) @This().Decoded {
 9697                return switch (inst.group.U) {
 9698                    .signed => switch (inst.group.opcode) {
 9699                        else => .unallocated,
 9700                        0b11011 => .{ .addv = inst.addv },
 9701                    },
 9702                    .unsigned => .unallocated,
 9703                };
 9704            }
 9705        };
 9706
 9707        /// Advanced SIMD three same
 9708        pub const SimdThreeSame = packed union {
 9709            group: @This().Group,
 9710            addp: Addp,
 9711            @"and": And,
 9712            bic: Bic,
 9713            orr: Orr,
 9714            orn: Orn,
 9715            eor: Eor,
 9716            bsl: Bsl,
 9717            bit: Bit,
 9718            bif: Bif,
 9719
 9720            pub const Group = packed struct {
 9721                Rd: Register.Encoded,
 9722                Rn: Register.Encoded,
 9723                decoded10: u1 = 0b1,
 9724                opcode: u5,
 9725                Rm: Register.Encoded,
 9726                decoded21: u1 = 0b1,
 9727                size: Size,
 9728                decoded24: u5 = 0b01110,
 9729                U: std.builtin.Signedness,
 9730                Q: Q,
 9731                decoded31: u1 = 0b0,
 9732            };
 9733
 9734            /// C7.2.5 ADDP (vector)
 9735            pub const Addp = packed struct {
 9736                Rd: Register.Encoded,
 9737                Rn: Register.Encoded,
 9738                decoded10: u1 = 0b1,
 9739                opcode: u5 = 0b10111,
 9740                Rm: Register.Encoded,
 9741                decoded21: u1 = 0b1,
 9742                size: Size,
 9743                decoded24: u5 = 0b01110,
 9744                U: std.builtin.Signedness = .signed,
 9745                Q: Q,
 9746                decoded31: u1 = 0b0,
 9747            };
 9748
 9749            /// C7.2.11 AND (vector)
 9750            pub const And = packed struct {
 9751                Rd: Register.Encoded,
 9752                Rn: Register.Encoded,
 9753                decoded10: u1 = 0b1,
 9754                opcode: u5 = 0b00011,
 9755                Rm: Register.Encoded,
 9756                decoded21: u1 = 0b1,
 9757                size: Size = .byte,
 9758                decoded24: u5 = 0b01110,
 9759                U: std.builtin.Signedness = .signed,
 9760                Q: Q,
 9761                decoded31: u1 = 0b0,
 9762            };
 9763
 9764            /// C7.2.21 BIC (vector, register)
 9765            pub const Bic = packed struct {
 9766                Rd: Register.Encoded,
 9767                Rn: Register.Encoded,
 9768                decoded10: u1 = 0b1,
 9769                opcode: u5 = 0b00011,
 9770                Rm: Register.Encoded,
 9771                decoded21: u1 = 0b1,
 9772                size: Size = .half,
 9773                decoded24: u5 = 0b01110,
 9774                U: std.builtin.Signedness = .signed,
 9775                Q: Q,
 9776                decoded31: u1 = 0b0,
 9777            };
 9778
 9779            /// C7.2.213 ORR (vector, register)
 9780            pub const Orr = packed struct {
 9781                Rd: Register.Encoded,
 9782                Rn: Register.Encoded,
 9783                decoded10: u1 = 0b1,
 9784                opcode: u5 = 0b00011,
 9785                Rm: Register.Encoded,
 9786                decoded21: u1 = 0b1,
 9787                size: Size = .single,
 9788                decoded24: u5 = 0b01110,
 9789                U: std.builtin.Signedness = .signed,
 9790                Q: Q,
 9791                decoded31: u1 = 0b0,
 9792            };
 9793
 9794            /// C7.2.211 ORN (vector)
 9795            pub const Orn = packed struct {
 9796                Rd: Register.Encoded,
 9797                Rn: Register.Encoded,
 9798                decoded10: u1 = 0b1,
 9799                opcode: u5 = 0b00011,
 9800                Rm: Register.Encoded,
 9801                decoded21: u1 = 0b1,
 9802                size: Size = .double,
 9803                decoded24: u5 = 0b01110,
 9804                U: std.builtin.Signedness = .signed,
 9805                Q: Q,
 9806                decoded31: u1 = 0b0,
 9807            };
 9808
 9809            /// C7.2.41 EOR (vector)
 9810            pub const Eor = packed struct {
 9811                Rd: Register.Encoded,
 9812                Rn: Register.Encoded,
 9813                decoded10: u1 = 0b1,
 9814                opcode: u5 = 0b00011,
 9815                Rm: Register.Encoded,
 9816                decoded21: u1 = 0b1,
 9817                size: Size = .byte,
 9818                decoded24: u5 = 0b01110,
 9819                U: std.builtin.Signedness = .unsigned,
 9820                Q: Q,
 9821                decoded31: u1 = 0b0,
 9822            };
 9823
 9824            /// C7.2.24 BSL
 9825            pub const Bsl = packed struct {
 9826                Rd: Register.Encoded,
 9827                Rn: Register.Encoded,
 9828                decoded10: u1 = 0b1,
 9829                opcode: u5 = 0b00011,
 9830                Rm: Register.Encoded,
 9831                decoded21: u1 = 0b1,
 9832                size: Size = .half,
 9833                decoded24: u5 = 0b01110,
 9834                U: std.builtin.Signedness = .unsigned,
 9835                Q: Q,
 9836                decoded31: u1 = 0b0,
 9837            };
 9838
 9839            /// C7.2.23 BIT
 9840            pub const Bit = packed struct {
 9841                Rd: Register.Encoded,
 9842                Rn: Register.Encoded,
 9843                decoded10: u1 = 0b1,
 9844                opcode: u5 = 0b00011,
 9845                Rm: Register.Encoded,
 9846                decoded21: u1 = 0b1,
 9847                size: Size = .single,
 9848                decoded24: u5 = 0b01110,
 9849                U: std.builtin.Signedness = .unsigned,
 9850                Q: Q,
 9851                decoded31: u1 = 0b0,
 9852            };
 9853
 9854            /// C7.2.22 BIF
 9855            pub const Bif = packed struct {
 9856                Rd: Register.Encoded,
 9857                Rn: Register.Encoded,
 9858                decoded10: u1 = 0b1,
 9859                opcode: u5 = 0b00011,
 9860                Rm: Register.Encoded,
 9861                decoded21: u1 = 0b1,
 9862                size: Size = .double,
 9863                decoded24: u5 = 0b01110,
 9864                U: std.builtin.Signedness = .unsigned,
 9865                Q: Q,
 9866                decoded31: u1 = 0b0,
 9867            };
 9868
 9869            pub const Decoded = union(enum) {
 9870                unallocated,
 9871                addp: Addp,
 9872                @"and": And,
 9873                bic: Bic,
 9874                orr: Orr,
 9875                orn: Orn,
 9876                eor: Eor,
 9877                bsl: Bsl,
 9878                bit: Bit,
 9879                bif: Bif,
 9880            };
 9881            pub fn decode(inst: @This()) @This().Decoded {
 9882                return switch (inst.group.U) {
 9883                    .signed => switch (inst.group.opcode) {
 9884                        else => .unallocated,
 9885                        0b10111 => .{ .addp = inst.addp },
 9886                        0b00011 => switch (inst.group.size) {
 9887                            .byte => .{ .@"and" = inst.@"and" },
 9888                            .half => .{ .bic = inst.bic },
 9889                            .single => .{ .orr = inst.orr },
 9890                            .double => .{ .orn = inst.orn },
 9891                        },
 9892                    },
 9893                    .unsigned => switch (inst.group.opcode) {
 9894                        else => .unallocated,
 9895                        0b00011 => switch (inst.group.size) {
 9896                            .byte => .{ .eor = inst.eor },
 9897                            .half => .{ .bsl = inst.bsl },
 9898                            .single => .{ .bit = inst.bit },
 9899                            .double => .{ .bif = inst.bif },
 9900                        },
 9901                    },
 9902                };
 9903            }
 9904        };
 9905
 9906        /// Advanced SIMD modified immediate
 9907        pub const SimdModifiedImmediate = packed union {
 9908            group: @This().Group,
 9909            movi: Movi,
 9910            orr: Orr,
 9911            fmov: Fmov,
 9912            mvni: Mvni,
 9913            bic: Bic,
 9914
 9915            pub const Group = packed struct {
 9916                Rd: Register.Encoded,
 9917                imm5: u5,
 9918                decoded10: u1 = 0b1,
 9919                o2: u1,
 9920                cmode: u4,
 9921                imm3: u3,
 9922                decoded19: u10 = 0b0111100000,
 9923                op: u1,
 9924                Q: Q,
 9925                decoded31: u1 = 0b0,
 9926            };
 9927
 9928            /// C7.2.204 MOVI
 9929            pub const Movi = packed struct {
 9930                Rd: Register.Encoded,
 9931                imm5: u5,
 9932                decoded10: u1 = 0b1,
 9933                o2: u1 = 0b0,
 9934                cmode: u4,
 9935                imm3: u3,
 9936                decoded19: u10 = 0b0111100000,
 9937                op: u1,
 9938                Q: Q,
 9939                decoded31: u1 = 0b0,
 9940            };
 9941
 9942            /// C7.2.212 ORR (vector, immediate)
 9943            pub const Orr = packed struct {
 9944                Rd: Register.Encoded,
 9945                imm5: u5,
 9946                decoded10: u1 = 0b1,
 9947                o2: u1 = 0b0,
 9948                cmode0: u1 = 0b1,
 9949                cmode: u3,
 9950                imm3: u3,
 9951                decoded19: u10 = 0b0111100000,
 9952                op: u1 = 0b0,
 9953                Q: Q,
 9954                decoded31: u1 = 0b0,
 9955            };
 9956
 9957            /// C7.2.129 FMOV (vector, immediate)
 9958            pub const Fmov = packed struct {
 9959                Rd: Register.Encoded,
 9960                imm5: u5,
 9961                decoded10: u1 = 0b1,
 9962                o2: u1,
 9963                cmode: u4 = 0b1111,
 9964                imm3: u3,
 9965                decoded19: u10 = 0b0111100000,
 9966                op: u1,
 9967                Q: Q,
 9968                decoded31: u1 = 0b0,
 9969            };
 9970
 9971            /// C7.2.208 MVNI
 9972            pub const Mvni = packed struct {
 9973                Rd: Register.Encoded,
 9974                imm5: u5,
 9975                decoded10: u1 = 0b1,
 9976                o2: u1 = 0b0,
 9977                cmode: u4,
 9978                imm3: u3,
 9979                decoded19: u10 = 0b0111100000,
 9980                op: u1 = 0b1,
 9981                Q: Q,
 9982                decoded31: u1 = 0b0,
 9983            };
 9984
 9985            /// C7.2.20 BIC (vector, immediate)
 9986            pub const Bic = packed struct {
 9987                Rd: Register.Encoded,
 9988                imm5: u5,
 9989                decoded10: u1 = 0b1,
 9990                o2: u1 = 0b0,
 9991                cmode0: u1 = 0b1,
 9992                cmode: u3,
 9993                imm3: u3,
 9994                decoded19: u10 = 0b0111100000,
 9995                op: u1 = 0b1,
 9996                Q: Q,
 9997                decoded31: u1 = 0b0,
 9998            };
 9999
10000            pub const Decoded = union(enum) {
10001                unallocated,
10002                fmov: Fmov,
10003            };
10004            pub fn decode(inst: @This()) @This().Decoded {
10005                return switch (inst.group.cmode) {
10006                    else => .unallocated,
10007                    0b1111 => switch (inst.group.op) {
10008                        0b0 => .{ .fmov = inst.fmov },
10009                        0b1 => switch (inst.group.Q) {
10010                            .double => .unallocated,
10011                            .quad => switch (inst.group.o2) {
10012                                0b1 => .unallocated,
10013                                0b0 => .{ .fmov = inst.fmov },
10014                            },
10015                        },
10016                    },
10017                };
10018            }
10019        };
10020
10021        /// Conversion between floating-point and fixed-point
10022        pub const ConvertFloatFixed = packed union {
10023            group: @This().Group,
10024
10025            pub const Group = packed struct {
10026                Rd: Register.Encoded,
10027                Rn: Register.Encoded,
10028                scale: u6,
10029                opcode: u3,
10030                rmode: u2,
10031                decoded21: u1 = 0b0,
10032                ptype: Ftype,
10033                decoded24: u5 = 0b11110,
10034                S: bool,
10035                decoded30: u1 = 0b0,
10036                sf: Register.GeneralSize,
10037            };
10038        };
10039
10040        /// Conversion between floating-point and integer
10041        pub const ConvertFloatInteger = packed union {
10042            group: @This().Group,
10043            fcvtns: Fcvtns,
10044            fcvtnu: Fcvtnu,
10045            scvtf: Scvtf,
10046            ucvtf: Ucvtf,
10047            fcvtas: Fcvtas,
10048            fcvtau: Fcvtau,
10049            fmov: Fmov,
10050            fcvtps: Fcvtps,
10051            fcvtpu: Fcvtpu,
10052            fcvtms: Fcvtms,
10053            fcvtmu: Fcvtmu,
10054            fcvtzs: Fcvtzs,
10055            fcvtzu: Fcvtzu,
10056            fjcvtzs: Fjcvtzs,
10057
10058            pub const Group = packed struct {
10059                Rd: Register.Encoded,
10060                Rn: Register.Encoded,
10061                decoded10: u6 = 0b000000,
10062                opcode: u3,
10063                rmode: u2,
10064                decoded21: u1 = 0b1,
10065                ptype: Ftype,
10066                decoded24: u5 = 0b11110,
10067                S: bool,
10068                decoded30: u1 = 0b0,
10069                sf: Register.GeneralSize,
10070            };
10071
10072            /// C7.2.81 FCVTNS (scalar)
10073            pub const Fcvtns = packed struct {
10074                Rd: Register.Encoded,
10075                Rn: Register.Encoded,
10076                decoded10: u6 = 0b000000,
10077                opcode: u3 = 0b000,
10078                rmode: Rmode = .n,
10079                decoded21: u1 = 0b1,
10080                ftype: Ftype,
10081                decoded24: u5 = 0b11110,
10082                S: bool = false,
10083                decoded30: u1 = 0b0,
10084                sf: Register.GeneralSize,
10085            };
10086
10087            /// C7.2.83 FCVTNU (scalar)
10088            pub const Fcvtnu = packed struct {
10089                Rd: Register.Encoded,
10090                Rn: Register.Encoded,
10091                decoded10: u6 = 0b000000,
10092                opcode: u3 = 0b001,
10093                rmode: Rmode = .n,
10094                decoded21: u1 = 0b1,
10095                ftype: Ftype,
10096                decoded24: u5 = 0b11110,
10097                S: bool = false,
10098                decoded30: u1 = 0b0,
10099                sf: Register.GeneralSize,
10100            };
10101
10102            /// C7.2.236 SCVTF (scalar, integer)
10103            pub const Scvtf = packed struct {
10104                Rd: Register.Encoded,
10105                Rn: Register.Encoded,
10106                decoded10: u6 = 0b000000,
10107                opcode: u3 = 0b010,
10108                rmode: Rmode = .n,
10109                decoded21: u1 = 0b1,
10110                ftype: Ftype,
10111                decoded24: u5 = 0b11110,
10112                S: bool = false,
10113                decoded30: u1 = 0b0,
10114                sf: Register.GeneralSize,
10115            };
10116
10117            /// C7.2.355 UCVTF (scalar, integer)
10118            pub const Ucvtf = packed struct {
10119                Rd: Register.Encoded,
10120                Rn: Register.Encoded,
10121                decoded10: u6 = 0b000000,
10122                opcode: u3 = 0b011,
10123                rmode: Rmode = .n,
10124                decoded21: u1 = 0b1,
10125                ftype: Ftype,
10126                decoded24: u5 = 0b11110,
10127                S: bool = false,
10128                decoded30: u1 = 0b0,
10129                sf: Register.GeneralSize,
10130            };
10131
10132            /// C7.2.71 FCVTAS (scalar)
10133            pub const Fcvtas = packed struct {
10134                Rd: Register.Encoded,
10135                Rn: Register.Encoded,
10136                decoded10: u6 = 0b000000,
10137                opcode: u3 = 0b100,
10138                rmode: Rmode = .n,
10139                decoded21: u1 = 0b1,
10140                ftype: Ftype,
10141                decoded24: u5 = 0b11110,
10142                S: bool = false,
10143                decoded30: u1 = 0b0,
10144                sf: Register.GeneralSize,
10145            };
10146
10147            /// C7.2.73 FCVTAU (scalar)
10148            pub const Fcvtau = packed struct {
10149                Rd: Register.Encoded,
10150                Rn: Register.Encoded,
10151                decoded10: u6 = 0b000000,
10152                opcode: u3 = 0b101,
10153                rmode: Rmode = .n,
10154                decoded21: u1 = 0b1,
10155                ftype: Ftype,
10156                decoded24: u5 = 0b11110,
10157                S: bool = false,
10158                decoded30: u1 = 0b0,
10159                sf: Register.GeneralSize,
10160            };
10161
10162            /// C7.2.131 FMOV (general)
10163            pub const Fmov = packed struct {
10164                Rd: Register.Encoded,
10165                Rn: Register.Encoded,
10166                decoded10: u6 = 0b000000,
10167                opcode: Opcode,
10168                rmode: Fmov.Rmode,
10169                decoded21: u1 = 0b1,
10170                ftype: Ftype,
10171                decoded24: u5 = 0b11110,
10172                S: bool = false,
10173                decoded30: u1 = 0b0,
10174                sf: Register.GeneralSize,
10175
10176                pub const Opcode = enum(u3) {
10177                    float_to_integer = 0b110,
10178                    integer_to_float = 0b111,
10179                    _,
10180                };
10181
10182                pub const Rmode = enum(u2) {
10183                    @"0" = 0b00,
10184                    @"1" = 0b01,
10185                    _,
10186                };
10187            };
10188
10189            /// C7.2.85 FCVTPS (scalar)
10190            pub const Fcvtps = packed struct {
10191                Rd: Register.Encoded,
10192                Rn: Register.Encoded,
10193                decoded10: u6 = 0b000000,
10194                opcode: u3 = 0b000,
10195                rmode: Rmode = .p,
10196                decoded21: u1 = 0b1,
10197                ftype: Ftype,
10198                decoded24: u5 = 0b11110,
10199                S: bool = false,
10200                decoded30: u1 = 0b0,
10201                sf: Register.GeneralSize,
10202            };
10203
10204            /// C7.2.87 FCVTPU (scalar)
10205            pub const Fcvtpu = packed struct {
10206                Rd: Register.Encoded,
10207                Rn: Register.Encoded,
10208                decoded10: u6 = 0b000000,
10209                opcode: u3 = 0b001,
10210                rmode: Rmode = .p,
10211                decoded21: u1 = 0b1,
10212                ftype: Ftype,
10213                decoded24: u5 = 0b11110,
10214                S: bool = false,
10215                decoded30: u1 = 0b0,
10216                sf: Register.GeneralSize,
10217            };
10218
10219            /// C7.2.76 FCVTMS (scalar)
10220            pub const Fcvtms = packed struct {
10221                Rd: Register.Encoded,
10222                Rn: Register.Encoded,
10223                decoded10: u6 = 0b000000,
10224                opcode: u3 = 0b000,
10225                rmode: Rmode = .m,
10226                decoded21: u1 = 0b1,
10227                ftype: Ftype,
10228                decoded24: u5 = 0b11110,
10229                S: bool = false,
10230                decoded30: u1 = 0b0,
10231                sf: Register.GeneralSize,
10232            };
10233
10234            /// C7.2.78 FCVTMU (scalar)
10235            pub const Fcvtmu = packed struct {
10236                Rd: Register.Encoded,
10237                Rn: Register.Encoded,
10238                decoded10: u6 = 0b000000,
10239                opcode: u3 = 0b001,
10240                rmode: Rmode = .m,
10241                decoded21: u1 = 0b1,
10242                ftype: Ftype,
10243                decoded24: u5 = 0b11110,
10244                S: bool = false,
10245                decoded30: u1 = 0b0,
10246                sf: Register.GeneralSize,
10247            };
10248
10249            /// C7.2.92 FCVTZS (scalar, integer)
10250            pub const Fcvtzs = packed struct {
10251                Rd: Register.Encoded,
10252                Rn: Register.Encoded,
10253                decoded10: u6 = 0b000000,
10254                opcode: u3 = 0b000,
10255                rmode: Rmode = .z,
10256                decoded21: u1 = 0b1,
10257                ftype: Ftype,
10258                decoded24: u5 = 0b11110,
10259                S: bool = false,
10260                decoded30: u1 = 0b0,
10261                sf: Register.GeneralSize,
10262            };
10263
10264            /// C7.2.96 FCVTZU (scalar, integer)
10265            pub const Fcvtzu = packed struct {
10266                Rd: Register.Encoded,
10267                Rn: Register.Encoded,
10268                decoded10: u6 = 0b000000,
10269                opcode: u3 = 0b001,
10270                rmode: Rmode = .z,
10271                decoded21: u1 = 0b1,
10272                ftype: Ftype,
10273                decoded24: u5 = 0b11110,
10274                S: bool = false,
10275                decoded30: u1 = 0b0,
10276                sf: Register.GeneralSize,
10277            };
10278
10279            /// C7.2.99 FJCVTZS
10280            pub const Fjcvtzs = packed struct {
10281                Rd: Register.Encoded,
10282                Rn: Register.Encoded,
10283                decoded10: u6 = 0b000000,
10284                opcode: u3 = 0b110,
10285                rmode: Rmode = .z,
10286                decoded21: u1 = 0b1,
10287                ftype: Ftype = .double,
10288                decoded24: u5 = 0b11110,
10289                S: bool = false,
10290                decoded30: u1 = 0b0,
10291                sf: Register.GeneralSize = .word,
10292            };
10293
10294            pub const Rmode = enum(u2) {
10295                /// to nearest
10296                n = 0b00,
10297                /// toward plus infinity
10298                p = 0b01,
10299                /// toward minus infinity
10300                m = 0b10,
10301                /// toward zero
10302                z = 0b11,
10303            };
10304
10305            pub const Decoded = union(enum) {
10306                unallocated,
10307                fcvtns: Fcvtns,
10308                fcvtnu: Fcvtnu,
10309                scvtf: Scvtf,
10310                ucvtf: Ucvtf,
10311                fcvtas: Fcvtas,
10312                fcvtau: Fcvtau,
10313                fmov: Fmov,
10314                fcvtps: Fcvtps,
10315                fcvtpu: Fcvtpu,
10316                fcvtms: Fcvtms,
10317                fcvtmu: Fcvtmu,
10318                fcvtzs: Fcvtzs,
10319                fcvtzu: Fcvtzu,
10320                fjcvtzs: Fjcvtzs,
10321            };
10322            pub fn decode(inst: @This()) @This().Decoded {
10323                return switch (inst.group.S) {
10324                    true => .unallocated,
10325                    false => switch (inst.group.ptype) {
10326                        .single, .double, .half => switch (inst.group.opcode) {
10327                            0b000 => switch (inst.group.rmode) {
10328                                0b00 => .{ .fcvtns = inst.fcvtns },
10329                                0b01 => .{ .fcvtps = inst.fcvtps },
10330                                0b10 => .{ .fcvtms = inst.fcvtms },
10331                                0b11 => .{ .fcvtzs = inst.fcvtzs },
10332                            },
10333                            0b001 => switch (inst.group.rmode) {
10334                                0b00 => .{ .fcvtnu = inst.fcvtnu },
10335                                0b01 => .{ .fcvtpu = inst.fcvtpu },
10336                                0b10 => .{ .fcvtmu = inst.fcvtmu },
10337                                0b11 => .{ .fcvtzu = inst.fcvtzu },
10338                            },
10339                            0b010 => switch (inst.group.rmode) {
10340                                else => .unallocated,
10341                                0b00 => .{ .scvtf = inst.scvtf },
10342                            },
10343                            0b011 => switch (inst.group.rmode) {
10344                                else => .unallocated,
10345                                0b00 => .{ .ucvtf = inst.ucvtf },
10346                            },
10347                            0b100 => switch (inst.group.rmode) {
10348                                else => .unallocated,
10349                                0b00 => .{ .fcvtas = inst.fcvtas },
10350                            },
10351                            0b101 => switch (inst.group.rmode) {
10352                                else => .unallocated,
10353                                0b00 => .{ .fcvtau = inst.fcvtau },
10354                            },
10355                            0b110 => switch (inst.group.rmode) {
10356                                else => .unallocated,
10357                                0b00 => .{ .fmov = inst.fmov },
10358                                0b11 => switch (inst.group.ptype) {
10359                                    .single, .double => .unallocated,
10360                                    .quad => unreachable,
10361                                    .half => .{ .fjcvtzs = inst.fjcvtzs },
10362                                },
10363                            },
10364                            0b111 => switch (inst.group.rmode) {
10365                                else => .unallocated,
10366                                0b00 => .{ .fmov = inst.fmov },
10367                            },
10368                        },
10369                        .quad => switch (inst.group.opcode) {
10370                            else => .unallocated,
10371                            0b110, 0b111 => switch (inst.group.rmode) {
10372                                else => .unallocated,
10373                                0b01 => switch (inst.group.sf) {
10374                                    .word => .unallocated,
10375                                    .doubleword => .{ .fmov = inst.fmov },
10376                                },
10377                            },
10378                        },
10379                    },
10380                };
10381            }
10382        };
10383
10384        /// Floating-point data-processing (1 source)
10385        pub const FloatDataProcessingOneSource = packed union {
10386            group: @This().Group,
10387            fmov: Fmov,
10388            fabs: Fabs,
10389            fneg: Fneg,
10390            fsqrt: Fsqrt,
10391            fcvt: Fcvt,
10392            frintn: Frintn,
10393            frintp: Frintp,
10394            frintm: Frintm,
10395            frintz: Frintz,
10396            frinta: Frinta,
10397            frintx: Frintx,
10398            frinti: Frinti,
10399
10400            pub const Group = packed struct {
10401                Rd: Register.Encoded,
10402                Rn: Register.Encoded,
10403                decoded10: u5 = 0b10000,
10404                opcode: u6,
10405                decoded21: u1 = 0b1,
10406                ptype: Ftype,
10407                decoded24: u5 = 0b11110,
10408                S: bool,
10409                decoded30: u1 = 0b0,
10410                M: u1,
10411            };
10412
10413            /// C7.2.130 FMOV (register)
10414            pub const Fmov = packed struct {
10415                Rd: Register.Encoded,
10416                Rn: Register.Encoded,
10417                decoded10: u5 = 0b10000,
10418                opc: u2 = 0b00,
10419                decoded17: u4 = 0b0000,
10420                decoded21: u1 = 0b1,
10421                ftype: Ftype,
10422                decoded24: u5 = 0b11110,
10423                S: bool = false,
10424                decoded30: u1 = 0b0,
10425                M: u1 = 0b0,
10426            };
10427
10428            /// C7.2.46 FABS (scalar)
10429            pub const Fabs = packed struct {
10430                Rd: Register.Encoded,
10431                Rn: Register.Encoded,
10432                decoded10: u5 = 0b10000,
10433                opc: u2 = 0b01,
10434                decoded17: u4 = 0b0000,
10435                decoded21: u1 = 0b1,
10436                ftype: Ftype,
10437                decoded24: u5 = 0b11110,
10438                S: bool = false,
10439                decoded30: u1 = 0b0,
10440                M: u1 = 0b0,
10441            };
10442
10443            /// C7.2.140 FNEG (scalar)
10444            pub const Fneg = packed struct {
10445                Rd: Register.Encoded,
10446                Rn: Register.Encoded,
10447                decoded10: u5 = 0b10000,
10448                opc: u2 = 0b10,
10449                decoded17: u4 = 0b0000,
10450                decoded21: u1 = 0b1,
10451                ftype: Ftype,
10452                decoded24: u5 = 0b11110,
10453                S: bool = false,
10454                decoded30: u1 = 0b0,
10455                M: u1 = 0b0,
10456            };
10457
10458            /// C7.2.172 FSQRT (scalar)
10459            pub const Fsqrt = packed struct {
10460                Rd: Register.Encoded,
10461                Rn: Register.Encoded,
10462                decoded10: u5 = 0b10000,
10463                opc: u2 = 0b11,
10464                decoded17: u4 = 0b0000,
10465                decoded21: u1 = 0b1,
10466                ftype: Ftype,
10467                decoded24: u5 = 0b11110,
10468                S: bool = false,
10469                decoded30: u1 = 0b0,
10470                M: u1 = 0b0,
10471            };
10472
10473            /// C7.2.69 FCVT
10474            pub const Fcvt = packed struct {
10475                Rd: Register.Encoded,
10476                Rn: Register.Encoded,
10477                decoded10: u5 = 0b10000,
10478                opc: Ftype,
10479                decoded17: u4 = 0b0001,
10480                decoded21: u1 = 0b1,
10481                ftype: Ftype,
10482                decoded24: u5 = 0b11110,
10483                S: bool = false,
10484                decoded30: u1 = 0b0,
10485                M: u1 = 0b0,
10486            };
10487
10488            /// C7.2.162 FRINTN (scalar)
10489            pub const Frintn = packed struct {
10490                Rd: Register.Encoded,
10491                Rn: Register.Encoded,
10492                decoded10: u5 = 0b10000,
10493                rmode: Rmode = .n,
10494                decoded18: u3 = 0b001,
10495                decoded21: u1 = 0b1,
10496                ftype: Ftype,
10497                decoded24: u5 = 0b11110,
10498                S: bool = false,
10499                decoded30: u1 = 0b0,
10500                M: u1 = 0b0,
10501            };
10502
10503            /// C7.2.164 FRINTP (scalar)
10504            pub const Frintp = packed struct {
10505                Rd: Register.Encoded,
10506                Rn: Register.Encoded,
10507                decoded10: u5 = 0b10000,
10508                rmode: Rmode = .p,
10509                decoded18: u3 = 0b001,
10510                decoded21: u1 = 0b1,
10511                ftype: Ftype,
10512                decoded24: u5 = 0b11110,
10513                S: bool = false,
10514                decoded30: u1 = 0b0,
10515                M: u1 = 0b0,
10516            };
10517
10518            /// C7.2.160 FRINTM (scalar)
10519            pub const Frintm = packed struct {
10520                Rd: Register.Encoded,
10521                Rn: Register.Encoded,
10522                decoded10: u5 = 0b10000,
10523                rmode: Rmode = .m,
10524                decoded18: u3 = 0b001,
10525                decoded21: u1 = 0b1,
10526                ftype: Ftype,
10527                decoded24: u5 = 0b11110,
10528                S: bool = false,
10529                decoded30: u1 = 0b0,
10530                M: u1 = 0b0,
10531            };
10532
10533            /// C7.2.168 FRINTZ (scalar)
10534            pub const Frintz = packed struct {
10535                Rd: Register.Encoded,
10536                Rn: Register.Encoded,
10537                decoded10: u5 = 0b10000,
10538                rmode: Rmode = .z,
10539                decoded18: u3 = 0b001,
10540                decoded21: u1 = 0b1,
10541                ftype: Ftype,
10542                decoded24: u5 = 0b11110,
10543                S: bool = false,
10544                decoded30: u1 = 0b0,
10545                M: u1 = 0b0,
10546            };
10547
10548            /// C7.2.156 FRINTA (scalar)
10549            pub const Frinta = packed struct {
10550                Rd: Register.Encoded,
10551                Rn: Register.Encoded,
10552                decoded10: u5 = 0b10000,
10553                rmode: Rmode = .a,
10554                decoded18: u3 = 0b001,
10555                decoded21: u1 = 0b1,
10556                ftype: Ftype,
10557                decoded24: u5 = 0b11110,
10558                S: bool = false,
10559                decoded30: u1 = 0b0,
10560                M: u1 = 0b0,
10561            };
10562
10563            /// C7.2.166 FRINTX (scalar)
10564            pub const Frintx = packed struct {
10565                Rd: Register.Encoded,
10566                Rn: Register.Encoded,
10567                decoded10: u5 = 0b10000,
10568                rmode: Rmode = .x,
10569                decoded18: u3 = 0b001,
10570                decoded21: u1 = 0b1,
10571                ftype: Ftype,
10572                decoded24: u5 = 0b11110,
10573                S: bool = false,
10574                decoded30: u1 = 0b0,
10575                M: u1 = 0b0,
10576            };
10577
10578            /// C7.2.158 FRINTI (scalar)
10579            pub const Frinti = packed struct {
10580                Rd: Register.Encoded,
10581                Rn: Register.Encoded,
10582                decoded10: u5 = 0b10000,
10583                rmode: Rmode = .i,
10584                decoded18: u3 = 0b001,
10585                decoded21: u1 = 0b1,
10586                ftype: Ftype,
10587                decoded24: u5 = 0b11110,
10588                S: bool = false,
10589                decoded30: u1 = 0b0,
10590                M: u1 = 0b0,
10591            };
10592
10593            pub const Rmode = enum(u3) {
10594                /// to nearest with ties to even
10595                n = 0b000,
10596                /// toward plus infinity
10597                p = 0b001,
10598                /// toward minus infinity
10599                m = 0b010,
10600                /// toward zero
10601                z = 0b011,
10602                /// to nearest with ties to away
10603                a = 0b100,
10604                /// exact, using current rounding mode
10605                x = 0b110,
10606                /// using current rounding mode
10607                i = 0b111,
10608                _,
10609            };
10610
10611            pub const Decoded = union(enum) {
10612                unallocated,
10613                fmov: Fmov,
10614                fabs: Fabs,
10615                fneg: Fneg,
10616                fsqrt: Fsqrt,
10617                fcvt: Fcvt,
10618                frintn: Frintn,
10619                frintp: Frintp,
10620                frintm: Frintm,
10621                frintz: Frintz,
10622                frinta: Frinta,
10623                frintx: Frintx,
10624                frinti: Frinti,
10625            };
10626            pub fn decode(inst: @This()) @This().Decoded {
10627                return switch (inst.group.M) {
10628                    0b0 => switch (inst.group.S) {
10629                        true => .unallocated,
10630                        false => switch (inst.group.ptype) {
10631                            .single, .double, .half => switch (inst.group.opcode) {
10632                                else => .unallocated,
10633                                0b000000 => .{ .fmov = inst.fmov },
10634                                0b000001 => .{ .fabs = inst.fabs },
10635                                0b000010 => .{ .fneg = inst.fneg },
10636                                0b000011 => .{ .fsqrt = inst.fsqrt },
10637                                0b000101, 0b000111 => .{ .fcvt = inst.fcvt },
10638                                0b001000 => .{ .frintn = inst.frintn },
10639                                0b001001 => .{ .frintp = inst.frintp },
10640                                0b001010 => .{ .frintm = inst.frintm },
10641                                0b001011 => .{ .frintz = inst.frintz },
10642                                0b001100 => .{ .frinta = inst.frinta },
10643                                0b001110 => .{ .frintx = inst.frintx },
10644                                0b001111 => .{ .frinti = inst.frinti },
10645                            },
10646                            .quad => .unallocated,
10647                        },
10648                    },
10649                    0b1 => .unallocated,
10650                };
10651            }
10652        };
10653
10654        /// Floating-point compare
10655        pub const FloatCompare = packed union {
10656            group: @This().Group,
10657            fcmp: Fcmp,
10658            fcmpe: Fcmpe,
10659
10660            pub const Group = packed struct {
10661                opcode2: u5,
10662                Rn: Register.Encoded,
10663                decoded10: u4 = 0b1000,
10664                op: u2,
10665                Rm: Register.Encoded,
10666                decoded21: u1 = 0b1,
10667                ptype: Ftype,
10668                decoded24: u5 = 0b11110,
10669                S: bool,
10670                decoded30: u1 = 0b0,
10671                M: u1,
10672            };
10673
10674            /// C7.2.66 FCMP
10675            pub const Fcmp = packed struct {
10676                decoded0: u3 = 0b000,
10677                opc0: Opc0,
10678                opc1: u1 = 0b0,
10679                Rn: Register.Encoded,
10680                decoded10: u4 = 0b1000,
10681                op: u2 = 0b00,
10682                Rm: Register.Encoded,
10683                decoded21: u1 = 0b1,
10684                ftype: Ftype,
10685                decoded24: u5 = 0b11110,
10686                S: bool = false,
10687                decoded30: u1 = 0b0,
10688                M: u1 = 0b0,
10689            };
10690
10691            /// C7.2.67 FCMPE
10692            pub const Fcmpe = packed struct {
10693                decoded0: u3 = 0b000,
10694                opc0: Opc0,
10695                opc1: u1 = 0b1,
10696                Rn: Register.Encoded,
10697                decoded10: u4 = 0b1000,
10698                op: u2 = 0b00,
10699                Rm: Register.Encoded,
10700                decoded21: u1 = 0b1,
10701                ftype: Ftype,
10702                decoded24: u5 = 0b11110,
10703                S: bool = false,
10704                decoded30: u1 = 0b0,
10705                M: u1 = 0b0,
10706            };
10707
10708            pub const Opc0 = enum(u1) {
10709                register = 0b00,
10710                zero = 0b01,
10711            };
10712        };
10713
10714        /// Floating-point immediate
10715        pub const FloatImmediate = packed union {
10716            group: @This().Group,
10717            fmov: Fmov,
10718
10719            pub const Group = packed struct {
10720                Rd: Register.Encoded,
10721                imm5: u5,
10722                decoded10: u3 = 0b100,
10723                imm8: u8,
10724                decoded21: u1 = 0b1,
10725                ptype: Ftype,
10726                decoded24: u5 = 0b11110,
10727                S: bool,
10728                decoded30: u1 = 0b0,
10729                M: u1,
10730            };
10731
10732            /// C7.2.132 FMOV (scalar, immediate)
10733            pub const Fmov = packed struct {
10734                Rd: Register.Encoded,
10735                imm5: u5 = 0b00000,
10736                decoded10: u3 = 0b100,
10737                imm8: Imm8,
10738                decoded21: u1 = 0b1,
10739                ftype: Ftype,
10740                decoded24: u5 = 0b11110,
10741                S: bool = false,
10742                decoded30: u1 = 0b0,
10743                M: u1 = 0b0,
10744
10745                pub const Imm8 = packed struct(u8) {
10746                    mantissa: u4,
10747                    exponent: i3,
10748                    sign: std.math.Sign,
10749
10750                    pub const Modified = packed struct(u8) { imm5: u5, imm3: u3 };
10751
10752                    pub fn fromModified(mod: Modified) Imm8 {
10753                        return @bitCast(mod);
10754                    }
10755
10756                    pub fn toModified(imm8: Imm8) Modified {
10757                        return @bitCast(imm8);
10758                    }
10759
10760                    pub fn decode(imm8: Imm8) f16 {
10761                        const Normalized = std.math.FloatRepr(f16).Normalized;
10762                        return Normalized.reconstruct(.{
10763                            .fraction = @as(Normalized.Fraction, imm8.mantissa) << 6,
10764                            .exponent = @as(Normalized.Exponent, imm8.exponent) + 1,
10765                        }, imm8.sign);
10766                    }
10767                };
10768            };
10769
10770            pub const Decoded = union(enum) {
10771                unallocated,
10772                fmov: Fmov,
10773            };
10774            pub fn decode(inst: @This()) @This().Decoded {
10775                return switch (inst.group.M) {
10776                    0b0 => switch (inst.group.S) {
10777                        true => .unallocated,
10778                        false => switch (inst.group.imm5) {
10779                            else => .unallocated,
10780                            0b00000 => switch (inst.group.ptype) {
10781                                .quad => .unallocated,
10782                                .single, .double, .half => .{ .fmov = inst.fmov },
10783                            },
10784                        },
10785                    },
10786                    0b1 => .unallocated,
10787                };
10788            }
10789        };
10790
10791        /// Floating-point conditional compare
10792        pub const FloatConditionalCompare = packed union {
10793            group: @This().Group,
10794
10795            pub const Group = packed struct {
10796                nzcv: Nzcv,
10797                op: u1,
10798                Rn: Register.Encoded,
10799                decoded10: u2 = 0b01,
10800                cond: ConditionCode,
10801                Rm: Register.Encoded,
10802                decoded21: u1 = 0b1,
10803                ptype: Ftype,
10804                decoded24: u5 = 0b11110,
10805                S: bool,
10806                decoded30: u1 = 0b0,
10807                M: u1,
10808            };
10809        };
10810
10811        /// Floating-point data-processing (2 source)
10812        pub const FloatDataProcessingTwoSource = packed union {
10813            group: @This().Group,
10814            fmul: Fmul,
10815            fdiv: Fdiv,
10816            fadd: Fadd,
10817            fsub: Fsub,
10818            fmax: Fmax,
10819            fmin: Fmin,
10820            fmaxnm: Fmaxnm,
10821            fminnm: Fminnm,
10822            fnmul: Fnmul,
10823
10824            pub const Group = packed struct {
10825                Rd: Register.Encoded,
10826                Rn: Register.Encoded,
10827                decoded10: u2 = 0b10,
10828                opcode: Opcode,
10829                Rm: Register.Encoded,
10830                decoded21: u1 = 0b1,
10831                ptype: Ftype,
10832                decoded24: u5 = 0b11110,
10833                S: bool,
10834                decoded30: u1 = 0b0,
10835                M: u1,
10836            };
10837
10838            /// C7.2.136 FMUL (scalar)
10839            pub const Fmul = packed struct {
10840                Rd: Register.Encoded,
10841                Rn: Register.Encoded,
10842                decoded10: u2 = 0b10,
10843                opcode: Opcode = .fmul,
10844                Rm: Register.Encoded,
10845                decoded21: u1 = 0b1,
10846                ftype: Ftype,
10847                decoded24: u5 = 0b11110,
10848                S: bool = false,
10849                decoded30: u1 = 0b0,
10850                M: u1 = 0b0,
10851            };
10852
10853            /// C7.2.98 FDIV (scalar)
10854            pub const Fdiv = packed struct {
10855                Rd: Register.Encoded,
10856                Rn: Register.Encoded,
10857                decoded10: u2 = 0b10,
10858                opcode: Opcode = .fdiv,
10859                Rm: Register.Encoded,
10860                decoded21: u1 = 0b1,
10861                ftype: Ftype,
10862                decoded24: u5 = 0b11110,
10863                S: bool = false,
10864                decoded30: u1 = 0b0,
10865                M: u1 = 0b0,
10866            };
10867
10868            /// C7.2.50 FADD (scalar)
10869            pub const Fadd = packed struct {
10870                Rd: Register.Encoded,
10871                Rn: Register.Encoded,
10872                decoded10: u2 = 0b10,
10873                opcode: Opcode = .fadd,
10874                Rm: Register.Encoded,
10875                decoded21: u1 = 0b1,
10876                ftype: Ftype,
10877                decoded24: u5 = 0b11110,
10878                S: bool = false,
10879                decoded30: u1 = 0b0,
10880                M: u1 = 0b0,
10881            };
10882
10883            /// C7.2.174 FSUB (scalar)
10884            pub const Fsub = packed struct {
10885                Rd: Register.Encoded,
10886                Rn: Register.Encoded,
10887                decoded10: u2 = 0b10,
10888                opcode: Opcode = .fsub,
10889                Rm: Register.Encoded,
10890                decoded21: u1 = 0b1,
10891                ftype: Ftype,
10892                decoded24: u5 = 0b11110,
10893                S: bool = false,
10894                decoded30: u1 = 0b0,
10895                M: u1 = 0b0,
10896            };
10897
10898            /// C7.2.102 FMAX (scalar)
10899            pub const Fmax = packed struct {
10900                Rd: Register.Encoded,
10901                Rn: Register.Encoded,
10902                decoded10: u2 = 0b10,
10903                opcode: Opcode = .fmax,
10904                Rm: Register.Encoded,
10905                decoded21: u1 = 0b1,
10906                ftype: Ftype,
10907                decoded24: u5 = 0b11110,
10908                S: bool = false,
10909                decoded30: u1 = 0b0,
10910                M: u1 = 0b0,
10911            };
10912
10913            /// C7.2.112 FMIN (scalar)
10914            pub const Fmin = packed struct {
10915                Rd: Register.Encoded,
10916                Rn: Register.Encoded,
10917                decoded10: u2 = 0b10,
10918                opcode: Opcode = .fmin,
10919                Rm: Register.Encoded,
10920                decoded21: u1 = 0b1,
10921                ftype: Ftype,
10922                decoded24: u5 = 0b11110,
10923                S: bool = false,
10924                decoded30: u1 = 0b0,
10925                M: u1 = 0b0,
10926            };
10927
10928            /// C7.2.104 FMAXNM (scalar)
10929            pub const Fmaxnm = packed struct {
10930                Rd: Register.Encoded,
10931                Rn: Register.Encoded,
10932                decoded10: u2 = 0b10,
10933                opcode: Opcode = .fmaxnm,
10934                Rm: Register.Encoded,
10935                decoded21: u1 = 0b1,
10936                ftype: Ftype,
10937                decoded24: u5 = 0b11110,
10938                S: bool = false,
10939                decoded30: u1 = 0b0,
10940                M: u1 = 0b0,
10941            };
10942
10943            /// C7.2.114 FMINNM (scalar)
10944            pub const Fminnm = packed struct {
10945                Rd: Register.Encoded,
10946                Rn: Register.Encoded,
10947                decoded10: u2 = 0b10,
10948                opcode: Opcode = .fminnm,
10949                Rm: Register.Encoded,
10950                decoded21: u1 = 0b1,
10951                ftype: Ftype,
10952                decoded24: u5 = 0b11110,
10953                S: bool = false,
10954                decoded30: u1 = 0b0,
10955                M: u1 = 0b0,
10956            };
10957
10958            /// C7.2.143 FNMUL (scalar)
10959            pub const Fnmul = packed struct {
10960                Rd: Register.Encoded,
10961                Rn: Register.Encoded,
10962                decoded10: u2 = 0b10,
10963                opcode: Opcode = .fnmul,
10964                Rm: Register.Encoded,
10965                decoded21: u1 = 0b1,
10966                ftype: Ftype,
10967                decoded24: u5 = 0b11110,
10968                S: bool = false,
10969                decoded30: u1 = 0b0,
10970                M: u1 = 0b0,
10971            };
10972
10973            pub const Opcode = enum(u4) {
10974                fmul = 0b0000,
10975                fdiv = 0b0001,
10976                fadd = 0b0010,
10977                fsub = 0b0011,
10978                fmax = 0b0100,
10979                fmin = 0b0101,
10980                fmaxnm = 0b0110,
10981                fminnm = 0b0111,
10982                fnmul = 0b1000,
10983                _,
10984            };
10985        };
10986
10987        /// Floating-point conditional select
10988        pub const FloatConditionalSelect = packed union {
10989            group: @This().Group,
10990            fcsel: Fcsel,
10991
10992            pub const Group = packed struct {
10993                Rd: Register.Encoded,
10994                Rn: Register.Encoded,
10995                decoded10: u2 = 0b11,
10996                cond: ConditionCode,
10997                Rm: Register.Encoded,
10998                decoded21: u1 = 0b1,
10999                ptype: Ftype,
11000                decoded24: u5 = 0b11110,
11001                S: bool,
11002                decoded30: u1 = 0b0,
11003                M: u1,
11004            };
11005
11006            /// C7.2.68 FCSEL
11007            pub const Fcsel = packed struct {
11008                Rd: Register.Encoded,
11009                Rn: Register.Encoded,
11010                decoded10: u2 = 0b11,
11011                cond: ConditionCode,
11012                Rm: Register.Encoded,
11013                decoded21: u1 = 0b1,
11014                ftype: Ftype,
11015                decoded24: u5 = 0b11110,
11016                S: bool = false,
11017                decoded30: u1 = 0b0,
11018                M: u1 = 0b0,
11019            };
11020
11021            pub const Decoded = union(enum) {
11022                unallocated,
11023                fcsel: Fcsel,
11024            };
11025            pub fn decode(inst: @This()) @This().Decoded {
11026                return switch (inst.group.ptype) {
11027                    .quad => .unallocated,
11028                    .single, .double, .half => switch (inst.group.S) {
11029                        true => .unallocated,
11030                        false => switch (inst.group.M) {
11031                            0b0 => .{ .fcsel = inst.fcsel },
11032                            0b1 => .unallocated,
11033                        },
11034                    },
11035                };
11036            }
11037        };
11038
11039        /// Floating-point data-processing (3 source)
11040        pub const FloatDataProcessingThreeSource = packed union {
11041            group: @This().Group,
11042            fmadd: Fmadd,
11043            fmsub: Fmsub,
11044            fnmadd: Fnmadd,
11045            fnmsub: Fnmsub,
11046
11047            pub const Group = packed struct {
11048                Rd: Register.Encoded,
11049                Rn: Register.Encoded,
11050                Ra: Register.Encoded,
11051                o0: AddSubtractOp,
11052                Rm: Register.Encoded,
11053                o1: u1,
11054                ptype: Ftype,
11055                decoded24: u5 = 0b11111,
11056                S: bool,
11057                decoded30: u1 = 0b0,
11058                M: u1,
11059            };
11060
11061            /// C7.2.100 FMADD
11062            pub const Fmadd = packed struct {
11063                Rd: Register.Encoded,
11064                Rn: Register.Encoded,
11065                Ra: Register.Encoded,
11066                o0: AddSubtractOp = .add,
11067                Rm: Register.Encoded,
11068                o1: O1 = .fm,
11069                ftype: Ftype,
11070                decoded24: u5 = 0b11111,
11071                S: bool = false,
11072                decoded30: u1 = 0b0,
11073                M: u1 = 0b0,
11074            };
11075
11076            /// C7.2.133 FMSUB
11077            pub const Fmsub = packed struct {
11078                Rd: Register.Encoded,
11079                Rn: Register.Encoded,
11080                Ra: Register.Encoded,
11081                o0: AddSubtractOp = .sub,
11082                Rm: Register.Encoded,
11083                o1: O1 = .fm,
11084                ftype: Ftype,
11085                decoded24: u5 = 0b11111,
11086                S: bool = false,
11087                decoded30: u1 = 0b0,
11088                M: u1 = 0b0,
11089            };
11090
11091            /// C7.2.141 FNMADD
11092            pub const Fnmadd = packed struct {
11093                Rd: Register.Encoded,
11094                Rn: Register.Encoded,
11095                Ra: Register.Encoded,
11096                o0: AddSubtractOp = .add,
11097                Rm: Register.Encoded,
11098                o1: O1 = .fnm,
11099                ftype: Ftype,
11100                decoded24: u5 = 0b11111,
11101                S: bool = false,
11102                decoded30: u1 = 0b0,
11103                M: u1 = 0b0,
11104            };
11105
11106            /// C7.2.142 FNMSUB
11107            pub const Fnmsub = packed struct {
11108                Rd: Register.Encoded,
11109                Rn: Register.Encoded,
11110                Ra: Register.Encoded,
11111                o0: AddSubtractOp = .sub,
11112                Rm: Register.Encoded,
11113                o1: O1 = .fnm,
11114                ftype: Ftype,
11115                decoded24: u5 = 0b11111,
11116                S: bool = false,
11117                decoded30: u1 = 0b0,
11118                M: u1 = 0b0,
11119            };
11120
11121            pub const O1 = enum(u1) {
11122                fm = 0b0,
11123                fnm = 0b1,
11124            };
11125        };
11126
11127        pub const Size = enum(u2) {
11128            byte = 0b00,
11129            half = 0b01,
11130            single = 0b10,
11131            double = 0b11,
11132
11133            pub fn n(s: Size) Size {
11134                return @enumFromInt(@intFromEnum(s) - 1);
11135            }
11136
11137            pub fn w(s: Size) Size {
11138                return @enumFromInt(@intFromEnum(s) + 1);
11139            }
11140
11141            pub fn toScalarSize(s: Size) Register.ScalarSize {
11142                return switch (s) {
11143                    .byte => .byte,
11144                    .half => .half,
11145                    .single => .single,
11146                    .double => .double,
11147                };
11148            }
11149
11150            pub fn fromScalarSize(ss: Register.ScalarSize) Size {
11151                return switch (ss) {
11152                    else => unreachable,
11153                    .byte => .byte,
11154                    .half => .half,
11155                    .single => .single,
11156                    .double => .double,
11157                };
11158            }
11159
11160            pub fn toSz(s: Size) Sz {
11161                return switch (s) {
11162                    else => unreachable,
11163                    .single => .single,
11164                    .double => .double,
11165                };
11166            }
11167        };
11168
11169        pub const Sz = enum(u1) {
11170            single = 0b0,
11171            double = 0b1,
11172
11173            pub fn toScalarSize(sz: Sz) Register.ScalarSize {
11174                return switch (sz) {
11175                    .single => .single,
11176                    .double => .double,
11177                };
11178            }
11179
11180            pub fn fromScalarSize(ss: Register.ScalarSize) Sz {
11181                return switch (ss) {
11182                    else => unreachable,
11183                    .single => .single,
11184                    .double => .double,
11185                };
11186            }
11187
11188            pub fn toSize(sz: Sz) Size {
11189                return switch (sz) {
11190                    .single => .single,
11191                    .double => .double,
11192                };
11193            }
11194        };
11195
11196        pub const Q = enum(u1) {
11197            double = 0b0,
11198            quad = 0b1,
11199        };
11200
11201        pub const Ftype = enum(u2) {
11202            single = 0b00,
11203            double = 0b01,
11204            quad = 0b10,
11205            half = 0b11,
11206
11207            pub fn toScalarSize(ftype: Ftype) Register.ScalarSize {
11208                return switch (ftype) {
11209                    .single => .single,
11210                    .double => .double,
11211                    .quad => .quad,
11212                    .half => .half,
11213                };
11214            }
11215
11216            pub fn fromScalarSize(ss: Register.ScalarSize) Ftype {
11217                return switch (ss) {
11218                    else => unreachable,
11219                    .single => .single,
11220                    .double => .double,
11221                    .quad => .quad,
11222                    .half => .half,
11223                };
11224            }
11225        };
11226
11227        pub const Decoded = union(enum) {
11228            unallocated,
11229            simd_scalar_copy: SimdScalarCopy,
11230            simd_scalar_two_register_miscellaneous_fp16: SimdScalarTwoRegisterMiscellaneousFp16,
11231            simd_scalar_two_register_miscellaneous: SimdScalarTwoRegisterMiscellaneous,
11232            simd_scalar_pairwise: SimdScalarPairwise,
11233            simd_copy: SimdCopy,
11234            simd_two_register_miscellaneous_fp16: SimdTwoRegisterMiscellaneousFp16,
11235            simd_two_register_miscellaneous: SimdTwoRegisterMiscellaneous,
11236            simd_across_lanes: SimdAcrossLanes,
11237            simd_three_same: SimdThreeSame,
11238            simd_modified_immediate: SimdModifiedImmediate,
11239            convert_float_fixed: ConvertFloatFixed,
11240            convert_float_integer: ConvertFloatInteger,
11241            float_data_processing_one_source: FloatDataProcessingOneSource,
11242            float_compare: FloatCompare,
11243            float_immediate: FloatImmediate,
11244            float_conditional_compare: FloatConditionalCompare,
11245            float_data_processing_two_source: FloatDataProcessingTwoSource,
11246            float_conditional_select: FloatConditionalSelect,
11247            float_data_processing_three_source: FloatDataProcessingThreeSource,
11248        };
11249        pub fn decode(inst: @This()) @This().Decoded {
11250            return switch (inst.group.op0) {
11251                else => .unallocated,
11252                0b0101, 0b0111 => switch (inst.group.op1) {
11253                    0b00...0b01 => if (inst.group.op3 & 0b000100001 == 0b000000001)
11254                        if (inst.group.op1 == 0b00 and inst.group.op2 & 0b1100 == 0b0000)
11255                            .{ .simd_scalar_copy = inst.simd_scalar_copy }
11256                        else
11257                            .unallocated
11258                    else if (inst.group.op3 & 0b110000011 == 0b000000010) switch (inst.group.op2) {
11259                        else => .unallocated,
11260                        0b1111 => .{ .simd_scalar_two_register_miscellaneous_fp16 = inst.simd_scalar_two_register_miscellaneous_fp16 },
11261                        0b0100, 0b1100 => .{ .simd_scalar_two_register_miscellaneous = inst.simd_scalar_two_register_miscellaneous },
11262                        0b0110, 0b1110 => .{ .simd_scalar_pairwise = inst.simd_scalar_pairwise },
11263                    } else .unallocated,
11264                    0b10, 0b11 => switch (@as(u1, @truncate(inst.group.op3 >> 0))) {
11265                        0b1 => switch (inst.group.op1) {
11266                            0b10 => .unallocated,
11267                            else => .unallocated,
11268                        },
11269                        0b0 => .unallocated,
11270                    },
11271                },
11272                0b0000, 0b0010, 0b0100, 0b0110 => if (inst.group.op1 == 0b00 and inst.group.op2 & 0b1100 == 0b0000 and inst.group.op3 & 0b000100001 == 0b0000000001)
11273                    .{ .simd_copy = inst.simd_copy }
11274                else if (inst.group.op1 & 0b10 == 0b00 and inst.group.op2 == 0b1111 and inst.group.op3 & 0b110000011 == 0b000000010)
11275                    .{ .simd_two_register_miscellaneous_fp16 = inst.simd_two_register_miscellaneous_fp16 }
11276                else if (inst.group.op1 & 0b10 == 0b00 and inst.group.op2 & 0b0111 == 0b0100 and inst.group.op3 & 0b110000011 == 0b000000010)
11277                    .{ .simd_two_register_miscellaneous = inst.simd_two_register_miscellaneous }
11278                else if (inst.group.op1 & 0b10 == 0b00 and inst.group.op2 & 0b0111 == 0b0110 and inst.group.op3 & 0b110000011 == 0b000000010)
11279                    .{ .simd_across_lanes = inst.simd_across_lanes }
11280                else if (inst.group.op1 & 0b10 == 0b00 and inst.group.op2 & 0b0100 == 0b0100 and inst.group.op3 & 0b000000001 == 0b000000001)
11281                    .{ .simd_three_same = inst.simd_three_same }
11282                else if (inst.group.op1 == 0b10 and inst.group.op2 == 0b0000 and inst.group.op3 & 0b000000001 == 0b000000001)
11283                    .{ .simd_modified_immediate = inst.simd_modified_immediate }
11284                else
11285                    .unallocated,
11286                0b0001, 0b0011, 0b1001, 0b1011 => switch (@as(u1, @truncate(inst.group.op1 >> 1))) {
11287                    0b0 => switch (@as(u1, @truncate(inst.group.op2 >> 2))) {
11288                        0b0 => .{ .convert_float_fixed = inst.convert_float_fixed },
11289                        0b1 => switch (@ctz(inst.group.op3)) {
11290                            else => .{ .convert_float_integer = inst.convert_float_integer },
11291                            4 => .{ .float_data_processing_one_source = inst.float_data_processing_one_source },
11292                            3 => .{ .float_compare = inst.float_compare },
11293                            2 => .{ .float_immediate = inst.float_immediate },
11294                            1 => .{ .float_data_processing_two_source = inst.float_data_processing_two_source },
11295                            0 => switch (@as(u1, @truncate(inst.group.op3 >> 1))) {
11296                                0b0 => .unallocated,
11297                                0b1 => .{ .float_conditional_select = inst.float_conditional_select },
11298                            },
11299                        },
11300                    },
11301                    0b1 => .unallocated,
11302                },
11303            };
11304        }
11305    };
11306
11307    pub const AddSubtractOp = enum(u1) {
11308        add = 0b0,
11309        sub = 0b1,
11310    };
11311
11312    pub const LogicalOpc = enum(u2) {
11313        @"and" = 0b00,
11314        orr = 0b01,
11315        eor = 0b10,
11316        ands = 0b11,
11317    };
11318
11319    pub const Nzcv = packed struct { v: bool, c: bool, z: bool, n: bool };
11320
11321    pub const Decoded = union(enum) {
11322        unallocated,
11323        reserved: Reserved,
11324        sme: Sme,
11325        sve: Sve,
11326        data_processing_immediate: DataProcessingImmediate,
11327        branch_exception_generating_system: BranchExceptionGeneratingSystem,
11328        load_store: LoadStore,
11329        data_processing_register: DataProcessingRegister,
11330        data_processing_vector: DataProcessingVector,
11331    };
11332    pub fn decode(inst: @This()) @This().Decoded {
11333        return switch (inst.group.op1) {
11334            0b0000 => switch (inst.group.op0) {
11335                0b0 => .{ .reserved = inst.reserved },
11336                0b1 => .{ .sme = inst.sme },
11337            },
11338            0b0001 => .unallocated,
11339            0b0010 => .{ .sve = inst.sve },
11340            0b0011 => .unallocated,
11341            0b1000, 0b1001 => .{ .data_processing_immediate = inst.data_processing_immediate },
11342            0b1010, 0b1011 => .{ .branch_exception_generating_system = inst.branch_exception_generating_system },
11343            0b0100, 0b0110, 0b1100, 0b1110 => .{ .load_store = inst.load_store },
11344            0b0101, 0b1101 => .{ .data_processing_register = inst.data_processing_register },
11345            0b0111, 0b1111 => .{ .data_processing_vector = inst.data_processing_vector },
11346        };
11347    }
11348
11349    /// C7.2.1 ABS
11350    pub fn abs(d: Register, n: Register) Instruction {
11351        switch (d.format) {
11352            else => unreachable,
11353            .scalar => |elem_size| {
11354                assert(elem_size == .double and elem_size == n.format.scalar);
11355                return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
11356                    .abs = .{
11357                        .Rd = d.alias.encode(.{ .V = true }),
11358                        .Rn = n.alias.encode(.{ .V = true }),
11359                        .size = .fromScalarSize(elem_size),
11360                    },
11361                } } };
11362            },
11363            .vector => |arrangement| {
11364                assert(arrangement != .@"1d" and n.format.vector == arrangement);
11365                return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
11366                    .abs = .{
11367                        .Rd = d.alias.encode(.{ .V = true }),
11368                        .Rn = n.alias.encode(.{ .V = true }),
11369                        .size = arrangement.elemSize(),
11370                        .Q = arrangement.size(),
11371                    },
11372                } } };
11373            },
11374        }
11375    }
11376    /// C6.2.1 ADC
11377    pub fn adc(d: Register, n: Register, m: Register) Instruction {
11378        const sf = d.format.general;
11379        assert(n.format.general == sf and m.format.general == sf);
11380        return .{ .data_processing_register = .{ .add_subtract_with_carry = .{
11381            .adc = .{
11382                .Rd = d.alias.encode(.{}),
11383                .Rn = n.alias.encode(.{}),
11384                .Rm = m.alias.encode(.{}),
11385                .sf = sf,
11386            },
11387        } } };
11388    }
11389    /// C6.2.2 ADCS
11390    pub fn adcs(d: Register, n: Register, m: Register) Instruction {
11391        const sf = d.format.general;
11392        assert(n.format.general == sf and m.format.general == sf);
11393        return .{ .data_processing_register = .{ .add_subtract_with_carry = .{
11394            .adcs = .{
11395                .Rd = d.alias.encode(.{}),
11396                .Rn = n.alias.encode(.{}),
11397                .Rm = m.alias.encode(.{}),
11398                .sf = sf,
11399            },
11400        } } };
11401    }
11402    /// C6.2.3 ADD (extended register)
11403    /// C6.2.4 ADD (immediate)
11404    /// C6.2.5 ADD (shifted register)
11405    pub fn add(d: Register, n: Register, form: union(enum) {
11406        extended_register_explicit: struct {
11407            register: Register,
11408            option: DataProcessingRegister.AddSubtractExtendedRegister.Option,
11409            amount: DataProcessingRegister.AddSubtractExtendedRegister.Extend.Amount,
11410        },
11411        extended_register: struct { register: Register, extend: DataProcessingRegister.AddSubtractExtendedRegister.Extend },
11412        immediate: u12,
11413        shifted_immediate: struct { immediate: u12, lsl: DataProcessingImmediate.AddSubtractImmediate.Shift = .@"0" },
11414        register: Register,
11415        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
11416        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
11417    }) Instruction {
11418        const sf = d.format.general;
11419        assert(n.format.general == sf);
11420        form: switch (form) {
11421            .extended_register_explicit => |extended_register_explicit| {
11422                assert(extended_register_explicit.register.format.general == switch (sf) {
11423                    .word => .word,
11424                    .doubleword => extended_register_explicit.option.sf(),
11425                });
11426                return .{ .data_processing_register = .{ .add_subtract_extended_register = .{
11427                    .add = .{
11428                        .Rd = d.alias.encode(.{ .sp = true }),
11429                        .Rn = n.alias.encode(.{ .sp = true }),
11430                        .imm3 = switch (extended_register_explicit.amount) {
11431                            0...4 => |amount| amount,
11432                            else => unreachable,
11433                        },
11434                        .option = extended_register_explicit.option,
11435                        .Rm = extended_register_explicit.register.alias.encode(.{}),
11436                        .sf = sf,
11437                    },
11438                } } };
11439            },
11440            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
11441                .register = extended_register.register,
11442                .option = extended_register.extend,
11443                .amount = switch (extended_register.extend) {
11444                    .uxtb, .uxth, .uxtw, .uxtx, .sxtb, .sxth, .sxtw, .sxtx => |amount| amount,
11445                },
11446            } },
11447            .immediate => |immediate| continue :form .{ .shifted_immediate = .{ .immediate = immediate } },
11448            .shifted_immediate => |shifted_immediate| {
11449                return .{ .data_processing_immediate = .{ .add_subtract_immediate = .{
11450                    .add = .{
11451                        .Rd = d.alias.encode(.{ .sp = true }),
11452                        .Rn = n.alias.encode(.{ .sp = true }),
11453                        .imm12 = shifted_immediate.immediate,
11454                        .sh = shifted_immediate.lsl,
11455                        .sf = sf,
11456                    },
11457                } } };
11458            },
11459            .register => |register| continue :form if (d.alias == .sp or n.alias == .sp or register.alias == .sp)
11460                .{ .extended_register = .{ .register = register, .extend = switch (sf) {
11461                    .word => .{ .uxtw = 0 },
11462                    .doubleword => .{ .uxtx = 0 },
11463                } } }
11464            else
11465                .{ .shifted_register = .{ .register = register } },
11466            .shifted_register_explicit => |shifted_register_explicit| {
11467                assert(shifted_register_explicit.register.format.general == sf);
11468                return .{ .data_processing_register = .{ .add_subtract_shifted_register = .{
11469                    .add = .{
11470                        .Rd = d.alias.encode(.{}),
11471                        .Rn = n.alias.encode(.{}),
11472                        .imm6 = switch (sf) {
11473                            .word => @as(u5, @intCast(shifted_register_explicit.amount)),
11474                            .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
11475                        },
11476                        .Rm = shifted_register_explicit.register.alias.encode(.{}),
11477                        .shift = switch (shifted_register_explicit.shift) {
11478                            .lsl, .lsr, .asr => |shift| shift,
11479                            .ror => unreachable,
11480                        },
11481                        .sf = sf,
11482                    },
11483                } } };
11484            },
11485            .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
11486                .register = shifted_register.register,
11487                .shift = shifted_register.shift,
11488                .amount = switch (shifted_register.shift) {
11489                    .lsl, .lsr, .asr => |amount| amount,
11490                    .ror => unreachable,
11491                },
11492            } },
11493        }
11494    }
11495    /// C7.2.6 ADDG
11496    pub fn addg(d: Register, n: Register, uimm6: u10, uimm4: u4) Instruction {
11497        assert(d.format.general == .doubleword and n.format.general == .doubleword);
11498        return .{ .data_processing_immediate = .{ .add_subtract_immediate_with_tags = .{
11499            .addg = .{
11500                .Xd = d.alias.encode(.{ .sp = true }),
11501                .Xn = n.alias.encode(.{ .sp = true }),
11502                .uimm4 = uimm4,
11503                .uimm6 = @intCast(@shrExact(uimm6, 4)),
11504            },
11505        } } };
11506    }
11507    /// C7.2.4 ADDP (scalar)
11508    /// C7.2.5 ADDP (vector)
11509    pub fn addp(d: Register, n: Register, form: union(enum) {
11510        scalar,
11511        vector: Register,
11512    }) Instruction {
11513        switch (form) {
11514            .scalar => {
11515                assert(d.format.scalar == .double and n.format.vector == .@"2d");
11516                return .{ .data_processing_vector = .{ .simd_scalar_pairwise = .{
11517                    .addp = .{
11518                        .Rd = d.alias.encode(.{ .V = true }),
11519                        .Rn = n.alias.encode(.{ .V = true }),
11520                        .size = .double,
11521                    },
11522                } } };
11523            },
11524            .vector => |m| {
11525                const arrangement = d.format.vector;
11526                assert(arrangement != .@"1d" and n.format.vector == arrangement and m.format.vector == arrangement);
11527                return .{ .data_processing_vector = .{ .simd_three_same = .{
11528                    .addp = .{
11529                        .Rd = d.alias.encode(.{ .V = true }),
11530                        .Rn = n.alias.encode(.{ .V = true }),
11531                        .Rm = m.alias.encode(.{ .V = true }),
11532                        .size = arrangement.elemSize(),
11533                        .Q = arrangement.size(),
11534                    },
11535                } } };
11536            },
11537        }
11538    }
11539    /// C6.2.7 ADDS (extended register)
11540    /// C6.2.8 ADDS (immediate)
11541    /// C6.2.9 ADDS (shifted register)
11542    pub fn adds(d: Register, n: Register, form: union(enum) {
11543        extended_register_explicit: struct {
11544            register: Register,
11545            option: DataProcessingRegister.AddSubtractExtendedRegister.Option,
11546            amount: DataProcessingRegister.AddSubtractExtendedRegister.Extend.Amount,
11547        },
11548        extended_register: struct { register: Register, extend: DataProcessingRegister.AddSubtractExtendedRegister.Extend },
11549        immediate: u12,
11550        shifted_immediate: struct { immediate: u12, lsl: DataProcessingImmediate.AddSubtractImmediate.Shift = .@"0" },
11551        register: Register,
11552        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
11553        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
11554    }) Instruction {
11555        const sf = d.format.general;
11556        assert(n.format.general == sf);
11557        form: switch (form) {
11558            .extended_register_explicit => |extended_register_explicit| {
11559                assert(extended_register_explicit.register.format.general == switch (sf) {
11560                    .word => .word,
11561                    .doubleword => extended_register_explicit.option.sf(),
11562                });
11563                return .{ .data_processing_register = .{ .add_subtract_extended_register = .{
11564                    .adds = .{
11565                        .Rd = d.alias.encode(.{}),
11566                        .Rn = n.alias.encode(.{ .sp = true }),
11567                        .imm3 = switch (extended_register_explicit.amount) {
11568                            0...4 => |amount| amount,
11569                            else => unreachable,
11570                        },
11571                        .option = extended_register_explicit.option,
11572                        .Rm = extended_register_explicit.register.alias.encode(.{}),
11573                        .sf = sf,
11574                    },
11575                } } };
11576            },
11577            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
11578                .register = extended_register.register,
11579                .option = extended_register.extend,
11580                .amount = switch (extended_register.extend) {
11581                    .uxtb, .uxth, .uxtw, .uxtx, .sxtb, .sxth, .sxtw, .sxtx => |amount| amount,
11582                },
11583            } },
11584            .immediate => |immediate| continue :form .{ .shifted_immediate = .{ .immediate = immediate } },
11585            .shifted_immediate => |shifted_immediate| {
11586                return .{ .data_processing_immediate = .{ .add_subtract_immediate = .{
11587                    .adds = .{
11588                        .Rd = d.alias.encode(.{}),
11589                        .Rn = n.alias.encode(.{ .sp = true }),
11590                        .imm12 = shifted_immediate.immediate,
11591                        .sh = shifted_immediate.lsl,
11592                        .sf = sf,
11593                    },
11594                } } };
11595            },
11596            .register => |register| continue :form if (d.alias == .sp or n.alias == .sp or register.alias == .sp)
11597                .{ .extended_register = .{ .register = register, .extend = switch (sf) {
11598                    .word => .{ .uxtw = 0 },
11599                    .doubleword => .{ .uxtx = 0 },
11600                } } }
11601            else
11602                .{ .shifted_register = .{ .register = register } },
11603            .shifted_register_explicit => |shifted_register_explicit| {
11604                assert(shifted_register_explicit.register.format.general == sf);
11605                return .{ .data_processing_register = .{ .add_subtract_shifted_register = .{
11606                    .adds = .{
11607                        .Rd = d.alias.encode(.{}),
11608                        .Rn = n.alias.encode(.{}),
11609                        .imm6 = switch (sf) {
11610                            .word => @as(u5, @intCast(shifted_register_explicit.amount)),
11611                            .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
11612                        },
11613                        .Rm = shifted_register_explicit.register.alias.encode(.{}),
11614                        .shift = switch (shifted_register_explicit.shift) {
11615                            .lsl, .lsr, .asr => |shift| shift,
11616                            .ror => unreachable,
11617                        },
11618                        .sf = sf,
11619                    },
11620                } } };
11621            },
11622            .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
11623                .register = shifted_register.register,
11624                .shift = shifted_register.shift,
11625                .amount = switch (shifted_register.shift) {
11626                    .lsl, .lsr, .asr => |amount| amount,
11627                    .ror => unreachable,
11628                },
11629            } },
11630        }
11631    }
11632    /// C7.2.6 ADDV
11633    pub fn addv(d: Register, n: Register) Instruction {
11634        const arrangement = n.format.vector;
11635        assert(arrangement.len() > 2 and d.format.scalar == arrangement.elemSize().toScalarSize());
11636        return .{ .data_processing_vector = .{ .simd_across_lanes = .{
11637            .addv = .{
11638                .Rd = d.alias.encode(.{ .V = true }),
11639                .Rn = n.alias.encode(.{ .V = true }),
11640                .size = arrangement.elemSize(),
11641                .Q = arrangement.size(),
11642            },
11643        } } };
11644    }
11645    /// C6.2.10 ADR
11646    pub fn adr(d: Register, label: i21) Instruction {
11647        assert(d.format.general == .doubleword);
11648        return .{ .data_processing_immediate = .{ .pc_relative_addressing = .{
11649            .adr = .{
11650                .Rd = d.alias.encode(.{}),
11651                .immhi = @intCast(label >> 2),
11652                .immlo = @truncate(@as(u21, @bitCast(label))),
11653            },
11654        } } };
11655    }
11656    /// C6.2.11 ADRP
11657    pub fn adrp(d: Register, label: i33) Instruction {
11658        assert(d.format.general == .doubleword);
11659        const imm: i21 = @intCast(@shrExact(label, 12));
11660        return .{ .data_processing_immediate = .{ .pc_relative_addressing = .{
11661            .adrp = .{
11662                .Rd = d.alias.encode(.{}),
11663                .immhi = @intCast(imm >> 2),
11664                .immlo = @truncate(@as(u21, @bitCast(imm))),
11665            },
11666        } } };
11667    }
11668    /// C6.2.12 AND (immediate)
11669    /// C6.2.13 AND (shifted register)
11670    /// C7.2.11 AND (vector)
11671    pub fn @"and"(d: Register, n: Register, form: union(enum) {
11672        immediate: DataProcessingImmediate.Bitmask,
11673        register: Register,
11674        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
11675        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
11676    }) Instruction {
11677        switch (d.format) {
11678            else => unreachable,
11679            .general => |sf| {
11680                assert(n.format.general == sf);
11681                form: switch (form) {
11682                    .immediate => |bitmask| {
11683                        assert(bitmask.validImmediate(sf));
11684                        return .{ .data_processing_immediate = .{ .logical_immediate = .{
11685                            .@"and" = .{
11686                                .Rd = d.alias.encode(.{ .sp = true }),
11687                                .Rn = n.alias.encode(.{}),
11688                                .imm = bitmask,
11689                                .sf = sf,
11690                            },
11691                        } } };
11692                    },
11693                    .register => |register| continue :form .{ .shifted_register = .{ .register = register } },
11694                    .shifted_register_explicit => |shifted_register_explicit| {
11695                        assert(shifted_register_explicit.register.format.general == sf);
11696                        return .{ .data_processing_register = .{ .logical_shifted_register = .{
11697                            .@"and" = .{
11698                                .Rd = d.alias.encode(.{}),
11699                                .Rn = n.alias.encode(.{}),
11700                                .imm6 = switch (sf) {
11701                                    .word => @as(u5, @intCast(shifted_register_explicit.amount)),
11702                                    .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
11703                                },
11704                                .Rm = shifted_register_explicit.register.alias.encode(.{}),
11705                                .shift = shifted_register_explicit.shift,
11706                                .sf = sf,
11707                            },
11708                        } } };
11709                    },
11710                    .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
11711                        .register = shifted_register.register,
11712                        .shift = shifted_register.shift,
11713                        .amount = switch (shifted_register.shift) {
11714                            .lsl, .lsr, .asr, .ror => |amount| amount,
11715                        },
11716                    } },
11717                }
11718            },
11719            .vector => |arrangement| {
11720                const m = form.register;
11721                assert(arrangement.elemSize() == .byte and n.format.vector == arrangement and m.format.vector == arrangement);
11722                return .{ .data_processing_vector = .{ .simd_three_same = .{
11723                    .@"and" = .{
11724                        .Rd = d.alias.encode(.{ .V = true }),
11725                        .Rn = n.alias.encode(.{ .V = true }),
11726                        .Rm = m.alias.encode(.{ .V = true }),
11727                        .Q = arrangement.size(),
11728                    },
11729                } } };
11730            },
11731        }
11732    }
11733    /// C6.2.14 ANDS (immediate)
11734    /// C6.2.15 ANDS (shifted register)
11735    pub fn ands(d: Register, n: Register, form: union(enum) {
11736        immediate: DataProcessingImmediate.Bitmask,
11737        register: Register,
11738        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
11739        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
11740    }) Instruction {
11741        const sf = d.format.general;
11742        assert(n.format.general == sf);
11743        form: switch (form) {
11744            .immediate => |bitmask| {
11745                assert(bitmask.validImmediate(sf));
11746                return .{ .data_processing_immediate = .{ .logical_immediate = .{
11747                    .ands = .{
11748                        .Rd = d.alias.encode(.{}),
11749                        .Rn = n.alias.encode(.{}),
11750                        .imm = bitmask,
11751                        .sf = sf,
11752                    },
11753                } } };
11754            },
11755            .register => |register| continue :form .{ .shifted_register = .{ .register = register } },
11756            .shifted_register_explicit => |shifted_register_explicit| {
11757                assert(shifted_register_explicit.register.format.general == sf);
11758                return .{ .data_processing_register = .{ .logical_shifted_register = .{
11759                    .ands = .{
11760                        .Rd = d.alias.encode(.{}),
11761                        .Rn = n.alias.encode(.{}),
11762                        .imm6 = switch (sf) {
11763                            .word => @as(u5, @intCast(shifted_register_explicit.amount)),
11764                            .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
11765                        },
11766                        .Rm = shifted_register_explicit.register.alias.encode(.{}),
11767                        .shift = shifted_register_explicit.shift,
11768                        .sf = sf,
11769                    },
11770                } } };
11771            },
11772            .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
11773                .register = shifted_register.register,
11774                .shift = shifted_register.shift,
11775                .amount = switch (shifted_register.shift) {
11776                    .lsl, .lsr, .asr, .ror => |amount| amount,
11777                },
11778            } },
11779        }
11780    }
11781    /// C6.2.18 ASRV
11782    pub fn asrv(d: Register, n: Register, m: Register) Instruction {
11783        const sf = d.format.general;
11784        assert(n.format.general == sf and m.format.general == sf);
11785        return .{ .data_processing_register = .{ .data_processing_two_source = .{
11786            .asrv = .{
11787                .Rd = d.alias.encode(.{}),
11788                .Rn = n.alias.encode(.{}),
11789                .Rm = m.alias.encode(.{}),
11790                .sf = sf,
11791            },
11792        } } };
11793    }
11794    /// C6.2.24 AXFLAG
11795    pub fn axflag() Instruction {
11796        return .{ .branch_exception_generating_system = .{ .pstate = .{
11797            .axflag = .{},
11798        } } };
11799    }
11800    /// C6.2.25 B
11801    pub fn b(label: i28) Instruction {
11802        return .{ .branch_exception_generating_system = .{ .unconditional_branch_immediate = .{
11803            .b = .{ .imm26 = @intCast(@shrExact(label, 2)) },
11804        } } };
11805    }
11806    /// C6.2.26 B.cond
11807    pub fn @"b."(cond: ConditionCode, label: i21) Instruction {
11808        return .{ .branch_exception_generating_system = .{ .conditional_branch_immediate = .{
11809            .b = .{
11810                .cond = cond,
11811                .imm19 = @intCast(@shrExact(label, 2)),
11812            },
11813        } } };
11814    }
11815    /// C6.2.27 BC.cond
11816    pub fn @"bc."(cond: ConditionCode, label: i21) Instruction {
11817        return .{ .branch_exception_generating_system = .{ .conditional_branch_immediate = .{
11818            .bc = .{
11819                .cond = cond,
11820                .imm19 = @intCast(@shrExact(label, 2)),
11821            },
11822        } } };
11823    }
11824    /// C6.2.30 BFM
11825    pub fn bfm(d: Register, n: Register, bitmask: DataProcessingImmediate.Bitmask) Instruction {
11826        const sf = d.format.general;
11827        assert(n.format.general == sf and bitmask.validBitfield(sf));
11828        return .{ .data_processing_immediate = .{ .bitfield = .{
11829            .bfm = .{
11830                .Rd = d.alias.encode(.{}),
11831                .Rn = n.alias.encode(.{}),
11832                .imm = bitmask,
11833                .sf = sf,
11834            },
11835        } } };
11836    }
11837    /// C6.2.32 BIC (shifted register)
11838    /// C7.2.20 BIC (vector, immediate)
11839    /// C7.2.21 BIC (vector, register)
11840    pub fn bic(d: Register, n: Register, form: union(enum) {
11841        shifted_immediate: struct { immediate: u8, lsl: u5 = 0 },
11842        register: Register,
11843        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
11844        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
11845    }) Instruction {
11846        switch (d.format) {
11847            else => unreachable,
11848            .general => |sf| {
11849                assert(n.format.general == sf);
11850                form: switch (form) {
11851                    else => unreachable,
11852                    .register => |register| continue :form .{ .shifted_register = .{ .register = register } },
11853                    .shifted_register_explicit => |shifted_register_explicit| {
11854                        assert(shifted_register_explicit.register.format.general == sf);
11855                        return .{ .data_processing_register = .{ .logical_shifted_register = .{
11856                            .bic = .{
11857                                .Rd = d.alias.encode(.{}),
11858                                .Rn = n.alias.encode(.{}),
11859                                .imm6 = switch (sf) {
11860                                    .word => @as(u5, @intCast(shifted_register_explicit.amount)),
11861                                    .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
11862                                },
11863                                .Rm = shifted_register_explicit.register.alias.encode(.{}),
11864                                .shift = shifted_register_explicit.shift,
11865                                .sf = sf,
11866                            },
11867                        } } };
11868                    },
11869                    .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
11870                        .register = shifted_register.register,
11871                        .shift = shifted_register.shift,
11872                        .amount = switch (shifted_register.shift) {
11873                            .lsl, .lsr, .asr, .ror => |amount| amount,
11874                        },
11875                    } },
11876                }
11877            },
11878            .vector => |arrangement| switch (form) {
11879                else => unreachable,
11880                .shifted_immediate => |shifted_immediate| {
11881                    assert(n.alias == d.alias and n.format.vector == arrangement);
11882                    return .{ .data_processing_vector = .{ .simd_modified_immediate = .{
11883                        .bic = .{
11884                            .Rd = d.alias.encode(.{ .V = true }),
11885                            .imm5 = @truncate(shifted_immediate.immediate >> 0),
11886                            .cmode = switch (arrangement) {
11887                                else => unreachable,
11888                                .@"4h", .@"8h" => @as(u3, 0b100) |
11889                                    @as(u3, @as(u1, @intCast(@shrExact(shifted_immediate.lsl, 3)))) << 0,
11890                                .@"2s", .@"4s" => @as(u3, 0b000) |
11891                                    @as(u3, @as(u2, @intCast(@shrExact(shifted_immediate.lsl, 3)))) << 0,
11892                            },
11893                            .imm3 = @intCast(shifted_immediate.immediate >> 5),
11894                            .Q = arrangement.size(),
11895                        },
11896                    } } };
11897                },
11898                .register => |m| {
11899                    assert(arrangement.elemSize() == .byte and n.format.vector == arrangement and m.format.vector == arrangement);
11900                    return .{ .data_processing_vector = .{ .simd_three_same = .{
11901                        .bic = .{
11902                            .Rd = d.alias.encode(.{ .V = true }),
11903                            .Rn = n.alias.encode(.{ .V = true }),
11904                            .Rm = m.alias.encode(.{ .V = true }),
11905                            .Q = arrangement.size(),
11906                        },
11907                    } } };
11908                },
11909            },
11910        }
11911    }
11912    /// C6.2.33 BICS (shifted register)
11913    pub fn bics(d: Register, n: Register, form: union(enum) {
11914        register: Register,
11915        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
11916        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
11917    }) Instruction {
11918        const sf = d.format.general;
11919        assert(n.format.general == sf);
11920        form: switch (form) {
11921            .register => |register| continue :form .{ .shifted_register = .{ .register = register } },
11922            .shifted_register_explicit => |shifted_register_explicit| {
11923                assert(shifted_register_explicit.register.format.general == sf);
11924                return .{ .data_processing_register = .{ .logical_shifted_register = .{
11925                    .bics = .{
11926                        .Rd = d.alias.encode(.{}),
11927                        .Rn = n.alias.encode(.{}),
11928                        .imm6 = switch (sf) {
11929                            .word => @as(u5, @intCast(shifted_register_explicit.amount)),
11930                            .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
11931                        },
11932                        .Rm = shifted_register_explicit.register.alias.encode(.{}),
11933                        .shift = shifted_register_explicit.shift,
11934                        .sf = sf,
11935                    },
11936                } } };
11937            },
11938            .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
11939                .register = shifted_register.register,
11940                .shift = shifted_register.shift,
11941                .amount = switch (shifted_register.shift) {
11942                    .lsl, .lsr, .asr, .ror => |amount| amount,
11943                },
11944            } },
11945        }
11946    }
11947    /// C7.2.22 BIF
11948    pub fn bif(d: Register, n: Register, m: Register) Instruction {
11949        const arrangement = d.format.vector;
11950        assert(arrangement.elemSize() == .byte and n.format.vector == arrangement and m.format.vector == arrangement);
11951        return .{ .data_processing_vector = .{ .simd_three_same = .{
11952            .bif = .{
11953                .Rd = d.alias.encode(.{ .V = true }),
11954                .Rn = n.alias.encode(.{ .V = true }),
11955                .Rm = m.alias.encode(.{ .V = true }),
11956                .Q = arrangement.size(),
11957            },
11958        } } };
11959    }
11960    /// C7.2.23 BIT
11961    pub fn bit(d: Register, n: Register, m: Register) Instruction {
11962        const arrangement = d.format.vector;
11963        assert(arrangement.elemSize() == .byte and n.format.vector == arrangement and m.format.vector == arrangement);
11964        return .{ .data_processing_vector = .{ .simd_three_same = .{
11965            .bit = .{
11966                .Rd = d.alias.encode(.{ .V = true }),
11967                .Rn = n.alias.encode(.{ .V = true }),
11968                .Rm = m.alias.encode(.{ .V = true }),
11969                .Q = arrangement.size(),
11970            },
11971        } } };
11972    }
11973    /// C7.2.24 BSL
11974    pub fn bsl(d: Register, n: Register, m: Register) Instruction {
11975        const arrangement = d.format.vector;
11976        assert(arrangement.elemSize() == .byte and n.format.vector == arrangement and m.format.vector == arrangement);
11977        return .{ .data_processing_vector = .{ .simd_three_same = .{
11978            .bsl = .{
11979                .Rd = d.alias.encode(.{ .V = true }),
11980                .Rn = n.alias.encode(.{ .V = true }),
11981                .Rm = m.alias.encode(.{ .V = true }),
11982                .Q = arrangement.size(),
11983            },
11984        } } };
11985    }
11986    /// C6.2.34 BL
11987    pub fn bl(label: i28) Instruction {
11988        return .{ .branch_exception_generating_system = .{ .unconditional_branch_immediate = .{
11989            .bl = .{ .imm26 = @intCast(@shrExact(label, 2)) },
11990        } } };
11991    }
11992    /// C6.2.35 BLR
11993    pub fn blr(n: Register) Instruction {
11994        assert(n.format.general == .doubleword);
11995        return .{ .branch_exception_generating_system = .{ .unconditional_branch_register = .{
11996            .blr = .{ .Rn = n.alias.encode(.{}) },
11997        } } };
11998    }
11999    /// C6.2.37 BR
12000    pub fn br(n: Register) Instruction {
12001        assert(n.format.general == .doubleword);
12002        return .{ .branch_exception_generating_system = .{ .unconditional_branch_register = .{
12003            .br = .{ .Rn = n.alias.encode(.{}) },
12004        } } };
12005    }
12006    /// C6.2.40 BRK
12007    pub fn brk(imm: u16) Instruction {
12008        return .{ .branch_exception_generating_system = .{ .exception_generating = .{
12009            .brk = .{ .imm16 = imm },
12010        } } };
12011    }
12012    /// C6.2.46 CBNZ
12013    pub fn cbnz(t: Register, label: i21) Instruction {
12014        return .{ .branch_exception_generating_system = .{ .compare_branch_immediate = .{
12015            .cbnz = .{
12016                .Rt = t.alias.encode(.{}),
12017                .imm19 = @intCast(@shrExact(label, 2)),
12018                .sf = t.format.general,
12019            },
12020        } } };
12021    }
12022    /// C6.2.47 CBZ
12023    pub fn cbz(t: Register, label: i21) Instruction {
12024        return .{ .branch_exception_generating_system = .{ .compare_branch_immediate = .{
12025            .cbz = .{
12026                .Rt = t.alias.encode(.{}),
12027                .imm19 = @intCast(@shrExact(label, 2)),
12028                .sf = t.format.general,
12029            },
12030        } } };
12031    }
12032    /// C6.2.48 CCMN (immediate)
12033    /// C6.2.49 CCMN (register)
12034    pub fn ccmn(
12035        n: Register,
12036        form: union(enum) { register: Register, immediate: u5 },
12037        nzcv: Nzcv,
12038        cond: ConditionCode,
12039    ) Instruction {
12040        const sf = n.format.general;
12041        switch (form) {
12042            .register => |m| {
12043                assert(m.format.general == sf);
12044                return .{ .data_processing_register = .{ .conditional_compare_register = .{
12045                    .ccmn = .{
12046                        .nzcv = nzcv,
12047                        .Rn = n.alias.encode(.{}),
12048                        .cond = cond,
12049                        .Rm = m.alias.encode(.{}),
12050                        .sf = sf,
12051                    },
12052                } } };
12053            },
12054            .immediate => |imm| return .{ .data_processing_register = .{ .conditional_compare_immediate = .{
12055                .ccmn = .{
12056                    .nzcv = nzcv,
12057                    .Rn = n.alias.encode(.{}),
12058                    .cond = cond,
12059                    .imm5 = imm,
12060                    .sf = sf,
12061                },
12062            } } },
12063        }
12064    }
12065    /// C6.2.50 CCMP (immediate)
12066    /// C6.2.51 CCMP (register)
12067    pub fn ccmp(
12068        n: Register,
12069        form: union(enum) { register: Register, immediate: u5 },
12070        nzcv: Nzcv,
12071        cond: ConditionCode,
12072    ) Instruction {
12073        const sf = n.format.general;
12074        switch (form) {
12075            .register => |m| {
12076                assert(m.format.general == sf);
12077                return .{ .data_processing_register = .{ .conditional_compare_register = .{
12078                    .ccmp = .{
12079                        .nzcv = nzcv,
12080                        .Rn = n.alias.encode(.{}),
12081                        .cond = cond,
12082                        .Rm = m.alias.encode(.{}),
12083                        .sf = sf,
12084                    },
12085                } } };
12086            },
12087            .immediate => |imm| return .{ .data_processing_register = .{ .conditional_compare_immediate = .{
12088                .ccmp = .{
12089                    .nzcv = nzcv,
12090                    .Rn = n.alias.encode(.{}),
12091                    .cond = cond,
12092                    .imm5 = imm,
12093                    .sf = sf,
12094                },
12095            } } },
12096        }
12097    }
12098    /// C6.2.52 CFINV
12099    pub fn cfinv() Instruction {
12100        return .{ .branch_exception_generating_system = .{ .pstate = .{
12101            .cfinv = .{},
12102        } } };
12103    }
12104    /// C6.2.56 CLREX
12105    pub fn clrex(imm: u4) Instruction {
12106        return .{ .branch_exception_generating_system = .{ .barriers = .{
12107            .clrex = .{
12108                .CRm = imm,
12109            },
12110        } } };
12111    }
12112    /// C6.2.57 CLS
12113    pub fn cls(d: Register, n: Register) Instruction {
12114        const sf = d.format.general;
12115        assert(n.format.general == sf);
12116        return .{ .data_processing_register = .{ .data_processing_one_source = .{
12117            .cls = .{
12118                .Rd = d.alias.encode(.{}),
12119                .Rn = n.alias.encode(.{}),
12120                .sf = sf,
12121            },
12122        } } };
12123    }
12124    /// C6.2.58 CLZ
12125    pub fn clz(d: Register, n: Register) Instruction {
12126        const sf = d.format.general;
12127        assert(n.format.general == sf);
12128        return .{ .data_processing_register = .{ .data_processing_one_source = .{
12129            .clz = .{
12130                .Rd = d.alias.encode(.{}),
12131                .Rn = n.alias.encode(.{}),
12132                .sf = sf,
12133            },
12134        } } };
12135    }
12136    /// C7.2.28 CMEQ (zero)
12137    pub fn cmeq(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12138        switch (form) {
12139            .zero => switch (d.format) {
12140                else => unreachable,
12141                .scalar => |elem_size| {
12142                    assert(elem_size == .double and elem_size == n.format.scalar);
12143                    return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12144                        .cmeq = .{
12145                            .Rd = d.alias.encode(.{ .V = true }),
12146                            .Rn = n.alias.encode(.{ .V = true }),
12147                            .size = .fromScalarSize(elem_size),
12148                        },
12149                    } } };
12150                },
12151                .vector => |arrangement| {
12152                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12153                    return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12154                        .cmeq = .{
12155                            .Rd = d.alias.encode(.{ .V = true }),
12156                            .Rn = n.alias.encode(.{ .V = true }),
12157                            .size = arrangement.elemSize(),
12158                            .Q = arrangement.size(),
12159                        },
12160                    } } };
12161                },
12162            },
12163        }
12164    }
12165    /// C7.2.30 CMGE (zero)
12166    pub fn cmge(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12167        switch (form) {
12168            .zero => switch (d.format) {
12169                else => unreachable,
12170                .scalar => |elem_size| {
12171                    assert(elem_size == .double and elem_size == n.format.scalar);
12172                    return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12173                        .cmge = .{
12174                            .Rd = d.alias.encode(.{ .V = true }),
12175                            .Rn = n.alias.encode(.{ .V = true }),
12176                            .size = .fromScalarSize(elem_size),
12177                        },
12178                    } } };
12179                },
12180                .vector => |arrangement| {
12181                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12182                    return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12183                        .cmge = .{
12184                            .Rd = d.alias.encode(.{ .V = true }),
12185                            .Rn = n.alias.encode(.{ .V = true }),
12186                            .size = arrangement.elemSize(),
12187                            .Q = arrangement.size(),
12188                        },
12189                    } } };
12190                },
12191            },
12192        }
12193    }
12194    /// C7.2.32 CMGT (zero)
12195    pub fn cmgt(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12196        switch (form) {
12197            .zero => switch (d.format) {
12198                else => unreachable,
12199                .scalar => |elem_size| {
12200                    assert(elem_size == .double and elem_size == n.format.scalar);
12201                    return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12202                        .cmgt = .{
12203                            .Rd = d.alias.encode(.{ .V = true }),
12204                            .Rn = n.alias.encode(.{ .V = true }),
12205                            .size = .fromScalarSize(elem_size),
12206                        },
12207                    } } };
12208                },
12209                .vector => |arrangement| {
12210                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12211                    return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12212                        .cmgt = .{
12213                            .Rd = d.alias.encode(.{ .V = true }),
12214                            .Rn = n.alias.encode(.{ .V = true }),
12215                            .size = arrangement.elemSize(),
12216                            .Q = arrangement.size(),
12217                        },
12218                    } } };
12219                },
12220            },
12221        }
12222    }
12223    /// C7.2.35 CMLE (zero)
12224    pub fn cmle(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12225        switch (form) {
12226            .zero => switch (d.format) {
12227                else => unreachable,
12228                .scalar => |elem_size| {
12229                    assert(elem_size == .double and elem_size == n.format.scalar);
12230                    return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12231                        .cmle = .{
12232                            .Rd = d.alias.encode(.{ .V = true }),
12233                            .Rn = n.alias.encode(.{ .V = true }),
12234                            .size = .fromScalarSize(elem_size),
12235                        },
12236                    } } };
12237                },
12238                .vector => |arrangement| {
12239                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12240                    return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12241                        .cmle = .{
12242                            .Rd = d.alias.encode(.{ .V = true }),
12243                            .Rn = n.alias.encode(.{ .V = true }),
12244                            .size = arrangement.elemSize(),
12245                            .Q = arrangement.size(),
12246                        },
12247                    } } };
12248                },
12249            },
12250        }
12251    }
12252    /// C7.2.36 CMLT (zero)
12253    pub fn cmlt(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12254        switch (form) {
12255            .zero => switch (d.format) {
12256                else => unreachable,
12257                .scalar => |elem_size| {
12258                    assert(elem_size == .double and elem_size == n.format.scalar);
12259                    return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12260                        .cmlt = .{
12261                            .Rd = d.alias.encode(.{ .V = true }),
12262                            .Rn = n.alias.encode(.{ .V = true }),
12263                            .size = .fromScalarSize(elem_size),
12264                        },
12265                    } } };
12266                },
12267                .vector => |arrangement| {
12268                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12269                    return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12270                        .cmlt = .{
12271                            .Rd = d.alias.encode(.{ .V = true }),
12272                            .Rn = n.alias.encode(.{ .V = true }),
12273                            .size = arrangement.elemSize(),
12274                            .Q = arrangement.size(),
12275                        },
12276                    } } };
12277                },
12278            },
12279        }
12280    }
12281    /// C7.2.38 CNT
12282    pub fn cnt(d: Register, n: Register) Instruction {
12283        const arrangement = d.format.vector;
12284        assert(arrangement.elemSize() == .byte and n.format.vector == arrangement);
12285        return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12286            .cnt = .{
12287                .Rd = d.alias.encode(.{ .V = true }),
12288                .Rn = n.alias.encode(.{ .V = true }),
12289                .size = arrangement.elemSize(),
12290                .Q = arrangement.size(),
12291            },
12292        } } };
12293    }
12294    /// C6.2.103 CSEL
12295    pub fn csel(d: Register, n: Register, m: Register, cond: ConditionCode) Instruction {
12296        const sf = d.format.general;
12297        assert(n.format.general == sf and m.format.general == sf);
12298        return .{ .data_processing_register = .{ .conditional_select = .{
12299            .csel = .{
12300                .Rd = d.alias.encode(.{}),
12301                .Rn = n.alias.encode(.{}),
12302                .cond = cond,
12303                .Rm = m.alias.encode(.{}),
12304                .sf = sf,
12305            },
12306        } } };
12307    }
12308    /// C6.2.106 CSINC
12309    pub fn csinc(d: Register, n: Register, m: Register, cond: ConditionCode) Instruction {
12310        const sf = d.format.general;
12311        assert(n.format.general == sf and m.format.general == sf);
12312        return .{ .data_processing_register = .{ .conditional_select = .{
12313            .csinc = .{
12314                .Rd = d.alias.encode(.{}),
12315                .Rn = n.alias.encode(.{}),
12316                .cond = cond,
12317                .Rm = m.alias.encode(.{}),
12318                .sf = sf,
12319            },
12320        } } };
12321    }
12322    /// C6.2.107 CSINV
12323    pub fn csinv(d: Register, n: Register, m: Register, cond: ConditionCode) Instruction {
12324        const sf = d.format.general;
12325        assert(n.format.general == sf and m.format.general == sf);
12326        return .{ .data_processing_register = .{ .conditional_select = .{
12327            .csinv = .{
12328                .Rd = d.alias.encode(.{}),
12329                .Rn = n.alias.encode(.{}),
12330                .cond = cond,
12331                .Rm = m.alias.encode(.{}),
12332                .sf = sf,
12333            },
12334        } } };
12335    }
12336    /// C6.2.108 CSNEG
12337    pub fn csneg(d: Register, n: Register, m: Register, cond: ConditionCode) Instruction {
12338        const sf = d.format.general;
12339        assert(n.format.general == sf and m.format.general == sf);
12340        return .{ .data_processing_register = .{ .conditional_select = .{
12341            .csneg = .{
12342                .Rd = d.alias.encode(.{}),
12343                .Rn = n.alias.encode(.{}),
12344                .cond = cond,
12345                .Rm = m.alias.encode(.{}),
12346                .sf = sf,
12347            },
12348        } } };
12349    }
12350    /// C6.2.110 DCPS1
12351    pub fn dcps1(imm: u16) Instruction {
12352        return .{ .branch_exception_generating_system = .{ .exception_generating = .{
12353            .dcps1 = .{ .imm16 = imm },
12354        } } };
12355    }
12356    /// C6.2.111 DCPS2
12357    pub fn dcps2(imm: u16) Instruction {
12358        return .{ .branch_exception_generating_system = .{ .exception_generating = .{
12359            .dcps2 = .{ .imm16 = imm },
12360        } } };
12361    }
12362    /// C6.2.112 DCPS3
12363    pub fn dcps3(imm: u16) Instruction {
12364        return .{ .branch_exception_generating_system = .{ .exception_generating = .{
12365            .dcps3 = .{ .imm16 = imm },
12366        } } };
12367    }
12368    /// C6.2.116 DSB
12369    pub fn dsb(option: BranchExceptionGeneratingSystem.Barriers.Option) Instruction {
12370        return .{ .branch_exception_generating_system = .{ .barriers = .{
12371            .dsb = .{
12372                .CRm = option,
12373            },
12374        } } };
12375    }
12376    /// C7.2.39 DUP (element)
12377    /// C7.2.40 DUP (general)
12378    pub fn dup(d: Register, n: Register) Instruction {
12379        switch (d.format) {
12380            else => unreachable,
12381            .scalar => |elem_size| {
12382                assert(@intFromEnum(elem_size) <= @intFromEnum(Register.ScalarSize.double) and elem_size == n.format.element.size);
12383                return .{ .data_processing_vector = .{ .simd_scalar_copy = .{
12384                    .dup = .{
12385                        .Rd = d.alias.encode(.{ .V = true }),
12386                        .Rn = n.alias.encode(.{ .V = true }),
12387                        .imm5 = @shlExact(@as(u5, n.format.element.index) << 1 | @as(u5, 0b1), @intFromEnum(elem_size)),
12388                    },
12389                } } };
12390            },
12391            .vector => |arrangement| {
12392                assert(arrangement != .@"1d");
12393                const elem_size = arrangement.elemSize();
12394                switch (n.format) {
12395                    else => unreachable,
12396                    .element => |element| {
12397                        assert(elem_size.toScalarSize() == element.size);
12398                        return .{ .data_processing_vector = .{ .simd_copy = .{
12399                            .dup = .{
12400                                .Rd = d.alias.encode(.{ .V = true }),
12401                                .Rn = n.alias.encode(.{ .V = true }),
12402                                .imm4 = .element,
12403                                .imm5 = @shlExact(@as(u5, element.index) << 1 | @as(u5, 0b1), @intFromEnum(elem_size)),
12404                                .Q = arrangement.size(),
12405                            },
12406                        } } };
12407                    },
12408                    .general => |sf| {
12409                        assert(sf == @as(Register.GeneralSize, switch (elem_size) {
12410                            .byte, .half, .single => .word,
12411                            .double => .doubleword,
12412                        }));
12413                        return .{ .data_processing_vector = .{ .simd_copy = .{
12414                            .dup = .{
12415                                .Rd = d.alias.encode(.{ .V = true }),
12416                                .Rn = n.alias.encode(.{}),
12417                                .imm4 = .general,
12418                                .imm5 = @shlExact(@as(u5, 0b1), @intFromEnum(elem_size)),
12419                                .Q = arrangement.size(),
12420                            },
12421                        } } };
12422                    },
12423                }
12424            },
12425        }
12426    }
12427    /// C6.2.118 EON (shifted register)
12428    pub fn eon(d: Register, n: Register, form: union(enum) {
12429        register: Register,
12430        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
12431        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
12432    }) Instruction {
12433        const sf = d.format.general;
12434        assert(n.format.general == sf);
12435        form: switch (form) {
12436            .register => |register| continue :form .{ .shifted_register = .{ .register = register } },
12437            .shifted_register_explicit => |shifted_register_explicit| {
12438                assert(shifted_register_explicit.register.format.general == sf);
12439                return .{ .data_processing_register = .{ .logical_shifted_register = .{
12440                    .eon = .{
12441                        .Rd = d.alias.encode(.{}),
12442                        .Rn = n.alias.encode(.{}),
12443                        .imm6 = switch (sf) {
12444                            .word => @as(u5, @intCast(shifted_register_explicit.amount)),
12445                            .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
12446                        },
12447                        .Rm = shifted_register_explicit.register.alias.encode(.{}),
12448                        .shift = shifted_register_explicit.shift,
12449                        .sf = sf,
12450                    },
12451                } } };
12452            },
12453            .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
12454                .register = shifted_register.register,
12455                .shift = shifted_register.shift,
12456                .amount = switch (shifted_register.shift) {
12457                    .lsl, .lsr, .asr, .ror => |amount| amount,
12458                },
12459            } },
12460        }
12461    }
12462    /// C6.2.119 EOR (immediate)
12463    /// C6.2.120 EOR (shifted register)
12464    /// C7.2.41 EOR (vector)
12465    pub fn eor(d: Register, n: Register, form: union(enum) {
12466        immediate: DataProcessingImmediate.Bitmask,
12467        register: Register,
12468        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
12469        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
12470    }) Instruction {
12471        switch (d.format) {
12472            else => unreachable,
12473            .general => |sf| {
12474                assert(n.format.general == sf);
12475                form: switch (form) {
12476                    .immediate => |bitmask| {
12477                        assert(bitmask.validImmediate(sf));
12478                        return .{ .data_processing_immediate = .{ .logical_immediate = .{
12479                            .eor = .{
12480                                .Rd = d.alias.encode(.{ .sp = true }),
12481                                .Rn = n.alias.encode(.{}),
12482                                .imm = bitmask,
12483                                .sf = sf,
12484                            },
12485                        } } };
12486                    },
12487                    .register => |register| continue :form .{ .shifted_register = .{ .register = register } },
12488                    .shifted_register_explicit => |shifted_register_explicit| {
12489                        assert(shifted_register_explicit.register.format.general == sf);
12490                        return .{ .data_processing_register = .{ .logical_shifted_register = .{
12491                            .eor = .{
12492                                .Rd = d.alias.encode(.{}),
12493                                .Rn = n.alias.encode(.{}),
12494                                .imm6 = switch (sf) {
12495                                    .word => @as(u5, @intCast(shifted_register_explicit.amount)),
12496                                    .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
12497                                },
12498                                .Rm = shifted_register_explicit.register.alias.encode(.{}),
12499                                .shift = shifted_register_explicit.shift,
12500                                .sf = sf,
12501                            },
12502                        } } };
12503                    },
12504                    .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
12505                        .register = shifted_register.register,
12506                        .shift = shifted_register.shift,
12507                        .amount = switch (shifted_register.shift) {
12508                            .lsl, .lsr, .asr, .ror => |amount| amount,
12509                        },
12510                    } },
12511                }
12512            },
12513            .vector => |arrangement| {
12514                const m = form.register;
12515                assert(arrangement.elemSize() == .byte and n.format.vector == arrangement and m.format.vector == arrangement);
12516                return .{ .data_processing_vector = .{ .simd_three_same = .{
12517                    .eor = .{
12518                        .Rd = d.alias.encode(.{ .V = true }),
12519                        .Rn = n.alias.encode(.{ .V = true }),
12520                        .Rm = m.alias.encode(.{ .V = true }),
12521                        .Q = arrangement.size(),
12522                    },
12523                } } };
12524            },
12525        }
12526    }
12527    /// C6.2.124 EXTR
12528    pub fn extr(d: Register, n: Register, m: Register, lsb: u6) Instruction {
12529        const sf = d.format.general;
12530        assert(n.format.general == sf and m.format.general == sf);
12531        return .{ .data_processing_immediate = .{ .extract = .{
12532            .extr = .{
12533                .Rd = d.alias.encode(.{}),
12534                .Rn = n.alias.encode(.{}),
12535                .imms = switch (sf) {
12536                    .word => @as(u5, @intCast(lsb)),
12537                    .doubleword => @as(u6, @intCast(lsb)),
12538                },
12539                .Rm = m.alias.encode(.{}),
12540                .N = sf,
12541                .sf = sf,
12542            },
12543        } } };
12544    }
12545    /// C7.2.45 FABS (vector)
12546    /// C7.2.46 FABS (scalar)
12547    pub fn fabs(d: Register, n: Register) Instruction {
12548        switch (d.format) {
12549            else => unreachable,
12550            .vector => |arrangement| {
12551                assert(n.format.vector == arrangement);
12552                switch (arrangement.elemSize()) {
12553                    else => unreachable,
12554                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
12555                        .fabs = .{
12556                            .Rd = d.alias.encode(.{ .V = true }),
12557                            .Rn = n.alias.encode(.{ .V = true }),
12558                            .Q = arrangement.size(),
12559                        },
12560                    } } },
12561                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12562                        .fabs = .{
12563                            .Rd = d.alias.encode(.{ .V = true }),
12564                            .Rn = n.alias.encode(.{ .V = true }),
12565                            .sz = arrangement.elemSz(),
12566                            .Q = arrangement.size(),
12567                        },
12568                    } } },
12569                }
12570            },
12571            .scalar => |ftype| {
12572                assert(n.format.scalar == ftype);
12573                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
12574                    .fabs = .{
12575                        .Rd = d.alias.encode(.{ .V = true }),
12576                        .Rn = n.alias.encode(.{ .V = true }),
12577                        .ftype = .fromScalarSize(ftype),
12578                    },
12579                } } };
12580            },
12581        }
12582    }
12583    /// C7.2.50 FADD (scalar)
12584    pub fn fadd(d: Register, n: Register, m: Register) Instruction {
12585        const ftype = d.format.scalar;
12586        assert(n.format.scalar == ftype and m.format.scalar == ftype);
12587        return .{ .data_processing_vector = .{ .float_data_processing_two_source = .{
12588            .fadd = .{
12589                .Rd = d.alias.encode(.{ .V = true }),
12590                .Rn = n.alias.encode(.{ .V = true }),
12591                .Rm = m.alias.encode(.{ .V = true }),
12592                .ftype = .fromScalarSize(ftype),
12593            },
12594        } } };
12595    }
12596    /// C7.2.57 FCMEQ (zero)
12597    pub fn fcmeq(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12598        switch (form) {
12599            .zero => switch (d.format) {
12600                else => unreachable,
12601                .scalar => |ftype| switch (n.format) {
12602                    else => unreachable,
12603                    .scalar => |n_scalar| {
12604                        assert(n_scalar == ftype);
12605                        switch (ftype) {
12606                            else => unreachable,
12607                            .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
12608                                .fcmeq = .{
12609                                    .Rd = d.alias.encode(.{ .V = true }),
12610                                    .Rn = n.alias.encode(.{ .V = true }),
12611                                },
12612                            } } },
12613                            .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12614                                .fcmeq = .{
12615                                    .Rd = d.alias.encode(.{ .V = true }),
12616                                    .Rn = n.alias.encode(.{ .V = true }),
12617                                    .sz = .fromScalarSize(ftype),
12618                                },
12619                            } } },
12620                        }
12621                    },
12622                },
12623                .vector => |arrangement| {
12624                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12625                    switch (arrangement.elemSize()) {
12626                        else => unreachable,
12627                        .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
12628                            .fcmeq = .{
12629                                .Rd = d.alias.encode(.{ .V = true }),
12630                                .Rn = n.alias.encode(.{ .V = true }),
12631                                .Q = arrangement.size(),
12632                            },
12633                        } } },
12634                        .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12635                            .fcmeq = .{
12636                                .Rd = d.alias.encode(.{ .V = true }),
12637                                .Rn = n.alias.encode(.{ .V = true }),
12638                                .sz = arrangement.elemSz(),
12639                                .Q = arrangement.size(),
12640                            },
12641                        } } },
12642                    }
12643                },
12644            },
12645        }
12646    }
12647    /// C7.2.59 FCMGE (zero)
12648    pub fn fcmge(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12649        switch (form) {
12650            .zero => switch (d.format) {
12651                else => unreachable,
12652                .scalar => |ftype| switch (n.format) {
12653                    else => unreachable,
12654                    .scalar => |n_scalar| {
12655                        assert(n_scalar == ftype);
12656                        switch (ftype) {
12657                            else => unreachable,
12658                            .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
12659                                .fcmge = .{
12660                                    .Rd = d.alias.encode(.{ .V = true }),
12661                                    .Rn = n.alias.encode(.{ .V = true }),
12662                                },
12663                            } } },
12664                            .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12665                                .fcmge = .{
12666                                    .Rd = d.alias.encode(.{ .V = true }),
12667                                    .Rn = n.alias.encode(.{ .V = true }),
12668                                    .sz = .fromScalarSize(ftype),
12669                                },
12670                            } } },
12671                        }
12672                    },
12673                },
12674                .vector => |arrangement| {
12675                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12676                    switch (arrangement.elemSize()) {
12677                        else => unreachable,
12678                        .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
12679                            .fcmge = .{
12680                                .Rd = d.alias.encode(.{ .V = true }),
12681                                .Rn = n.alias.encode(.{ .V = true }),
12682                                .Q = arrangement.size(),
12683                            },
12684                        } } },
12685                        .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12686                            .fcmge = .{
12687                                .Rd = d.alias.encode(.{ .V = true }),
12688                                .Rn = n.alias.encode(.{ .V = true }),
12689                                .sz = arrangement.elemSz(),
12690                                .Q = arrangement.size(),
12691                            },
12692                        } } },
12693                    }
12694                },
12695            },
12696        }
12697    }
12698    /// C7.2.61 FCMGT (zero)
12699    pub fn fcmgt(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12700        switch (form) {
12701            .zero => switch (d.format) {
12702                else => unreachable,
12703                .scalar => |ftype| switch (n.format) {
12704                    else => unreachable,
12705                    .scalar => |n_scalar| {
12706                        assert(n_scalar == ftype);
12707                        switch (ftype) {
12708                            else => unreachable,
12709                            .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
12710                                .fcmgt = .{
12711                                    .Rd = d.alias.encode(.{ .V = true }),
12712                                    .Rn = n.alias.encode(.{ .V = true }),
12713                                },
12714                            } } },
12715                            .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12716                                .fcmgt = .{
12717                                    .Rd = d.alias.encode(.{ .V = true }),
12718                                    .Rn = n.alias.encode(.{ .V = true }),
12719                                    .sz = .fromScalarSize(ftype),
12720                                },
12721                            } } },
12722                        }
12723                    },
12724                },
12725                .vector => |arrangement| {
12726                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12727                    switch (arrangement.elemSize()) {
12728                        else => unreachable,
12729                        .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
12730                            .fcmgt = .{
12731                                .Rd = d.alias.encode(.{ .V = true }),
12732                                .Rn = n.alias.encode(.{ .V = true }),
12733                                .Q = arrangement.size(),
12734                            },
12735                        } } },
12736                        .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12737                            .fcmgt = .{
12738                                .Rd = d.alias.encode(.{ .V = true }),
12739                                .Rn = n.alias.encode(.{ .V = true }),
12740                                .sz = arrangement.elemSz(),
12741                                .Q = arrangement.size(),
12742                            },
12743                        } } },
12744                    }
12745                },
12746            },
12747        }
12748    }
12749    /// C7.2.64 FCMLE (zero)
12750    pub fn fcmle(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12751        switch (form) {
12752            .zero => switch (d.format) {
12753                else => unreachable,
12754                .scalar => |ftype| switch (n.format) {
12755                    else => unreachable,
12756                    .scalar => |n_scalar| {
12757                        assert(n_scalar == ftype);
12758                        switch (ftype) {
12759                            else => unreachable,
12760                            .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
12761                                .fcmle = .{
12762                                    .Rd = d.alias.encode(.{ .V = true }),
12763                                    .Rn = n.alias.encode(.{ .V = true }),
12764                                },
12765                            } } },
12766                            .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12767                                .fcmle = .{
12768                                    .Rd = d.alias.encode(.{ .V = true }),
12769                                    .Rn = n.alias.encode(.{ .V = true }),
12770                                    .sz = .fromScalarSize(ftype),
12771                                },
12772                            } } },
12773                        }
12774                    },
12775                },
12776                .vector => |arrangement| {
12777                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12778                    switch (arrangement.elemSize()) {
12779                        else => unreachable,
12780                        .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
12781                            .fcmle = .{
12782                                .Rd = d.alias.encode(.{ .V = true }),
12783                                .Rn = n.alias.encode(.{ .V = true }),
12784                                .Q = arrangement.size(),
12785                            },
12786                        } } },
12787                        .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12788                            .fcmle = .{
12789                                .Rd = d.alias.encode(.{ .V = true }),
12790                                .Rn = n.alias.encode(.{ .V = true }),
12791                                .sz = arrangement.elemSz(),
12792                                .Q = arrangement.size(),
12793                            },
12794                        } } },
12795                    }
12796                },
12797            },
12798        }
12799    }
12800    /// C7.2.65 FCMLT (zero)
12801    pub fn fcmlt(d: Register, n: Register, form: union(enum) { zero }) Instruction {
12802        switch (form) {
12803            .zero => switch (d.format) {
12804                else => unreachable,
12805                .scalar => |ftype| switch (n.format) {
12806                    else => unreachable,
12807                    .scalar => |n_scalar| {
12808                        assert(n_scalar == ftype);
12809                        switch (ftype) {
12810                            else => unreachable,
12811                            .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
12812                                .fcmlt = .{
12813                                    .Rd = d.alias.encode(.{ .V = true }),
12814                                    .Rn = n.alias.encode(.{ .V = true }),
12815                                },
12816                            } } },
12817                            .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12818                                .fcmlt = .{
12819                                    .Rd = d.alias.encode(.{ .V = true }),
12820                                    .Rn = n.alias.encode(.{ .V = true }),
12821                                    .sz = .fromScalarSize(ftype),
12822                                },
12823                            } } },
12824                        }
12825                    },
12826                },
12827                .vector => |arrangement| {
12828                    assert(arrangement != .@"1d" and n.format.vector == arrangement);
12829                    switch (arrangement.elemSize()) {
12830                        else => unreachable,
12831                        .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
12832                            .fcmlt = .{
12833                                .Rd = d.alias.encode(.{ .V = true }),
12834                                .Rn = n.alias.encode(.{ .V = true }),
12835                                .Q = arrangement.size(),
12836                            },
12837                        } } },
12838                        .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12839                            .fcmlt = .{
12840                                .Rd = d.alias.encode(.{ .V = true }),
12841                                .Rn = n.alias.encode(.{ .V = true }),
12842                                .sz = arrangement.elemSz(),
12843                                .Q = arrangement.size(),
12844                            },
12845                        } } },
12846                    }
12847                },
12848            },
12849        }
12850    }
12851    /// C7.2.66 FCMP
12852    pub fn fcmp(n: Register, form: union(enum) { register: Register, zero }) Instruction {
12853        const ftype = n.format.scalar;
12854        switch (form) {
12855            .register => |m| {
12856                assert(m.format.scalar == ftype);
12857                return .{ .data_processing_vector = .{ .float_compare = .{
12858                    .fcmp = .{
12859                        .opc0 = .register,
12860                        .Rn = n.alias.encode(.{ .V = true }),
12861                        .Rm = m.alias.encode(.{ .V = true }),
12862                        .ftype = .fromScalarSize(ftype),
12863                    },
12864                } } };
12865            },
12866            .zero => return .{ .data_processing_vector = .{ .float_compare = .{
12867                .fcmp = .{
12868                    .opc0 = .register,
12869                    .Rn = n.alias.encode(.{ .V = true }),
12870                    .Rm = @enumFromInt(0b00000),
12871                    .ftype = .fromScalarSize(ftype),
12872                },
12873            } } },
12874        }
12875    }
12876    /// C7.2.67 FCMPE
12877    pub fn fcmpe(n: Register, form: union(enum) { register: Register, zero }) Instruction {
12878        const ftype = n.format.scalar;
12879        switch (form) {
12880            .register => |m| {
12881                assert(m.format.scalar == ftype);
12882                return .{ .data_processing_vector = .{ .float_compare = .{
12883                    .fcmpe = .{
12884                        .opc0 = .zero,
12885                        .Rn = n.alias.encode(.{ .V = true }),
12886                        .Rm = m.alias.encode(.{ .V = true }),
12887                        .ftype = .fromScalarSize(ftype),
12888                    },
12889                } } };
12890            },
12891            .zero => return .{ .data_processing_vector = .{ .float_compare = .{
12892                .fcmpe = .{
12893                    .opc0 = .zero,
12894                    .Rn = n.alias.encode(.{ .V = true }),
12895                    .Rm = @enumFromInt(0b00000),
12896                    .ftype = .fromScalarSize(ftype),
12897                },
12898            } } },
12899        }
12900    }
12901    /// C7.2.68 FCSEL
12902    pub fn fcsel(d: Register, n: Register, m: Register, cond: ConditionCode) Instruction {
12903        const ftype = d.format.scalar;
12904        assert(n.format.scalar == ftype and m.format.scalar == ftype);
12905        return .{ .data_processing_vector = .{ .float_conditional_select = .{
12906            .fcsel = .{
12907                .Rd = d.alias.encode(.{ .V = true }),
12908                .Rn = n.alias.encode(.{ .V = true }),
12909                .cond = cond,
12910                .Rm = m.alias.encode(.{ .V = true }),
12911                .ftype = .fromScalarSize(ftype),
12912            },
12913        } } };
12914    }
12915    /// C7.2.69 FCVT
12916    pub fn fcvt(d: Register, n: Register) Instruction {
12917        assert(d.format.scalar != n.format.scalar);
12918        return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
12919            .fcvt = .{
12920                .Rd = d.alias.encode(.{ .V = true }),
12921                .Rn = n.alias.encode(.{ .V = true }),
12922                .opc = switch (d.format.scalar) {
12923                    else => unreachable,
12924                    .single => .single,
12925                    .double => .double,
12926                    .half => .half,
12927                },
12928                .ftype = .fromScalarSize(n.format.scalar),
12929            },
12930        } } };
12931    }
12932    /// C7.2.70 FCVTAS (vector)
12933    /// C7.2.71 FCVTAS (scalar)
12934    pub fn fcvtas(d: Register, n: Register) Instruction {
12935        switch (d.format) {
12936            else => unreachable,
12937            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
12938                .fcvtas = .{
12939                    .Rd = d.alias.encode(.{}),
12940                    .Rn = n.alias.encode(.{ .V = true }),
12941                    .ftype = .fromScalarSize(n.format.scalar),
12942                    .sf = sf,
12943                },
12944            } } },
12945            .scalar => |elem_size| switch (n.format) {
12946                else => unreachable,
12947                .scalar => |ftype| {
12948                    assert(ftype == elem_size);
12949                    switch (elem_size) {
12950                        else => unreachable,
12951                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
12952                            .fcvtas = .{
12953                                .Rd = d.alias.encode(.{ .V = true }),
12954                                .Rn = n.alias.encode(.{ .V = true }),
12955                            },
12956                        } } },
12957                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
12958                            .fcvtas = .{
12959                                .Rd = d.alias.encode(.{ .V = true }),
12960                                .Rn = n.alias.encode(.{ .V = true }),
12961                                .sz = .fromScalarSize(elem_size),
12962                            },
12963                        } } },
12964                    }
12965                },
12966            },
12967            .vector => |arrangement| {
12968                assert(arrangement != .@"1d" and n.format.vector == arrangement);
12969                switch (arrangement.elemSize()) {
12970                    else => unreachable,
12971                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
12972                        .fcvtas = .{
12973                            .Rd = d.alias.encode(.{ .V = true }),
12974                            .Rn = n.alias.encode(.{ .V = true }),
12975                            .Q = arrangement.size(),
12976                        },
12977                    } } },
12978                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
12979                        .fcvtas = .{
12980                            .Rd = d.alias.encode(.{ .V = true }),
12981                            .Rn = n.alias.encode(.{ .V = true }),
12982                            .sz = arrangement.elemSz(),
12983                            .Q = arrangement.size(),
12984                        },
12985                    } } },
12986                }
12987            },
12988        }
12989    }
12990    /// C7.2.72 FCVTAU (vector)
12991    /// C7.2.73 FCVTAU (scalar)
12992    pub fn fcvtau(d: Register, n: Register) Instruction {
12993        switch (d.format) {
12994            else => unreachable,
12995            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
12996                .fcvtau = .{
12997                    .Rd = d.alias.encode(.{}),
12998                    .Rn = n.alias.encode(.{ .V = true }),
12999                    .ftype = .fromScalarSize(n.format.scalar),
13000                    .sf = sf,
13001                },
13002            } } },
13003            .scalar => |elem_size| switch (n.format) {
13004                else => unreachable,
13005                .scalar => |ftype| {
13006                    assert(ftype == elem_size);
13007                    switch (elem_size) {
13008                        else => unreachable,
13009                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
13010                            .fcvtau = .{
13011                                .Rd = d.alias.encode(.{ .V = true }),
13012                                .Rn = n.alias.encode(.{ .V = true }),
13013                            },
13014                        } } },
13015                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
13016                            .fcvtau = .{
13017                                .Rd = d.alias.encode(.{ .V = true }),
13018                                .Rn = n.alias.encode(.{ .V = true }),
13019                                .sz = .fromScalarSize(elem_size),
13020                            },
13021                        } } },
13022                    }
13023                },
13024            },
13025            .vector => |arrangement| {
13026                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13027                switch (arrangement.elemSize()) {
13028                    else => unreachable,
13029                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13030                        .fcvtau = .{
13031                            .Rd = d.alias.encode(.{ .V = true }),
13032                            .Rn = n.alias.encode(.{ .V = true }),
13033                            .Q = arrangement.size(),
13034                        },
13035                    } } },
13036                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13037                        .fcvtau = .{
13038                            .Rd = d.alias.encode(.{ .V = true }),
13039                            .Rn = n.alias.encode(.{ .V = true }),
13040                            .sz = arrangement.elemSz(),
13041                            .Q = arrangement.size(),
13042                        },
13043                    } } },
13044                }
13045            },
13046        }
13047    }
13048    /// C7.2.75 FCVTMS (vector)
13049    /// C7.2.76 FCVTMS (scalar)
13050    pub fn fcvtms(d: Register, n: Register) Instruction {
13051        switch (d.format) {
13052            else => unreachable,
13053            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13054                .fcvtms = .{
13055                    .Rd = d.alias.encode(.{}),
13056                    .Rn = n.alias.encode(.{ .V = true }),
13057                    .ftype = .fromScalarSize(n.format.scalar),
13058                    .sf = sf,
13059                },
13060            } } },
13061            .scalar => |elem_size| switch (n.format) {
13062                else => unreachable,
13063                .scalar => |ftype| {
13064                    assert(ftype == elem_size);
13065                    switch (elem_size) {
13066                        else => unreachable,
13067                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
13068                            .fcvtms = .{
13069                                .Rd = d.alias.encode(.{ .V = true }),
13070                                .Rn = n.alias.encode(.{ .V = true }),
13071                            },
13072                        } } },
13073                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
13074                            .fcvtms = .{
13075                                .Rd = d.alias.encode(.{ .V = true }),
13076                                .Rn = n.alias.encode(.{ .V = true }),
13077                                .sz = .fromScalarSize(elem_size),
13078                            },
13079                        } } },
13080                    }
13081                },
13082            },
13083            .vector => |arrangement| {
13084                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13085                switch (arrangement.elemSize()) {
13086                    else => unreachable,
13087                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13088                        .fcvtms = .{
13089                            .Rd = d.alias.encode(.{ .V = true }),
13090                            .Rn = n.alias.encode(.{ .V = true }),
13091                            .Q = arrangement.size(),
13092                        },
13093                    } } },
13094                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13095                        .fcvtms = .{
13096                            .Rd = d.alias.encode(.{ .V = true }),
13097                            .Rn = n.alias.encode(.{ .V = true }),
13098                            .sz = arrangement.elemSz(),
13099                            .Q = arrangement.size(),
13100                        },
13101                    } } },
13102                }
13103            },
13104        }
13105    }
13106    /// C7.2.77 FCVTMU (vector)
13107    /// C7.2.78 FCVTMU (scalar)
13108    pub fn fcvtmu(d: Register, n: Register) Instruction {
13109        switch (d.format) {
13110            else => unreachable,
13111            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13112                .fcvtmu = .{
13113                    .Rd = d.alias.encode(.{}),
13114                    .Rn = n.alias.encode(.{ .V = true }),
13115                    .ftype = .fromScalarSize(n.format.scalar),
13116                    .sf = sf,
13117                },
13118            } } },
13119            .scalar => |elem_size| switch (n.format) {
13120                else => unreachable,
13121                .scalar => |ftype| {
13122                    assert(ftype == elem_size);
13123                    switch (elem_size) {
13124                        else => unreachable,
13125                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
13126                            .fcvtmu = .{
13127                                .Rd = d.alias.encode(.{ .V = true }),
13128                                .Rn = n.alias.encode(.{ .V = true }),
13129                            },
13130                        } } },
13131                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
13132                            .fcvtmu = .{
13133                                .Rd = d.alias.encode(.{ .V = true }),
13134                                .Rn = n.alias.encode(.{ .V = true }),
13135                                .sz = .fromScalarSize(elem_size),
13136                            },
13137                        } } },
13138                    }
13139                },
13140            },
13141            .vector => |arrangement| {
13142                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13143                switch (arrangement.elemSize()) {
13144                    else => unreachable,
13145                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13146                        .fcvtmu = .{
13147                            .Rd = d.alias.encode(.{ .V = true }),
13148                            .Rn = n.alias.encode(.{ .V = true }),
13149                            .Q = arrangement.size(),
13150                        },
13151                    } } },
13152                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13153                        .fcvtmu = .{
13154                            .Rd = d.alias.encode(.{ .V = true }),
13155                            .Rn = n.alias.encode(.{ .V = true }),
13156                            .sz = arrangement.elemSz(),
13157                            .Q = arrangement.size(),
13158                        },
13159                    } } },
13160                }
13161            },
13162        }
13163    }
13164    /// C7.2.80 FCVTNS (vector)
13165    /// C7.2.81 FCVTNS (scalar)
13166    pub fn fcvtns(d: Register, n: Register) Instruction {
13167        switch (d.format) {
13168            else => unreachable,
13169            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13170                .fcvtns = .{
13171                    .Rd = d.alias.encode(.{}),
13172                    .Rn = n.alias.encode(.{ .V = true }),
13173                    .ftype = .fromScalarSize(n.format.scalar),
13174                    .sf = sf,
13175                },
13176            } } },
13177            .scalar => |elem_size| switch (n.format) {
13178                else => unreachable,
13179                .scalar => |ftype| {
13180                    assert(ftype == elem_size);
13181                    switch (elem_size) {
13182                        else => unreachable,
13183                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
13184                            .fcvtns = .{
13185                                .Rd = d.alias.encode(.{ .V = true }),
13186                                .Rn = n.alias.encode(.{ .V = true }),
13187                            },
13188                        } } },
13189                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
13190                            .fcvtns = .{
13191                                .Rd = d.alias.encode(.{ .V = true }),
13192                                .Rn = n.alias.encode(.{ .V = true }),
13193                                .sz = .fromScalarSize(elem_size),
13194                            },
13195                        } } },
13196                    }
13197                },
13198            },
13199            .vector => |arrangement| {
13200                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13201                switch (arrangement.elemSize()) {
13202                    else => unreachable,
13203                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13204                        .fcvtns = .{
13205                            .Rd = d.alias.encode(.{ .V = true }),
13206                            .Rn = n.alias.encode(.{ .V = true }),
13207                            .Q = arrangement.size(),
13208                        },
13209                    } } },
13210                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13211                        .fcvtns = .{
13212                            .Rd = d.alias.encode(.{ .V = true }),
13213                            .Rn = n.alias.encode(.{ .V = true }),
13214                            .sz = arrangement.elemSz(),
13215                            .Q = arrangement.size(),
13216                        },
13217                    } } },
13218                }
13219            },
13220        }
13221    }
13222    /// C7.2.82 FCVTNU (vector)
13223    /// C7.2.83 FCVTNU (scalar)
13224    pub fn fcvtnu(d: Register, n: Register) Instruction {
13225        switch (d.format) {
13226            else => unreachable,
13227            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13228                .fcvtnu = .{
13229                    .Rd = d.alias.encode(.{}),
13230                    .Rn = n.alias.encode(.{ .V = true }),
13231                    .ftype = .fromScalarSize(n.format.scalar),
13232                    .sf = sf,
13233                },
13234            } } },
13235            .scalar => |elem_size| switch (n.format) {
13236                else => unreachable,
13237                .scalar => |ftype| {
13238                    assert(ftype == elem_size);
13239                    switch (elem_size) {
13240                        else => unreachable,
13241                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
13242                            .fcvtnu = .{
13243                                .Rd = d.alias.encode(.{ .V = true }),
13244                                .Rn = n.alias.encode(.{ .V = true }),
13245                            },
13246                        } } },
13247                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
13248                            .fcvtnu = .{
13249                                .Rd = d.alias.encode(.{ .V = true }),
13250                                .Rn = n.alias.encode(.{ .V = true }),
13251                                .sz = .fromScalarSize(elem_size),
13252                            },
13253                        } } },
13254                    }
13255                },
13256            },
13257            .vector => |arrangement| {
13258                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13259                switch (arrangement.elemSize()) {
13260                    else => unreachable,
13261                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13262                        .fcvtnu = .{
13263                            .Rd = d.alias.encode(.{ .V = true }),
13264                            .Rn = n.alias.encode(.{ .V = true }),
13265                            .Q = arrangement.size(),
13266                        },
13267                    } } },
13268                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13269                        .fcvtnu = .{
13270                            .Rd = d.alias.encode(.{ .V = true }),
13271                            .Rn = n.alias.encode(.{ .V = true }),
13272                            .sz = arrangement.elemSz(),
13273                            .Q = arrangement.size(),
13274                        },
13275                    } } },
13276                }
13277            },
13278        }
13279    }
13280    /// C7.2.84 FCVTPS (vector)
13281    /// C7.2.85 FCVTPS (scalar)
13282    pub fn fcvtps(d: Register, n: Register) Instruction {
13283        switch (d.format) {
13284            else => unreachable,
13285            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13286                .fcvtps = .{
13287                    .Rd = d.alias.encode(.{}),
13288                    .Rn = n.alias.encode(.{ .V = true }),
13289                    .ftype = .fromScalarSize(n.format.scalar),
13290                    .sf = sf,
13291                },
13292            } } },
13293            .scalar => |elem_size| switch (n.format) {
13294                else => unreachable,
13295                .scalar => |ftype| {
13296                    assert(ftype == elem_size);
13297                    switch (elem_size) {
13298                        else => unreachable,
13299                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
13300                            .fcvtps = .{
13301                                .Rd = d.alias.encode(.{ .V = true }),
13302                                .Rn = n.alias.encode(.{ .V = true }),
13303                            },
13304                        } } },
13305                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
13306                            .fcvtps = .{
13307                                .Rd = d.alias.encode(.{ .V = true }),
13308                                .Rn = n.alias.encode(.{ .V = true }),
13309                                .sz = .fromScalarSize(elem_size),
13310                            },
13311                        } } },
13312                    }
13313                },
13314            },
13315            .vector => |arrangement| {
13316                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13317                switch (arrangement.elemSize()) {
13318                    else => unreachable,
13319                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13320                        .fcvtps = .{
13321                            .Rd = d.alias.encode(.{ .V = true }),
13322                            .Rn = n.alias.encode(.{ .V = true }),
13323                            .Q = arrangement.size(),
13324                        },
13325                    } } },
13326                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13327                        .fcvtps = .{
13328                            .Rd = d.alias.encode(.{ .V = true }),
13329                            .Rn = n.alias.encode(.{ .V = true }),
13330                            .sz = arrangement.elemSz(),
13331                            .Q = arrangement.size(),
13332                        },
13333                    } } },
13334                }
13335            },
13336        }
13337    }
13338    /// C7.2.86 FCVTPU (vector)
13339    /// C7.2.87 FCVTPU (scalar)
13340    pub fn fcvtpu(d: Register, n: Register) Instruction {
13341        switch (d.format) {
13342            else => unreachable,
13343            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13344                .fcvtpu = .{
13345                    .Rd = d.alias.encode(.{}),
13346                    .Rn = n.alias.encode(.{ .V = true }),
13347                    .ftype = .fromScalarSize(n.format.scalar),
13348                    .sf = sf,
13349                },
13350            } } },
13351            .scalar => |elem_size| switch (n.format) {
13352                else => unreachable,
13353                .scalar => |ftype| {
13354                    assert(ftype == elem_size);
13355                    switch (elem_size) {
13356                        else => unreachable,
13357                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
13358                            .fcvtpu = .{
13359                                .Rd = d.alias.encode(.{ .V = true }),
13360                                .Rn = n.alias.encode(.{ .V = true }),
13361                            },
13362                        } } },
13363                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
13364                            .fcvtpu = .{
13365                                .Rd = d.alias.encode(.{ .V = true }),
13366                                .Rn = n.alias.encode(.{ .V = true }),
13367                                .sz = .fromScalarSize(elem_size),
13368                            },
13369                        } } },
13370                    }
13371                },
13372            },
13373            .vector => |arrangement| {
13374                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13375                switch (arrangement.elemSize()) {
13376                    else => unreachable,
13377                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13378                        .fcvtpu = .{
13379                            .Rd = d.alias.encode(.{ .V = true }),
13380                            .Rn = n.alias.encode(.{ .V = true }),
13381                            .Q = arrangement.size(),
13382                        },
13383                    } } },
13384                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13385                        .fcvtpu = .{
13386                            .Rd = d.alias.encode(.{ .V = true }),
13387                            .Rn = n.alias.encode(.{ .V = true }),
13388                            .sz = arrangement.elemSz(),
13389                            .Q = arrangement.size(),
13390                        },
13391                    } } },
13392                }
13393            },
13394        }
13395    }
13396    /// C7.2.90 FCVTZS (vector, integer)
13397    /// C7.2.92 FCVTZS (scalar, integer)
13398    pub fn fcvtzs(d: Register, n: Register) Instruction {
13399        switch (d.format) {
13400            else => unreachable,
13401            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13402                .fcvtzs = .{
13403                    .Rd = d.alias.encode(.{}),
13404                    .Rn = n.alias.encode(.{ .V = true }),
13405                    .ftype = .fromScalarSize(n.format.scalar),
13406                    .sf = sf,
13407                },
13408            } } },
13409            .scalar => |elem_size| switch (n.format) {
13410                else => unreachable,
13411                .scalar => |ftype| {
13412                    assert(ftype == elem_size);
13413                    switch (elem_size) {
13414                        else => unreachable,
13415                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
13416                            .fcvtzs = .{
13417                                .Rd = d.alias.encode(.{ .V = true }),
13418                                .Rn = n.alias.encode(.{ .V = true }),
13419                            },
13420                        } } },
13421                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
13422                            .fcvtzs = .{
13423                                .Rd = d.alias.encode(.{ .V = true }),
13424                                .Rn = n.alias.encode(.{ .V = true }),
13425                                .sz = .fromScalarSize(elem_size),
13426                            },
13427                        } } },
13428                    }
13429                },
13430            },
13431            .vector => |arrangement| {
13432                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13433                switch (arrangement.elemSize()) {
13434                    else => unreachable,
13435                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13436                        .fcvtzs = .{
13437                            .Rd = d.alias.encode(.{ .V = true }),
13438                            .Rn = n.alias.encode(.{ .V = true }),
13439                            .Q = arrangement.size(),
13440                        },
13441                    } } },
13442                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13443                        .fcvtzs = .{
13444                            .Rd = d.alias.encode(.{ .V = true }),
13445                            .Rn = n.alias.encode(.{ .V = true }),
13446                            .sz = arrangement.elemSz(),
13447                            .Q = arrangement.size(),
13448                        },
13449                    } } },
13450                }
13451            },
13452        }
13453    }
13454    /// C7.2.94 FCVTZU (vector, integer)
13455    /// C7.2.96 FCVTZU (scalar, integer)
13456    pub fn fcvtzu(d: Register, n: Register) Instruction {
13457        switch (d.format) {
13458            else => unreachable,
13459            .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13460                .fcvtzu = .{
13461                    .Rd = d.alias.encode(.{}),
13462                    .Rn = n.alias.encode(.{ .V = true }),
13463                    .ftype = .fromScalarSize(n.format.scalar),
13464                    .sf = sf,
13465                },
13466            } } },
13467            .scalar => |elem_size| switch (n.format) {
13468                else => unreachable,
13469                .scalar => |ftype| {
13470                    assert(ftype == elem_size);
13471                    switch (elem_size) {
13472                        else => unreachable,
13473                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
13474                            .fcvtzu = .{
13475                                .Rd = d.alias.encode(.{ .V = true }),
13476                                .Rn = n.alias.encode(.{ .V = true }),
13477                            },
13478                        } } },
13479                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
13480                            .fcvtzu = .{
13481                                .Rd = d.alias.encode(.{ .V = true }),
13482                                .Rn = n.alias.encode(.{ .V = true }),
13483                                .sz = .fromScalarSize(elem_size),
13484                            },
13485                        } } },
13486                    }
13487                },
13488            },
13489            .vector => |arrangement| {
13490                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13491                switch (arrangement.elemSize()) {
13492                    else => unreachable,
13493                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13494                        .fcvtzu = .{
13495                            .Rd = d.alias.encode(.{ .V = true }),
13496                            .Rn = n.alias.encode(.{ .V = true }),
13497                            .Q = arrangement.size(),
13498                        },
13499                    } } },
13500                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13501                        .fcvtzu = .{
13502                            .Rd = d.alias.encode(.{ .V = true }),
13503                            .Rn = n.alias.encode(.{ .V = true }),
13504                            .sz = arrangement.elemSz(),
13505                            .Q = arrangement.size(),
13506                        },
13507                    } } },
13508                }
13509            },
13510        }
13511    }
13512    /// C7.2.98 FDIV (scalar)
13513    pub fn fdiv(d: Register, n: Register, m: Register) Instruction {
13514        const ftype = d.format.scalar;
13515        assert(n.format.scalar == ftype and m.format.scalar == ftype);
13516        return .{ .data_processing_vector = .{ .float_data_processing_two_source = .{
13517            .fdiv = .{
13518                .Rd = d.alias.encode(.{ .V = true }),
13519                .Rn = n.alias.encode(.{ .V = true }),
13520                .Rm = m.alias.encode(.{ .V = true }),
13521                .ftype = .fromScalarSize(ftype),
13522            },
13523        } } };
13524    }
13525    /// C7.2.99 FJCVTZS
13526    pub fn fjcvtzs(d: Register, n: Register) Instruction {
13527        assert(d.format.general == .word);
13528        assert(n.format.scalar == .double);
13529        return .{ .data_processing_vector = .{ .convert_float_integer = .{
13530            .fjcvtzs = .{
13531                .Rd = d.alias.encode(.{}),
13532                .Rn = n.alias.encode(.{ .V = true }),
13533            },
13534        } } };
13535    }
13536    /// C7.2.100 FMADD
13537    pub fn fmadd(d: Register, n: Register, m: Register, a: Register) Instruction {
13538        const ftype = d.format.scalar;
13539        assert(n.format.scalar == ftype and m.format.scalar == ftype and a.format.scalar == ftype);
13540        return .{ .data_processing_vector = .{ .float_data_processing_three_source = .{
13541            .fmadd = .{
13542                .Rd = d.alias.encode(.{ .V = true }),
13543                .Rn = n.alias.encode(.{ .V = true }),
13544                .Rm = m.alias.encode(.{ .V = true }),
13545                .Ra = a.alias.encode(.{ .V = true }),
13546                .ftype = .fromScalarSize(ftype),
13547            },
13548        } } };
13549    }
13550    /// C7.2.102 FMAX (scalar)
13551    pub fn fmax(d: Register, n: Register, m: Register) Instruction {
13552        const ftype = d.format.scalar;
13553        assert(n.format.scalar == ftype and m.format.scalar == ftype);
13554        return .{ .data_processing_vector = .{ .float_data_processing_two_source = .{
13555            .fmax = .{
13556                .Rd = d.alias.encode(.{ .V = true }),
13557                .Rn = n.alias.encode(.{ .V = true }),
13558                .Rm = m.alias.encode(.{ .V = true }),
13559                .ftype = .fromScalarSize(ftype),
13560            },
13561        } } };
13562    }
13563    /// C7.2.104 FMAXNM (scalar)
13564    pub fn fmaxnm(d: Register, n: Register, m: Register) Instruction {
13565        const ftype = d.format.scalar;
13566        assert(n.format.scalar == ftype and m.format.scalar == ftype);
13567        return .{ .data_processing_vector = .{ .float_data_processing_two_source = .{
13568            .fmaxnm = .{
13569                .Rd = d.alias.encode(.{ .V = true }),
13570                .Rn = n.alias.encode(.{ .V = true }),
13571                .Rm = m.alias.encode(.{ .V = true }),
13572                .ftype = .fromScalarSize(ftype),
13573            },
13574        } } };
13575    }
13576    /// C7.2.112 FMIN (scalar)
13577    pub fn fmin(d: Register, n: Register, m: Register) Instruction {
13578        const ftype = d.format.scalar;
13579        assert(n.format.scalar == ftype and m.format.scalar == ftype);
13580        return .{ .data_processing_vector = .{ .float_data_processing_two_source = .{
13581            .fmin = .{
13582                .Rd = d.alias.encode(.{ .V = true }),
13583                .Rn = n.alias.encode(.{ .V = true }),
13584                .Rm = m.alias.encode(.{ .V = true }),
13585                .ftype = .fromScalarSize(ftype),
13586            },
13587        } } };
13588    }
13589    /// C7.2.114 FMINNM (scalar)
13590    pub fn fminnm(d: Register, n: Register, m: Register) Instruction {
13591        const ftype = d.format.scalar;
13592        assert(n.format.scalar == ftype and m.format.scalar == ftype);
13593        return .{ .data_processing_vector = .{ .float_data_processing_two_source = .{
13594            .fminnm = .{
13595                .Rd = d.alias.encode(.{ .V = true }),
13596                .Rn = n.alias.encode(.{ .V = true }),
13597                .Rm = m.alias.encode(.{ .V = true }),
13598                .ftype = .fromScalarSize(ftype),
13599            },
13600        } } };
13601    }
13602    /// C7.2.129 FMOV (vector, immediate)
13603    /// C7.2.130 FMOV (register)
13604    /// C7.2.131 FMOV (general)
13605    /// C7.2.132 FMOV (scalar, immediate)
13606    pub fn fmov(d: Register, form: union(enum) { immediate: f16, register: Register }) Instruction {
13607        switch (form) {
13608            .immediate => |immediate| {
13609                const repr: std.math.FloatRepr(f16) = @bitCast(immediate);
13610                const imm: DataProcessingVector.FloatImmediate.Fmov.Imm8 = .{
13611                    .mantissa = @intCast(@shrExact(repr.mantissa, 6)),
13612                    .exponent = @intCast(repr.exponent.unbias() - 1),
13613                    .sign = repr.sign,
13614                };
13615                switch (d.format) {
13616                    else => unreachable,
13617                    .scalar => |ftype| return .{ .data_processing_vector = .{ .float_immediate = .{
13618                        .fmov = .{
13619                            .Rd = d.alias.encode(.{ .V = true }),
13620                            .imm8 = imm,
13621                            .ftype = .fromScalarSize(ftype),
13622                        },
13623                    } } },
13624                    .vector => |arrangement| {
13625                        const elem_size = arrangement.elemSize();
13626                        assert(arrangement.len() > 1);
13627                        const mod_imm = imm.toModified();
13628                        return .{ .data_processing_vector = .{ .simd_modified_immediate = .{
13629                            .fmov = .{
13630                                .Rd = d.alias.encode(.{ .V = true }),
13631                                .imm5 = mod_imm.imm5,
13632                                .o2 = switch (elem_size) {
13633                                    .byte => unreachable,
13634                                    .half => 0b1,
13635                                    .single, .double => 0b0,
13636                                },
13637                                .imm3 = mod_imm.imm3,
13638                                .op = switch (elem_size) {
13639                                    .byte => unreachable,
13640                                    .half, .single => 0b0,
13641                                    .double => 0b1,
13642                                },
13643                                .Q = arrangement.size(),
13644                            },
13645                        } } };
13646                    },
13647                }
13648            },
13649            .register => |n| switch (d.format) {
13650                else => unreachable,
13651                .general => |sf| switch (n.format) {
13652                    else => unreachable,
13653                    .scalar => |ftype| {
13654                        switch (ftype) {
13655                            else => unreachable,
13656                            .half => {},
13657                            .single => assert(sf == .word),
13658                            .double => assert(sf == .doubleword),
13659                        }
13660                        return .{ .data_processing_vector = .{ .convert_float_integer = .{
13661                            .fmov = .{
13662                                .Rd = d.alias.encode(.{}),
13663                                .Rn = n.alias.encode(.{ .V = true }),
13664                                .opcode = .float_to_integer,
13665                                .rmode = .@"0",
13666                                .ftype = .fromScalarSize(ftype),
13667                                .sf = sf,
13668                            },
13669                        } } };
13670                    },
13671                    .element => |element| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13672                        .fmov = .{
13673                            .Rd = d.alias.encode(.{}),
13674                            .Rn = n.alias.encode(.{ .V = true }),
13675                            .opcode = .float_to_integer,
13676                            .rmode = switch (element.index) {
13677                                else => unreachable,
13678                                1 => .@"1",
13679                            },
13680                            .ftype = switch (element.size) {
13681                                else => unreachable,
13682                                .double => .quad,
13683                            },
13684                            .sf = sf,
13685                        },
13686                    } } },
13687                },
13688                .scalar => |ftype| switch (n.format) {
13689                    else => unreachable,
13690                    .general => |sf| {
13691                        switch (ftype) {
13692                            else => unreachable,
13693                            .half => {},
13694                            .single => assert(sf == .word),
13695                            .double => assert(sf == .doubleword),
13696                        }
13697                        return .{ .data_processing_vector = .{ .convert_float_integer = .{
13698                            .fmov = .{
13699                                .Rd = d.alias.encode(.{ .V = true }),
13700                                .Rn = n.alias.encode(.{}),
13701                                .opcode = .integer_to_float,
13702                                .rmode = .@"0",
13703                                .ftype = .fromScalarSize(ftype),
13704                                .sf = sf,
13705                            },
13706                        } } };
13707                    },
13708                    .scalar => {
13709                        assert(n.format.scalar == ftype);
13710                        return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
13711                            .fmov = .{
13712                                .Rd = d.alias.encode(.{ .V = true }),
13713                                .Rn = n.alias.encode(.{ .V = true }),
13714                                .ftype = .fromScalarSize(ftype),
13715                            },
13716                        } } };
13717                    },
13718                },
13719                .element => |element| switch (n.format) {
13720                    else => unreachable,
13721                    .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
13722                        .fmov = .{
13723                            .Rd = d.alias.encode(.{ .V = true }),
13724                            .Rn = n.alias.encode(.{}),
13725                            .opcode = .integer_to_float,
13726                            .rmode = switch (element.index) {
13727                                else => unreachable,
13728                                1 => .@"1",
13729                            },
13730                            .ftype = switch (element.size) {
13731                                else => unreachable,
13732                                .double => .quad,
13733                            },
13734                            .sf = sf,
13735                        },
13736                    } } },
13737                },
13738            },
13739        }
13740    }
13741    /// C7.2.133 FMSUB
13742    pub fn fmsub(d: Register, n: Register, m: Register, a: Register) Instruction {
13743        const ftype = d.format.scalar;
13744        assert(n.format.scalar == ftype and m.format.scalar == ftype and a.format.scalar == ftype);
13745        return .{ .data_processing_vector = .{ .float_data_processing_three_source = .{
13746            .fmsub = .{
13747                .Rd = d.alias.encode(.{ .V = true }),
13748                .Rn = n.alias.encode(.{ .V = true }),
13749                .Rm = m.alias.encode(.{ .V = true }),
13750                .Ra = a.alias.encode(.{ .V = true }),
13751                .ftype = .fromScalarSize(ftype),
13752            },
13753        } } };
13754    }
13755    /// C7.2.136 FMUL (scalar)
13756    pub fn fmul(d: Register, n: Register, m: Register) Instruction {
13757        const ftype = d.format.scalar;
13758        assert(n.format.scalar == ftype and m.format.scalar == ftype);
13759        return .{ .data_processing_vector = .{ .float_data_processing_two_source = .{
13760            .fmul = .{
13761                .Rd = d.alias.encode(.{ .V = true }),
13762                .Rn = n.alias.encode(.{ .V = true }),
13763                .Rm = m.alias.encode(.{ .V = true }),
13764                .ftype = .fromScalarSize(ftype),
13765            },
13766        } } };
13767    }
13768    /// C7.2.139 FNEG (vector)
13769    /// C7.2.140 FNEG (scalar)
13770    pub fn fneg(d: Register, n: Register) Instruction {
13771        switch (d.format) {
13772            else => unreachable,
13773            .vector => |arrangement| {
13774                assert(n.format.vector == arrangement);
13775                switch (arrangement.elemSize()) {
13776                    else => unreachable,
13777                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13778                        .fneg = .{
13779                            .Rd = d.alias.encode(.{ .V = true }),
13780                            .Rn = n.alias.encode(.{ .V = true }),
13781                            .Q = arrangement.size(),
13782                        },
13783                    } } },
13784                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13785                        .fneg = .{
13786                            .Rd = d.alias.encode(.{ .V = true }),
13787                            .Rn = n.alias.encode(.{ .V = true }),
13788                            .sz = arrangement.elemSz(),
13789                            .Q = arrangement.size(),
13790                        },
13791                    } } },
13792                }
13793            },
13794            .scalar => |ftype| {
13795                assert(n.format.scalar == ftype);
13796                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
13797                    .fneg = .{
13798                        .Rd = d.alias.encode(.{ .V = true }),
13799                        .Rn = n.alias.encode(.{ .V = true }),
13800                        .ftype = .fromScalarSize(ftype),
13801                    },
13802                } } };
13803            },
13804        }
13805    }
13806    /// C7.2.141 FNMADD
13807    pub fn fnmadd(d: Register, n: Register, m: Register, a: Register) Instruction {
13808        const ftype = d.format.scalar;
13809        assert(n.format.scalar == ftype and m.format.scalar == ftype and a.format.scalar == ftype);
13810        return .{ .data_processing_vector = .{ .float_data_processing_three_source = .{
13811            .fnmadd = .{
13812                .Rd = d.alias.encode(.{ .V = true }),
13813                .Rn = n.alias.encode(.{ .V = true }),
13814                .Rm = m.alias.encode(.{ .V = true }),
13815                .Ra = a.alias.encode(.{ .V = true }),
13816                .ftype = .fromScalarSize(ftype),
13817            },
13818        } } };
13819    }
13820    /// C7.2.142 FNMSUB
13821    pub fn fnmsub(d: Register, n: Register, m: Register, a: Register) Instruction {
13822        const ftype = d.format.scalar;
13823        assert(n.format.scalar == ftype and m.format.scalar == ftype and a.format.scalar == ftype);
13824        return .{ .data_processing_vector = .{ .float_data_processing_three_source = .{
13825            .fnmsub = .{
13826                .Rd = d.alias.encode(.{ .V = true }),
13827                .Rn = n.alias.encode(.{ .V = true }),
13828                .Rm = m.alias.encode(.{ .V = true }),
13829                .Ra = a.alias.encode(.{ .V = true }),
13830                .ftype = .fromScalarSize(ftype),
13831            },
13832        } } };
13833    }
13834    /// C7.2.143 FNMUL (scalar)
13835    pub fn fnmul(d: Register, n: Register, m: Register) Instruction {
13836        const ftype = d.format.scalar;
13837        assert(n.format.scalar == ftype and m.format.scalar == ftype);
13838        return .{ .data_processing_vector = .{ .float_data_processing_two_source = .{
13839            .fnmul = .{
13840                .Rd = d.alias.encode(.{ .V = true }),
13841                .Rn = n.alias.encode(.{ .V = true }),
13842                .Rm = m.alias.encode(.{ .V = true }),
13843                .ftype = .fromScalarSize(ftype),
13844            },
13845        } } };
13846    }
13847    /// C7.2.155 FRINTA (vector)
13848    /// C7.2.156 FRINTA (scalar)
13849    pub fn frinta(d: Register, n: Register) Instruction {
13850        switch (d.format) {
13851            else => unreachable,
13852            .vector => |arrangement| {
13853                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13854                switch (arrangement.elemSize()) {
13855                    else => unreachable,
13856                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13857                        .frinta = .{
13858                            .Rd = d.alias.encode(.{ .V = true }),
13859                            .Rn = n.alias.encode(.{ .V = true }),
13860                            .Q = arrangement.size(),
13861                        },
13862                    } } },
13863                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13864                        .frinta = .{
13865                            .Rd = d.alias.encode(.{ .V = true }),
13866                            .Rn = n.alias.encode(.{ .V = true }),
13867                            .sz = arrangement.elemSz(),
13868                            .Q = arrangement.size(),
13869                        },
13870                    } } },
13871                }
13872            },
13873            .scalar => |ftype| {
13874                assert(n.format.scalar == ftype);
13875                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
13876                    .frinta = .{
13877                        .Rd = d.alias.encode(.{ .V = true }),
13878                        .Rn = n.alias.encode(.{ .V = true }),
13879                        .ftype = .fromScalarSize(ftype),
13880                    },
13881                } } };
13882            },
13883        }
13884    }
13885    /// C7.2.157 FRINTI (vector)
13886    /// C7.2.158 FRINTI (scalar)
13887    pub fn frinti(d: Register, n: Register) Instruction {
13888        switch (d.format) {
13889            else => unreachable,
13890            .vector => |arrangement| {
13891                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13892                switch (arrangement.elemSize()) {
13893                    else => unreachable,
13894                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13895                        .frinti = .{
13896                            .Rd = d.alias.encode(.{ .V = true }),
13897                            .Rn = n.alias.encode(.{ .V = true }),
13898                            .Q = arrangement.size(),
13899                        },
13900                    } } },
13901                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13902                        .frinti = .{
13903                            .Rd = d.alias.encode(.{ .V = true }),
13904                            .Rn = n.alias.encode(.{ .V = true }),
13905                            .sz = arrangement.elemSz(),
13906                            .Q = arrangement.size(),
13907                        },
13908                    } } },
13909                }
13910            },
13911            .scalar => |ftype| {
13912                assert(n.format.scalar == ftype);
13913                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
13914                    .frinti = .{
13915                        .Rd = d.alias.encode(.{ .V = true }),
13916                        .Rn = n.alias.encode(.{ .V = true }),
13917                        .ftype = .fromScalarSize(ftype),
13918                    },
13919                } } };
13920            },
13921        }
13922    }
13923    /// C7.2.159 FRINTM (vector)
13924    /// C7.2.160 FRINTM (scalar)
13925    pub fn frintm(d: Register, n: Register) Instruction {
13926        switch (d.format) {
13927            else => unreachable,
13928            .vector => |arrangement| {
13929                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13930                switch (arrangement.elemSize()) {
13931                    else => unreachable,
13932                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13933                        .frintm = .{
13934                            .Rd = d.alias.encode(.{ .V = true }),
13935                            .Rn = n.alias.encode(.{ .V = true }),
13936                            .Q = arrangement.size(),
13937                        },
13938                    } } },
13939                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13940                        .frintm = .{
13941                            .Rd = d.alias.encode(.{ .V = true }),
13942                            .Rn = n.alias.encode(.{ .V = true }),
13943                            .sz = arrangement.elemSz(),
13944                            .Q = arrangement.size(),
13945                        },
13946                    } } },
13947                }
13948            },
13949            .scalar => |ftype| {
13950                assert(n.format.scalar == ftype);
13951                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
13952                    .frintm = .{
13953                        .Rd = d.alias.encode(.{ .V = true }),
13954                        .Rn = n.alias.encode(.{ .V = true }),
13955                        .ftype = .fromScalarSize(ftype),
13956                    },
13957                } } };
13958            },
13959        }
13960    }
13961    /// C7.2.161 FRINTN (vector)
13962    /// C7.2.162 FRINTN (scalar)
13963    pub fn frintn(d: Register, n: Register) Instruction {
13964        switch (d.format) {
13965            else => unreachable,
13966            .vector => |arrangement| {
13967                assert(arrangement != .@"1d" and n.format.vector == arrangement);
13968                switch (arrangement.elemSize()) {
13969                    else => unreachable,
13970                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
13971                        .frintn = .{
13972                            .Rd = d.alias.encode(.{ .V = true }),
13973                            .Rn = n.alias.encode(.{ .V = true }),
13974                            .Q = arrangement.size(),
13975                        },
13976                    } } },
13977                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
13978                        .frintn = .{
13979                            .Rd = d.alias.encode(.{ .V = true }),
13980                            .Rn = n.alias.encode(.{ .V = true }),
13981                            .sz = arrangement.elemSz(),
13982                            .Q = arrangement.size(),
13983                        },
13984                    } } },
13985                }
13986            },
13987            .scalar => |ftype| {
13988                assert(n.format.scalar == ftype);
13989                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
13990                    .frintn = .{
13991                        .Rd = d.alias.encode(.{ .V = true }),
13992                        .Rn = n.alias.encode(.{ .V = true }),
13993                        .ftype = .fromScalarSize(ftype),
13994                    },
13995                } } };
13996            },
13997        }
13998    }
13999    /// C7.2.163 FRINTP (vector)
14000    /// C7.2.164 FRINTP (scalar)
14001    pub fn frintp(d: Register, n: Register) Instruction {
14002        switch (d.format) {
14003            else => unreachable,
14004            .vector => |arrangement| {
14005                assert(arrangement != .@"1d" and n.format.vector == arrangement);
14006                switch (arrangement.elemSize()) {
14007                    else => unreachable,
14008                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
14009                        .frintp = .{
14010                            .Rd = d.alias.encode(.{ .V = true }),
14011                            .Rn = n.alias.encode(.{ .V = true }),
14012                            .Q = arrangement.size(),
14013                        },
14014                    } } },
14015                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
14016                        .frintp = .{
14017                            .Rd = d.alias.encode(.{ .V = true }),
14018                            .Rn = n.alias.encode(.{ .V = true }),
14019                            .sz = arrangement.elemSz(),
14020                            .Q = arrangement.size(),
14021                        },
14022                    } } },
14023                }
14024            },
14025            .scalar => |ftype| {
14026                assert(n.format.scalar == ftype);
14027                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
14028                    .frintp = .{
14029                        .Rd = d.alias.encode(.{ .V = true }),
14030                        .Rn = n.alias.encode(.{ .V = true }),
14031                        .ftype = .fromScalarSize(ftype),
14032                    },
14033                } } };
14034            },
14035        }
14036    }
14037    /// C7.2.165 FRINTX (vector)
14038    /// C7.2.166 FRINTX (scalar)
14039    pub fn frintx(d: Register, n: Register) Instruction {
14040        switch (d.format) {
14041            else => unreachable,
14042            .vector => |arrangement| {
14043                assert(arrangement != .@"1d" and n.format.vector == arrangement);
14044                switch (arrangement.elemSize()) {
14045                    else => unreachable,
14046                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
14047                        .frintx = .{
14048                            .Rd = d.alias.encode(.{ .V = true }),
14049                            .Rn = n.alias.encode(.{ .V = true }),
14050                            .Q = arrangement.size(),
14051                        },
14052                    } } },
14053                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
14054                        .frintx = .{
14055                            .Rd = d.alias.encode(.{ .V = true }),
14056                            .Rn = n.alias.encode(.{ .V = true }),
14057                            .sz = arrangement.elemSz(),
14058                            .Q = arrangement.size(),
14059                        },
14060                    } } },
14061                }
14062            },
14063            .scalar => |ftype| {
14064                assert(n.format.scalar == ftype);
14065                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
14066                    .frintx = .{
14067                        .Rd = d.alias.encode(.{ .V = true }),
14068                        .Rn = n.alias.encode(.{ .V = true }),
14069                        .ftype = .fromScalarSize(ftype),
14070                    },
14071                } } };
14072            },
14073        }
14074    }
14075    /// C7.2.167 FRINTZ (vector)
14076    /// C7.2.168 FRINTZ (scalar)
14077    pub fn frintz(d: Register, n: Register) Instruction {
14078        switch (d.format) {
14079            else => unreachable,
14080            .vector => |arrangement| {
14081                assert(arrangement != .@"1d" and n.format.vector == arrangement);
14082                switch (arrangement.elemSize()) {
14083                    else => unreachable,
14084                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
14085                        .frintz = .{
14086                            .Rd = d.alias.encode(.{ .V = true }),
14087                            .Rn = n.alias.encode(.{ .V = true }),
14088                            .Q = arrangement.size(),
14089                        },
14090                    } } },
14091                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
14092                        .frintz = .{
14093                            .Rd = d.alias.encode(.{ .V = true }),
14094                            .Rn = n.alias.encode(.{ .V = true }),
14095                            .sz = arrangement.elemSz(),
14096                            .Q = arrangement.size(),
14097                        },
14098                    } } },
14099                }
14100            },
14101            .scalar => |ftype| {
14102                assert(n.format.scalar == ftype);
14103                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
14104                    .frintz = .{
14105                        .Rd = d.alias.encode(.{ .V = true }),
14106                        .Rn = n.alias.encode(.{ .V = true }),
14107                        .ftype = .fromScalarSize(ftype),
14108                    },
14109                } } };
14110            },
14111        }
14112    }
14113    /// C7.2.171 FSQRT (vector)
14114    /// C7.2.172 FSQRT (scalar)
14115    pub fn fsqrt(d: Register, n: Register) Instruction {
14116        switch (d.format) {
14117            else => unreachable,
14118            .vector => |arrangement| {
14119                assert(n.format.vector == arrangement);
14120                switch (arrangement.elemSize()) {
14121                    else => unreachable,
14122                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
14123                        .fsqrt = .{
14124                            .Rd = d.alias.encode(.{ .V = true }),
14125                            .Rn = n.alias.encode(.{ .V = true }),
14126                            .Q = arrangement.size(),
14127                        },
14128                    } } },
14129                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
14130                        .fsqrt = .{
14131                            .Rd = d.alias.encode(.{ .V = true }),
14132                            .Rn = n.alias.encode(.{ .V = true }),
14133                            .sz = arrangement.elemSz(),
14134                            .Q = arrangement.size(),
14135                        },
14136                    } } },
14137                }
14138            },
14139            .scalar => |ftype| {
14140                assert(n.format.scalar == ftype);
14141                return .{ .data_processing_vector = .{ .float_data_processing_one_source = .{
14142                    .fsqrt = .{
14143                        .Rd = d.alias.encode(.{ .V = true }),
14144                        .Rn = n.alias.encode(.{ .V = true }),
14145                        .ftype = .fromScalarSize(ftype),
14146                    },
14147                } } };
14148            },
14149        }
14150    }
14151    /// C7.2.174 FSUB (scalar)
14152    pub fn fsub(d: Register, n: Register, m: Register) Instruction {
14153        const ftype = d.format.scalar;
14154        assert(n.format.scalar == ftype and m.format.scalar == ftype);
14155        return .{ .data_processing_vector = .{ .float_data_processing_two_source = .{
14156            .fsub = .{
14157                .Rd = d.alias.encode(.{ .V = true }),
14158                .Rn = n.alias.encode(.{ .V = true }),
14159                .Rm = m.alias.encode(.{ .V = true }),
14160                .ftype = .fromScalarSize(ftype),
14161            },
14162        } } };
14163    }
14164    /// C6.2.126 HINT
14165    pub fn hint(imm: u7) Instruction {
14166        return .{ .branch_exception_generating_system = .{ .hints = .{
14167            .group = .{
14168                .op2 = @truncate(imm >> 0),
14169                .CRm = @intCast(imm >> 3),
14170            },
14171        } } };
14172    }
14173    /// C6.2.127 HLT
14174    pub fn hlt(imm: u16) Instruction {
14175        return .{ .branch_exception_generating_system = .{ .exception_generating = .{
14176            .hlt = .{ .imm16 = imm },
14177        } } };
14178    }
14179    /// C6.2.128 HVC
14180    pub fn hvc(imm: u16) Instruction {
14181        return .{ .branch_exception_generating_system = .{ .exception_generating = .{
14182            .hvc = .{ .imm16 = imm },
14183        } } };
14184    }
14185    /// C7.2.175 INS (element)
14186    /// C7.2.176 INS (general)
14187    pub fn ins(d: Register, n: Register) Instruction {
14188        const elem_size = d.format.element.size;
14189        switch (n.format) {
14190            else => unreachable,
14191            .element => |element| {
14192                assert(elem_size == element.size);
14193                return .{ .data_processing_vector = .{ .simd_copy = .{
14194                    .ins = .{
14195                        .Rd = d.alias.encode(.{ .V = true }),
14196                        .Rn = n.alias.encode(.{ .V = true }),
14197                        .imm4 = .{ .element = element.index << @intCast(@intFromEnum(elem_size)) },
14198                        .imm5 = (@as(u5, d.format.element.index) << 1 | @as(u5, 0b1) << 0) << @intFromEnum(elem_size),
14199                        .op = .element,
14200                    },
14201                } } };
14202            },
14203            .general => |general| {
14204                assert(general == @as(Register.GeneralSize, switch (elem_size) {
14205                    else => unreachable,
14206                    .byte, .half, .single => .word,
14207                    .double => .doubleword,
14208                }));
14209                return .{ .data_processing_vector = .{ .simd_copy = .{
14210                    .ins = .{
14211                        .Rd = d.alias.encode(.{ .V = true }),
14212                        .Rn = n.alias.encode(.{}),
14213                        .imm4 = .{ .general = .general },
14214                        .imm5 = (@as(u5, d.format.element.index) << 1 | @as(u5, 0b1) << 0) << @intFromEnum(elem_size),
14215                        .op = .general,
14216                    },
14217                } } };
14218            },
14219        }
14220    }
14221    /// C6.2.131 ISB
14222    pub fn isb(option: BranchExceptionGeneratingSystem.Barriers.Option) Instruction {
14223        return .{ .branch_exception_generating_system = .{ .barriers = .{
14224            .isb = .{
14225                .CRm = option,
14226            },
14227        } } };
14228    }
14229    /// C6.2.164 LDP
14230    /// C7.2.190 LDP (SIMD&FP)
14231    pub fn ldp(t1: Register, t2: Register, form: union(enum) {
14232        post_index: struct { base: Register, index: i10 },
14233        pre_index: struct { base: Register, index: i10 },
14234        signed_offset: struct { base: Register, offset: i10 = 0 },
14235        base: Register,
14236    }) Instruction {
14237        switch (t1.format) {
14238            else => unreachable,
14239            .general => |sf| {
14240                assert(t2.format.general == sf);
14241                form: switch (form) {
14242                    .post_index => |post_index| {
14243                        assert(post_index.base.format.general == .doubleword);
14244                        return .{ .load_store = .{ .register_pair_post_indexed = .{ .integer = .{
14245                            .ldp = .{
14246                                .Rt = t1.alias.encode(.{}),
14247                                .Rn = post_index.base.alias.encode(.{ .sp = true }),
14248                                .Rt2 = t2.alias.encode(.{}),
14249                                .imm7 = @intCast(@shrExact(post_index.index, @as(u2, 2) + @intFromEnum(sf))),
14250                                .sf = sf,
14251                            },
14252                        } } } };
14253                    },
14254                    .pre_index => |pre_index| {
14255                        assert(pre_index.base.format.general == .doubleword);
14256                        return .{ .load_store = .{ .register_pair_pre_indexed = .{ .integer = .{
14257                            .ldp = .{
14258                                .Rt = t1.alias.encode(.{}),
14259                                .Rn = pre_index.base.alias.encode(.{ .sp = true }),
14260                                .Rt2 = t2.alias.encode(.{}),
14261                                .imm7 = @intCast(@shrExact(pre_index.index, @as(u2, 2) + @intFromEnum(sf))),
14262                                .sf = sf,
14263                            },
14264                        } } } };
14265                    },
14266                    .signed_offset => |signed_offset| {
14267                        assert(signed_offset.base.format.general == .doubleword);
14268                        return .{ .load_store = .{ .register_pair_offset = .{ .integer = .{
14269                            .ldp = .{
14270                                .Rt = t1.alias.encode(.{}),
14271                                .Rn = signed_offset.base.alias.encode(.{ .sp = true }),
14272                                .Rt2 = t2.alias.encode(.{}),
14273                                .imm7 = @intCast(@shrExact(signed_offset.offset, @as(u2, 2) + @intFromEnum(sf))),
14274                                .sf = sf,
14275                            },
14276                        } } } };
14277                    },
14278                    .base => |base| continue :form .{ .signed_offset = .{ .base = base } },
14279                }
14280            },
14281            .scalar => |vs| {
14282                assert(t2.format.scalar == vs);
14283                form: switch (form) {
14284                    .post_index => |post_index| {
14285                        assert(post_index.base.format.general == .doubleword);
14286                        return .{ .load_store = .{ .register_pair_post_indexed = .{ .vector = .{
14287                            .ldp = .{
14288                                .Rt = t1.alias.encode(.{ .V = true }),
14289                                .Rn = post_index.base.alias.encode(.{ .sp = true }),
14290                                .Rt2 = t2.alias.encode(.{ .V = true }),
14291                                .imm7 = @intCast(@shrExact(post_index.index, @intFromEnum(vs))),
14292                                .opc = .encode(vs),
14293                            },
14294                        } } } };
14295                    },
14296                    .signed_offset => |signed_offset| {
14297                        assert(signed_offset.base.format.general == .doubleword);
14298                        return .{ .load_store = .{ .register_pair_offset = .{ .vector = .{
14299                            .ldp = .{
14300                                .Rt = t1.alias.encode(.{ .V = true }),
14301                                .Rn = signed_offset.base.alias.encode(.{ .sp = true }),
14302                                .Rt2 = t2.alias.encode(.{ .V = true }),
14303                                .imm7 = @intCast(@shrExact(signed_offset.offset, @intFromEnum(vs))),
14304                                .opc = .encode(vs),
14305                            },
14306                        } } } };
14307                    },
14308                    .pre_index => |pre_index| {
14309                        assert(pre_index.base.format.general == .doubleword);
14310                        return .{ .load_store = .{ .register_pair_pre_indexed = .{ .vector = .{
14311                            .ldp = .{
14312                                .Rt = t1.alias.encode(.{ .V = true }),
14313                                .Rn = pre_index.base.alias.encode(.{ .sp = true }),
14314                                .Rt2 = t2.alias.encode(.{ .V = true }),
14315                                .imm7 = @intCast(@shrExact(pre_index.index, @intFromEnum(vs))),
14316                                .opc = .encode(vs),
14317                            },
14318                        } } } };
14319                    },
14320                    .base => |base| continue :form .{ .signed_offset = .{ .base = base } },
14321                }
14322            },
14323        }
14324    }
14325    /// C6.2.166 LDR (immediate)
14326    /// C6.2.167 LDR (literal)
14327    /// C6.2.168 LDR (register)
14328    /// C7.2.191 LDR (immediate, SIMD&FP)
14329    /// C7.2.192 LDR (literal, SIMD&FP)
14330    /// C7.2.193 LDR (register, SIMD&FP)
14331    pub fn ldr(t: Register, form: union(enum) {
14332        post_index: struct { base: Register, index: i9 },
14333        pre_index: struct { base: Register, index: i9 },
14334        unsigned_offset: struct { base: Register, offset: u16 = 0 },
14335        base: Register,
14336        literal: i21,
14337        extended_register_explicit: struct {
14338            base: Register,
14339            index: Register,
14340            option: LoadStore.RegisterRegisterOffset.Option,
14341            amount: LoadStore.RegisterRegisterOffset.Extend.Amount,
14342        },
14343        extended_register: struct {
14344            base: Register,
14345            index: Register,
14346            extend: LoadStore.RegisterRegisterOffset.Extend,
14347        },
14348    }) Instruction {
14349        switch (t.format) {
14350            else => unreachable,
14351            .general => |sf| form: switch (form) {
14352                .post_index => |post_index| {
14353                    assert(post_index.base.format.general == .doubleword);
14354                    return .{ .load_store = .{ .register_immediate_post_indexed = .{ .integer = .{
14355                        .ldr = .{
14356                            .Rt = t.alias.encode(.{}),
14357                            .Rn = post_index.base.alias.encode(.{ .sp = true }),
14358                            .imm9 = post_index.index,
14359                            .sf = sf,
14360                        },
14361                    } } } };
14362                },
14363                .pre_index => |pre_index| {
14364                    assert(pre_index.base.format.general == .doubleword);
14365                    return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .integer = .{
14366                        .ldr = .{
14367                            .Rt = t.alias.encode(.{}),
14368                            .Rn = pre_index.base.alias.encode(.{ .sp = true }),
14369                            .imm9 = pre_index.index,
14370                            .sf = sf,
14371                        },
14372                    } } } };
14373                },
14374                .unsigned_offset => |unsigned_offset| {
14375                    assert(unsigned_offset.base.format.general == .doubleword);
14376                    return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
14377                        .ldr = .{
14378                            .Rt = t.alias.encode(.{}),
14379                            .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
14380                            .imm12 = @intCast(@shrExact(unsigned_offset.offset, @as(u2, 2) + @intFromEnum(sf))),
14381                            .sf = sf,
14382                        },
14383                    } } } };
14384                },
14385                .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
14386                .literal => |offset| return .{ .load_store = .{ .register_literal = .{ .integer = .{
14387                    .ldr = .{
14388                        .Rt = t.alias.encode(.{}),
14389                        .imm19 = @intCast(@shrExact(offset, 2)),
14390                        .sf = sf,
14391                    },
14392                } } } },
14393                .extended_register_explicit => |extended_register_explicit| {
14394                    assert(extended_register_explicit.base.format.general == .doubleword and
14395                        extended_register_explicit.index.format.general == extended_register_explicit.option.sf());
14396                    return .{ .load_store = .{ .register_register_offset = .{ .integer = .{
14397                        .ldr = .{
14398                            .Rt = t.alias.encode(.{}),
14399                            .Rn = extended_register_explicit.base.alias.encode(.{ .sp = true }),
14400                            .S = switch (sf) {
14401                                .word => switch (extended_register_explicit.amount) {
14402                                    0 => false,
14403                                    2 => true,
14404                                    else => unreachable,
14405                                },
14406                                .doubleword => switch (extended_register_explicit.amount) {
14407                                    0 => false,
14408                                    3 => true,
14409                                    else => unreachable,
14410                                },
14411                            },
14412                            .option = extended_register_explicit.option,
14413                            .Rm = extended_register_explicit.index.alias.encode(.{}),
14414                            .sf = sf,
14415                        },
14416                    } } } };
14417                },
14418                .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
14419                    .base = extended_register.base,
14420                    .index = extended_register.index,
14421                    .option = extended_register.extend,
14422                    .amount = switch (extended_register.extend) {
14423                        .uxtw, .lsl, .sxtw, .sxtx => |amount| amount,
14424                    },
14425                } },
14426            },
14427            .scalar => |vs| form: switch (form) {
14428                .post_index => |post_index| {
14429                    assert(post_index.base.format.general == .doubleword);
14430                    return .{ .load_store = .{ .register_immediate_post_indexed = .{ .vector = .{
14431                        .ldr = .{
14432                            .Rt = t.alias.encode(.{ .V = true }),
14433                            .Rn = post_index.base.alias.encode(.{ .sp = true }),
14434                            .imm9 = post_index.index,
14435                            .opc1 = .encode(vs),
14436                            .size = .encode(vs),
14437                        },
14438                    } } } };
14439                },
14440                .pre_index => |pre_index| {
14441                    assert(pre_index.base.format.general == .doubleword);
14442                    return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .vector = .{
14443                        .ldr = .{
14444                            .Rt = t.alias.encode(.{ .V = true }),
14445                            .Rn = pre_index.base.alias.encode(.{ .sp = true }),
14446                            .imm9 = pre_index.index,
14447                            .opc1 = .encode(vs),
14448                            .size = .encode(vs),
14449                        },
14450                    } } } };
14451                },
14452                .unsigned_offset => |unsigned_offset| {
14453                    assert(unsigned_offset.base.format.general == .doubleword);
14454                    return .{ .load_store = .{ .register_unsigned_immediate = .{ .vector = .{
14455                        .ldr = .{
14456                            .Rt = t.alias.encode(.{ .V = true }),
14457                            .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
14458                            .imm12 = @intCast(@shrExact(unsigned_offset.offset, @intFromEnum(vs))),
14459                            .opc1 = .encode(vs),
14460                            .size = .encode(vs),
14461                        },
14462                    } } } };
14463                },
14464                .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
14465                .literal => |offset| return .{ .load_store = .{ .register_literal = .{ .vector = .{
14466                    .ldr = .{
14467                        .Rt = t.alias.encode(.{ .V = true }),
14468                        .imm19 = @intCast(@shrExact(offset, 2)),
14469                        .opc = .encode(vs),
14470                    },
14471                } } } },
14472                .extended_register_explicit => |extended_register_explicit| {
14473                    assert(extended_register_explicit.base.format.general == .doubleword and
14474                        extended_register_explicit.index.format.general == extended_register_explicit.option.sf());
14475                    return .{ .load_store = .{ .register_register_offset = .{ .vector = .{
14476                        .ldr = .{
14477                            .Rt = t.alias.encode(.{ .V = true }),
14478                            .Rn = extended_register_explicit.base.alias.encode(.{ .sp = true }),
14479                            .S = switch (vs) {
14480                                .byte => switch (extended_register_explicit.amount) {
14481                                    0 => false,
14482                                    else => unreachable,
14483                                },
14484                                .half => switch (extended_register_explicit.amount) {
14485                                    0 => false,
14486                                    1 => true,
14487                                    else => unreachable,
14488                                },
14489                                .single => switch (extended_register_explicit.amount) {
14490                                    0 => false,
14491                                    2 => true,
14492                                    else => unreachable,
14493                                },
14494                                .double => switch (extended_register_explicit.amount) {
14495                                    0 => false,
14496                                    3 => true,
14497                                    else => unreachable,
14498                                },
14499                                .quad => switch (extended_register_explicit.amount) {
14500                                    0 => false,
14501                                    4 => true,
14502                                    else => unreachable,
14503                                },
14504                            },
14505                            .option = extended_register_explicit.option,
14506                            .Rm = extended_register_explicit.index.alias.encode(.{}),
14507                            .opc1 = .encode(vs),
14508                            .size = .encode(vs),
14509                        },
14510                    } } } };
14511                },
14512                .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
14513                    .base = extended_register.base,
14514                    .index = extended_register.index,
14515                    .option = extended_register.extend,
14516                    .amount = switch (extended_register.extend) {
14517                        .uxtw, .lsl, .sxtw, .sxtx => |amount| amount,
14518                    },
14519                } },
14520            },
14521        }
14522    }
14523    /// C6.2.170 LDRB (immediate)
14524    /// C6.2.171 LDRB (register)
14525    pub fn ldrb(t: Register, form: union(enum) {
14526        post_index: struct { base: Register, index: i9 },
14527        pre_index: struct { base: Register, index: i9 },
14528        unsigned_offset: struct { base: Register, offset: u12 = 0 },
14529        base: Register,
14530        extended_register_explicit: struct {
14531            base: Register,
14532            index: Register,
14533            option: LoadStore.RegisterRegisterOffset.Option,
14534            amount: LoadStore.RegisterRegisterOffset.Extend.Amount,
14535        },
14536        extended_register: struct {
14537            base: Register,
14538            index: Register,
14539            extend: LoadStore.RegisterRegisterOffset.Extend,
14540        },
14541    }) Instruction {
14542        assert(t.format.general == .word);
14543        form: switch (form) {
14544            .post_index => |post_index| {
14545                assert(post_index.base.format.general == .doubleword);
14546                return .{ .load_store = .{ .register_immediate_post_indexed = .{ .integer = .{
14547                    .ldrb = .{
14548                        .Rt = t.alias.encode(.{}),
14549                        .Rn = post_index.base.alias.encode(.{ .sp = true }),
14550                        .imm9 = post_index.index,
14551                    },
14552                } } } };
14553            },
14554            .pre_index => |pre_index| {
14555                assert(pre_index.base.format.general == .doubleword);
14556                return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .integer = .{
14557                    .ldrb = .{
14558                        .Rt = t.alias.encode(.{}),
14559                        .Rn = pre_index.base.alias.encode(.{ .sp = true }),
14560                        .imm9 = pre_index.index,
14561                    },
14562                } } } };
14563            },
14564            .unsigned_offset => |unsigned_offset| {
14565                assert(unsigned_offset.base.format.general == .doubleword);
14566                return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
14567                    .ldrb = .{
14568                        .Rt = t.alias.encode(.{}),
14569                        .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
14570                        .imm12 = unsigned_offset.offset,
14571                    },
14572                } } } };
14573            },
14574            .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
14575            .extended_register_explicit => |extended_register_explicit| {
14576                assert(extended_register_explicit.base.format.general == .doubleword and
14577                    extended_register_explicit.index.format.general == extended_register_explicit.option.sf());
14578                return .{ .load_store = .{ .register_register_offset = .{ .integer = .{
14579                    .ldrb = .{
14580                        .Rt = t.alias.encode(.{}),
14581                        .Rn = extended_register_explicit.base.alias.encode(.{ .sp = true }),
14582                        .S = switch (extended_register_explicit.amount) {
14583                            0 => false,
14584                            else => unreachable,
14585                        },
14586                        .option = extended_register_explicit.option,
14587                        .Rm = extended_register_explicit.index.alias.encode(.{}),
14588                    },
14589                } } } };
14590            },
14591            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
14592                .base = extended_register.base,
14593                .index = extended_register.index,
14594                .option = extended_register.extend,
14595                .amount = switch (extended_register.extend) {
14596                    .uxtw, .lsl, .sxtw, .sxtx => |amount| amount,
14597                },
14598            } },
14599        }
14600    }
14601    /// C6.2.172 LDRH (immediate)
14602    /// C6.2.173 LDRH (register)
14603    pub fn ldrh(t: Register, form: union(enum) {
14604        post_index: struct { base: Register, index: i9 },
14605        pre_index: struct { base: Register, index: i9 },
14606        unsigned_offset: struct { base: Register, offset: u13 = 0 },
14607        base: Register,
14608        extended_register_explicit: struct {
14609            base: Register,
14610            index: Register,
14611            option: LoadStore.RegisterRegisterOffset.Option,
14612            amount: LoadStore.RegisterRegisterOffset.Extend.Amount,
14613        },
14614        extended_register: struct {
14615            base: Register,
14616            index: Register,
14617            extend: LoadStore.RegisterRegisterOffset.Extend,
14618        },
14619    }) Instruction {
14620        assert(t.format.general == .word);
14621        form: switch (form) {
14622            .post_index => |post_index| {
14623                assert(post_index.base.format.general == .doubleword);
14624                return .{ .load_store = .{ .register_immediate_post_indexed = .{ .integer = .{
14625                    .ldrh = .{
14626                        .Rt = t.alias.encode(.{}),
14627                        .Rn = post_index.base.alias.encode(.{ .sp = true }),
14628                        .imm9 = post_index.index,
14629                    },
14630                } } } };
14631            },
14632            .pre_index => |pre_index| {
14633                assert(pre_index.base.format.general == .doubleword);
14634                return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .integer = .{
14635                    .ldrh = .{
14636                        .Rt = t.alias.encode(.{}),
14637                        .Rn = pre_index.base.alias.encode(.{ .sp = true }),
14638                        .imm9 = pre_index.index,
14639                    },
14640                } } } };
14641            },
14642            .unsigned_offset => |unsigned_offset| {
14643                assert(unsigned_offset.base.format.general == .doubleword);
14644                return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
14645                    .ldrh = .{
14646                        .Rt = t.alias.encode(.{}),
14647                        .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
14648                        .imm12 = @intCast(@shrExact(unsigned_offset.offset, 1)),
14649                    },
14650                } } } };
14651            },
14652            .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
14653            .extended_register_explicit => |extended_register_explicit| {
14654                assert(extended_register_explicit.base.format.general == .doubleword and
14655                    extended_register_explicit.index.format.general == extended_register_explicit.option.sf());
14656                return .{ .load_store = .{ .register_register_offset = .{ .integer = .{
14657                    .ldrh = .{
14658                        .Rt = t.alias.encode(.{}),
14659                        .Rn = extended_register_explicit.base.alias.encode(.{ .sp = true }),
14660                        .S = switch (extended_register_explicit.amount) {
14661                            0 => false,
14662                            1 => true,
14663                            else => unreachable,
14664                        },
14665                        .option = extended_register_explicit.option,
14666                        .Rm = extended_register_explicit.index.alias.encode(.{}),
14667                    },
14668                } } } };
14669            },
14670            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
14671                .base = extended_register.base,
14672                .index = extended_register.index,
14673                .option = extended_register.extend,
14674                .amount = switch (extended_register.extend) {
14675                    .uxtw, .lsl, .sxtw, .sxtx => |amount| amount,
14676                },
14677            } },
14678        }
14679    }
14680    /// C6.2.174 LDRSB (immediate)
14681    /// C6.2.175 LDRSB (register)
14682    pub fn ldrsb(t: Register, form: union(enum) {
14683        post_index: struct { base: Register, index: i9 },
14684        pre_index: struct { base: Register, index: i9 },
14685        unsigned_offset: struct { base: Register, offset: u12 = 0 },
14686        base: Register,
14687        extended_register_explicit: struct {
14688            base: Register,
14689            index: Register,
14690            option: LoadStore.RegisterRegisterOffset.Option,
14691            amount: LoadStore.RegisterRegisterOffset.Extend.Amount,
14692        },
14693        extended_register: struct {
14694            base: Register,
14695            index: Register,
14696            extend: LoadStore.RegisterRegisterOffset.Extend,
14697        },
14698    }) Instruction {
14699        const sf = t.format.general;
14700        form: switch (form) {
14701            .post_index => |post_index| {
14702                assert(post_index.base.format.general == .doubleword);
14703                return .{ .load_store = .{ .register_immediate_post_indexed = .{ .integer = .{
14704                    .ldrsb = .{
14705                        .Rt = t.alias.encode(.{}),
14706                        .Rn = post_index.base.alias.encode(.{ .sp = true }),
14707                        .imm9 = post_index.index,
14708                        .opc0 = ~@intFromEnum(sf),
14709                    },
14710                } } } };
14711            },
14712            .pre_index => |pre_index| {
14713                assert(pre_index.base.format.general == .doubleword);
14714                return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .integer = .{
14715                    .ldrsb = .{
14716                        .Rt = t.alias.encode(.{}),
14717                        .Rn = pre_index.base.alias.encode(.{ .sp = true }),
14718                        .imm9 = pre_index.index,
14719                        .opc0 = ~@intFromEnum(sf),
14720                    },
14721                } } } };
14722            },
14723            .unsigned_offset => |unsigned_offset| {
14724                assert(unsigned_offset.base.format.general == .doubleword);
14725                return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
14726                    .ldrsb = .{
14727                        .Rt = t.alias.encode(.{}),
14728                        .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
14729                        .imm12 = unsigned_offset.offset,
14730                        .opc0 = ~@intFromEnum(sf),
14731                    },
14732                } } } };
14733            },
14734            .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
14735            .extended_register_explicit => |extended_register_explicit| {
14736                assert(extended_register_explicit.base.format.general == .doubleword and
14737                    extended_register_explicit.index.format.general == extended_register_explicit.option.sf());
14738                return .{ .load_store = .{ .register_register_offset = .{ .integer = .{
14739                    .ldrsb = .{
14740                        .Rt = t.alias.encode(.{}),
14741                        .Rn = extended_register_explicit.base.alias.encode(.{ .sp = true }),
14742                        .S = switch (extended_register_explicit.amount) {
14743                            0 => false,
14744                            else => unreachable,
14745                        },
14746                        .option = extended_register_explicit.option,
14747                        .Rm = extended_register_explicit.index.alias.encode(.{}),
14748                        .opc0 = ~@intFromEnum(sf),
14749                    },
14750                } } } };
14751            },
14752            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
14753                .base = extended_register.base,
14754                .index = extended_register.index,
14755                .option = extended_register.extend,
14756                .amount = switch (extended_register.extend) {
14757                    .uxtw, .lsl, .sxtw, .sxtx => |amount| amount,
14758                },
14759            } },
14760        }
14761    }
14762    /// C6.2.176 LDRSH (immediate)
14763    /// C6.2.177 LDRSH (register)
14764    pub fn ldrsh(t: Register, form: union(enum) {
14765        post_index: struct { base: Register, index: i9 },
14766        pre_index: struct { base: Register, index: i9 },
14767        unsigned_offset: struct { base: Register, offset: u13 = 0 },
14768        base: Register,
14769        extended_register_explicit: struct {
14770            base: Register,
14771            index: Register,
14772            option: LoadStore.RegisterRegisterOffset.Option,
14773            amount: LoadStore.RegisterRegisterOffset.Extend.Amount,
14774        },
14775        extended_register: struct {
14776            base: Register,
14777            index: Register,
14778            extend: LoadStore.RegisterRegisterOffset.Extend,
14779        },
14780    }) Instruction {
14781        const sf = t.format.general;
14782        form: switch (form) {
14783            .post_index => |post_index| {
14784                assert(post_index.base.format.general == .doubleword);
14785                return .{ .load_store = .{ .register_immediate_post_indexed = .{ .integer = .{
14786                    .ldrsh = .{
14787                        .Rt = t.alias.encode(.{}),
14788                        .Rn = post_index.base.alias.encode(.{ .sp = true }),
14789                        .imm9 = post_index.index,
14790                        .opc0 = ~@intFromEnum(sf),
14791                    },
14792                } } } };
14793            },
14794            .pre_index => |pre_index| {
14795                assert(pre_index.base.format.general == .doubleword);
14796                return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .integer = .{
14797                    .ldrsh = .{
14798                        .Rt = t.alias.encode(.{}),
14799                        .Rn = pre_index.base.alias.encode(.{ .sp = true }),
14800                        .imm9 = pre_index.index,
14801                        .opc0 = ~@intFromEnum(sf),
14802                    },
14803                } } } };
14804            },
14805            .unsigned_offset => |unsigned_offset| {
14806                assert(unsigned_offset.base.format.general == .doubleword);
14807                return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
14808                    .ldrsh = .{
14809                        .Rt = t.alias.encode(.{}),
14810                        .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
14811                        .imm12 = @intCast(@shrExact(unsigned_offset.offset, 1)),
14812                        .opc0 = ~@intFromEnum(sf),
14813                    },
14814                } } } };
14815            },
14816            .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
14817            .extended_register_explicit => |extended_register_explicit| {
14818                assert(extended_register_explicit.base.format.general == .doubleword and
14819                    extended_register_explicit.index.format.general == extended_register_explicit.option.sf());
14820                return .{ .load_store = .{ .register_register_offset = .{ .integer = .{
14821                    .ldrsh = .{
14822                        .Rt = t.alias.encode(.{}),
14823                        .Rn = extended_register_explicit.base.alias.encode(.{ .sp = true }),
14824                        .S = switch (extended_register_explicit.amount) {
14825                            0 => false,
14826                            1 => true,
14827                            else => unreachable,
14828                        },
14829                        .option = extended_register_explicit.option,
14830                        .Rm = extended_register_explicit.index.alias.encode(.{}),
14831                        .opc0 = ~@intFromEnum(sf),
14832                    },
14833                } } } };
14834            },
14835            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
14836                .base = extended_register.base,
14837                .index = extended_register.index,
14838                .option = extended_register.extend,
14839                .amount = switch (extended_register.extend) {
14840                    .uxtw, .lsl, .sxtw, .sxtx => |amount| amount,
14841                },
14842            } },
14843        }
14844    }
14845    /// C6.2.178 LDRSW (immediate)
14846    /// C6.2.179 LDRSW (literal)
14847    /// C6.2.180 LDRSW (register)
14848    pub fn ldrsw(t: Register, form: union(enum) {
14849        post_index: struct { base: Register, index: i9 },
14850        pre_index: struct { base: Register, index: i9 },
14851        unsigned_offset: struct { base: Register, offset: u14 = 0 },
14852        base: Register,
14853        literal: i21,
14854        extended_register_explicit: struct {
14855            base: Register,
14856            index: Register,
14857            option: LoadStore.RegisterRegisterOffset.Option,
14858            amount: LoadStore.RegisterRegisterOffset.Extend.Amount,
14859        },
14860        extended_register: struct {
14861            base: Register,
14862            index: Register,
14863            extend: LoadStore.RegisterRegisterOffset.Extend,
14864        },
14865    }) Instruction {
14866        assert(t.format.general == .doubleword);
14867        form: switch (form) {
14868            .post_index => |post_index| {
14869                assert(post_index.base.format.general == .doubleword);
14870                return .{ .load_store = .{ .register_immediate_post_indexed = .{ .integer = .{
14871                    .ldrsw = .{
14872                        .Rt = t.alias.encode(.{}),
14873                        .Rn = post_index.base.alias.encode(.{ .sp = true }),
14874                        .imm9 = post_index.index,
14875                    },
14876                } } } };
14877            },
14878            .pre_index => |pre_index| {
14879                assert(pre_index.base.format.general == .doubleword);
14880                return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .integer = .{
14881                    .ldrsw = .{
14882                        .Rt = t.alias.encode(.{}),
14883                        .Rn = pre_index.base.alias.encode(.{ .sp = true }),
14884                        .imm9 = pre_index.index,
14885                    },
14886                } } } };
14887            },
14888            .unsigned_offset => |unsigned_offset| {
14889                assert(unsigned_offset.base.format.general == .doubleword);
14890                return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
14891                    .ldrsw = .{
14892                        .Rt = t.alias.encode(.{}),
14893                        .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
14894                        .imm12 = @intCast(@shrExact(unsigned_offset.offset, 2)),
14895                    },
14896                } } } };
14897            },
14898            .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
14899            .literal => |offset| return .{ .load_store = .{ .register_literal = .{ .integer = .{
14900                .ldrsw = .{
14901                    .Rt = t.alias.encode(.{}),
14902                    .imm19 = @intCast(@shrExact(offset, 2)),
14903                },
14904            } } } },
14905            .extended_register_explicit => |extended_register_explicit| {
14906                assert(extended_register_explicit.base.format.general == .doubleword and
14907                    extended_register_explicit.index.format.general == extended_register_explicit.option.sf());
14908                return .{ .load_store = .{ .register_register_offset = .{ .integer = .{
14909                    .ldrsw = .{
14910                        .Rt = t.alias.encode(.{}),
14911                        .Rn = extended_register_explicit.base.alias.encode(.{ .sp = true }),
14912                        .S = switch (extended_register_explicit.amount) {
14913                            0 => false,
14914                            2 => true,
14915                            else => unreachable,
14916                        },
14917                        .option = extended_register_explicit.option,
14918                        .Rm = extended_register_explicit.index.alias.encode(.{}),
14919                    },
14920                } } } };
14921            },
14922            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
14923                .base = extended_register.base,
14924                .index = extended_register.index,
14925                .option = extended_register.extend,
14926                .amount = switch (extended_register.extend) {
14927                    .uxtw, .lsl, .sxtw, .sxtx => |amount| amount,
14928                },
14929            } },
14930        }
14931    }
14932    /// C6.2.202 LDUR
14933    /// C7.2.194 LDUR (SIMD&FP)
14934    pub fn ldur(t: Register, n: Register, simm: i9) Instruction {
14935        assert(n.format.general == .doubleword);
14936        switch (t.format) {
14937            else => unreachable,
14938            .general => |sf| return .{ .load_store = .{ .register_unscaled_immediate = .{ .integer = .{
14939                .ldur = .{
14940                    .Rt = t.alias.encode(.{}),
14941                    .Rn = n.alias.encode(.{ .sp = true }),
14942                    .imm9 = simm,
14943                    .sf = sf,
14944                },
14945            } } } },
14946            .scalar => |vs| return .{ .load_store = .{ .register_unscaled_immediate = .{ .vector = .{
14947                .ldur = .{
14948                    .Rt = t.alias.encode(.{ .V = true }),
14949                    .Rn = n.alias.encode(.{ .sp = true }),
14950                    .imm9 = simm,
14951                    .opc1 = .encode(vs),
14952                    .size = .encode(vs),
14953                },
14954            } } } },
14955        }
14956    }
14957    /// C6.2.203 LDURB
14958    pub fn ldurb(t: Register, n: Register, simm: i9) Instruction {
14959        assert(t.format.general == .word and n.format.general == .doubleword);
14960        return .{ .load_store = .{ .register_unscaled_immediate = .{ .integer = .{
14961            .ldurb = .{
14962                .Rt = t.alias.encode(.{}),
14963                .Rn = n.alias.encode(.{ .sp = true }),
14964                .imm9 = simm,
14965            },
14966        } } } };
14967    }
14968    /// C6.2.204 LDURH
14969    pub fn ldurh(t: Register, n: Register, simm: i9) Instruction {
14970        assert(t.format.general == .word and n.format.general == .doubleword);
14971        return .{ .load_store = .{ .register_unscaled_immediate = .{ .integer = .{
14972            .ldurh = .{
14973                .Rt = t.alias.encode(.{}),
14974                .Rn = n.alias.encode(.{ .sp = true }),
14975                .imm9 = simm,
14976            },
14977        } } } };
14978    }
14979    /// C6.2.205 LDURSB
14980    pub fn ldursb(t: Register, n: Register, simm: i9) Instruction {
14981        assert(n.format.general == .doubleword);
14982        return .{ .load_store = .{ .register_unscaled_immediate = .{ .integer = .{
14983            .ldursb = .{
14984                .Rt = t.alias.encode(.{}),
14985                .Rn = n.alias.encode(.{ .sp = true }),
14986                .imm9 = simm,
14987                .opc0 = ~@intFromEnum(t.format.general),
14988            },
14989        } } } };
14990    }
14991    /// C6.2.206 LDURSH
14992    pub fn ldursh(t: Register, n: Register, simm: i9) Instruction {
14993        assert(n.format.general == .doubleword);
14994        return .{ .load_store = .{ .register_unscaled_immediate = .{ .integer = .{
14995            .ldursh = .{
14996                .Rt = t.alias.encode(.{}),
14997                .Rn = n.alias.encode(.{ .sp = true }),
14998                .imm9 = simm,
14999                .opc0 = ~@intFromEnum(t.format.general),
15000            },
15001        } } } };
15002    }
15003    /// C6.2.207 LDURSW
15004    pub fn ldursw(t: Register, n: Register, simm: i9) Instruction {
15005        assert(t.format.general == .doubleword and n.format.general == .doubleword);
15006        return .{ .load_store = .{ .register_unscaled_immediate = .{ .integer = .{
15007            .ldursw = .{
15008                .Rt = t.alias.encode(.{}),
15009                .Rn = n.alias.encode(.{ .sp = true }),
15010                .imm9 = simm,
15011            },
15012        } } } };
15013    }
15014    /// C6.2.214 LSLV
15015    pub fn lslv(d: Register, n: Register, m: Register) Instruction {
15016        const sf = d.format.general;
15017        assert(n.format.general == sf and m.format.general == sf);
15018        return .{ .data_processing_register = .{ .data_processing_two_source = .{
15019            .lslv = .{
15020                .Rd = d.alias.encode(.{}),
15021                .Rn = n.alias.encode(.{}),
15022                .Rm = m.alias.encode(.{}),
15023                .sf = sf,
15024            },
15025        } } };
15026    }
15027    /// C6.2.217 LSRV
15028    pub fn lsrv(d: Register, n: Register, m: Register) Instruction {
15029        const sf = d.format.general;
15030        assert(n.format.general == sf and m.format.general == sf);
15031        return .{ .data_processing_register = .{ .data_processing_two_source = .{
15032            .lsrv = .{
15033                .Rd = d.alias.encode(.{}),
15034                .Rn = n.alias.encode(.{}),
15035                .Rm = m.alias.encode(.{}),
15036                .sf = sf,
15037            },
15038        } } };
15039    }
15040    /// C6.2.218 MADD
15041    pub fn madd(d: Register, n: Register, m: Register, a: Register) Instruction {
15042        const sf = d.format.general;
15043        assert(n.format.general == sf and m.format.general == sf and a.format.general == sf);
15044        return .{ .data_processing_register = .{ .data_processing_three_source = .{
15045            .madd = .{
15046                .Rd = d.alias.encode(.{}),
15047                .Rn = n.alias.encode(.{}),
15048                .Ra = a.alias.encode(.{}),
15049                .Rm = m.alias.encode(.{}),
15050                .sf = sf,
15051            },
15052        } } };
15053    }
15054    /// C7.2.204 MOVI
15055    pub fn movi(d: Register, imm8: u8, shift: union(enum) { lsl: u5, msl: u5, replicate }) Instruction {
15056        const arrangement = switch (d.format) {
15057            else => unreachable,
15058            .scalar => |vs| switch (vs) {
15059                else => unreachable,
15060                .double => .@"1d",
15061            },
15062            .vector => |arrangement| switch (arrangement) {
15063                .@"1d" => unreachable,
15064                else => arrangement,
15065            },
15066        };
15067        return .{ .data_processing_vector = .{ .simd_modified_immediate = .{
15068            .movi = .{
15069                .Rd = d.alias.encode(.{ .V = true }),
15070                .imm5 = @truncate(imm8 >> 0),
15071                .cmode = switch (shift) {
15072                    .lsl => |amount| switch (arrangement) {
15073                        else => unreachable,
15074                        .@"8b", .@"16b" => @as(u4, 0b1110) |
15075                            @as(u4, @as(u0, @intCast(@shrExact(amount, 3)))) << 1,
15076                        .@"4h", .@"8h" => @as(u4, 0b1000) |
15077                            @as(u4, @as(u1, @intCast(@shrExact(amount, 3)))) << 1,
15078                        .@"2s", .@"4s" => @as(u4, 0b0000) |
15079                            @as(u4, @as(u2, @intCast(@shrExact(amount, 3)))) << 1,
15080                    },
15081                    .msl => |amount| switch (arrangement) {
15082                        else => unreachable,
15083                        .@"2s", .@"4s" => @as(u4, 0b1100) |
15084                            @as(u4, @as(u1, @intCast(@shrExact(amount, 3) - 1))) << 0,
15085                    },
15086                    .replicate => switch (arrangement) {
15087                        else => unreachable,
15088                        .@"1d", .@"2d" => 0b1110,
15089                    },
15090                },
15091                .imm3 = @intCast(imm8 >> 5),
15092                .op = switch (shift) {
15093                    .lsl, .msl => 0b0,
15094                    .replicate => 0b1,
15095                },
15096                .Q = arrangement.size(),
15097            },
15098        } } };
15099    }
15100    /// C6.2.225 MOVK
15101    pub fn movk(
15102        d: Register,
15103        imm: u16,
15104        shift: struct { lsl: DataProcessingImmediate.MoveWideImmediate.Hw = .@"0" },
15105    ) Instruction {
15106        const sf = d.format.general;
15107        assert(sf == .doubleword or shift.lsl.sf() == .word);
15108        return .{ .data_processing_immediate = .{ .move_wide_immediate = .{
15109            .movk = .{
15110                .Rd = d.alias.encode(.{}),
15111                .imm16 = imm,
15112                .hw = shift.lsl,
15113                .sf = sf,
15114            },
15115        } } };
15116    }
15117    /// C6.2.226 MOVN
15118    pub fn movn(
15119        d: Register,
15120        imm: u16,
15121        shift: struct { lsl: DataProcessingImmediate.MoveWideImmediate.Hw = .@"0" },
15122    ) Instruction {
15123        const sf = d.format.general;
15124        assert(sf == .doubleword or shift.lsl.sf() == .word);
15125        return .{ .data_processing_immediate = .{ .move_wide_immediate = .{
15126            .movn = .{
15127                .Rd = d.alias.encode(.{}),
15128                .imm16 = imm,
15129                .hw = shift.lsl,
15130                .sf = sf,
15131            },
15132        } } };
15133    }
15134    /// C6.2.227 MOVZ
15135    pub fn movz(
15136        d: Register,
15137        imm: u16,
15138        shift: struct { lsl: DataProcessingImmediate.MoveWideImmediate.Hw = .@"0" },
15139    ) Instruction {
15140        const sf = d.format.general;
15141        assert(sf == .doubleword or shift.lsl.sf() == .word);
15142        return .{ .data_processing_immediate = .{ .move_wide_immediate = .{
15143            .movz = .{
15144                .Rd = d.alias.encode(.{}),
15145                .imm16 = imm,
15146                .hw = shift.lsl,
15147                .sf = sf,
15148            },
15149        } } };
15150    }
15151    /// C6.2.228 MRS
15152    pub fn mrs(t: Register, systemreg: Register.System) Instruction {
15153        assert(t.format.general == .doubleword and systemreg.op0 >= 0b10);
15154        return .{ .branch_exception_generating_system = .{ .system_register_move = .{
15155            .mrs = .{
15156                .Rt = t.alias.encode(.{}),
15157                .systemreg = systemreg,
15158            },
15159        } } };
15160    }
15161    /// C6.2.230 MSR (register)
15162    pub fn msr(systemreg: Register.System, t: Register) Instruction {
15163        assert(systemreg.op0 >= 0b10 and t.format.general == .doubleword);
15164        return .{ .branch_exception_generating_system = .{ .system_register_move = .{
15165            .msr = .{
15166                .Rt = t.alias.encode(.{}),
15167                .systemreg = systemreg,
15168            },
15169        } } };
15170    }
15171    /// C6.2.231 MSUB
15172    pub fn msub(d: Register, n: Register, m: Register, a: Register) Instruction {
15173        const sf = d.format.general;
15174        assert(n.format.general == sf and m.format.general == sf and a.format.general == sf);
15175        return .{ .data_processing_register = .{ .data_processing_three_source = .{
15176            .msub = .{
15177                .Rd = d.alias.encode(.{}),
15178                .Rn = n.alias.encode(.{}),
15179                .Ra = a.alias.encode(.{}),
15180                .Rm = m.alias.encode(.{}),
15181                .sf = sf,
15182            },
15183        } } };
15184    }
15185    /// C7.2.209 NEG (vector)
15186    pub fn neg(d: Register, n: Register) Instruction {
15187        switch (d.format) {
15188            else => unreachable,
15189            .scalar => |elem_size| {
15190                assert(elem_size == .double and elem_size == n.format.scalar);
15191                return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
15192                    .neg = .{
15193                        .Rd = d.alias.encode(.{ .V = true }),
15194                        .Rn = n.alias.encode(.{ .V = true }),
15195                        .size = .fromScalarSize(elem_size),
15196                    },
15197                } } };
15198            },
15199            .vector => |arrangement| {
15200                assert(arrangement != .@"1d" and n.format.vector == arrangement);
15201                return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
15202                    .neg = .{
15203                        .Rd = d.alias.encode(.{ .V = true }),
15204                        .Rn = n.alias.encode(.{ .V = true }),
15205                        .size = arrangement.elemSize(),
15206                        .Q = arrangement.size(),
15207                    },
15208                } } };
15209            },
15210        }
15211    }
15212    /// C6.2.238 NOP
15213    pub fn nop() Instruction {
15214        return .{ .branch_exception_generating_system = .{ .hints = .{
15215            .nop = .{},
15216        } } };
15217    }
15218    /// C7.2.210 NOT
15219    pub fn not(d: Register, n: Register) Instruction {
15220        const arrangement = d.format.vector;
15221        assert(arrangement.elemSize() == .byte and n.format.vector == arrangement);
15222        return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
15223            .not = .{
15224                .Rd = d.alias.encode(.{ .V = true }),
15225                .Rn = n.alias.encode(.{ .V = true }),
15226                .size = arrangement.elemSize(),
15227                .Q = arrangement.size(),
15228            },
15229        } } };
15230    }
15231    /// C6.2.239 ORN (shifted register)
15232    /// C7.2.211 ORN (vector)
15233    pub fn orn(d: Register, n: Register, form: union(enum) {
15234        register: Register,
15235        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
15236        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
15237    }) Instruction {
15238        switch (d.format) {
15239            else => unreachable,
15240            .general => |sf| {
15241                assert(n.format.general == sf);
15242                form: switch (form) {
15243                    .register => |register| continue :form .{ .shifted_register = .{ .register = register } },
15244                    .shifted_register_explicit => |shifted_register_explicit| {
15245                        assert(shifted_register_explicit.register.format.general == sf);
15246                        return .{ .data_processing_register = .{ .logical_shifted_register = .{
15247                            .orn = .{
15248                                .Rd = d.alias.encode(.{}),
15249                                .Rn = n.alias.encode(.{}),
15250                                .imm6 = switch (sf) {
15251                                    .word => @as(u5, @intCast(shifted_register_explicit.amount)),
15252                                    .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
15253                                },
15254                                .Rm = shifted_register_explicit.register.alias.encode(.{}),
15255                                .shift = shifted_register_explicit.shift,
15256                                .sf = sf,
15257                            },
15258                        } } };
15259                    },
15260                    .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
15261                        .register = shifted_register.register,
15262                        .shift = shifted_register.shift,
15263                        .amount = switch (shifted_register.shift) {
15264                            .lsl, .lsr, .asr, .ror => |amount| amount,
15265                        },
15266                    } },
15267                }
15268            },
15269            .vector => |arrangement| {
15270                const m = form.register;
15271                assert(arrangement.elemSize() == .byte and n.format.vector == arrangement and m.format.vector == arrangement);
15272                return .{ .data_processing_vector = .{ .simd_three_same = .{
15273                    .orn = .{
15274                        .Rd = d.alias.encode(.{ .V = true }),
15275                        .Rn = n.alias.encode(.{ .V = true }),
15276                        .Rm = m.alias.encode(.{ .V = true }),
15277                        .Q = arrangement.size(),
15278                    },
15279                } } };
15280            },
15281        }
15282    }
15283    /// C6.2.240 ORR (immediate)
15284    /// C6.2.241 ORR (shifted register)
15285    /// C7.2.212 ORR (vector, immediate)
15286    /// C7.2.213 ORR (vector, register)
15287    pub fn orr(d: Register, n: Register, form: union(enum) {
15288        immediate: DataProcessingImmediate.Bitmask,
15289        shifted_immediate: struct { immediate: u8, lsl: u5 = 0 },
15290        register: Register,
15291        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
15292        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
15293    }) Instruction {
15294        switch (d.format) {
15295            else => unreachable,
15296            .general => |sf| {
15297                assert(n.format.general == sf);
15298                form: switch (form) {
15299                    .immediate => |bitmask| {
15300                        assert(bitmask.validImmediate(sf));
15301                        return .{ .data_processing_immediate = .{ .logical_immediate = .{
15302                            .orr = .{
15303                                .Rd = d.alias.encode(.{ .sp = true }),
15304                                .Rn = n.alias.encode(.{}),
15305                                .imm = bitmask,
15306                                .sf = sf,
15307                            },
15308                        } } };
15309                    },
15310                    .shifted_immediate => unreachable,
15311                    .register => |register| continue :form .{ .shifted_register = .{ .register = register } },
15312                    .shifted_register_explicit => |shifted_register_explicit| {
15313                        assert(shifted_register_explicit.register.format.general == sf);
15314                        return .{ .data_processing_register = .{ .logical_shifted_register = .{
15315                            .orr = .{
15316                                .Rd = d.alias.encode(.{}),
15317                                .Rn = n.alias.encode(.{}),
15318                                .imm6 = switch (sf) {
15319                                    .word => @as(u5, @intCast(shifted_register_explicit.amount)),
15320                                    .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
15321                                },
15322                                .Rm = shifted_register_explicit.register.alias.encode(.{}),
15323                                .shift = shifted_register_explicit.shift,
15324                                .sf = sf,
15325                            },
15326                        } } };
15327                    },
15328                    .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
15329                        .register = shifted_register.register,
15330                        .shift = shifted_register.shift,
15331                        .amount = switch (shifted_register.shift) {
15332                            .lsl, .lsr, .asr, .ror => |amount| amount,
15333                        },
15334                    } },
15335                }
15336            },
15337            .vector => |arrangement| switch (form) {
15338                else => unreachable,
15339                .shifted_immediate => |shifted_immediate| {
15340                    assert(n.alias == d.alias and n.format.vector == arrangement);
15341                    return .{ .data_processing_vector = .{ .simd_modified_immediate = .{
15342                        .orr = .{
15343                            .Rd = d.alias.encode(.{ .V = true }),
15344                            .imm5 = @truncate(shifted_immediate.immediate >> 0),
15345                            .cmode = switch (arrangement) {
15346                                else => unreachable,
15347                                .@"4h", .@"8h" => @as(u3, 0b100) |
15348                                    @as(u3, @as(u1, @intCast(@shrExact(shifted_immediate.lsl, 3)))) << 0,
15349                                .@"2s", .@"4s" => @as(u3, 0b000) |
15350                                    @as(u3, @as(u2, @intCast(@shrExact(shifted_immediate.lsl, 3)))) << 0,
15351                            },
15352                            .imm3 = @intCast(shifted_immediate.immediate >> 5),
15353                            .Q = arrangement.size(),
15354                        },
15355                    } } };
15356                },
15357                .register => |m| {
15358                    assert(arrangement.elemSize() == .byte and n.format.vector == arrangement and m.format.vector == arrangement);
15359                    return .{ .data_processing_vector = .{ .simd_three_same = .{
15360                        .orr = .{
15361                            .Rd = d.alias.encode(.{ .V = true }),
15362                            .Rn = n.alias.encode(.{ .V = true }),
15363                            .Rm = m.alias.encode(.{ .V = true }),
15364                            .Q = arrangement.size(),
15365                        },
15366                    } } };
15367                },
15368            },
15369        }
15370    }
15371    /// C6.2.247 PRFM (immediate)
15372    /// C6.2.248 PRFM (literal)
15373    /// C6.2.249 PRFM (register)
15374    pub fn prfm(prfop: LoadStore.PrfOp, form: union(enum) {
15375        unsigned_offset: struct { base: Register, offset: u15 = 0 },
15376        base: Register,
15377        literal: i21,
15378        extended_register_explicit: struct {
15379            base: Register,
15380            index: Register,
15381            option: LoadStore.RegisterRegisterOffset.Option,
15382            amount: LoadStore.RegisterRegisterOffset.Extend.Amount,
15383        },
15384        extended_register: struct {
15385            base: Register,
15386            index: Register,
15387            extend: LoadStore.RegisterRegisterOffset.Extend,
15388        },
15389    }) Instruction {
15390        form: switch (form) {
15391            .unsigned_offset => |unsigned_offset| {
15392                assert(unsigned_offset.base.format.general == .doubleword);
15393                return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
15394                    .prfm = .{
15395                        .prfop = prfop,
15396                        .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
15397                        .imm12 = @intCast(@shrExact(unsigned_offset.offset, 3)),
15398                    },
15399                } } } };
15400            },
15401            .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
15402            .literal => |offset| return .{ .load_store = .{ .register_literal = .{ .integer = .{
15403                .prfm = .{
15404                    .prfop = prfop,
15405                    .imm19 = @intCast(@shrExact(offset, 2)),
15406                },
15407            } } } },
15408            .extended_register_explicit => |extended_register_explicit| {
15409                assert(extended_register_explicit.base.format.general == .doubleword and
15410                    extended_register_explicit.index.format.general == extended_register_explicit.option.sf());
15411                return .{ .load_store = .{ .register_register_offset = .{ .integer = .{
15412                    .prfm = .{
15413                        .prfop = prfop,
15414                        .Rn = extended_register_explicit.base.alias.encode(.{ .sp = true }),
15415                        .S = switch (extended_register_explicit.amount) {
15416                            0 => false,
15417                            3 => true,
15418                            else => unreachable,
15419                        },
15420                        .option = extended_register_explicit.option,
15421                        .Rm = extended_register_explicit.index.alias.encode(.{}),
15422                    },
15423                } } } };
15424            },
15425            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
15426                .base = extended_register.base,
15427                .index = extended_register.index,
15428                .option = extended_register.extend,
15429                .amount = switch (extended_register.extend) {
15430                    .uxtw, .lsl, .sxtw, .sxtx => |amount| amount,
15431                },
15432            } },
15433        }
15434    }
15435    /// C6.2.253 RBIT
15436    pub fn rbit(d: Register, n: Register) Instruction {
15437        const sf = d.format.general;
15438        assert(n.format.general == sf);
15439        return .{ .data_processing_register = .{ .data_processing_one_source = .{
15440            .rbit = .{
15441                .Rd = d.alias.encode(.{}),
15442                .Rn = n.alias.encode(.{}),
15443                .sf = sf,
15444            },
15445        } } };
15446    }
15447    /// C6.2.254 RET
15448    pub fn ret(n: Register) Instruction {
15449        assert(n.format.general == .doubleword);
15450        return .{ .branch_exception_generating_system = .{ .unconditional_branch_register = .{
15451            .ret = .{ .Rn = n.alias.encode(.{}) },
15452        } } };
15453    }
15454    /// C6.2.256 REV
15455    pub fn rev(d: Register, n: Register) Instruction {
15456        const sf = d.format.general;
15457        assert(n.format.general == sf);
15458        return .{ .data_processing_register = .{ .data_processing_one_source = .{
15459            .rev = .{
15460                .Rd = d.alias.encode(.{}),
15461                .Rn = n.alias.encode(.{}),
15462                .opc0 = sf,
15463                .sf = sf,
15464            },
15465        } } };
15466    }
15467    /// C6.2.257 REV16
15468    pub fn rev16(d: Register, n: Register) Instruction {
15469        const sf = d.format.general;
15470        assert(n.format.general == sf);
15471        return .{ .data_processing_register = .{ .data_processing_one_source = .{
15472            .rev16 = .{
15473                .Rd = d.alias.encode(.{}),
15474                .Rn = n.alias.encode(.{}),
15475                .sf = sf,
15476            },
15477        } } };
15478    }
15479    /// C6.2.258 REV32
15480    pub fn rev32(d: Register, n: Register) Instruction {
15481        assert(d.format.general == .doubleword and n.format.general == .doubleword);
15482        return .{ .data_processing_register = .{ .data_processing_one_source = .{
15483            .rev32 = .{
15484                .Rd = d.alias.encode(.{}),
15485                .Rn = n.alias.encode(.{}),
15486            },
15487        } } };
15488    }
15489    /// C6.2.263 RORV
15490    pub fn rorv(d: Register, n: Register, m: Register) Instruction {
15491        const sf = d.format.general;
15492        assert(n.format.general == sf and m.format.general == sf);
15493        return .{ .data_processing_register = .{ .data_processing_two_source = .{
15494            .rorv = .{
15495                .Rd = d.alias.encode(.{}),
15496                .Rn = n.alias.encode(.{}),
15497                .Rm = m.alias.encode(.{}),
15498                .sf = sf,
15499            },
15500        } } };
15501    }
15502    /// C6.2.264 SB
15503    pub fn sb() Instruction {
15504        return .{ .branch_exception_generating_system = .{ .barriers = .{
15505            .sb = .{},
15506        } } };
15507    }
15508    /// C6.2.265 SBC
15509    pub fn sbc(d: Register, n: Register, m: Register) Instruction {
15510        const sf = d.format.general;
15511        assert(n.format.general == sf and m.format.general == sf);
15512        return .{ .data_processing_register = .{ .add_subtract_with_carry = .{
15513            .sbc = .{
15514                .Rd = d.alias.encode(.{}),
15515                .Rn = n.alias.encode(.{}),
15516                .Rm = m.alias.encode(.{}),
15517                .sf = sf,
15518            },
15519        } } };
15520    }
15521    /// C6.2.266 SBCS
15522    pub fn sbcs(d: Register, n: Register, m: Register) Instruction {
15523        const sf = d.format.general;
15524        assert(n.format.general == sf and m.format.general == sf);
15525        return .{ .data_processing_register = .{ .add_subtract_with_carry = .{
15526            .sbcs = .{
15527                .Rd = d.alias.encode(.{}),
15528                .Rn = n.alias.encode(.{}),
15529                .Rm = m.alias.encode(.{}),
15530                .sf = sf,
15531            },
15532        } } };
15533    }
15534    /// C6.2.268 SBFM
15535    pub fn sbfm(d: Register, n: Register, bitmask: DataProcessingImmediate.Bitmask) Instruction {
15536        const sf = d.format.general;
15537        assert(n.format.general == sf and bitmask.validBitfield(sf));
15538        return .{ .data_processing_immediate = .{ .bitfield = .{
15539            .sbfm = .{
15540                .Rd = d.alias.encode(.{}),
15541                .Rn = n.alias.encode(.{}),
15542                .imm = bitmask,
15543                .sf = sf,
15544            },
15545        } } };
15546    }
15547    /// C7.2.234 SCVTF (vector, integer)
15548    /// C7.2.236 SCVTF (scalar, integer)
15549    pub fn scvtf(d: Register, n: Register) Instruction {
15550        switch (d.format) {
15551            else => unreachable,
15552            .scalar => |ftype| switch (n.format) {
15553                else => unreachable,
15554                .scalar => |elem_size| {
15555                    assert(ftype == elem_size);
15556                    switch (ftype) {
15557                        else => unreachable,
15558                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
15559                            .scvtf = .{
15560                                .Rd = d.alias.encode(.{ .V = true }),
15561                                .Rn = n.alias.encode(.{ .V = true }),
15562                            },
15563                        } } },
15564                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
15565                            .scvtf = .{
15566                                .Rd = d.alias.encode(.{ .V = true }),
15567                                .Rn = n.alias.encode(.{ .V = true }),
15568                                .sz = .fromScalarSize(ftype),
15569                            },
15570                        } } },
15571                    }
15572                },
15573                .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
15574                    .scvtf = .{
15575                        .Rd = d.alias.encode(.{ .V = true }),
15576                        .Rn = n.alias.encode(.{}),
15577                        .ftype = .fromScalarSize(ftype),
15578                        .sf = sf,
15579                    },
15580                } } },
15581            },
15582            .vector => |arrangement| {
15583                assert(arrangement != .@"1d" and n.format.vector == arrangement);
15584                switch (arrangement.elemSize()) {
15585                    else => unreachable,
15586                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
15587                        .scvtf = .{
15588                            .Rd = d.alias.encode(.{ .V = true }),
15589                            .Rn = n.alias.encode(.{ .V = true }),
15590                            .Q = arrangement.size(),
15591                        },
15592                    } } },
15593                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
15594                        .scvtf = .{
15595                            .Rd = d.alias.encode(.{ .V = true }),
15596                            .Rn = n.alias.encode(.{ .V = true }),
15597                            .sz = arrangement.elemSz(),
15598                            .Q = arrangement.size(),
15599                        },
15600                    } } },
15601                }
15602            },
15603        }
15604    }
15605    /// C6.2.270 SDIV
15606    pub fn sdiv(d: Register, n: Register, m: Register) Instruction {
15607        const sf = d.format.general;
15608        assert(n.format.general == sf and m.format.general == sf);
15609        return .{ .data_processing_register = .{ .data_processing_two_source = .{
15610            .sdiv = .{
15611                .Rd = d.alias.encode(.{}),
15612                .Rn = n.alias.encode(.{}),
15613                .Rm = m.alias.encode(.{}),
15614                .sf = sf,
15615            },
15616        } } };
15617    }
15618    /// C6.2.280 SEV
15619    pub fn sev() Instruction {
15620        return .{ .branch_exception_generating_system = .{ .hints = .{
15621            .sev = .{},
15622        } } };
15623    }
15624    /// C6.2.281 SEVL
15625    pub fn sevl() Instruction {
15626        return .{ .branch_exception_generating_system = .{ .hints = .{
15627            .sevl = .{},
15628        } } };
15629    }
15630    /// C6.2.282 SMADDL
15631    pub fn smaddl(d: Register, n: Register, m: Register, a: Register) Instruction {
15632        assert(d.format.general == .doubleword and n.format.general == .word and m.format.general == .word and a.format.general == .doubleword);
15633        return .{ .data_processing_register = .{ .data_processing_three_source = .{
15634            .smaddl = .{
15635                .Rd = d.alias.encode(.{}),
15636                .Rn = n.alias.encode(.{}),
15637                .Ra = a.alias.encode(.{}),
15638                .Rm = m.alias.encode(.{}),
15639            },
15640        } } };
15641    }
15642    /// C6.2.283 SMC
15643    pub fn smc(imm: u16) Instruction {
15644        return .{ .branch_exception_generating_system = .{ .exception_generating = .{
15645            .smc = .{ .imm16 = imm },
15646        } } };
15647    }
15648    /// C7.2.279 SMOV
15649    pub fn smov(d: Register, n: Register) Instruction {
15650        const sf = d.format.general;
15651        const vs = n.format.element.size;
15652        switch (vs) {
15653            else => unreachable,
15654            .byte, .half => {},
15655            .single => assert(sf == .doubleword),
15656        }
15657        return .{ .data_processing_vector = .{ .simd_copy = .{
15658            .smov = .{
15659                .Rd = d.alias.encode(.{}),
15660                .Rn = n.alias.encode(.{ .V = true }),
15661                .imm5 = switch (vs) {
15662                    else => unreachable,
15663                    .byte => @as(u5, @as(u4, @intCast(n.format.element.index))) << 1 | @as(u5, 0b1) << 0,
15664                    .half => @as(u5, @as(u3, @intCast(n.format.element.index))) << 2 | @as(u5, 0b10) << 0,
15665                    .single => @as(u5, @as(u2, @intCast(n.format.element.index))) << 3 | @as(u5, 0b100) << 0,
15666                },
15667                .Q = sf,
15668            },
15669        } } };
15670    }
15671    /// C6.2.287 SMSUBL
15672    pub fn smsubl(d: Register, n: Register, m: Register, a: Register) Instruction {
15673        assert(d.format.general == .doubleword and n.format.general == .word and m.format.general == .word and a.format.general == .doubleword);
15674        return .{ .data_processing_register = .{ .data_processing_three_source = .{
15675            .smsubl = .{
15676                .Rd = d.alias.encode(.{}),
15677                .Rn = n.alias.encode(.{}),
15678                .Ra = a.alias.encode(.{}),
15679                .Rm = m.alias.encode(.{}),
15680            },
15681        } } };
15682    }
15683    /// C6.2.288 SMULH
15684    pub fn smulh(d: Register, n: Register, m: Register) Instruction {
15685        assert(d.format.general == .doubleword and n.format.general == .doubleword and m.format.general == .doubleword);
15686        return .{ .data_processing_register = .{ .data_processing_three_source = .{
15687            .smulh = .{
15688                .Rd = d.alias.encode(.{}),
15689                .Rn = n.alias.encode(.{}),
15690                .Rm = m.alias.encode(.{}),
15691            },
15692        } } };
15693    }
15694    /// C7.2.282 SQABS
15695    pub fn sqabs(d: Register, n: Register) Instruction {
15696        switch (d.format) {
15697            else => unreachable,
15698            .scalar => |elem_size| {
15699                assert(elem_size == n.format.scalar);
15700                return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
15701                    .sqabs = .{
15702                        .Rd = d.alias.encode(.{ .V = true }),
15703                        .Rn = n.alias.encode(.{ .V = true }),
15704                        .size = .fromScalarSize(elem_size),
15705                    },
15706                } } };
15707            },
15708            .vector => |arrangement| {
15709                assert(arrangement != .@"1d" and n.format.vector == arrangement);
15710                return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
15711                    .sqabs = .{
15712                        .Rd = d.alias.encode(.{ .V = true }),
15713                        .Rn = n.alias.encode(.{ .V = true }),
15714                        .size = arrangement.elemSize(),
15715                        .Q = arrangement.size(),
15716                    },
15717                } } };
15718            },
15719        }
15720    }
15721    /// C7.2.308 SQXTN
15722    pub fn sqxtn(d: Register, n: Register) Instruction {
15723        switch (d.format) {
15724            else => unreachable,
15725            .scalar => |elem_size| {
15726                assert(elem_size == n.format.scalar.n());
15727                return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
15728                    .sqxtn = .{
15729                        .Rd = d.alias.encode(.{ .V = true }),
15730                        .Rn = n.alias.encode(.{ .V = true }),
15731                        .size = .fromScalarSize(elem_size),
15732                    },
15733                } } };
15734            },
15735            .vector => |arrangement| {
15736                assert(arrangement.len() == n.format.vector.len() and arrangement.elemSize() == n.format.vector.elemSize().n());
15737                return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
15738                    .sqxtn = .{
15739                        .Rd = d.alias.encode(.{ .V = true }),
15740                        .Rn = n.alias.encode(.{ .V = true }),
15741                        .size = arrangement.elemSize(),
15742                        .Q = arrangement.size(),
15743                    },
15744                } } };
15745            },
15746        }
15747    }
15748    /// C7.2.308 SQXTN2
15749    pub fn sqxtn2(d: Register, n: Register) Instruction {
15750        const arrangement = d.format.vector;
15751        assert(arrangement.len() == n.format.vector.len() * 2 and arrangement.elemSize() == n.format.vector.elemSize().n());
15752        return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
15753            .sqxtn = .{
15754                .Rd = d.alias.encode(.{ .V = true }),
15755                .Rn = n.alias.encode(.{ .V = true }),
15756                .size = arrangement.elemSize(),
15757                .Q = arrangement.size(),
15758            },
15759        } } };
15760    }
15761    /// C6.2.321 STP
15762    /// C7.2.330 STP (SIMD&FP)
15763    pub fn stp(t1: Register, t2: Register, form: union(enum) {
15764        post_index: struct { base: Register, index: i10 },
15765        pre_index: struct { base: Register, index: i10 },
15766        signed_offset: struct { base: Register, offset: i10 = 0 },
15767        base: Register,
15768    }) Instruction {
15769        switch (t1.format) {
15770            else => unreachable,
15771            .general => |sf| {
15772                assert(t2.format.general == sf);
15773                form: switch (form) {
15774                    .post_index => |post_index| {
15775                        assert(post_index.base.format.general == .doubleword);
15776                        return .{ .load_store = .{ .register_pair_post_indexed = .{ .integer = .{
15777                            .stp = .{
15778                                .Rt = t1.alias.encode(.{}),
15779                                .Rn = post_index.base.alias.encode(.{ .sp = true }),
15780                                .Rt2 = t2.alias.encode(.{}),
15781                                .imm7 = @intCast(@shrExact(post_index.index, @as(u2, 2) + @intFromEnum(sf))),
15782                                .sf = sf,
15783                            },
15784                        } } } };
15785                    },
15786                    .pre_index => |pre_index| {
15787                        assert(pre_index.base.format.general == .doubleword);
15788                        return .{ .load_store = .{ .register_pair_pre_indexed = .{ .integer = .{
15789                            .stp = .{
15790                                .Rt = t1.alias.encode(.{}),
15791                                .Rn = pre_index.base.alias.encode(.{ .sp = true }),
15792                                .Rt2 = t2.alias.encode(.{}),
15793                                .imm7 = @intCast(@shrExact(pre_index.index, @as(u2, 2) + @intFromEnum(sf))),
15794                                .sf = sf,
15795                            },
15796                        } } } };
15797                    },
15798                    .signed_offset => |signed_offset| {
15799                        assert(signed_offset.base.format.general == .doubleword);
15800                        return .{ .load_store = .{ .register_pair_offset = .{ .integer = .{
15801                            .stp = .{
15802                                .Rt = t1.alias.encode(.{}),
15803                                .Rn = signed_offset.base.alias.encode(.{ .sp = true }),
15804                                .Rt2 = t2.alias.encode(.{}),
15805                                .imm7 = @intCast(@shrExact(signed_offset.offset, @as(u2, 2) + @intFromEnum(sf))),
15806                                .sf = sf,
15807                            },
15808                        } } } };
15809                    },
15810                    .base => |base| continue :form .{ .signed_offset = .{ .base = base } },
15811                }
15812            },
15813            .scalar => |vs| {
15814                assert(t2.format.scalar == vs);
15815                form: switch (form) {
15816                    .post_index => |post_index| {
15817                        assert(post_index.base.format.general == .doubleword);
15818                        return .{ .load_store = .{ .register_pair_post_indexed = .{ .vector = .{
15819                            .stp = .{
15820                                .Rt = t1.alias.encode(.{ .V = true }),
15821                                .Rn = post_index.base.alias.encode(.{ .sp = true }),
15822                                .Rt2 = t2.alias.encode(.{ .V = true }),
15823                                .imm7 = @intCast(@shrExact(post_index.index, @intFromEnum(vs))),
15824                                .opc = .encode(vs),
15825                            },
15826                        } } } };
15827                    },
15828                    .signed_offset => |signed_offset| {
15829                        assert(signed_offset.base.format.general == .doubleword);
15830                        return .{ .load_store = .{ .register_pair_offset = .{ .vector = .{
15831                            .stp = .{
15832                                .Rt = t1.alias.encode(.{ .V = true }),
15833                                .Rn = signed_offset.base.alias.encode(.{ .sp = true }),
15834                                .Rt2 = t2.alias.encode(.{ .V = true }),
15835                                .imm7 = @intCast(@shrExact(signed_offset.offset, @intFromEnum(vs))),
15836                                .opc = .encode(vs),
15837                            },
15838                        } } } };
15839                    },
15840                    .pre_index => |pre_index| {
15841                        assert(pre_index.base.format.general == .doubleword);
15842                        return .{ .load_store = .{ .register_pair_pre_indexed = .{ .vector = .{
15843                            .stp = .{
15844                                .Rt = t1.alias.encode(.{ .V = true }),
15845                                .Rn = pre_index.base.alias.encode(.{ .sp = true }),
15846                                .Rt2 = t2.alias.encode(.{ .V = true }),
15847                                .imm7 = @intCast(@shrExact(pre_index.index, @intFromEnum(vs))),
15848                                .opc = .encode(vs),
15849                            },
15850                        } } } };
15851                    },
15852                    .base => |base| continue :form .{ .signed_offset = .{ .base = base } },
15853                }
15854            },
15855        }
15856    }
15857    /// C6.2.322 STR (immediate)
15858    /// C7.2.331 STR (immediate, SIMD&FP)
15859    pub fn str(t: Register, form: union(enum) {
15860        post_index: struct { base: Register, index: i9 },
15861        pre_index: struct { base: Register, index: i9 },
15862        unsigned_offset: struct { base: Register, offset: u16 = 0 },
15863        base: Register,
15864    }) Instruction {
15865        switch (t.format) {
15866            else => unreachable,
15867            .general => |sf| form: switch (form) {
15868                .post_index => |post_index| {
15869                    assert(post_index.base.format.general == .doubleword);
15870                    return .{ .load_store = .{ .register_immediate_post_indexed = .{ .integer = .{
15871                        .str = .{
15872                            .Rt = t.alias.encode(.{}),
15873                            .Rn = post_index.base.alias.encode(.{ .sp = true }),
15874                            .imm9 = post_index.index,
15875                            .sf = sf,
15876                        },
15877                    } } } };
15878                },
15879                .pre_index => |pre_index| {
15880                    assert(pre_index.base.format.general == .doubleword);
15881                    return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .integer = .{
15882                        .str = .{
15883                            .Rt = t.alias.encode(.{}),
15884                            .Rn = pre_index.base.alias.encode(.{ .sp = true }),
15885                            .imm9 = pre_index.index,
15886                            .sf = sf,
15887                        },
15888                    } } } };
15889                },
15890                .unsigned_offset => |unsigned_offset| {
15891                    assert(unsigned_offset.base.format.general == .doubleword);
15892                    return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
15893                        .str = .{
15894                            .Rt = t.alias.encode(.{}),
15895                            .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
15896                            .imm12 = @intCast(@shrExact(unsigned_offset.offset, @as(u2, 2) + @intFromEnum(sf))),
15897                            .sf = sf,
15898                        },
15899                    } } } };
15900                },
15901                .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
15902            },
15903            .scalar => |vs| form: switch (form) {
15904                .post_index => |post_index| {
15905                    assert(post_index.base.format.general == .doubleword);
15906                    return .{ .load_store = .{ .register_immediate_post_indexed = .{ .vector = .{
15907                        .str = .{
15908                            .Rt = t.alias.encode(.{ .V = true }),
15909                            .Rn = post_index.base.alias.encode(.{ .sp = true }),
15910                            .imm9 = post_index.index,
15911                            .opc1 = .encode(vs),
15912                            .size = .encode(vs),
15913                        },
15914                    } } } };
15915                },
15916                .pre_index => |pre_index| {
15917                    assert(pre_index.base.format.general == .doubleword);
15918                    return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .vector = .{
15919                        .str = .{
15920                            .Rt = t.alias.encode(.{ .V = true }),
15921                            .Rn = pre_index.base.alias.encode(.{ .sp = true }),
15922                            .imm9 = pre_index.index,
15923                            .opc1 = .encode(vs),
15924                            .size = .encode(vs),
15925                        },
15926                    } } } };
15927                },
15928                .unsigned_offset => |unsigned_offset| {
15929                    assert(unsigned_offset.base.format.general == .doubleword);
15930                    return .{ .load_store = .{ .register_unsigned_immediate = .{ .vector = .{
15931                        .str = .{
15932                            .Rt = t.alias.encode(.{ .V = true }),
15933                            .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
15934                            .imm12 = @intCast(@shrExact(unsigned_offset.offset, @intFromEnum(vs))),
15935                            .opc1 = .encode(vs),
15936                            .size = .encode(vs),
15937                        },
15938                    } } } };
15939                },
15940                .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
15941            },
15942        }
15943    }
15944    /// C6.2.324 STRB (immediate)
15945    pub fn strb(t: Register, form: union(enum) {
15946        post_index: struct { base: Register, index: i9 },
15947        pre_index: struct { base: Register, index: i9 },
15948        unsigned_offset: struct { base: Register, offset: u12 = 0 },
15949        base: Register,
15950    }) Instruction {
15951        assert(t.format.general == .word);
15952        form: switch (form) {
15953            .post_index => |post_index| {
15954                assert(post_index.base.format.general == .doubleword);
15955                return .{ .load_store = .{ .register_immediate_post_indexed = .{ .integer = .{
15956                    .strb = .{
15957                        .Rt = t.alias.encode(.{}),
15958                        .Rn = post_index.base.alias.encode(.{ .sp = true }),
15959                        .imm9 = post_index.index,
15960                    },
15961                } } } };
15962            },
15963            .pre_index => |pre_index| {
15964                assert(pre_index.base.format.general == .doubleword);
15965                return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .integer = .{
15966                    .strb = .{
15967                        .Rt = t.alias.encode(.{}),
15968                        .Rn = pre_index.base.alias.encode(.{ .sp = true }),
15969                        .imm9 = pre_index.index,
15970                    },
15971                } } } };
15972            },
15973            .unsigned_offset => |unsigned_offset| {
15974                assert(unsigned_offset.base.format.general == .doubleword);
15975                return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
15976                    .strb = .{
15977                        .Rt = t.alias.encode(.{}),
15978                        .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
15979                        .imm12 = unsigned_offset.offset,
15980                    },
15981                } } } };
15982            },
15983            .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
15984        }
15985    }
15986    /// C6.2.326 STRH (immediate)
15987    pub fn strh(t: Register, form: union(enum) {
15988        post_index: struct { base: Register, index: i9 },
15989        pre_index: struct { base: Register, index: i9 },
15990        unsigned_offset: struct { base: Register, offset: u13 = 0 },
15991        base: Register,
15992    }) Instruction {
15993        assert(t.format.general == .word);
15994        form: switch (form) {
15995            .post_index => |post_index| {
15996                assert(post_index.base.format.general == .doubleword);
15997                return .{ .load_store = .{ .register_immediate_post_indexed = .{ .integer = .{
15998                    .strh = .{
15999                        .Rt = t.alias.encode(.{}),
16000                        .Rn = post_index.base.alias.encode(.{ .sp = true }),
16001                        .imm9 = post_index.index,
16002                    },
16003                } } } };
16004            },
16005            .pre_index => |pre_index| {
16006                assert(pre_index.base.format.general == .doubleword);
16007                return .{ .load_store = .{ .register_immediate_pre_indexed = .{ .integer = .{
16008                    .strh = .{
16009                        .Rt = t.alias.encode(.{}),
16010                        .Rn = pre_index.base.alias.encode(.{ .sp = true }),
16011                        .imm9 = pre_index.index,
16012                    },
16013                } } } };
16014            },
16015            .unsigned_offset => |unsigned_offset| {
16016                assert(unsigned_offset.base.format.general == .doubleword);
16017                return .{ .load_store = .{ .register_unsigned_immediate = .{ .integer = .{
16018                    .strh = .{
16019                        .Rt = t.alias.encode(.{}),
16020                        .Rn = unsigned_offset.base.alias.encode(.{ .sp = true }),
16021                        .imm12 = @intCast(@shrExact(unsigned_offset.offset, 1)),
16022                    },
16023                } } } };
16024            },
16025            .base => |base| continue :form .{ .unsigned_offset = .{ .base = base } },
16026        }
16027    }
16028    /// C6.2.346 STUR
16029    /// C7.2.333 STUR (SIMD&FP)
16030    pub fn stur(t: Register, n: Register, simm: i9) Instruction {
16031        assert(n.format.general == .doubleword);
16032        switch (t.format) {
16033            else => unreachable,
16034            .general => |sf| return .{ .load_store = .{ .register_unscaled_immediate = .{ .integer = .{
16035                .stur = .{
16036                    .Rt = t.alias.encode(.{}),
16037                    .Rn = n.alias.encode(.{ .sp = true }),
16038                    .imm9 = simm,
16039                    .sf = sf,
16040                },
16041            } } } },
16042            .scalar => |vs| return .{ .load_store = .{ .register_unscaled_immediate = .{ .vector = .{
16043                .stur = .{
16044                    .Rt = t.alias.encode(.{ .V = true }),
16045                    .Rn = n.alias.encode(.{ .sp = true }),
16046                    .imm9 = simm,
16047                    .opc1 = .encode(vs),
16048                    .size = .encode(vs),
16049                },
16050            } } } },
16051        }
16052    }
16053    /// C6.2.347 STURB
16054    pub fn sturb(t: Register, n: Register, simm: i9) Instruction {
16055        assert(t.format.general == .word and n.format.general == .doubleword);
16056        return .{ .load_store = .{ .register_unscaled_immediate = .{ .integer = .{
16057            .sturb = .{
16058                .Rt = t.alias.encode(.{}),
16059                .Rn = n.alias.encode(.{ .sp = true }),
16060                .imm9 = simm,
16061            },
16062        } } } };
16063    }
16064    /// C6.2.348 STURH
16065    pub fn sturh(t: Register, n: Register, simm: i9) Instruction {
16066        assert(t.format.general == .word and n.format.general == .doubleword);
16067        return .{ .load_store = .{ .register_unscaled_immediate = .{ .integer = .{
16068            .sturh = .{
16069                .Rt = t.alias.encode(.{}),
16070                .Rn = n.alias.encode(.{ .sp = true }),
16071                .imm9 = simm,
16072            },
16073        } } } };
16074    }
16075    /// C6.2.356 SUB (extended register)
16076    /// C6.2.357 SUB (immediate)
16077    /// C6.2.358 SUB (shifted register)
16078    pub fn sub(d: Register, n: Register, form: union(enum) {
16079        extended_register_explicit: struct {
16080            register: Register,
16081            option: DataProcessingRegister.AddSubtractExtendedRegister.Option,
16082            amount: DataProcessingRegister.AddSubtractExtendedRegister.Extend.Amount,
16083        },
16084        extended_register: struct { register: Register, extend: DataProcessingRegister.AddSubtractExtendedRegister.Extend },
16085        immediate: u12,
16086        shifted_immediate: struct { immediate: u12, lsl: DataProcessingImmediate.AddSubtractImmediate.Shift = .@"0" },
16087        register: Register,
16088        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
16089        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
16090    }) Instruction {
16091        const sf = d.format.general;
16092        assert(n.format.general == sf);
16093        form: switch (form) {
16094            .extended_register_explicit => |extended_register_explicit| {
16095                assert(extended_register_explicit.register.format.general == switch (sf) {
16096                    .word => .word,
16097                    .doubleword => extended_register_explicit.option.sf(),
16098                });
16099                return .{ .data_processing_register = .{ .add_subtract_extended_register = .{
16100                    .sub = .{
16101                        .Rd = d.alias.encode(.{ .sp = true }),
16102                        .Rn = n.alias.encode(.{ .sp = true }),
16103                        .imm3 = switch (extended_register_explicit.amount) {
16104                            0...4 => |amount| amount,
16105                            else => unreachable,
16106                        },
16107                        .option = extended_register_explicit.option,
16108                        .Rm = extended_register_explicit.register.alias.encode(.{}),
16109                        .sf = sf,
16110                    },
16111                } } };
16112            },
16113            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
16114                .register = extended_register.register,
16115                .option = extended_register.extend,
16116                .amount = switch (extended_register.extend) {
16117                    .uxtb, .uxth, .uxtw, .uxtx, .sxtb, .sxth, .sxtw, .sxtx => |amount| amount,
16118                },
16119            } },
16120            .immediate => |immediate| continue :form .{ .shifted_immediate = .{ .immediate = immediate } },
16121            .shifted_immediate => |shifted_immediate| {
16122                return .{ .data_processing_immediate = .{ .add_subtract_immediate = .{
16123                    .sub = .{
16124                        .Rd = d.alias.encode(.{ .sp = true }),
16125                        .Rn = n.alias.encode(.{ .sp = true }),
16126                        .imm12 = shifted_immediate.immediate,
16127                        .sh = shifted_immediate.lsl,
16128                        .sf = sf,
16129                    },
16130                } } };
16131            },
16132            .register => |register| continue :form if (d.alias == .sp or n.alias == .sp or register.alias == .sp)
16133                .{ .extended_register = .{ .register = register, .extend = switch (sf) {
16134                    .word => .{ .uxtw = 0 },
16135                    .doubleword => .{ .uxtx = 0 },
16136                } } }
16137            else
16138                .{ .shifted_register = .{ .register = register } },
16139            .shifted_register_explicit => |shifted_register_explicit| {
16140                assert(shifted_register_explicit.register.format.general == sf);
16141                return .{ .data_processing_register = .{ .add_subtract_shifted_register = .{
16142                    .sub = .{
16143                        .Rd = d.alias.encode(.{}),
16144                        .Rn = n.alias.encode(.{}),
16145                        .imm6 = switch (sf) {
16146                            .word => @as(u5, @intCast(shifted_register_explicit.amount)),
16147                            .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
16148                        },
16149                        .Rm = shifted_register_explicit.register.alias.encode(.{}),
16150                        .shift = switch (shifted_register_explicit.shift) {
16151                            .lsl, .lsr, .asr => |shift| shift,
16152                            .ror => unreachable,
16153                        },
16154                        .sf = sf,
16155                    },
16156                } } };
16157            },
16158            .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
16159                .register = shifted_register.register,
16160                .shift = shifted_register.shift,
16161                .amount = switch (shifted_register.shift) {
16162                    .lsl, .lsr, .asr => |amount| amount,
16163                    .ror => unreachable,
16164                },
16165            } },
16166        }
16167    }
16168    /// C7.2.359 SUBG
16169    pub fn subg(d: Register, n: Register, uimm6: u10, uimm4: u4) Instruction {
16170        assert(d.format.general == .doubleword and n.format.general == .doubleword);
16171        return .{ .data_processing_immediate = .{ .add_subtract_immediate_with_tags = .{
16172            .subg = .{
16173                .Xd = d.alias.encode(.{ .sp = true }),
16174                .Xn = n.alias.encode(.{ .sp = true }),
16175                .uimm4 = uimm4,
16176                .uimm6 = @intCast(@shrExact(uimm6, 4)),
16177            },
16178        } } };
16179    }
16180    /// C6.2.362 SUBS (extended register)
16181    /// C6.2.363 SUBS (immediate)
16182    /// C6.2.364 SUBS (shifted register)
16183    pub fn subs(d: Register, n: Register, form: union(enum) {
16184        extended_register_explicit: struct {
16185            register: Register,
16186            option: DataProcessingRegister.AddSubtractExtendedRegister.Option,
16187            amount: DataProcessingRegister.AddSubtractExtendedRegister.Extend.Amount,
16188        },
16189        extended_register: struct { register: Register, extend: DataProcessingRegister.AddSubtractExtendedRegister.Extend },
16190        immediate: u12,
16191        shifted_immediate: struct { immediate: u12, lsl: DataProcessingImmediate.AddSubtractImmediate.Shift = .@"0" },
16192        register: Register,
16193        shifted_register_explicit: struct { register: Register, shift: DataProcessingRegister.Shift.Op, amount: u6 },
16194        shifted_register: struct { register: Register, shift: DataProcessingRegister.Shift = .none },
16195    }) Instruction {
16196        const sf = d.format.general;
16197        assert(n.format.general == sf);
16198        form: switch (form) {
16199            .extended_register_explicit => |extended_register_explicit| {
16200                assert(extended_register_explicit.register.format.general == switch (sf) {
16201                    .word => .word,
16202                    .doubleword => extended_register_explicit.option.sf(),
16203                });
16204                return .{ .data_processing_register = .{ .add_subtract_extended_register = .{
16205                    .subs = .{
16206                        .Rd = d.alias.encode(.{}),
16207                        .Rn = n.alias.encode(.{ .sp = true }),
16208                        .imm3 = switch (extended_register_explicit.amount) {
16209                            0...4 => |amount| amount,
16210                            else => unreachable,
16211                        },
16212                        .option = extended_register_explicit.option,
16213                        .Rm = extended_register_explicit.register.alias.encode(.{}),
16214                        .sf = sf,
16215                    },
16216                } } };
16217            },
16218            .extended_register => |extended_register| continue :form .{ .extended_register_explicit = .{
16219                .register = extended_register.register,
16220                .option = extended_register.extend,
16221                .amount = switch (extended_register.extend) {
16222                    .uxtb, .uxth, .uxtw, .uxtx, .sxtb, .sxth, .sxtw, .sxtx => |amount| amount,
16223                },
16224            } },
16225            .immediate => |immediate| continue :form .{ .shifted_immediate = .{ .immediate = immediate } },
16226            .shifted_immediate => |shifted_immediate| {
16227                return .{ .data_processing_immediate = .{ .add_subtract_immediate = .{
16228                    .subs = .{
16229                        .Rd = d.alias.encode(.{}),
16230                        .Rn = n.alias.encode(.{ .sp = true }),
16231                        .imm12 = shifted_immediate.immediate,
16232                        .sh = shifted_immediate.lsl,
16233                        .sf = sf,
16234                    },
16235                } } };
16236            },
16237            .register => |register| continue :form if (d.alias == .sp or n.alias == .sp or register.alias == .sp)
16238                .{ .extended_register = .{ .register = register, .extend = switch (sf) {
16239                    .word => .{ .uxtw = 0 },
16240                    .doubleword => .{ .uxtx = 0 },
16241                } } }
16242            else
16243                .{ .shifted_register = .{ .register = register } },
16244            .shifted_register_explicit => |shifted_register_explicit| {
16245                assert(shifted_register_explicit.register.format.general == sf);
16246                return .{ .data_processing_register = .{ .add_subtract_shifted_register = .{
16247                    .subs = .{
16248                        .Rd = d.alias.encode(.{}),
16249                        .Rn = n.alias.encode(.{}),
16250                        .imm6 = switch (sf) {
16251                            .word => @as(u5, @intCast(shifted_register_explicit.amount)),
16252                            .doubleword => @as(u6, @intCast(shifted_register_explicit.amount)),
16253                        },
16254                        .Rm = shifted_register_explicit.register.alias.encode(.{}),
16255                        .shift = switch (shifted_register_explicit.shift) {
16256                            .lsl, .lsr, .asr => |shift| shift,
16257                            .ror => unreachable,
16258                        },
16259                        .sf = sf,
16260                    },
16261                } } };
16262            },
16263            .shifted_register => |shifted_register| continue :form .{ .shifted_register_explicit = .{
16264                .register = shifted_register.register,
16265                .shift = shifted_register.shift,
16266                .amount = switch (shifted_register.shift) {
16267                    .lsl, .lsr, .asr => |amount| amount,
16268                    .ror => unreachable,
16269                },
16270            } },
16271        }
16272    }
16273    /// C7.2.337 SUQADD
16274    pub fn suqadd(d: Register, n: Register) Instruction {
16275        switch (d.format) {
16276            else => unreachable,
16277            .scalar => |elem_size| {
16278                assert(elem_size == n.format.scalar);
16279                return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
16280                    .suqadd = .{
16281                        .Rd = d.alias.encode(.{ .V = true }),
16282                        .Rn = n.alias.encode(.{ .V = true }),
16283                        .size = .fromScalarSize(elem_size),
16284                    },
16285                } } };
16286            },
16287            .vector => |arrangement| {
16288                assert(arrangement != .@"1d" and n.format.vector == arrangement);
16289                return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
16290                    .suqadd = .{
16291                        .Rd = d.alias.encode(.{ .V = true }),
16292                        .Rn = n.alias.encode(.{ .V = true }),
16293                        .size = arrangement.elemSize(),
16294                        .Q = arrangement.size(),
16295                    },
16296                } } };
16297            },
16298        }
16299    }
16300    /// C6.2.365 SVC
16301    pub fn svc(imm: u16) Instruction {
16302        return .{ .branch_exception_generating_system = .{ .exception_generating = .{
16303            .svc = .{ .imm16 = imm },
16304        } } };
16305    }
16306    /// C6.2.372 SYS
16307    pub fn sys(op1: u3, n: u4, m: u4, op2: u3, t: Register) Instruction {
16308        assert(t.format.general == .doubleword);
16309        return .{ .branch_exception_generating_system = .{ .system = .{
16310            .sys = .{
16311                .Rt = t.alias.encode(.{}),
16312                .op2 = op2,
16313                .CRm = m,
16314                .CRn = n,
16315                .op1 = op1,
16316            },
16317        } } };
16318    }
16319    /// C6.2.373 SYSL
16320    pub fn sysl(t: Register, op1: u3, n: u4, m: u4, op2: u3) Instruction {
16321        assert(t.format.general == .doubleword);
16322        return .{ .branch_exception_generating_system = .{ .system = .{
16323            .sysl = .{
16324                .Rt = t.alias.encode(.{}),
16325                .op2 = op2,
16326                .CRm = m,
16327                .CRn = n,
16328                .op1 = op1,
16329            },
16330        } } };
16331    }
16332    /// C6.2.374 TBNZ
16333    pub fn tbnz(t: Register, imm: u6, label: i16) Instruction {
16334        return .{ .branch_exception_generating_system = .{ .test_branch_immediate = .{
16335            .tbnz = .{
16336                .Rt = t.alias.encode(.{}),
16337                .imm14 = @intCast(@shrExact(label, 2)),
16338                .b40 = @truncate(switch (t.format.general) {
16339                    .word => @as(u5, @intCast(imm)),
16340                    .doubleword => imm,
16341                }),
16342                .b5 = @intCast(imm >> 5),
16343            },
16344        } } };
16345    }
16346    /// C6.2.375 TBZ
16347    pub fn tbz(t: Register, imm: u6, label: i16) Instruction {
16348        return .{ .branch_exception_generating_system = .{ .test_branch_immediate = .{
16349            .tbz = .{
16350                .Rt = t.alias.encode(.{}),
16351                .imm14 = @intCast(@shrExact(label, 2)),
16352                .b40 = @truncate(switch (t.format.general) {
16353                    .word => @as(u5, @intCast(imm)),
16354                    .doubleword => imm,
16355                }),
16356                .b5 = @intCast(imm >> 5),
16357            },
16358        } } };
16359    }
16360    /// C6.2.376 TCANCEL
16361    pub fn tcancel(imm: u16) Instruction {
16362        return .{ .branch_exception_generating_system = .{ .exception_generating = .{
16363            .tcancel = .{ .imm16 = imm },
16364        } } };
16365    }
16366    /// C6.2.385 UBFM
16367    pub fn ubfm(d: Register, n: Register, bitmask: DataProcessingImmediate.Bitmask) Instruction {
16368        const sf = d.format.general;
16369        assert(n.format.general == sf and bitmask.validBitfield(sf));
16370        return .{ .data_processing_immediate = .{ .bitfield = .{
16371            .ubfm = .{
16372                .Rd = d.alias.encode(.{}),
16373                .Rn = n.alias.encode(.{}),
16374                .imm = bitmask,
16375                .sf = sf,
16376            },
16377        } } };
16378    }
16379    /// C7.2.353 UCVTF (vector, integer)
16380    /// C7.2.355 UCVTF (scalar, integer)
16381    pub fn ucvtf(d: Register, n: Register) Instruction {
16382        switch (d.format) {
16383            else => unreachable,
16384            .scalar => |ftype| switch (n.format) {
16385                else => unreachable,
16386                .scalar => |elem_size| {
16387                    assert(ftype == elem_size);
16388                    switch (ftype) {
16389                        else => unreachable,
16390                        .half => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous_fp16 = .{
16391                            .ucvtf = .{
16392                                .Rd = d.alias.encode(.{ .V = true }),
16393                                .Rn = n.alias.encode(.{ .V = true }),
16394                            },
16395                        } } },
16396                        .single, .double => return .{ .data_processing_vector = .{ .simd_scalar_two_register_miscellaneous = .{
16397                            .ucvtf = .{
16398                                .Rd = d.alias.encode(.{ .V = true }),
16399                                .Rn = n.alias.encode(.{ .V = true }),
16400                                .sz = .fromScalarSize(ftype),
16401                            },
16402                        } } },
16403                    }
16404                },
16405                .general => |sf| return .{ .data_processing_vector = .{ .convert_float_integer = .{
16406                    .ucvtf = .{
16407                        .Rd = d.alias.encode(.{ .V = true }),
16408                        .Rn = n.alias.encode(.{}),
16409                        .ftype = .fromScalarSize(ftype),
16410                        .sf = sf,
16411                    },
16412                } } },
16413            },
16414            .vector => |arrangement| {
16415                assert(arrangement != .@"1d" and n.format.vector == arrangement);
16416                switch (arrangement.elemSize()) {
16417                    else => unreachable,
16418                    .half => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous_fp16 = .{
16419                        .ucvtf = .{
16420                            .Rd = d.alias.encode(.{ .V = true }),
16421                            .Rn = n.alias.encode(.{ .V = true }),
16422                            .Q = arrangement.size(),
16423                        },
16424                    } } },
16425                    .single, .double => return .{ .data_processing_vector = .{ .simd_two_register_miscellaneous = .{
16426                        .ucvtf = .{
16427                            .Rd = d.alias.encode(.{ .V = true }),
16428                            .Rn = n.alias.encode(.{ .V = true }),
16429                            .sz = arrangement.elemSz(),
16430                            .Q = arrangement.size(),
16431                        },
16432                    } } },
16433                }
16434            },
16435        }
16436    }
16437    /// C6.2.387 UDF
16438    pub fn udf(imm: u16) Instruction {
16439        return .{ .reserved = .{
16440            .udf = .{ .imm16 = imm },
16441        } };
16442    }
16443    /// C6.2.388 UDIV
16444    pub fn udiv(d: Register, n: Register, m: Register) Instruction {
16445        const sf = d.format.general;
16446        assert(n.format.general == sf and m.format.general == sf);
16447        return .{ .data_processing_register = .{ .data_processing_two_source = .{
16448            .udiv = .{
16449                .Rd = d.alias.encode(.{}),
16450                .Rn = n.alias.encode(.{}),
16451                .Rm = m.alias.encode(.{}),
16452                .sf = sf,
16453            },
16454        } } };
16455    }
16456    /// C6.2.389 UMADDL
16457    pub fn umaddl(d: Register, n: Register, m: Register, a: Register) Instruction {
16458        assert(d.format.general == .doubleword and n.format.general == .word and m.format.general == .word and a.format.general == .doubleword);
16459        return .{ .data_processing_register = .{ .data_processing_three_source = .{
16460            .umaddl = .{
16461                .Rd = d.alias.encode(.{}),
16462                .Rn = n.alias.encode(.{}),
16463                .Ra = a.alias.encode(.{}),
16464                .Rm = m.alias.encode(.{}),
16465            },
16466        } } };
16467    }
16468    /// C6.2.391 UMSUBL
16469    pub fn umsubl(d: Register, n: Register, m: Register, a: Register) Instruction {
16470        assert(d.format.general == .doubleword and n.format.general == .word and m.format.general == .word and a.format.general == .doubleword);
16471        return .{ .data_processing_register = .{ .data_processing_three_source = .{
16472            .umsubl = .{
16473                .Rd = d.alias.encode(.{}),
16474                .Rn = n.alias.encode(.{}),
16475                .Ra = a.alias.encode(.{}),
16476                .Rm = m.alias.encode(.{}),
16477            },
16478        } } };
16479    }
16480    /// C7.2.371 UMOV
16481    pub fn umov(d: Register, n: Register) Instruction {
16482        const sf = d.format.general;
16483        const vs = n.format.element.size;
16484        switch (vs) {
16485            else => unreachable,
16486            .byte, .half, .single => assert(sf == .word),
16487            .double => assert(sf == .doubleword),
16488        }
16489        return .{ .data_processing_vector = .{ .simd_copy = .{
16490            .umov = .{
16491                .Rd = d.alias.encode(.{}),
16492                .Rn = n.alias.encode(.{ .V = true }),
16493                .imm5 = switch (vs) {
16494                    else => unreachable,
16495                    .byte => @as(u5, @as(u4, @intCast(n.format.element.index))) << 1 | @as(u5, 0b1) << 0,
16496                    .half => @as(u5, @as(u3, @intCast(n.format.element.index))) << 2 | @as(u5, 0b10) << 0,
16497                    .single => @as(u5, @as(u2, @intCast(n.format.element.index))) << 3 | @as(u5, 0b100) << 0,
16498                    .double => @as(u5, @as(u1, @intCast(n.format.element.index))) << 4 | @as(u5, 0b1000) << 0,
16499                },
16500                .Q = sf,
16501            },
16502        } } };
16503    }
16504    /// C6.2.392 UMULH
16505    pub fn umulh(d: Register, n: Register, m: Register) Instruction {
16506        assert(d.format.general == .doubleword and n.format.general == .doubleword and m.format.general == .doubleword);
16507        return .{ .data_processing_register = .{ .data_processing_three_source = .{
16508            .umulh = .{
16509                .Rd = d.alias.encode(.{}),
16510                .Rn = n.alias.encode(.{}),
16511                .Rm = m.alias.encode(.{}),
16512            },
16513        } } };
16514    }
16515    /// C6.2.396 WFE
16516    pub fn wfe() Instruction {
16517        return .{ .branch_exception_generating_system = .{ .hints = .{
16518            .wfe = .{},
16519        } } };
16520    }
16521    /// C6.2.398 WFI
16522    pub fn wfi() Instruction {
16523        return .{ .branch_exception_generating_system = .{ .hints = .{
16524            .wfi = .{},
16525        } } };
16526    }
16527    /// C6.2.400 XAFLAG
16528    pub fn xaflag() Instruction {
16529        return .{ .branch_exception_generating_system = .{ .pstate = .{
16530            .xaflag = .{},
16531        } } };
16532    }
16533    /// C6.2.402 YIELD
16534    pub fn yield() Instruction {
16535        return .{ .branch_exception_generating_system = .{ .hints = .{
16536            .yield = .{},
16537        } } };
16538    }
16539
16540    pub const size = @divExact(@bitSizeOf(Backing), 8);
16541    pub const Backing = u32;
16542    pub fn read(mem: *const [size]u8) Instruction {
16543        return @bitCast(std.mem.readInt(Backing, mem, .little));
16544    }
16545    pub fn write(inst: Instruction, mem: *[size]u8) void {
16546        std.mem.writeInt(Backing, mem, @bitCast(inst), .little);
16547    }
16548
16549    pub fn format(inst: Instruction, writer: *std.Io.Writer) std.Io.Writer.Error!void {
16550        const dis: aarch64.Disassemble = .{};
16551        try dis.printInstruction(inst, writer);
16552    }
16553
16554    comptime {
16555        @setEvalBranchQuota(110_000);
16556        verify(@typeName(Instruction), Instruction);
16557    }
16558    fn verify(name: []const u8, Type: type) void {
16559        switch (@typeInfo(Type)) {
16560            .@"union" => |info| {
16561                if (info.layout != .@"packed" or @bitSizeOf(Type) != @bitSizeOf(Backing)) {
16562                    @compileLog(name ++ " should have u32 abi");
16563                }
16564                for (info.fields) |field| verify(name ++ "." ++ field.name, field.type);
16565            },
16566            .@"struct" => |info| {
16567                if (info.layout != .@"packed" or info.backing_integer != Backing) {
16568                    @compileLog(name ++ " should have u32 abi");
16569                }
16570                var bit_offset = 0;
16571                for (info.fields) |field| {
16572                    if (std.mem.startsWith(u8, field.name, "encoded")) {
16573                        if (if (std.fmt.parseInt(u5, field.name["encoded".len..], 10)) |encoded_bit_offset| encoded_bit_offset != bit_offset else |_| true) {
16574                            @compileError(std.fmt.comptimePrint("{s}.{s} should be named encoded{d}", .{ name, field.name, bit_offset }));
16575                        }
16576                        if (field.default_value_ptr != null) {
16577                            @compileError(std.fmt.comptimePrint("{s}.{s} should be named decoded{d}", .{ name, field.name, bit_offset }));
16578                        }
16579                    } else if (std.mem.startsWith(u8, field.name, "decoded")) {
16580                        if (if (std.fmt.parseInt(u5, field.name["decoded".len..], 10)) |decoded_bit_offset| decoded_bit_offset != bit_offset else |_| true) {
16581                            @compileError(std.fmt.comptimePrint("{s}.{s} should be named decoded{d}", .{ name, field.name, bit_offset }));
16582                        }
16583                        if (field.default_value_ptr == null) {
16584                            @compileError(std.fmt.comptimePrint("{s}.{s} should be named encoded{d}", .{ name, field.name, bit_offset }));
16585                        }
16586                    }
16587                    bit_offset += @bitSizeOf(field.type);
16588                }
16589            },
16590            else => @compileError(name ++ " has an unexpected field type"),
16591        }
16592    }
16593};
16594
16595const aarch64 = @import("../aarch64.zig");
16596const assert = std.debug.assert;
16597const std = @import("std");