[PATCH v2 1/9] aarch64: Extend aarch64_field to support constants

Richard Earnshaw Richard.Earnshaw@arm.com
Thu Oct 9 09:24:21 GMT 2025


On 09/10/2025 08:41, Alice Carlotti wrote:
> Many instructions have constraints on the range of registers they can
> use.  This means that some bits in the register number are fixed, and
> therefore aren't mapped to a field in the instruction encoding.
> Currently we use various adhoc rules to handle these fixed bits, but
> this doesn't handle all cases and we often have to write new code to
> support new combinations of permitted registers.
> 
> This patch allows these constant bits to instead be specified in the
> same structure used to represent instruction fields.  Uses of the new
> constant fields will be introduced in subsequent patches.
> 
> 
> diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
> index 75216fd8dc3c4b269dcb123e9896c2d2f0e6debc..fafbc4db375a0fd552b947f31825c1295e119925 100644
> --- a/opcodes/aarch64-asm.c
> +++ b/opcodes/aarch64-asm.c
> @@ -313,7 +313,7 @@ aarch64_ins_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
>   			   const aarch64_inst *inst ATTRIBUTE_UNUSED,
>   			   aarch64_operand_error *errors ATTRIBUTE_UNUSED)
>   {
> -  aarch64_field field = {0, 0};
> +  aarch64_field field = AARCH64_FIELD_NIL;
>     aarch64_insn QSsize = 0;	/* fields Q:S:size.  */
>     aarch64_insn opcodeh2 = 0;	/* opcode<2:1> */
>   
> @@ -459,7 +459,7 @@ aarch64_ins_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
>     uint64_t imm = info->imm.value;
>     enum aarch64_modifier_kind kind = info->shifter.kind;
>     int amount = info->shifter.amount;
> -  aarch64_field field = {0, 0};
> +  aarch64_field field = AARCH64_FIELD_NIL;
>   
>     /* a:b:c:d:e:f:g:h */
>     if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
> @@ -1833,7 +1833,7 @@ static void
>   encode_asimd_fcvt (aarch64_inst *inst)
>   {
>     aarch64_insn value;
> -  aarch64_field field = {0, 0};
> +  aarch64_field field = AARCH64_FIELD_NIL;
>     enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_NIL;
>   
>     switch (inst->opcode->op)
> @@ -1865,7 +1865,7 @@ static void
>   encode_asisd_fcvtxn (aarch64_inst *inst)
>   {
>     aarch64_insn val = 1;
> -  aarch64_field field = {0, 0};
> +  aarch64_field field = AARCH64_FIELD_NIL;
>     assert (inst->operands[0].qualifier == AARCH64_OPND_QLF_S_S);
>     gen_sub_field (FLD_size, 0, 1, &field);
>     insert_field_2 (&field, &inst->value, val, 0);
> @@ -1876,7 +1876,7 @@ static void
>   encode_fcvt (aarch64_inst *inst)
>   {
>     aarch64_insn val;
> -  const aarch64_field field = {15, 2};
> +  const aarch64_field field = AARCH64_FIELD (15, 2);
>   
>     /* opc dstsize */
>     switch (inst->operands[0].qualifier)
> @@ -2096,7 +2096,7 @@ do_special_encoding (struct aarch64_inst *inst)
>     if (inst->opcode->flags & F_T)
>       {
>         int num;	/* num of consecutive '0's on the right side of imm5<3:0>.  */
> -      aarch64_field field = {0, 0};
> +      aarch64_field field = AARCH64_FIELD_NIL;
>         enum aarch64_opnd_qualifier qualifier;
>   
>         idx = 0;
> @@ -2157,7 +2157,7 @@ do_special_encoding (struct aarch64_inst *inst)
>       {
>         /* e.g. LDRSB <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}].  */
>         enum aarch64_opnd_qualifier qualifier;
> -      aarch64_field field = {0, 0};
> +      aarch64_field field = AARCH64_FIELD_NIL;
>         assert (aarch64_get_operand_class (inst->opcode->operands[0])
>   	      == AARCH64_OPND_CLASS_INT_REG);
>         gen_sub_field (FLD_opc, 0, 1, &field);
> diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
> index 3ca22bb5c8ac4e4ce544c6ff13a618c4fbe225c6..e66a729f30ac888944961f986ddb4aab7a407881 100644
> --- a/opcodes/aarch64-dis.c
> +++ b/opcodes/aarch64-dis.c
> @@ -584,7 +584,7 @@ aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
>   			   const aarch64_inst *inst ATTRIBUTE_UNUSED,
>   			   aarch64_operand_error *errors ATTRIBUTE_UNUSED)
>   {
> -  aarch64_field field = {0, 0};
> +  aarch64_field field = AARCH64_FIELD_NIL;
>     aarch64_insn QSsize;		/* fields Q:S:size.  */
>     aarch64_insn opcodeh2;	/* opcode<2:1> */
>   
> @@ -796,7 +796,7 @@ aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
>   {
>     uint64_t imm;
>     enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
> -  aarch64_field field = {0, 0};
> +  aarch64_field field = AARCH64_FIELD_NIL;
>   
>     assert (info->idx == 1);
>   
> @@ -2596,7 +2596,7 @@ decode_sizeq (aarch64_inst *inst)
>   static int
>   decode_asimd_fcvt (aarch64_inst *inst)
>   {
> -  aarch64_field field = {0, 0};
> +  aarch64_field field = AARCH64_FIELD_NIL;
>     aarch64_insn value;
>     enum aarch64_opnd_qualifier qualifier;
>   
> @@ -2629,7 +2629,7 @@ decode_asimd_fcvt (aarch64_inst *inst)
>   static int
>   decode_asisd_fcvtxn (aarch64_inst *inst)
>   {
> -  aarch64_field field = {0, 0};
> +  aarch64_field field = AARCH64_FIELD_NIL;
>     gen_sub_field (FLD_size, 0, 1, &field);
>     if (!extract_field_2 (&field, inst->value, 0))
>       return 0;
> @@ -2643,7 +2643,7 @@ decode_fcvt (aarch64_inst *inst)
>   {
>     enum aarch64_opnd_qualifier qualifier;
>     aarch64_insn value;
> -  const aarch64_field field = {15, 2};
> +  const aarch64_field field = AARCH64_FIELD (15, 2);
>   
>     /* opc dstsize */
>     value = extract_field_2 (&field, inst->value, 0);
> @@ -2922,7 +2922,7 @@ do_special_decoding (aarch64_inst *inst)
>   
>     if (inst->opcode->flags & F_LDS_SIZE)
>       {
> -      aarch64_field field = {0, 0};
> +      aarch64_field field = AARCH64_FIELD_NIL;
>         assert (aarch64_get_operand_class (inst->opcode->operands[0])
>   	      == AARCH64_OPND_CLASS_INT_REG);
>         gen_sub_field (FLD_opc, 0, 1, &field);
> diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
> index 4b173201e92bc7fd5c6d4e306e1f8fb332b0e041..cea61eb606f33294e341112a05b186bbad38ddac 100644
> --- a/opcodes/aarch64-opc.c
> +++ b/opcodes/aarch64-opc.c
> @@ -225,220 +225,219 @@ aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
>   +   Keep synced with 'enum aarch64_field_kind'.  */
>   const aarch64_field aarch64_fields[] =
>   {
> -    {  0,  0 },	/* NIL.  */
> -    {  8,  4 },	/* CRm: in the system instructions.  */
> -    { 10,  2 }, /* CRm_dsb_nxs: 2-bit imm. encoded in CRm<3:2>.  */
> -    { 12,  4 },	/* CRn: in the system instructions.  */
> -    { 10,  8 }, /* CSSC_imm8.  */
> -    { 11,  1 },	/* H: in advsimd scalar x indexed element instructions.  */
> -    { 21,  1 },	/* L: in advsimd scalar x indexed element instructions.  */
> -    {  0,  5 },	/* LSE128_Rt: Shared input+output operand register.  */
> -    { 16,  5 },	/* LSE128_Rt2: Shared input+output operand register 2.  */
> -    { 20,  1 },	/* M: in advsimd scalar x indexed element instructions.  */
> -    { 22,  1 },	/* N: in logical (immediate) instructions.  */
> -    { 30,  1 },	/* Q: in most AdvSIMD instructions.  */
> -    { 10,  5 },	/* Ra: in fp instructions.  */
> -    {  0,  5 },	/* Rd: in many integer instructions.  */
> -    { 16,  5 },	/* Rm: in ld/st reg offset and some integer inst.  */
> -    {  5,  5 },	/* Rn: in many integer instructions.  */
> -    { 16,  5 },	/* Rs: in load/store exclusive instructions.  */
> -    {  0,  5 },	/* Rt: in load/store instructions.  */
> -    { 10,  5 },	/* Rt2: in load/store pair instructions.  */
> -    { 12,  1 },	/* S: in load/store reg offset instructions.  */
> -    { 12,  2 }, /* SM3_imm2: Indexed element SM3 2 bits index immediate.  */
> -    {  1,  3 }, /* SME_Pdx2: predicate register, multiple of 2, [3:1].  */
> -    { 13,  3 }, /* SME_Pm: second source scalable predicate register P0-P7.  */
> -    {  0,  3 }, /* SME_PNd3: PN0-PN7, bits [2:0].  */
> -    {  5,  3 }, /* SME_PNn3: PN0-PN7, bits [7:5].  */
> -    { 16,  1 }, /* SME_Q: Q class bit, bit 16.  */
> -    { 16,  2 }, /* SME_Rm: index base register W12-W15 [17:16].  */
> -    { 13,  2 }, /* SME_Rv: vector select register W12-W15, bits [14:13].  */
> -    { 15,  1 }, /* SME_V: (horizontal / vertical tiles), bit 15.  */
> -    { 10,  1 }, /* SME_VL_10: VLx2 or VLx4, bit [10].  */
> -    { 13,  1 }, /* SME_VL_13: VLx2 or VLx4, bit [13].  */
> -    {  0,  1 }, /* SME_ZAda_1b: tile ZA0-ZA1.  */
> -    {  0,  2 }, /* SME_ZAda_2b: tile ZA0-ZA3.  */
> -    {  0,  3 }, /* SME_ZAda_3b: tile ZA0-ZA7.  */
> -    {  1,  4 }, /* SME_Zdn2: Z0-Z31, multiple of 2, bits [4:1].  */
> -    {  2,  3 }, /* SME_Zdn4: Z0-Z31, multiple of 4, bits [4:2].  */
> -    { 16,  4 }, /* SME_Zm: Z0-Z15, bits [19:16].  */
> -    { 17,  4 }, /* SME_Zm2: Z0-Z31, multiple of 2, bits [20:17].  */
> -    { 18,  3 }, /* SME_Zm4: Z0-Z31, multiple of 4, bits [20:18].  */
> -    {  6,  4 }, /* SME_Zn2: Z0-Z31, multiple of 2, bits [9:6].  */
> -    {  7,  3 }, /* SME_Zn4: Z0-Z31, multiple of 4, bits [9:7].  */
> -    {  4,  1 }, /* SME_ZtT: upper bit of Zt, bit [4].  */
> -    {  0,  3 }, /* SME_Zt3: lower 3 bits of Zt, bits [2:0].  */
> -    {  0,  2 }, /* SME_Zt2: lower 2 bits of Zt, bits [1:0].  */
> -    { 23,  1 }, /* SME_i1: immediate field, bit 23.  */
> -    { 12,  2 }, /* SME_size_12: bits [13:12].  */
> -    { 22,  2 }, /* SME_size_22: size<1>, size<0> class field, [23:22].  */
> -    { 23,  1 }, /* SME_sz_23: bit [23].  */
> -    { 22,  1 }, /* SME_tszh: immediate and qualifier field, bit 22.  */
> -    { 18,  3 }, /* SME_tszl: immediate and qualifier field, bits [20:18].  */
> -    { 0,   8 }, /* SME_zero_mask: list of up to 8 tile names separated by commas [7:0].  */
> -    {  4,  1 }, /* SVE_M_4: Merge/zero select, bit 4.  */
> -    { 14,  1 }, /* SVE_M_14: Merge/zero select, bit 14.  */
> -    { 16,  1 }, /* SVE_M_16: Merge/zero select, bit 16.  */
> -    { 17,  1 }, /* SVE_N: SVE equivalent of N.  */
> -    {  0,  4 }, /* SVE_Pd: p0-p15, bits [3,0].  */
> -    { 10,  3 }, /* SVE_Pg3: p0-p7, bits [12,10].  */
> -    {  5,  4 }, /* SVE_Pg4_5: p0-p15, bits [8,5].  */
> -    { 10,  4 }, /* SVE_Pg4_10: p0-p15, bits [13,10].  */
> -    { 16,  4 }, /* SVE_Pg4_16: p0-p15, bits [19,16].  */
> -    { 16,  4 }, /* SVE_Pm: p0-p15, bits [19,16].  */
> -    {  5,  4 }, /* SVE_Pn: p0-p15, bits [8,5].  */
> -    {  0,  4 }, /* SVE_Pt: p0-p15, bits [3,0].  */
> -    {  5,  5 }, /* SVE_Rm: SVE alternative position for Rm.  */
> -    { 16,  5 }, /* SVE_Rn: SVE alternative position for Rn.  */
> -    {  0,  5 }, /* SVE_Vd: Scalar SIMD&FP register, bits [4,0].  */
> -    {  5,  5 }, /* SVE_Vm: Scalar SIMD&FP register, bits [9,5].  */
> -    {  5,  5 }, /* SVE_Vn: Scalar SIMD&FP register, bits [9,5].  */
> -    {  5,  5 }, /* SVE_Za_5: SVE vector register, bits [9,5].  */
> -    { 16,  5 }, /* SVE_Za_16: SVE vector register, bits [20,16].  */
> -    {  0,  5 }, /* SVE_Zd: SVE vector register. bits [4,0].  */
> -    {  5,  5 }, /* SVE_Zm_5: SVE vector register, bits [9,5].  */
> -    { 16,  5 }, /* SVE_Zm_16: SVE vector register, bits [20,16]. */
> -    {  5,  5 }, /* SVE_Zn: SVE vector register, bits [9,5].  */
> -    {  0,  5 }, /* SVE_Zt: SVE vector register, bits [4,0].  */
> -    {  5,  1 }, /* SVE_i1: single-bit immediate.  */
> -    { 23,  1 }, /* SVE_i1_23: single-bit immediate.  */
> -    { 22,  2 }, /* SVE_i2: 2-bit index, bits [23,22].  */
> -    { 20,  1 }, /* SVE_i2h: high bit of 2bit immediate, bits.  */
> -    { 22,  1 }, /* SVE_i3h: high bit of 3-bit immediate.  */
> -    { 19,  2 }, /* SVE_i3h2: two high bits of 3bit immediate, bits [20,19].  */
> -    { 22,  2 }, /* SVE_i3h3: two high bits of 3bit immediate, bits [22,23].  */
> -    { 11,  1 }, /* SVE_i3l: low bit of 3-bit immediate.  */
> -    { 12,  1 }, /* SVE_i3l2: low bit of 3-bit immediate, bit 12.  */
> -    { 10,  2 }, /* SVE_i4l2: two low bits of 4bit immediate, bits [11,10].  */
> -    { 16,  3 }, /* SVE_imm3: 3-bit immediate field.  */
> -    { 16,  4 }, /* SVE_imm4: 4-bit immediate field.  */
> -    {  5,  5 }, /* SVE_imm5: 5-bit immediate field.  */
> -    { 16,  5 }, /* SVE_imm5b: secondary 5-bit immediate field.  */
> -    { 16,  6 }, /* SVE_imm6: 6-bit immediate field.  */
> -    { 14,  7 }, /* SVE_imm7: 7-bit immediate field.  */
> -    {  5,  8 }, /* SVE_imm8: 8-bit immediate field.  */
> -    {  5,  9 }, /* SVE_imm9: 9-bit immediate field.  */
> -    { 11,  6 }, /* SVE_immr: SVE equivalent of immr.  */
> -    {  5,  6 }, /* SVE_imms: SVE equivalent of imms.  */
> -    { 10,  2 }, /* SVE_msz: 2-bit shift amount for ADR.  */
> -    {  5,  5 }, /* SVE_pattern: vector pattern enumeration.  */
> -    {  0,  4 }, /* SVE_prfop: prefetch operation for SVE PRF[BHWD].  */
> -    { 16,  1 }, /* SVE_rot1: 1-bit rotation amount.  */
> -    { 10,  2 }, /* SVE_rot2: 2-bit rotation amount.  */
> -    { 10,  1 }, /* SVE_rot3: 1-bit rotation amount at bit 10.  */
> -    { 17,  2 }, /* SVE_size: 2-bit element size, bits [18,17].  */
> -    { 22,  1 }, /* SVE_sz: 1-bit element size select.  */
> -    { 30,  1 }, /* SVE_sz2: 1-bit element size select.  */
> -    { 17,  1 }, /* SVE_sz3: 1-bit element size select.  */
> -    { 14,  1 }, /* SVE_sz4: 1-bit element size select.  */
> -    { 16,  4 }, /* SVE_tsz: triangular size select.  */
> -    { 22,  2 }, /* SVE_tszh: triangular size select high, bits [23,22].  */
> -    {  8,  2 }, /* SVE_tszl_8: triangular size select low, bits [9,8].  */
> -    { 19,  2 }, /* SVE_tszl_19: triangular size select low, bits [20,19].  */
> -    { 14,  1 }, /* SVE_xs_14: UXTW/SXTW select (bit 14).  */
> -    { 22,  1 }, /* SVE_xs_22: UXTW/SXTW select (bit 22).  */
> -    { 22,  1 },	/* S_imm10: in LDRAA and LDRAB instructions.  */
> -    { 16,  3 },	/* abc: a:b:c bits in AdvSIMD modified immediate.  */
> -    { 13,  3 },	/* asisdlso_opcode: opcode in advsimd ld/st single element.  */
> -    { 19,  5 },	/* b40: in the test bit and branch instructions.  */
> -    { 31,  1 },	/* b5: in the test bit and branch instructions.  */
> -    { 12,  4 },	/* cmode: in advsimd modified immediate instructions.  */
> -    { 12,  4 },	/* cond: condition flags as a source operand.  */
> -    {  0,  4 },	/* cond2: condition in truly conditional-executed inst.  */
> -    {  5,  5 },	/* defgh: d:e:f:g:h bits in AdvSIMD modified immediate.  */
> -    { 21,  2 },	/* hw: in move wide constant instructions.  */
> -    {  0,  1 },	/* imm1_0: general immediate in bits [0].  */
> -    {  2,  1 },	/* imm1_2: general immediate in bits [2].  */
> -    {  3,  1 },	/* imm1_3: general immediate in bits [3].  */
> -    {  8,  1 },	/* imm1_8: general immediate in bits [8].  */
> -    { 10,  1 },	/* imm1_10: general immediate in bits [10].  */
> -    { 14,  1 },	/* imm1_14: general immediate in bits [14].  */
> -    { 15,  1 },	/* imm1_15: general immediate in bits [15].  */
> -    { 16,  1 },	/* imm1_16: general immediate in bits [16].  */
> -    {  0,  2 },	/* imm2_0: general immediate in bits [1:0].  */
> -    {  1,  2 },	/* imm2_1: general immediate in bits [2:1].  */
> -    {  2,  2 },	/* imm2_2: general immediate in bits [3:2].  */
> -    {  8,  2 },	/* imm2_8: general immediate in bits [9:8].  */
> -    { 10,  2 }, /* imm2_10: 2-bit immediate, bits [11:10] */
> -    { 12,  2 }, /* imm2_12: 2-bit immediate, bits [13:12] */
> -    { 13,  2 }, /* imm2_13: 2-bit immediate, bits [14:13] */
> -    { 15,  2 }, /* imm2_15: 2-bit immediate, bits [16:15] */
> -    { 16,  2 }, /* imm2_16: 2-bit immediate, bits [17:16] */
> -    { 19,  2 }, /* imm2_19: 2-bit immediate, bits [20:19] */
> -    {  0,  3 },	/* imm3_0: general immediate in bits [2:0].  */
> -    {  5,  3 },	/* imm3_5: general immediate in bits [7:5].  */
> -    { 10,  3 },	/* imm3_10: in add/sub extended reg instructions.  */
> -    { 12,  3 },	/* imm3_12: general immediate in bits [14:12].  */
> -    { 14,  3 },	/* imm3_14: general immediate in bits [16:14].  */
> -    { 15,  3 },	/* imm3_15: general immediate in bits [17:15].  */
> -    { 19,  3 },	/* imm3_19: general immediate in bits [21:19].  */
> -    {  0,  4 },	/* imm4_0: in rmif instructions.  */
> -    {  5,  4 }, /* imm4_5: in SME instructions.  */
> -    { 10,  4 },	/* imm4_10: in adddg/subg instructions.  */
> -    { 11,  4 },	/* imm4_11: in advsimd ext and advsimd ins instructions.  */
> -    { 14,  4 },	/* imm4_14: general immediate in bits [17:14].  */
> -    { 16,  5 },	/* imm5: in conditional compare (immediate) instructions.  */
> -    { 10,  6 },	/* imm6_10: in add/sub reg shifted instructions.  */
> -    { 15,  6 },	/* imm6_15: in rmif instructions.  */
> -    { 15,  7 },	/* imm7: in load/store pair pre/post index instructions.  */
> -    { 13,  8 },	/* imm8: in floating-point scalar move immediate inst.  */
> -    { 12,  9 },	/* imm9: in load/store pre/post index instructions.  */
> -    {  5,  9 },	/* imm9_5: in CB<cc> (immediate).  */
> -    { 10, 12 },	/* imm12: in ld/st unsigned imm or add/sub shifted inst.  */
> -    {  5, 14 },	/* imm14: in test bit and branch instructions.  */
> -    {  0, 16 },	/* imm16_0: in udf instruction. */
> -    {  5, 16 },	/* imm16_5: in exception instructions.  */
> -    { 17,  1 }, /* imm17_1: in 1 bit element index.  */
> -    { 17,  2 }, /* imm17_2: in 2 bits element index.  */
> -    {  5, 19 },	/* imm19: e.g. in CBZ.  */
> -    {  0, 26 },	/* imm26: in unconditional branch instructions.  */
> -    { 16,  3 },	/* immb: in advsimd shift by immediate instructions.  */
> -    { 19,  4 },	/* immh: in advsimd shift by immediate instructions.  */
> -    {  5, 19 },	/* immhi: e.g. in ADRP.  */
> -    { 29,  2 },	/* immlo: e.g. in ADRP.  */
> -    { 16,  6 },	/* immr: in bitfield and logical immediate instructions.  */
> -    { 10,  6 },	/* imms: in bitfield and logical immediate instructions.  */
> -    { 11,  1 },	/* index: in ld/st inst deciding the pre/post-index.  */
> -    { 24,  1 },	/* index2: in ld/st pair inst deciding the pre/post-index.  */
> -    { 30,  2 },	/* ldst_size: size field in ld/st reg offset inst.  */
> -    { 13,  2 },	/* len: in advsimd tbl/tbx instructions.  */
> -    { 30,  1 },	/* lse_sz: in LSE extension atomic instructions.  */
> -    {  0,  4 },	/* nzcv: flag bit specifier, encoded in the "nzcv" field.  */
> -    { 29,  1 },	/* op: in AdvSIMD modified immediate instructions.  */
> -    { 19,  2 },	/* op0: in the system instructions.  */
> -    { 16,  3 },	/* op1: in the system instructions.  */
> -    {  5,  3 },	/* op2: in the system instructions.  */
> -    { 22,  2 },	/* opc: in load/store reg offset instructions.  */
> -    { 23,  1 },	/* opc1: in load/store reg offset instructions.  */
> -    { 12,  4 },	/* opcode: in advsimd load/store instructions.  */
> -    { 13,  3 },	/* option: in ld/st reg offset + add/sub extended reg inst.  */
> -    { 11,  2 }, /* rotate1: FCMLA immediate rotate.  */
> -    { 13,  2 }, /* rotate2: Indexed element FCMLA immediate rotate.  */
> -    { 12,  1 }, /* rotate3: FCADD immediate rotate.  */
> -    { 10,  6 },	/* scale: in the fixed-point scalar to fp converting inst.  */
> -    { 31,  1 },	/* sf: in integer data processing instructions.  */
> -    { 22,  2 },	/* shift: in add/sub reg/imm shifted instructions.  */
> -    { 22,  2 },	/* size: in most AdvSIMD and floating-point instructions.  */
> -    { 22,  1 }, /* sz: 1-bit element size select.  */
> -    { 22,  2 },	/* type: floating point type field in fp data inst.  */
> -    { 10,  2 },	/* vldst_size: size field in the AdvSIMD load/store inst.  */
> -    {  5,  3 }, /* off3: immediate offset used to calculate slice number in a
> -		   ZA tile.  */
> -    {  5,  2 }, /* off2: immediate offset used to calculate slice number in
> -		   a ZA tile.  */
> -    {  7,  1 }, /* ZAn_1: name of the 1bit encoded ZA tile.  */
> -    {  5,  1 }, /* ol: immediate offset used to calculate slice number in a ZA
> -		   tile.  */
> -    {  6,  2 }, /* ZAn_2: name of the 2bit encoded ZA tile.  */
> -    {  5,  3 }, /* ZAn_3: name of the 3bit encoded ZA tile.  */
> -    {  6,  1 }, /* ZAn: name of the bit encoded ZA tile.  */
> -    { 12,  4 },	/* opc2: in rcpc3 ld/st inst deciding the pre/post-index.  */
> -    { 30,  2 },	/* rcpc3_size: in rcpc3 ld/st, field controls Rt/Rt2 width.  */
> -    {  5,  1 },	/* FLD_brbop: used in BRB to mean IALL or INJ.  */
> -    {  8,  1 }, /* ZA8_1: name of the 1 bit encoded ZA tile ZA0-ZA1.  */
> -    {  7,  2 }, /* ZA7_2: name of the 2 bits encoded ZA tile ZA0-ZA3.  */
> -    {  6,  3 }, /* ZA6_3: name of the 3 bits encoded ZA tile ZA0-ZA7.  */
> -    {  5,  4 }, /* ZA5_4: name of the 4 bits encoded ZA tile ZA0-ZA15.  */
> +    AARCH64_FIELD_NIL,	/* NIL.  */
> +    AARCH64_FIELD_CONST (0, 1),	/* CONST_0.  */
> +    AARCH64_FIELD_CONST (1, 1),	/* CONST_1.  */
> +    AARCH64_FIELD ( 8, 4), /* CRm: in the system instructions.  */
> +    AARCH64_FIELD (10, 2), /* CRm_dsb_nxs: 2-bit imm. encoded in CRm<3:2>.  */
> +    AARCH64_FIELD (12, 4), /* CRn: in the system instructions.  */
> +    AARCH64_FIELD (10, 8), /* CSSC_imm8.  */
> +    AARCH64_FIELD (11, 1), /* H: in advsimd scalar x indexed element instructions.  */
> +    AARCH64_FIELD (21, 1), /* L: in advsimd scalar x indexed element instructions.  */
> +    AARCH64_FIELD ( 0, 5), /* LSE128_Rt: Shared input+output operand register.  */
> +    AARCH64_FIELD (16, 5), /* LSE128_Rt2: Shared input+output operand register 2.  */
> +    AARCH64_FIELD (20, 1), /* M: in advsimd scalar x indexed element instructions.  */
> +    AARCH64_FIELD (22, 1), /* N: in logical (immediate) instructions.  */
> +    AARCH64_FIELD (30, 1), /* Q: in most AdvSIMD instructions.  */
> +    AARCH64_FIELD (10, 5), /* Ra: in fp instructions.  */
> +    AARCH64_FIELD ( 0, 5), /* Rd: in many integer instructions.  */
> +    AARCH64_FIELD (16, 5), /* Rm: in ld/st reg offset and some integer inst.  */
> +    AARCH64_FIELD ( 5, 5), /* Rn: in many integer instructions.  */
> +    AARCH64_FIELD (16, 5), /* Rs: in load/store exclusive instructions.  */
> +    AARCH64_FIELD ( 0, 5), /* Rt: in load/store instructions.  */
> +    AARCH64_FIELD (10, 5), /* Rt2: in load/store pair instructions.  */
> +    AARCH64_FIELD (12, 1), /* S: in load/store reg offset instructions.  */
> +    AARCH64_FIELD (12, 2), /* SM3_imm2: Indexed element SM3 2 bits index immediate.  */
> +    AARCH64_FIELD ( 1, 3), /* SME_Pdx2: predicate register, multiple of 2, [3:1].  */
> +    AARCH64_FIELD (13, 3), /* SME_Pm: second source scalable predicate register P0-P7.  */
> +    AARCH64_FIELD ( 0, 3), /* SME_PNd3: PN0-PN7, bits [2:0].  */
> +    AARCH64_FIELD ( 5, 3), /* SME_PNn3: PN0-PN7, bits [7:5].  */
> +    AARCH64_FIELD (16, 1), /* SME_Q: Q class bit, bit 16.  */
> +    AARCH64_FIELD (16, 2), /* SME_Rm: index base register W12-W15 [17:16].  */
> +    AARCH64_FIELD (13, 2), /* SME_Rv: vector select register W12-W15, bits [14:13].  */
> +    AARCH64_FIELD (15, 1), /* SME_V: (horizontal / vertical tiles), bit 15.  */
> +    AARCH64_FIELD (10, 1), /* SME_VL_10: VLx2 or VLx4, bit [10].  */
> +    AARCH64_FIELD (13, 1), /* SME_VL_13: VLx2 or VLx4, bit [13].  */
> +    AARCH64_FIELD ( 0, 1), /* SME_ZAda_1b: tile ZA0-ZA1.  */
> +    AARCH64_FIELD ( 0, 2), /* SME_ZAda_2b: tile ZA0-ZA3.  */
> +    AARCH64_FIELD ( 0, 3), /* SME_ZAda_3b: tile ZA0-ZA7.  */
> +    AARCH64_FIELD ( 1, 4), /* SME_Zdn2: Z0-Z31, multiple of 2, bits [4:1].  */
> +    AARCH64_FIELD ( 2, 3), /* SME_Zdn4: Z0-Z31, multiple of 4, bits [4:2].  */
> +    AARCH64_FIELD (16, 4), /* SME_Zm: Z0-Z15, bits [19:16].  */
> +    AARCH64_FIELD (17, 4), /* SME_Zm2: Z0-Z31, multiple of 2, bits [20:17].  */
> +    AARCH64_FIELD (18, 3), /* SME_Zm4: Z0-Z31, multiple of 4, bits [20:18].  */
> +    AARCH64_FIELD ( 6, 4), /* SME_Zn2: Z0-Z31, multiple of 2, bits [9:6].  */
> +    AARCH64_FIELD ( 7, 3), /* SME_Zn4: Z0-Z31, multiple of 4, bits [9:7].  */
> +    AARCH64_FIELD ( 4, 1), /* SME_ZtT: upper bit of Zt, bit [4].  */
> +    AARCH64_FIELD ( 0, 3), /* SME_Zt3: lower 3 bits of Zt, bits [2:0].  */
> +    AARCH64_FIELD ( 0, 2), /* SME_Zt2: lower 2 bits of Zt, bits [1:0].  */
> +    AARCH64_FIELD (23, 1), /* SME_i1: immediate field, bit 23.  */
> +    AARCH64_FIELD (12, 2), /* SME_size_12: bits [13:12].  */
> +    AARCH64_FIELD (22, 2), /* SME_size_22: size<1>, size<0> class field, [23:22].  */
> +    AARCH64_FIELD (23, 1), /* SME_sz_23: bit [23].  */
> +    AARCH64_FIELD (22, 1), /* SME_tszh: immediate and qualifier field, bit 22.  */
> +    AARCH64_FIELD (18, 3), /* SME_tszl: immediate and qualifier field, bits [20:18].  */
> +    AARCH64_FIELD (0,  8), /* SME_zero_mask: list of up to 8 tile names separated by commas [7:0].  */
> +    AARCH64_FIELD ( 4, 1), /* SVE_M_4: Merge/zero select, bit 4.  */
> +    AARCH64_FIELD (14, 1), /* SVE_M_14: Merge/zero select, bit 14.  */
> +    AARCH64_FIELD (16, 1), /* SVE_M_16: Merge/zero select, bit 16.  */
> +    AARCH64_FIELD (17, 1), /* SVE_N: SVE equivalent of N.  */
> +    AARCH64_FIELD ( 0, 4), /* SVE_Pd: p0-p15, bits [3,0].  */
> +    AARCH64_FIELD (10, 3), /* SVE_Pg3: p0-p7, bits [12,10].  */
> +    AARCH64_FIELD ( 5, 4), /* SVE_Pg4_5: p0-p15, bits [8,5].  */
> +    AARCH64_FIELD (10, 4), /* SVE_Pg4_10: p0-p15, bits [13,10].  */
> +    AARCH64_FIELD (16, 4), /* SVE_Pg4_16: p0-p15, bits [19,16].  */
> +    AARCH64_FIELD (16, 4), /* SVE_Pm: p0-p15, bits [19,16].  */
> +    AARCH64_FIELD ( 5, 4), /* SVE_Pn: p0-p15, bits [8,5].  */
> +    AARCH64_FIELD ( 0, 4), /* SVE_Pt: p0-p15, bits [3,0].  */
> +    AARCH64_FIELD ( 5, 5), /* SVE_Rm: SVE alternative position for Rm.  */
> +    AARCH64_FIELD (16, 5), /* SVE_Rn: SVE alternative position for Rn.  */
> +    AARCH64_FIELD ( 0, 5), /* SVE_Vd: Scalar SIMD&FP register, bits [4,0].  */
> +    AARCH64_FIELD ( 5, 5), /* SVE_Vm: Scalar SIMD&FP register, bits [9,5].  */
> +    AARCH64_FIELD ( 5, 5), /* SVE_Vn: Scalar SIMD&FP register, bits [9,5].  */
> +    AARCH64_FIELD ( 5, 5), /* SVE_Za_5: SVE vector register, bits [9,5].  */
> +    AARCH64_FIELD (16, 5), /* SVE_Za_16: SVE vector register, bits [20,16].  */
> +    AARCH64_FIELD ( 0, 5), /* SVE_Zd: SVE vector register. bits [4,0].  */
> +    AARCH64_FIELD ( 5, 5), /* SVE_Zm_5: SVE vector register, bits [9,5].  */
> +    AARCH64_FIELD (16, 5), /* SVE_Zm_16: SVE vector register, bits [20,16]. */
> +    AARCH64_FIELD ( 5, 5), /* SVE_Zn: SVE vector register, bits [9,5].  */
> +    AARCH64_FIELD ( 0, 5), /* SVE_Zt: SVE vector register, bits [4,0].  */
> +    AARCH64_FIELD ( 5, 1), /* SVE_i1: single-bit immediate.  */
> +    AARCH64_FIELD (23, 1), /* SVE_i1_23: single-bit immediate.  */
> +    AARCH64_FIELD (22, 2), /* SVE_i2: 2-bit index, bits [23,22].  */
> +    AARCH64_FIELD (20, 1), /* SVE_i2h: high bit of 2bit immediate, bits.  */
> +    AARCH64_FIELD (22, 1), /* SVE_i3h: high bit of 3-bit immediate.  */
> +    AARCH64_FIELD (19, 2), /* SVE_i3h2: two high bits of 3bit immediate, bits [20,19].  */
> +    AARCH64_FIELD (22, 2), /* SVE_i3h3: two high bits of 3bit immediate, bits [22,23].  */
> +    AARCH64_FIELD (11, 1), /* SVE_i3l: low bit of 3-bit immediate.  */
> +    AARCH64_FIELD (12, 1), /* SVE_i3l2: low bit of 3-bit immediate, bit 12.  */
> +    AARCH64_FIELD (10, 2), /* SVE_i4l2: two low bits of 4bit immediate, bits [11,10].  */
> +    AARCH64_FIELD (16, 3), /* SVE_imm3: 3-bit immediate field.  */
> +    AARCH64_FIELD (16, 4), /* SVE_imm4: 4-bit immediate field.  */
> +    AARCH64_FIELD ( 5, 5), /* SVE_imm5: 5-bit immediate field.  */
> +    AARCH64_FIELD (16, 5), /* SVE_imm5b: secondary 5-bit immediate field.  */
> +    AARCH64_FIELD (16, 6), /* SVE_imm6: 6-bit immediate field.  */
> +    AARCH64_FIELD (14, 7), /* SVE_imm7: 7-bit immediate field.  */
> +    AARCH64_FIELD ( 5, 8), /* SVE_imm8: 8-bit immediate field.  */
> +    AARCH64_FIELD ( 5, 9), /* SVE_imm9: 9-bit immediate field.  */
> +    AARCH64_FIELD (11, 6), /* SVE_immr: SVE equivalent of immr.  */
> +    AARCH64_FIELD ( 5, 6), /* SVE_imms: SVE equivalent of imms.  */
> +    AARCH64_FIELD (10, 2), /* SVE_msz: 2-bit shift amount for ADR.  */
> +    AARCH64_FIELD ( 5, 5), /* SVE_pattern: vector pattern enumeration.  */
> +    AARCH64_FIELD ( 0, 4), /* SVE_prfop: prefetch operation for SVE PRF[BHWD].  */
> +    AARCH64_FIELD (16, 1), /* SVE_rot1: 1-bit rotation amount.  */
> +    AARCH64_FIELD (10, 2), /* SVE_rot2: 2-bit rotation amount.  */
> +    AARCH64_FIELD (10, 1), /* SVE_rot3: 1-bit rotation amount at bit 10.  */
> +    AARCH64_FIELD (17, 2), /* SVE_size: 2-bit element size, bits [18,17].  */
> +    AARCH64_FIELD (22, 1), /* SVE_sz: 1-bit element size select.  */
> +    AARCH64_FIELD (30, 1), /* SVE_sz2: 1-bit element size select.  */
> +    AARCH64_FIELD (17, 1), /* SVE_sz3: 1-bit element size select.  */
> +    AARCH64_FIELD (14, 1), /* SVE_sz4: 1-bit element size select.  */
> +    AARCH64_FIELD (16, 4), /* SVE_tsz: triangular size select.  */
> +    AARCH64_FIELD (22, 2), /* SVE_tszh: triangular size select high, bits [23,22].  */
> +    AARCH64_FIELD ( 8, 2), /* SVE_tszl_8: triangular size select low, bits [9,8].  */
> +    AARCH64_FIELD (19, 2), /* SVE_tszl_19: triangular size select low, bits [20,19].  */
> +    AARCH64_FIELD (14, 1), /* SVE_xs_14: UXTW/SXTW select (bit 14).  */
> +    AARCH64_FIELD (22, 1), /* SVE_xs_22: UXTW/SXTW select (bit 22).  */
> +    AARCH64_FIELD (22, 1), /* S_imm10: in LDRAA and LDRAB instructions.  */
> +    AARCH64_FIELD (16, 3), /* abc: a:b:c bits in AdvSIMD modified immediate.  */
> +    AARCH64_FIELD (13, 3), /* asisdlso_opcode: opcode in advsimd ld/st single element.  */
> +    AARCH64_FIELD (19, 5), /* b40: in the test bit and branch instructions.  */
> +    AARCH64_FIELD (31, 1), /* b5: in the test bit and branch instructions.  */
> +    AARCH64_FIELD (12, 4), /* cmode: in advsimd modified immediate instructions.  */
> +    AARCH64_FIELD (12, 4), /* cond: condition flags as a source operand.  */
> +    AARCH64_FIELD ( 0, 4), /* cond2: condition in truly conditional-executed inst.  */
> +    AARCH64_FIELD ( 5, 5), /* defgh: d:e:f:g:h bits in AdvSIMD modified immediate.  */
> +    AARCH64_FIELD (21, 2), /* hw: in move wide constant instructions.  */
> +    AARCH64_FIELD ( 0, 1), /* imm1_0: general immediate in bits [0].  */
> +    AARCH64_FIELD ( 2, 1), /* imm1_2: general immediate in bits [2].  */
> +    AARCH64_FIELD ( 3, 1), /* imm1_3: general immediate in bits [3].  */
> +    AARCH64_FIELD ( 8, 1), /* imm1_8: general immediate in bits [8].  */
> +    AARCH64_FIELD (10, 1), /* imm1_10: general immediate in bits [10].  */
> +    AARCH64_FIELD (14, 1), /* imm1_14: general immediate in bits [14].  */
> +    AARCH64_FIELD (15, 1), /* imm1_15: general immediate in bits [15].  */
> +    AARCH64_FIELD (16, 1), /* imm1_16: general immediate in bits [16].  */
> +    AARCH64_FIELD ( 0, 2), /* imm2_0: general immediate in bits [1:0].  */
> +    AARCH64_FIELD ( 1, 2), /* imm2_1: general immediate in bits [2:1].  */
> +    AARCH64_FIELD ( 2, 2), /* imm2_2: general immediate in bits [3:2].  */
> +    AARCH64_FIELD ( 8, 2), /* imm2_8: general immediate in bits [9:8].  */
> +    AARCH64_FIELD (10, 2), /* imm2_10: 2-bit immediate, bits [11:10] */
> +    AARCH64_FIELD (12, 2), /* imm2_12: 2-bit immediate, bits [13:12] */
> +    AARCH64_FIELD (13, 2), /* imm2_13: 2-bit immediate, bits [14:13] */
> +    AARCH64_FIELD (15, 2), /* imm2_15: 2-bit immediate, bits [16:15] */
> +    AARCH64_FIELD (16, 2), /* imm2_16: 2-bit immediate, bits [17:16] */
> +    AARCH64_FIELD (19, 2), /* imm2_19: 2-bit immediate, bits [20:19] */
> +    AARCH64_FIELD ( 0, 3), /* imm3_0: general immediate in bits [2:0].  */
> +    AARCH64_FIELD ( 5, 3), /* imm3_5: general immediate in bits [7:5].  */
> +    AARCH64_FIELD (10, 3), /* imm3_10: in add/sub extended reg instructions.  */
> +    AARCH64_FIELD (12, 3), /* imm3_12: general immediate in bits [14:12].  */
> +    AARCH64_FIELD (14, 3), /* imm3_14: general immediate in bits [16:14].  */
> +    AARCH64_FIELD (15, 3), /* imm3_15: general immediate in bits [17:15].  */
> +    AARCH64_FIELD (19, 3), /* imm3_19: general immediate in bits [21:19].  */
> +    AARCH64_FIELD ( 0, 4), /* imm4_0: in rmif instructions.  */
> +    AARCH64_FIELD ( 5, 4), /* imm4_5: in SME instructions.  */
> +    AARCH64_FIELD (10, 4), /* imm4_10: in adddg/subg instructions.  */
> +    AARCH64_FIELD (11, 4), /* imm4_11: in advsimd ext and advsimd ins instructions.  */
> +    AARCH64_FIELD (14, 4), /* imm4_14: general immediate in bits [17:14].  */
> +    AARCH64_FIELD (16, 5), /* imm5: in conditional compare (immediate) instructions.  */
> +    AARCH64_FIELD (10, 6), /* imm6_10: in add/sub reg shifted instructions.  */
> +    AARCH64_FIELD (15, 6), /* imm6_15: in rmif instructions.  */
> +    AARCH64_FIELD (15, 7), /* imm7: in load/store pair pre/post index instructions.  */
> +    AARCH64_FIELD (13, 8), /* imm8: in floating-point scalar move immediate inst.  */
> +    AARCH64_FIELD (12, 9), /* imm9: in load/store pre/post index instructions.  */
> +    AARCH64_FIELD ( 5, 9), /* imm9_5: in CB<cc> (immediate).  */
> +    AARCH64_FIELD (10,12), /* imm12: in ld/st unsigned imm or add/sub shifted inst.  */
> +    AARCH64_FIELD ( 5,14), /* imm14: in test bit and branch instructions.  */
> +    AARCH64_FIELD ( 0,16), /* imm16_0: in udf instruction. */
> +    AARCH64_FIELD ( 5,16), /* imm16_5: in exception instructions.  */
> +    AARCH64_FIELD (17, 1), /* imm17_1: in 1 bit element index.  */
> +    AARCH64_FIELD (17, 2), /* imm17_2: in 2 bits element index.  */
> +    AARCH64_FIELD ( 5,19), /* imm19: e.g. in CBZ.  */
> +    AARCH64_FIELD ( 0,26), /* imm26: in unconditional branch instructions.  */
> +    AARCH64_FIELD (16, 3), /* immb: in advsimd shift by immediate instructions.  */
> +    AARCH64_FIELD (19, 4), /* immh: in advsimd shift by immediate instructions.  */
> +    AARCH64_FIELD ( 5,19), /* immhi: e.g. in ADRP.  */
> +    AARCH64_FIELD (29, 2), /* immlo: e.g. in ADRP.  */
> +    AARCH64_FIELD (16, 6), /* immr: in bitfield and logical immediate instructions.  */
> +    AARCH64_FIELD (10, 6), /* imms: in bitfield and logical immediate instructions.  */
> +    AARCH64_FIELD (11, 1), /* index: in ld/st inst deciding the pre/post-index.  */
> +    AARCH64_FIELD (24, 1), /* index2: in ld/st pair inst deciding the pre/post-index.  */
> +    AARCH64_FIELD (30, 2), /* ldst_size: size field in ld/st reg offset inst.  */
> +    AARCH64_FIELD (13, 2), /* len: in advsimd tbl/tbx instructions.  */
> +    AARCH64_FIELD (30, 1), /* lse_sz: in LSE extension atomic instructions.  */
> +    AARCH64_FIELD ( 0, 4), /* nzcv: flag bit specifier, encoded in the "nzcv" field.  */
> +    AARCH64_FIELD (29, 1), /* op: in AdvSIMD modified immediate instructions.  */
> +    AARCH64_FIELD (19, 2), /* op0: in the system instructions.  */
> +    AARCH64_FIELD (16, 3), /* op1: in the system instructions.  */
> +    AARCH64_FIELD ( 5, 3), /* op2: in the system instructions.  */
> +    AARCH64_FIELD (22, 2), /* opc: in load/store reg offset instructions.  */
> +    AARCH64_FIELD (23, 1), /* opc1: in load/store reg offset instructions.  */
> +    AARCH64_FIELD (12, 4), /* opcode: in advsimd load/store instructions.  */
> +    AARCH64_FIELD (13, 3), /* option: in ld/st reg offset + add/sub extended reg inst.  */
> +    AARCH64_FIELD (11, 2), /* rotate1: FCMLA immediate rotate.  */
> +    AARCH64_FIELD (13, 2), /* rotate2: Indexed element FCMLA immediate rotate.  */
> +    AARCH64_FIELD (12, 1), /* rotate3: FCADD immediate rotate.  */
> +    AARCH64_FIELD (10, 6), /* scale: in the fixed-point scalar to fp converting inst.  */
> +    AARCH64_FIELD (31, 1), /* sf: in integer data processing instructions.  */
> +    AARCH64_FIELD (22, 2), /* shift: in add/sub reg/imm shifted instructions.  */
> +    AARCH64_FIELD (22, 2), /* size: in most AdvSIMD and floating-point instructions.  */
> +    AARCH64_FIELD (22, 1), /* sz: 1-bit element size select.  */
> +    AARCH64_FIELD (22, 2), /* type: floating point type field in fp data inst.  */
> +    AARCH64_FIELD (10, 2), /* vldst_size: size field in the AdvSIMD load/store inst.  */
> +    AARCH64_FIELD ( 5, 3), /* off3: immediate offset used to calculate slice number in a ZA tile.  */
> +    AARCH64_FIELD ( 5, 2), /* off2: immediate offset used to calculate slice number in a ZA tile.  */
> +    AARCH64_FIELD ( 7, 1), /* ZAn_1: name of the 1bit encoded ZA tile.  */
> +    AARCH64_FIELD ( 5, 1), /* ol: immediate offset used to calculate slice number in a ZA tile. */
> +    AARCH64_FIELD ( 6, 2), /* ZAn_2: name of the 2bit encoded ZA tile.  */
> +    AARCH64_FIELD ( 5, 3), /* ZAn_3: name of the 3bit encoded ZA tile.  */
> +    AARCH64_FIELD ( 6, 1), /* ZAn: name of the bit encoded ZA tile.  */
> +    AARCH64_FIELD (12, 4), /* opc2: in rcpc3 ld/st inst deciding the pre/post-index.  */
> +    AARCH64_FIELD (30, 2), /* rcpc3_size: in rcpc3 ld/st, field controls Rt/Rt2 width.  */
> +    AARCH64_FIELD ( 5, 1), /* FLD_brbop: used in BRB to mean IALL or INJ.  */
> +    AARCH64_FIELD ( 8, 1), /* ZA8_1: name of the 1 bit encoded ZA tile ZA0-ZA1.  */
> +    AARCH64_FIELD ( 7, 2), /* ZA7_2: name of the 2 bits encoded ZA tile ZA0-ZA3.  */
> +    AARCH64_FIELD ( 6, 3), /* ZA6_3: name of the 3 bits encoded ZA tile ZA0-ZA7.  */
> +    AARCH64_FIELD ( 5, 4), /* ZA5_4: name of the 4 bits encoded ZA tile ZA0-ZA15.  */
>   };
>   
>   enum aarch64_operand_class
> diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
> index 4182c9d5f678beac3a240e08c9842e8620a32bb6..a70b9b776a793d63b758bb52028e71570eb45e00 100644
> --- a/opcodes/aarch64-opc.h
> +++ b/opcodes/aarch64-opc.h
> @@ -30,6 +30,8 @@
>   enum aarch64_field_kind
>   {
>     FLD_NIL,
> +  FLD_CONST_0,
> +  FLD_CONST_1,
>     FLD_CRm,
>     FLD_CRm_dsb_nxs,
>     FLD_CRn,
> @@ -242,15 +244,41 @@ enum aarch64_field_kind
>     FLD_ZA5_4,
>   };
>   
> -/* Field description.  */
> +/* Field description.
> +
> +   If is_const is false, this identifies a bitfield in an instruction encoding
> +   that has size WIDTH and has its least significant bit at position NUM.
> +
> +   If is_const is true, this represents the constant bit string of size WIDTH
> +   bits stored in the least significant bits of NUM.  In this case, the
> +   leading 8-WIDTH bits of VALUE must be zero.
> +
> +   A sequence of fields can be used to describe how instruction operands are
> +   represented in the 32-bit instruction encoding.
> +
> +   For example, consider an instruction operand Zd that is an even numbered
> +   register in z16-z30, with the middle three bits of the register number
> +   stored in bits [19:17] of the encoding.  The register number can then be
> +   constructed by concatenating:
> +   - a constant bit '1' (represented here as {1, 1, true}),
> +   - bits [19:17] of the encoding (represented here as {17, 3, false}), and
> +   - a constant bit '0' (represented here as {1, 1, true}).

Surely this should be {1, 0, true}??

> +   This sequence of fields fully describes both the constraints on which
> +   register numbers are valid, and how valid register numbers are represented
> +   in the instruction encoding.  */
>   struct aarch64_field
>   {
> -  int lsb;
> -  int width;
> +  unsigned int width:8;
> +  unsigned int num:7;
> +  bool is_const:1;
>   };
>   
>   typedef struct aarch64_field aarch64_field;
>   
> +#define AARCH64_FIELD(lsb, width) {width, lsb, false}
> +#define AARCH64_FIELD_CONST(val, width) {width, val, true}
> +#define AARCH64_FIELD_NIL {0, 0, false}
> +
>   extern const aarch64_field aarch64_fields[];
>   

>   /* Operand description.  */
> @@ -484,7 +512,7 @@ gen_sub_field (enum aarch64_field_kind kind, int lsb_rel, int width, aarch64_fie
>     const aarch64_field *field = &aarch64_fields[kind];
>     if (lsb_rel < 0 || width <= 0 || lsb_rel + width > field->width)
>       return 0;
> -  ret->lsb = field->lsb + lsb_rel;
> +  ret->num = field->num + lsb_rel;
>     ret->width = width;
>     return 1;
>   }
> @@ -496,10 +524,16 @@ static inline void
>   insert_field_2 (const aarch64_field *field, aarch64_insn *code,
>   		aarch64_insn value, aarch64_insn mask)
>   {
> -  assert (field->width < 32 && field->width >= 1 && field->lsb >= 0
> -	  && field->lsb + field->width <= 32);
> +  assert (field->width < 32 && field->width >= 1
> +	  && (field->is_const ? (field->num < 1 << field->width)
> +			      : (field->num + field->width <= 32)));
>     value &= gen_mask (field->width);
> -  value <<= field->lsb;
> +  if (field->is_const)
> +    {
> +      assert (value == field->num);
> +      return;
> +    }
> +  value <<= field->num;
>     /* In some opcodes, field can be part of the base opcode, e.g. the size
>        field in FADD.  The following helps avoid corrupt the base opcode.  */
>     value &= ~mask;
> @@ -514,9 +548,13 @@ extract_field_2 (const aarch64_field *field, aarch64_insn code,
>   		 aarch64_insn mask)
>   {
>     aarch64_insn value;
> +  /* Check for constant field.  */
> +  if (field->is_const)
> +    return field->num;
> +
>     /* Clear any bit that is a part of the base opcode.  */
>     code &= ~mask;
> -  value = (code >> field->lsb) & gen_mask (field->width);
> +  value = (code >> field->num) & gen_mask (field->width);
>     return value;
>   }
>   
Looks much better otherwise.
R.



More information about the Binutils mailing list