[AArch64][SVE 27/32] Add SVE integer immediate operands
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 21 Sep 2016 15:56:57 +0000 (16:56 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Wed, 21 Sep 2016 15:56:57 +0000 (16:56 +0100)
This patch adds the new SVE integer immediate operands.  There are
three kinds:

- simple signed and unsigned ranges, but with new widths and positions.

- 13-bit logical immediates.  These have the same form as in base AArch64,
  but at a different bit position.

  In the case of the "MOV Zn.<T>, #<limm>" alias of DUPM, the logical
  immediate <limm> is not allowed to be a valid DUP immediate, since DUP
  is preferred over DUPM for constants that both instructions can handle.

- a new 9-bit arithmetic immediate, of the form "<imm8>{, LSL #8}".
  In some contexts the operand is signed and in others it's unsigned.
  As an extension, we allow shifted immediates to be written as a single
  integer, e.g. "#256" is equivalent to "#1, LSL #8".  We also use the
  shiftless form as the preferred disassembly, except for the special
  case of "#0, LSL #8" (a redundant encoding of 0).

include/
* opcode/aarch64.h (AARCH64_OPND_SIMM5): New aarch64_opnd.
(AARCH64_OPND_SVE_AIMM, AARCH64_OPND_SVE_ASIMM)
(AARCH64_OPND_SVE_INV_LIMM, AARCH64_OPND_SVE_LIMM)
(AARCH64_OPND_SVE_LIMM_MOV, AARCH64_OPND_SVE_SHLIMM_PRED)
(AARCH64_OPND_SVE_SHLIMM_UNPRED, AARCH64_OPND_SVE_SHRIMM_PRED)
(AARCH64_OPND_SVE_SHRIMM_UNPRED, AARCH64_OPND_SVE_SIMM5)
(AARCH64_OPND_SVE_SIMM5B, AARCH64_OPND_SVE_SIMM6)
(AARCH64_OPND_SVE_SIMM8, AARCH64_OPND_SVE_UIMM3)
(AARCH64_OPND_SVE_UIMM7, AARCH64_OPND_SVE_UIMM8)
(AARCH64_OPND_SVE_UIMM8_53): Likewise.
(aarch64_sve_dupm_mov_immediate_p): Declare.

opcodes/
* aarch64-tbl.h (AARCH64_OPERANDS): Add entries for the new SVE
integer immediate operands.
* aarch64-opc.h (FLD_SVE_immN, FLD_SVE_imm3, FLD_SVE_imm5)
(FLD_SVE_imm5b, FLD_SVE_imm7, FLD_SVE_imm8, FLD_SVE_imm9)
(FLD_SVE_immr, FLD_SVE_imms, FLD_SVE_tszh): New aarch64_field_kinds.
* aarch64-opc.c (fields): Add corresponding entries.
(operand_general_constraint_met_p): Handle the new SVE integer
immediate operands.
(aarch64_print_operand): Likewise.
(aarch64_sve_dupm_mov_immediate_p): New function.
* aarch64-opc-2.c: Regenerate.
* aarch64-asm.h (ins_inv_limm, ins_sve_aimm, ins_sve_asimm)
(ins_sve_limm_mov, ins_sve_shlimm, ins_sve_shrimm): New inserters.
* aarch64-asm.c (aarch64_ins_limm_1): New function, split out from...
(aarch64_ins_limm): ...here.
(aarch64_ins_inv_limm): New function.
(aarch64_ins_sve_aimm): Likewise.
(aarch64_ins_sve_asimm): Likewise.
(aarch64_ins_sve_limm_mov): Likewise.
(aarch64_ins_sve_shlimm): Likewise.
(aarch64_ins_sve_shrimm): Likewise.
* aarch64-asm-2.c: Regenerate.
* aarch64-dis.h (ext_inv_limm, ext_sve_aimm, ext_sve_asimm)
(ext_sve_limm_mov, ext_sve_shlimm, ext_sve_shrimm): New extractors.
* aarch64-dis.c (decode_limm): New function, split out from...
(aarch64_ext_limm): ...here.
(aarch64_ext_inv_limm): New function.
(decode_sve_aimm): Likewise.
(aarch64_ext_sve_aimm): Likewise.
(aarch64_ext_sve_asimm): Likewise.
(aarch64_ext_sve_limm_mov): Likewise.
(aarch64_top_bit): Likewise.
(aarch64_ext_sve_shlimm): Likewise.
(aarch64_ext_sve_shrimm): Likewise.
* aarch64-dis-2.c: Regenerate.

gas/
* config/tc-aarch64.c (parse_operands): Handle the new SVE integer
immediate operands.

15 files changed:
gas/ChangeLog
gas/config/tc-aarch64.c
include/ChangeLog
include/opcode/aarch64.h
opcodes/ChangeLog
opcodes/aarch64-asm-2.c
opcodes/aarch64-asm.c
opcodes/aarch64-asm.h
opcodes/aarch64-dis-2.c
opcodes/aarch64-dis.c
opcodes/aarch64-dis.h
opcodes/aarch64-opc-2.c
opcodes/aarch64-opc.c
opcodes/aarch64-opc.h
opcodes/aarch64-tbl.h

index 4593a787c823a49b541fa785982a9814d3d6d44d..a1467996212292616e65f629f972dd6137a87592 100644 (file)
@@ -1,3 +1,8 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * config/tc-aarch64.c (parse_operands): Handle the new SVE integer
+       immediate operands.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * config/tc-aarch64.c (SHIFTED_NONE, SHIFTED_MUL_VL): New
index 930b07a00903e06e308d2b761e289aa5861d8c1e..6b9ae29f85c0233cd2f4faaf9e04c46ffed08593 100644 (file)
@@ -5501,6 +5501,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
          break;
 
        case AARCH64_OPND_CCMP_IMM:
+       case AARCH64_OPND_SIMM5:
        case AARCH64_OPND_FBITS:
        case AARCH64_OPND_UIMM4:
        case AARCH64_OPND_UIMM3_OP1:
@@ -5508,10 +5509,36 @@ parse_operands (char *str, const aarch64_opcode *opcode)
        case AARCH64_OPND_IMM_VLSL:
        case AARCH64_OPND_IMM:
        case AARCH64_OPND_WIDTH:
+       case AARCH64_OPND_SVE_INV_LIMM:
+       case AARCH64_OPND_SVE_LIMM:
+       case AARCH64_OPND_SVE_LIMM_MOV:
+       case AARCH64_OPND_SVE_SHLIMM_PRED:
+       case AARCH64_OPND_SVE_SHLIMM_UNPRED:
+       case AARCH64_OPND_SVE_SHRIMM_PRED:
+       case AARCH64_OPND_SVE_SHRIMM_UNPRED:
+       case AARCH64_OPND_SVE_SIMM5:
+       case AARCH64_OPND_SVE_SIMM5B:
+       case AARCH64_OPND_SVE_SIMM6:
+       case AARCH64_OPND_SVE_SIMM8:
+       case AARCH64_OPND_SVE_UIMM3:
+       case AARCH64_OPND_SVE_UIMM7:
+       case AARCH64_OPND_SVE_UIMM8:
+       case AARCH64_OPND_SVE_UIMM8_53:
          po_imm_nc_or_fail ();
          info->imm.value = val;
          break;
 
+       case AARCH64_OPND_SVE_AIMM:
+       case AARCH64_OPND_SVE_ASIMM:
+         po_imm_nc_or_fail ();
+         info->imm.value = val;
+         skip_whitespace (str);
+         if (skip_past_comma (&str))
+           po_misc_or_fail (parse_shift (&str, info, SHIFTED_LSL));
+         else
+           inst.base.operands[i].shifter.kind = AARCH64_MOD_LSL;
+         break;
+
        case AARCH64_OPND_SVE_PATTERN:
          po_enum_or_fail (aarch64_sve_pattern_array);
          info->imm.value = val;
index f28903fa4f6a6e0577dc8f16e459ce931638c0f3..6c9c9194952f35fd63d22dd4f8861f7661862007 100644 (file)
@@ -1,3 +1,17 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * opcode/aarch64.h (AARCH64_OPND_SIMM5): New aarch64_opnd.
+       (AARCH64_OPND_SVE_AIMM, AARCH64_OPND_SVE_ASIMM)
+       (AARCH64_OPND_SVE_INV_LIMM, AARCH64_OPND_SVE_LIMM)
+       (AARCH64_OPND_SVE_LIMM_MOV, AARCH64_OPND_SVE_SHLIMM_PRED)
+       (AARCH64_OPND_SVE_SHLIMM_UNPRED, AARCH64_OPND_SVE_SHRIMM_PRED)
+       (AARCH64_OPND_SVE_SHRIMM_UNPRED, AARCH64_OPND_SVE_SIMM5)
+       (AARCH64_OPND_SVE_SIMM5B, AARCH64_OPND_SVE_SIMM6)
+       (AARCH64_OPND_SVE_SIMM8, AARCH64_OPND_SVE_UIMM3)
+       (AARCH64_OPND_SVE_UIMM7, AARCH64_OPND_SVE_UIMM8)
+       (AARCH64_OPND_SVE_UIMM8_53): Likewise.
+       (aarch64_sve_dupm_mov_immediate_p): Declare.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * opcode/aarch64.h (AARCH64_OPND_SVE_ADDR_RI_S4xVL): New aarch64_opnd.
index 837d6bd7580f5f379ddcbfb40ac8243e856d8386..36e95b4567216d3249af7de136f410ccbf11ac3d 100644 (file)
@@ -200,6 +200,7 @@ enum aarch64_opnd
   AARCH64_OPND_BIT_NUM,        /* Immediate.  */
   AARCH64_OPND_EXCEPTION,/* imm16 operand in exception instructions.  */
   AARCH64_OPND_CCMP_IMM,/* Immediate in conditional compare instructions.  */
+  AARCH64_OPND_SIMM5,  /* 5-bit signed immediate in the imm5 field.  */
   AARCH64_OPND_NZCV,   /* Flag bit specifier giving an alternative value for
                           each condition flag.  */
 
@@ -289,6 +290,11 @@ enum aarch64_opnd
   AARCH64_OPND_SVE_ADDR_ZZ_LSL,     /* SVE [Zn.<T>, Zm,<T>, LSL #<msz>].  */
   AARCH64_OPND_SVE_ADDR_ZZ_SXTW,    /* SVE [Zn.<T>, Zm,<T>, SXTW #<msz>].  */
   AARCH64_OPND_SVE_ADDR_ZZ_UXTW,    /* SVE [Zn.<T>, Zm,<T>, UXTW #<msz>].  */
+  AARCH64_OPND_SVE_AIMM,       /* SVE unsigned arithmetic immediate.  */
+  AARCH64_OPND_SVE_ASIMM,      /* SVE signed arithmetic immediate.  */
+  AARCH64_OPND_SVE_INV_LIMM,   /* SVE inverted logical immediate.  */
+  AARCH64_OPND_SVE_LIMM,       /* SVE logical immediate.  */
+  AARCH64_OPND_SVE_LIMM_MOV,   /* SVE logical immediate for MOV.  */
   AARCH64_OPND_SVE_PATTERN,    /* SVE vector pattern enumeration.  */
   AARCH64_OPND_SVE_PATTERN_SCALED, /* Likewise, with additional MUL factor.  */
   AARCH64_OPND_SVE_PRFOP,      /* SVE prefetch operation.  */
@@ -300,6 +306,18 @@ enum aarch64_opnd
   AARCH64_OPND_SVE_Pm,         /* SVE p0-p15 in Pm.  */
   AARCH64_OPND_SVE_Pn,         /* SVE p0-p15 in Pn.  */
   AARCH64_OPND_SVE_Pt,         /* SVE p0-p15 in Pt.  */
+  AARCH64_OPND_SVE_SHLIMM_PRED,          /* SVE shift left amount (predicated).  */
+  AARCH64_OPND_SVE_SHLIMM_UNPRED, /* SVE shift left amount (unpredicated).  */
+  AARCH64_OPND_SVE_SHRIMM_PRED,          /* SVE shift right amount (predicated).  */
+  AARCH64_OPND_SVE_SHRIMM_UNPRED, /* SVE shift right amount (unpredicated).  */
+  AARCH64_OPND_SVE_SIMM5,      /* SVE signed 5-bit immediate.  */
+  AARCH64_OPND_SVE_SIMM5B,     /* SVE secondary signed 5-bit immediate.  */
+  AARCH64_OPND_SVE_SIMM6,      /* SVE signed 6-bit immediate.  */
+  AARCH64_OPND_SVE_SIMM8,      /* SVE signed 8-bit immediate.  */
+  AARCH64_OPND_SVE_UIMM3,      /* SVE unsigned 3-bit immediate.  */
+  AARCH64_OPND_SVE_UIMM7,      /* SVE unsigned 7-bit immediate.  */
+  AARCH64_OPND_SVE_UIMM8,      /* SVE unsigned 8-bit immediate.  */
+  AARCH64_OPND_SVE_UIMM8_53,   /* SVE split unsigned 8-bit immediate.  */
   AARCH64_OPND_SVE_Za_5,       /* SVE vector register in Za, bits [9,5].  */
   AARCH64_OPND_SVE_Za_16,      /* SVE vector register in Za, bits [20,16].  */
   AARCH64_OPND_SVE_Zd,         /* SVE vector register in Zd.  */
@@ -1065,6 +1083,9 @@ aarch64_get_operand_name (enum aarch64_opnd);
 extern const char *
 aarch64_get_operand_desc (enum aarch64_opnd);
 
+extern bfd_boolean
+aarch64_sve_dupm_mov_immediate_p (uint64_t, int);
+
 #ifdef DEBUG_AARCH64
 extern int debug_dump;
 
index de052a93540e0375384deb7f1fa7ca91c0bd950e..10fdd1fe0fff38e45b92c4b25c5ad84c882f3173 100644 (file)
@@ -1,3 +1,41 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * aarch64-tbl.h (AARCH64_OPERANDS): Add entries for the new SVE
+       integer immediate operands.
+       * aarch64-opc.h (FLD_SVE_immN, FLD_SVE_imm3, FLD_SVE_imm5)
+       (FLD_SVE_imm5b, FLD_SVE_imm7, FLD_SVE_imm8, FLD_SVE_imm9)
+       (FLD_SVE_immr, FLD_SVE_imms, FLD_SVE_tszh): New aarch64_field_kinds.
+       * aarch64-opc.c (fields): Add corresponding entries.
+       (operand_general_constraint_met_p): Handle the new SVE integer
+       immediate operands.
+       (aarch64_print_operand): Likewise.
+       (aarch64_sve_dupm_mov_immediate_p): New function.
+       * aarch64-opc-2.c: Regenerate.
+       * aarch64-asm.h (ins_inv_limm, ins_sve_aimm, ins_sve_asimm)
+       (ins_sve_limm_mov, ins_sve_shlimm, ins_sve_shrimm): New inserters.
+       * aarch64-asm.c (aarch64_ins_limm_1): New function, split out from...
+       (aarch64_ins_limm): ...here.
+       (aarch64_ins_inv_limm): New function.
+       (aarch64_ins_sve_aimm): Likewise.
+       (aarch64_ins_sve_asimm): Likewise.
+       (aarch64_ins_sve_limm_mov): Likewise.
+       (aarch64_ins_sve_shlimm): Likewise.
+       (aarch64_ins_sve_shrimm): Likewise.
+       * aarch64-asm-2.c: Regenerate.
+       * aarch64-dis.h (ext_inv_limm, ext_sve_aimm, ext_sve_asimm)
+       (ext_sve_limm_mov, ext_sve_shlimm, ext_sve_shrimm): New extractors.
+       * aarch64-dis.c (decode_limm): New function, split out from...
+       (aarch64_ext_limm): ...here.
+       (aarch64_ext_inv_limm): New function.
+       (decode_sve_aimm): Likewise.
+       (aarch64_ext_sve_aimm): Likewise.
+       (aarch64_ext_sve_asimm): Likewise.
+       (aarch64_ext_sve_limm_mov): Likewise.
+       (aarch64_top_bit): Likewise.
+       (aarch64_ext_sve_shlimm): Likewise.
+       (aarch64_ext_sve_shrimm): Likewise.
+       * aarch64-dis-2.c: Regenerate.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * aarch64-tbl.h (AARCH64_OPERANDS): Add entries for new MUL VL
index da590cab8d6583425eb615eb6fe28e1677bfa6d5..491ea53dc0961b33ff3c32ddf6d206e2e4779a8c 100644 (file)
@@ -480,12 +480,6 @@ aarch64_insert_operand (const aarch64_operand *self,
     case 27:
     case 35:
     case 36:
-    case 129:
-    case 130:
-    case 131:
-    case 132:
-    case 133:
-    case 134:
     case 135:
     case 136:
     case 137:
@@ -494,7 +488,13 @@ aarch64_insert_operand (const aarch64_operand *self,
     case 140:
     case 141:
     case 142:
-    case 145:
+    case 155:
+    case 156:
+    case 157:
+    case 158:
+    case 159:
+    case 160:
+    case 163:
       return aarch64_ins_regno (self, info, code, inst);
     case 12:
       return aarch64_ins_reg_extended (self, info, code, inst);
@@ -527,12 +527,21 @@ aarch64_insert_operand (const aarch64_operand *self,
     case 56:
     case 57:
     case 58:
-    case 67:
+    case 59:
     case 68:
     case 69:
     case 70:
-    case 126:
-    case 128:
+    case 71:
+    case 132:
+    case 134:
+    case 147:
+    case 148:
+    case 149:
+    case 150:
+    case 151:
+    case 152:
+    case 153:
+    case 154:
       return aarch64_ins_imm (self, info, code, inst);
     case 38:
     case 39:
@@ -543,61 +552,61 @@ aarch64_insert_operand (const aarch64_operand *self,
       return aarch64_ins_advsimd_imm_modified (self, info, code, inst);
     case 46:
       return aarch64_ins_fpimm (self, info, code, inst);
-    case 59:
-      return aarch64_ins_limm (self, info, code, inst);
     case 60:
-      return aarch64_ins_aimm (self, info, code, inst);
+    case 130:
+      return aarch64_ins_limm (self, info, code, inst);
     case 61:
-      return aarch64_ins_imm_half (self, info, code, inst);
+      return aarch64_ins_aimm (self, info, code, inst);
     case 62:
+      return aarch64_ins_imm_half (self, info, code, inst);
+    case 63:
       return aarch64_ins_fbits (self, info, code, inst);
-    case 64:
     case 65:
+    case 66:
       return aarch64_ins_cond (self, info, code, inst);
-    case 71:
-    case 77:
-      return aarch64_ins_addr_simple (self, info, code, inst);
     case 72:
-      return aarch64_ins_addr_regoff (self, info, code, inst);
+    case 78:
+      return aarch64_ins_addr_simple (self, info, code, inst);
     case 73:
+      return aarch64_ins_addr_regoff (self, info, code, inst);
     case 74:
     case 75:
-      return aarch64_ins_addr_simm (self, info, code, inst);
     case 76:
+      return aarch64_ins_addr_simm (self, info, code, inst);
+    case 77:
       return aarch64_ins_addr_uimm12 (self, info, code, inst);
-    case 78:
-      return aarch64_ins_simd_addr_post (self, info, code, inst);
     case 79:
-      return aarch64_ins_sysreg (self, info, code, inst);
+      return aarch64_ins_simd_addr_post (self, info, code, inst);
     case 80:
-      return aarch64_ins_pstatefield (self, info, code, inst);
+      return aarch64_ins_sysreg (self, info, code, inst);
     case 81:
+      return aarch64_ins_pstatefield (self, info, code, inst);
     case 82:
     case 83:
     case 84:
-      return aarch64_ins_sysins_op (self, info, code, inst);
     case 85:
+      return aarch64_ins_sysins_op (self, info, code, inst);
     case 86:
-      return aarch64_ins_barrier (self, info, code, inst);
     case 87:
-      return aarch64_ins_prfop (self, info, code, inst);
+      return aarch64_ins_barrier (self, info, code, inst);
     case 88:
-      return aarch64_ins_hint (self, info, code, inst);
+      return aarch64_ins_prfop (self, info, code, inst);
     case 89:
+      return aarch64_ins_hint (self, info, code, inst);
     case 90:
     case 91:
     case 92:
-      return aarch64_ins_sve_addr_ri_s4xvl (self, info, code, inst);
     case 93:
-      return aarch64_ins_sve_addr_ri_s6xvl (self, info, code, inst);
+      return aarch64_ins_sve_addr_ri_s4xvl (self, info, code, inst);
     case 94:
-      return aarch64_ins_sve_addr_ri_s9xvl (self, info, code, inst);
+      return aarch64_ins_sve_addr_ri_s6xvl (self, info, code, inst);
     case 95:
+      return aarch64_ins_sve_addr_ri_s9xvl (self, info, code, inst);
     case 96:
     case 97:
     case 98:
-      return aarch64_ins_sve_addr_ri_u6 (self, info, code, inst);
     case 99:
+      return aarch64_ins_sve_addr_ri_u6 (self, info, code, inst);
     case 100:
     case 101:
     case 102:
@@ -609,8 +618,8 @@ aarch64_insert_operand (const aarch64_operand *self,
     case 108:
     case 109:
     case 110:
-      return aarch64_ins_sve_addr_rr_lsl (self, info, code, inst);
     case 111:
+      return aarch64_ins_sve_addr_rr_lsl (self, info, code, inst);
     case 112:
     case 113:
     case 114:
@@ -618,24 +627,39 @@ aarch64_insert_operand (const aarch64_operand *self,
     case 116:
     case 117:
     case 118:
-      return aarch64_ins_sve_addr_rz_xtw (self, info, code, inst);
     case 119:
+      return aarch64_ins_sve_addr_rz_xtw (self, info, code, inst);
     case 120:
     case 121:
     case 122:
-      return aarch64_ins_sve_addr_zi_u5 (self, info, code, inst);
     case 123:
-      return aarch64_ins_sve_addr_zz_lsl (self, info, code, inst);
+      return aarch64_ins_sve_addr_zi_u5 (self, info, code, inst);
     case 124:
-      return aarch64_ins_sve_addr_zz_sxtw (self, info, code, inst);
+      return aarch64_ins_sve_addr_zz_lsl (self, info, code, inst);
     case 125:
+      return aarch64_ins_sve_addr_zz_sxtw (self, info, code, inst);
+    case 126:
       return aarch64_ins_sve_addr_zz_uxtw (self, info, code, inst);
     case 127:
+      return aarch64_ins_sve_aimm (self, info, code, inst);
+    case 128:
+      return aarch64_ins_sve_asimm (self, info, code, inst);
+    case 129:
+      return aarch64_ins_inv_limm (self, info, code, inst);
+    case 131:
+      return aarch64_ins_sve_limm_mov (self, info, code, inst);
+    case 133:
       return aarch64_ins_sve_scale (self, info, code, inst);
     case 143:
-      return aarch64_ins_sve_index (self, info, code, inst);
     case 144:
+      return aarch64_ins_sve_shlimm (self, info, code, inst);
+    case 145:
     case 146:
+      return aarch64_ins_sve_shrimm (self, info, code, inst);
+    case 161:
+      return aarch64_ins_sve_index (self, info, code, inst);
+    case 162:
+    case 164:
       return aarch64_ins_sve_reglist (self, info, code, inst);
     default: assert (0); abort ();
     }
index 944a9eba5415bdab4311a710c5f6f96fec67de06..61d0d95dce31bb281fe0e98c707ba2780ca8504b 100644 (file)
@@ -452,17 +452,18 @@ aarch64_ins_aimm (const aarch64_operand *self, const aarch64_opnd_info *info,
   return NULL;
 }
 
-/* Insert logical/bitmask immediate for e.g. the last operand in
-     ORR <Wd|WSP>, <Wn>, #<imm>.  */
-const char *
-aarch64_ins_limm (const aarch64_operand *self, const aarch64_opnd_info *info,
-                 aarch64_insn *code, const aarch64_inst *inst ATTRIBUTE_UNUSED)
+/* Common routine shared by aarch64_ins{,_inv}_limm.  INVERT_P says whether
+   the operand should be inverted before encoding.  */
+static const char *
+aarch64_ins_limm_1 (const aarch64_operand *self,
+                   const aarch64_opnd_info *info, aarch64_insn *code,
+                   const aarch64_inst *inst, bfd_boolean invert_p)
 {
   aarch64_insn value;
   uint64_t imm = info->imm.value;
   int esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
 
-  if (inst->opcode->op == OP_BIC)
+  if (invert_p)
     imm = ~imm;
   if (aarch64_logical_immediate_p (imm, esize, &value) == FALSE)
     /* The constraint check should have guaranteed this wouldn't happen.  */
@@ -473,6 +474,25 @@ aarch64_ins_limm (const aarch64_operand *self, const aarch64_opnd_info *info,
   return NULL;
 }
 
+/* Insert logical/bitmask immediate for e.g. the last operand in
+     ORR <Wd|WSP>, <Wn>, #<imm>.  */
+const char *
+aarch64_ins_limm (const aarch64_operand *self, const aarch64_opnd_info *info,
+                 aarch64_insn *code, const aarch64_inst *inst)
+{
+  return aarch64_ins_limm_1 (self, info, code, inst,
+                            inst->opcode->op == OP_BIC);
+}
+
+/* Insert a logical/bitmask immediate for the BIC alias of AND (etc.).  */
+const char *
+aarch64_ins_inv_limm (const aarch64_operand *self,
+                     const aarch64_opnd_info *info, aarch64_insn *code,
+                     const aarch64_inst *inst)
+{
+  return aarch64_ins_limm_1 (self, info, code, inst, TRUE);
+}
+
 /* Encode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
    or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>.  */
 const char *
@@ -903,6 +923,30 @@ aarch64_ins_sve_addr_zz_uxtw (const aarch64_operand *self,
   return aarch64_ext_sve_addr_zz (self, info, code);
 }
 
+/* Encode an SVE ADD/SUB immediate.  */
+const char *
+aarch64_ins_sve_aimm (const aarch64_operand *self,
+                     const aarch64_opnd_info *info, aarch64_insn *code,
+                     const aarch64_inst *inst ATTRIBUTE_UNUSED)
+{
+  if (info->shifter.amount == 8)
+    insert_all_fields (self, code, (info->imm.value & 0xff) | 256);
+  else if (info->imm.value != 0 && (info->imm.value & 0xff) == 0)
+    insert_all_fields (self, code, ((info->imm.value / 256) & 0xff) | 256);
+  else
+    insert_all_fields (self, code, info->imm.value & 0xff);
+  return NULL;
+}
+
+/* Encode an SVE CPY/DUP immediate.  */
+const char *
+aarch64_ins_sve_asimm (const aarch64_operand *self,
+                      const aarch64_opnd_info *info, aarch64_insn *code,
+                      const aarch64_inst *inst)
+{
+  return aarch64_ins_sve_aimm (self, info, code, inst);
+}
+
 /* Encode Zn[MM], where MM has a 7-bit triangular encoding.  The fields
    array specifies which field to use for Zn.  MM is encoded in the
    concatenation of imm5 and SVE_tszh, with imm5 being the less
@@ -919,6 +963,15 @@ aarch64_ins_sve_index (const aarch64_operand *self,
   return NULL;
 }
 
+/* Encode a logical/bitmask immediate for the MOV alias of SVE DUPM.  */
+const char *
+aarch64_ins_sve_limm_mov (const aarch64_operand *self,
+                         const aarch64_opnd_info *info, aarch64_insn *code,
+                         const aarch64_inst *inst)
+{
+  return aarch64_ins_limm (self, info, code, inst);
+}
+
 /* Encode {Zn.<T> - Zm.<T>}.  The fields array specifies which field
    to use for Zn.  */
 const char *
@@ -943,6 +996,38 @@ aarch64_ins_sve_scale (const aarch64_operand *self,
   return NULL;
 }
 
+/* Encode an SVE shift left immediate.  */
+const char *
+aarch64_ins_sve_shlimm (const aarch64_operand *self,
+                       const aarch64_opnd_info *info, aarch64_insn *code,
+                       const aarch64_inst *inst)
+{
+  const aarch64_opnd_info *prev_operand;
+  unsigned int esize;
+
+  assert (info->idx > 0);
+  prev_operand = &inst->operands[info->idx - 1];
+  esize = aarch64_get_qualifier_esize (prev_operand->qualifier);
+  insert_all_fields (self, code, 8 * esize + info->imm.value);
+  return NULL;
+}
+
+/* Encode an SVE shift right immediate.  */
+const char *
+aarch64_ins_sve_shrimm (const aarch64_operand *self,
+                       const aarch64_opnd_info *info, aarch64_insn *code,
+                       const aarch64_inst *inst)
+{
+  const aarch64_opnd_info *prev_operand;
+  unsigned int esize;
+
+  assert (info->idx > 0);
+  prev_operand = &inst->operands[info->idx - 1];
+  esize = aarch64_get_qualifier_esize (prev_operand->qualifier);
+  insert_all_fields (self, code, 16 * esize - info->imm.value);
+  return NULL;
+}
+
 /* Miscellaneous encoding functions.  */
 
 /* Encode size[0], i.e. bit 22, for
index 5e13de0483163bb9c1bec302150ee560dddee0e2..bbd320eb8eb1ef657c31a828fa11d4dc7db40408 100644 (file)
@@ -54,6 +54,7 @@ AARCH64_DECL_OPD_INSERTER (ins_fpimm);
 AARCH64_DECL_OPD_INSERTER (ins_fbits);
 AARCH64_DECL_OPD_INSERTER (ins_aimm);
 AARCH64_DECL_OPD_INSERTER (ins_limm);
+AARCH64_DECL_OPD_INSERTER (ins_inv_limm);
 AARCH64_DECL_OPD_INSERTER (ins_ft);
 AARCH64_DECL_OPD_INSERTER (ins_addr_simple);
 AARCH64_DECL_OPD_INSERTER (ins_addr_regoff);
@@ -79,9 +80,14 @@ AARCH64_DECL_OPD_INSERTER (ins_sve_addr_zi_u5);
 AARCH64_DECL_OPD_INSERTER (ins_sve_addr_zz_lsl);
 AARCH64_DECL_OPD_INSERTER (ins_sve_addr_zz_sxtw);
 AARCH64_DECL_OPD_INSERTER (ins_sve_addr_zz_uxtw);
+AARCH64_DECL_OPD_INSERTER (ins_sve_aimm);
+AARCH64_DECL_OPD_INSERTER (ins_sve_asimm);
 AARCH64_DECL_OPD_INSERTER (ins_sve_index);
+AARCH64_DECL_OPD_INSERTER (ins_sve_limm_mov);
 AARCH64_DECL_OPD_INSERTER (ins_sve_reglist);
 AARCH64_DECL_OPD_INSERTER (ins_sve_scale);
+AARCH64_DECL_OPD_INSERTER (ins_sve_shlimm);
+AARCH64_DECL_OPD_INSERTER (ins_sve_shrimm);
 
 #undef AARCH64_DECL_OPD_INSERTER
 
index 48d6ce7fefd2ee11ec92c520e259adf6c9a7b7cb..45274565dcded0466e6a449c6f1b92dbda8ad161 100644 (file)
@@ -10426,12 +10426,6 @@ aarch64_extract_operand (const aarch64_operand *self,
     case 27:
     case 35:
     case 36:
-    case 129:
-    case 130:
-    case 131:
-    case 132:
-    case 133:
-    case 134:
     case 135:
     case 136:
     case 137:
@@ -10440,7 +10434,13 @@ aarch64_extract_operand (const aarch64_operand *self,
     case 140:
     case 141:
     case 142:
-    case 145:
+    case 155:
+    case 156:
+    case 157:
+    case 158:
+    case 159:
+    case 160:
+    case 163:
       return aarch64_ext_regno (self, info, code, inst);
     case 8:
       return aarch64_ext_regrt_sysins (self, info, code, inst);
@@ -10477,13 +10477,22 @@ aarch64_extract_operand (const aarch64_operand *self,
     case 56:
     case 57:
     case 58:
-    case 66:
+    case 59:
     case 67:
     case 68:
     case 69:
     case 70:
-    case 126:
-    case 128:
+    case 71:
+    case 132:
+    case 134:
+    case 147:
+    case 148:
+    case 149:
+    case 150:
+    case 151:
+    case 152:
+    case 153:
+    case 154:
       return aarch64_ext_imm (self, info, code, inst);
     case 38:
     case 39:
@@ -10496,61 +10505,61 @@ aarch64_extract_operand (const aarch64_operand *self,
       return aarch64_ext_shll_imm (self, info, code, inst);
     case 46:
       return aarch64_ext_fpimm (self, info, code, inst);
-    case 59:
-      return aarch64_ext_limm (self, info, code, inst);
     case 60:
-      return aarch64_ext_aimm (self, info, code, inst);
+    case 130:
+      return aarch64_ext_limm (self, info, code, inst);
     case 61:
-      return aarch64_ext_imm_half (self, info, code, inst);
+      return aarch64_ext_aimm (self, info, code, inst);
     case 62:
+      return aarch64_ext_imm_half (self, info, code, inst);
+    case 63:
       return aarch64_ext_fbits (self, info, code, inst);
-    case 64:
     case 65:
+    case 66:
       return aarch64_ext_cond (self, info, code, inst);
-    case 71:
-    case 77:
-      return aarch64_ext_addr_simple (self, info, code, inst);
     case 72:
-      return aarch64_ext_addr_regoff (self, info, code, inst);
+    case 78:
+      return aarch64_ext_addr_simple (self, info, code, inst);
     case 73:
+      return aarch64_ext_addr_regoff (self, info, code, inst);
     case 74:
     case 75:
-      return aarch64_ext_addr_simm (self, info, code, inst);
     case 76:
+      return aarch64_ext_addr_simm (self, info, code, inst);
+    case 77:
       return aarch64_ext_addr_uimm12 (self, info, code, inst);
-    case 78:
-      return aarch64_ext_simd_addr_post (self, info, code, inst);
     case 79:
-      return aarch64_ext_sysreg (self, info, code, inst);
+      return aarch64_ext_simd_addr_post (self, info, code, inst);
     case 80:
-      return aarch64_ext_pstatefield (self, info, code, inst);
+      return aarch64_ext_sysreg (self, info, code, inst);
     case 81:
+      return aarch64_ext_pstatefield (self, info, code, inst);
     case 82:
     case 83:
     case 84:
-      return aarch64_ext_sysins_op (self, info, code, inst);
     case 85:
+      return aarch64_ext_sysins_op (self, info, code, inst);
     case 86:
-      return aarch64_ext_barrier (self, info, code, inst);
     case 87:
-      return aarch64_ext_prfop (self, info, code, inst);
+      return aarch64_ext_barrier (self, info, code, inst);
     case 88:
-      return aarch64_ext_hint (self, info, code, inst);
+      return aarch64_ext_prfop (self, info, code, inst);
     case 89:
+      return aarch64_ext_hint (self, info, code, inst);
     case 90:
     case 91:
     case 92:
-      return aarch64_ext_sve_addr_ri_s4xvl (self, info, code, inst);
     case 93:
-      return aarch64_ext_sve_addr_ri_s6xvl (self, info, code, inst);
+      return aarch64_ext_sve_addr_ri_s4xvl (self, info, code, inst);
     case 94:
-      return aarch64_ext_sve_addr_ri_s9xvl (self, info, code, inst);
+      return aarch64_ext_sve_addr_ri_s6xvl (self, info, code, inst);
     case 95:
+      return aarch64_ext_sve_addr_ri_s9xvl (self, info, code, inst);
     case 96:
     case 97:
     case 98:
-      return aarch64_ext_sve_addr_ri_u6 (self, info, code, inst);
     case 99:
+      return aarch64_ext_sve_addr_ri_u6 (self, info, code, inst);
     case 100:
     case 101:
     case 102:
@@ -10562,8 +10571,8 @@ aarch64_extract_operand (const aarch64_operand *self,
     case 108:
     case 109:
     case 110:
-      return aarch64_ext_sve_addr_rr_lsl (self, info, code, inst);
     case 111:
+      return aarch64_ext_sve_addr_rr_lsl (self, info, code, inst);
     case 112:
     case 113:
     case 114:
@@ -10571,24 +10580,39 @@ aarch64_extract_operand (const aarch64_operand *self,
     case 116:
     case 117:
     case 118:
-      return aarch64_ext_sve_addr_rz_xtw (self, info, code, inst);
     case 119:
+      return aarch64_ext_sve_addr_rz_xtw (self, info, code, inst);
     case 120:
     case 121:
     case 122:
-      return aarch64_ext_sve_addr_zi_u5 (self, info, code, inst);
     case 123:
-      return aarch64_ext_sve_addr_zz_lsl (self, info, code, inst);
+      return aarch64_ext_sve_addr_zi_u5 (self, info, code, inst);
     case 124:
-      return aarch64_ext_sve_addr_zz_sxtw (self, info, code, inst);
+      return aarch64_ext_sve_addr_zz_lsl (self, info, code, inst);
     case 125:
+      return aarch64_ext_sve_addr_zz_sxtw (self, info, code, inst);
+    case 126:
       return aarch64_ext_sve_addr_zz_uxtw (self, info, code, inst);
     case 127:
+      return aarch64_ext_sve_aimm (self, info, code, inst);
+    case 128:
+      return aarch64_ext_sve_asimm (self, info, code, inst);
+    case 129:
+      return aarch64_ext_inv_limm (self, info, code, inst);
+    case 131:
+      return aarch64_ext_sve_limm_mov (self, info, code, inst);
+    case 133:
       return aarch64_ext_sve_scale (self, info, code, inst);
     case 143:
-      return aarch64_ext_sve_index (self, info, code, inst);
     case 144:
+      return aarch64_ext_sve_shlimm (self, info, code, inst);
+    case 145:
     case 146:
+      return aarch64_ext_sve_shrimm (self, info, code, inst);
+    case 161:
+      return aarch64_ext_sve_index (self, info, code, inst);
+    case 162:
+    case 164:
       return aarch64_ext_sve_reglist (self, info, code, inst);
     default: assert (0); abort ();
     }
index ba6befdb55a4912a45e49a74fbfa5b2eedc2cdfe..ed050cd3e04eaa1f201995cce9cda9b9a5dff7e7 100644 (file)
@@ -734,32 +734,21 @@ aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
   return 1;
 }
 
-/* Decode logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>.  */
-
-int
-aarch64_ext_limm (const aarch64_operand *self ATTRIBUTE_UNUSED,
-                 aarch64_opnd_info *info, const aarch64_insn code,
-                 const aarch64_inst *inst ATTRIBUTE_UNUSED)
+/* Return true if VALUE is a valid logical immediate encoding, storing the
+   decoded value in *RESULT if so.  ESIZE is the number of bytes in the
+   decoded immediate.  */
+static int
+decode_limm (uint32_t esize, aarch64_insn value, int64_t *result)
 {
   uint64_t imm, mask;
-  uint32_t sf;
   uint32_t N, R, S;
   unsigned simd_size;
-  aarch64_insn value;
-
-  value = extract_fields (code, 0, 3, FLD_N, FLD_immr, FLD_imms);
-  assert (inst->operands[0].qualifier == AARCH64_OPND_QLF_W
-         || inst->operands[0].qualifier == AARCH64_OPND_QLF_X);
-  sf = aarch64_get_qualifier_esize (inst->operands[0].qualifier) != 4;
 
   /* value is N:immr:imms.  */
   S = value & 0x3f;
   R = (value >> 6) & 0x3f;
   N = (value >> 12) & 0x1;
 
-  if (sf == 0 && N == 1)
-    return 0;
-
   /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
      (in other words, right rotated by R), then replicated.  */
   if (N != 0)
@@ -782,6 +771,10 @@ aarch64_ext_limm (const aarch64_operand *self ATTRIBUTE_UNUSED,
       /* Top bits are IGNORED.  */
       R &= simd_size - 1;
     }
+
+  if (simd_size > esize * 8)
+    return 0;
+
   /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected.  */
   if (S == simd_size - 1)
     return 0;
@@ -803,8 +796,35 @@ aarch64_ext_limm (const aarch64_operand *self ATTRIBUTE_UNUSED,
     default: assert (0); return 0;
     }
 
-  info->imm.value = sf ? imm : imm & 0xffffffff;
+  *result = imm & ~((uint64_t) -1 << (esize * 4) << (esize * 4));
+
+  return 1;
+}
+
+/* Decode a logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>.  */
+int
+aarch64_ext_limm (const aarch64_operand *self,
+                 aarch64_opnd_info *info, const aarch64_insn code,
+                 const aarch64_inst *inst)
+{
+  uint32_t esize;
+  aarch64_insn value;
+
+  value = extract_fields (code, 0, 3, self->fields[0], self->fields[1],
+                         self->fields[2]);
+  esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
+  return decode_limm (esize, value, &info->imm.value);
+}
 
+/* Decode a logical immediate for the BIC alias of AND (etc.).  */
+int
+aarch64_ext_inv_limm (const aarch64_operand *self,
+                     aarch64_opnd_info *info, const aarch64_insn code,
+                     const aarch64_inst *inst)
+{
+  if (!aarch64_ext_limm (self, info, code, inst))
+    return 0;
+  info->imm.value = ~info->imm.value;
   return 1;
 }
 
@@ -1404,6 +1424,47 @@ aarch64_ext_sve_addr_zz_uxtw (const aarch64_operand *self,
   return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_UXTW);
 }
 
+/* Finish decoding an SVE arithmetic immediate, given that INFO already
+   has the raw field value and that the low 8 bits decode to VALUE.  */
+static int
+decode_sve_aimm (aarch64_opnd_info *info, int64_t value)
+{
+  info->shifter.kind = AARCH64_MOD_LSL;
+  info->shifter.amount = 0;
+  if (info->imm.value & 0x100)
+    {
+      if (value == 0)
+       /* Decode 0x100 as #0, LSL #8.  */
+       info->shifter.amount = 8;
+      else
+       value *= 256;
+    }
+  info->shifter.operator_present = (info->shifter.amount != 0);
+  info->shifter.amount_present = (info->shifter.amount != 0);
+  info->imm.value = value;
+  return 1;
+}
+
+/* Decode an SVE ADD/SUB immediate.  */
+int
+aarch64_ext_sve_aimm (const aarch64_operand *self,
+                     aarch64_opnd_info *info, const aarch64_insn code,
+                     const aarch64_inst *inst)
+{
+  return (aarch64_ext_imm (self, info, code, inst)
+         && decode_sve_aimm (info, (uint8_t) info->imm.value));
+}
+
+/* Decode an SVE CPY/DUP immediate.  */
+int
+aarch64_ext_sve_asimm (const aarch64_operand *self,
+                      aarch64_opnd_info *info, const aarch64_insn code,
+                      const aarch64_inst *inst)
+{
+  return (aarch64_ext_imm (self, info, code, inst)
+         && decode_sve_aimm (info, (int8_t) info->imm.value));
+}
+
 /* Decode Zn[MM], where MM has a 7-bit triangular encoding.  The fields
    array specifies which field to use for Zn.  MM is encoded in the
    concatenation of imm5 and SVE_tszh, with imm5 being the less
@@ -1425,6 +1486,17 @@ aarch64_ext_sve_index (const aarch64_operand *self,
   return 1;
 }
 
+/* Decode a logical immediate for the MOV alias of SVE DUPM.  */
+int
+aarch64_ext_sve_limm_mov (const aarch64_operand *self,
+                         aarch64_opnd_info *info, const aarch64_insn code,
+                         const aarch64_inst *inst)
+{
+  int esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
+  return (aarch64_ext_limm (self, info, code, inst)
+         && aarch64_sve_dupm_mov_immediate_p (info->imm.value, esize));
+}
+
 /* Decode {Zn.<T> - Zm.<T>}.  The fields array specifies which field
    to use for Zn.  The opcode-dependent value specifies the number
    of registers in the list.  */
@@ -1457,6 +1529,44 @@ aarch64_ext_sve_scale (const aarch64_operand *self,
   info->shifter.amount_present = (val != 0);
   return 1;
 }
+
+/* Return the top set bit in VALUE, which is expected to be relatively
+   small.  */
+static uint64_t
+get_top_bit (uint64_t value)
+{
+  while ((value & -value) != value)
+    value -= value & -value;
+  return value;
+}
+
+/* Decode an SVE shift-left immediate.  */
+int
+aarch64_ext_sve_shlimm (const aarch64_operand *self,
+                       aarch64_opnd_info *info, const aarch64_insn code,
+                       const aarch64_inst *inst)
+{
+  if (!aarch64_ext_imm (self, info, code, inst)
+      || info->imm.value == 0)
+    return 0;
+
+  info->imm.value -= get_top_bit (info->imm.value);
+  return 1;
+}
+
+/* Decode an SVE shift-right immediate.  */
+int
+aarch64_ext_sve_shrimm (const aarch64_operand *self,
+                       aarch64_opnd_info *info, const aarch64_insn code,
+                       const aarch64_inst *inst)
+{
+  if (!aarch64_ext_imm (self, info, code, inst)
+      || info->imm.value == 0)
+    return 0;
+
+  info->imm.value = get_top_bit (info->imm.value) * 2 - info->imm.value;
+  return 1;
+}
 \f
 /* Bitfields that are commonly used to encode certain operands' information
    may be partially used as part of the base opcode in some instructions.
index 5619877be540bbc4f49e23c16d893eede7385ed5..10983d124f40a3f189b4d99dee65c3420c09e623 100644 (file)
@@ -76,6 +76,7 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_fpimm);
 AARCH64_DECL_OPD_EXTRACTOR (ext_fbits);
 AARCH64_DECL_OPD_EXTRACTOR (ext_aimm);
 AARCH64_DECL_OPD_EXTRACTOR (ext_limm);
+AARCH64_DECL_OPD_EXTRACTOR (ext_inv_limm);
 AARCH64_DECL_OPD_EXTRACTOR (ext_ft);
 AARCH64_DECL_OPD_EXTRACTOR (ext_addr_simple);
 AARCH64_DECL_OPD_EXTRACTOR (ext_addr_regoff);
@@ -101,9 +102,14 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_sve_addr_zi_u5);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_addr_zz_lsl);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_addr_zz_sxtw);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_addr_zz_uxtw);
+AARCH64_DECL_OPD_EXTRACTOR (ext_sve_aimm);
+AARCH64_DECL_OPD_EXTRACTOR (ext_sve_asimm);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_index);
+AARCH64_DECL_OPD_EXTRACTOR (ext_sve_limm_mov);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_reglist);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_scale);
+AARCH64_DECL_OPD_EXTRACTOR (ext_sve_shlimm);
+AARCH64_DECL_OPD_EXTRACTOR (ext_sve_shrimm);
 
 #undef AARCH64_DECL_OPD_EXTRACTOR
 
index a72f577ac77849f77b2dc8a81c57bb210b4f51c1..d86e7dc241de0593561b44943b341161c2090baf 100644 (file)
@@ -82,6 +82,7 @@ const struct aarch64_operand aarch64_operands[] =
   {AARCH64_OPND_CLASS_IMMEDIATE, "BIT_NUM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_b5, FLD_b40}, "the bit number to be tested"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "EXCEPTION", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_imm16}, "a 16-bit unsigned immediate"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "CCMP_IMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_imm5}, "a 5-bit unsigned immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SIMM5", OPD_F_SEXT | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_imm5}, "a 5-bit signed immediate"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "NZCV", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_nzcv}, "a flag bit specifier giving an alternative value for each flag"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "LIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_N,FLD_immr,FLD_imms}, "Logical immediate"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "AIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_shift,FLD_imm12}, "a 12-bit unsigned immediate with optional left shift of 12 bits"},
@@ -150,6 +151,11 @@ const struct aarch64_operand aarch64_operands[] =
   {AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_ZZ_LSL", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Zn,FLD_SVE_Zm_16}, "an address with a vector register offset"},
   {AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_ZZ_SXTW", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Zn,FLD_SVE_Zm_16}, "an address with a vector register offset"},
   {AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_ZZ_UXTW", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Zn,FLD_SVE_Zm_16}, "an address with a vector register offset"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_AIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm9}, "a 9-bit unsigned arithmetic operand"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_ASIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm9}, "a 9-bit signed arithmetic operand"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_INV_LIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms}, "an inverted 13-bit logical immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_LIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms}, "a 13-bit logical immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_LIMM_MOV", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms}, "a 13-bit logical move immediate"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_PATTERN", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_pattern}, "an enumeration value such as POW2"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_PATTERN_SCALED", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_pattern}, "an enumeration value such as POW2"},
   {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_PRFOP", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_prfop}, "an enumeration value such as PLDL1KEEP"},
@@ -161,6 +167,18 @@ const struct aarch64_operand aarch64_operands[] =
   {AARCH64_OPND_CLASS_PRED_REG, "SVE_Pm", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Pm}, "an SVE predicate register"},
   {AARCH64_OPND_CLASS_PRED_REG, "SVE_Pn", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Pn}, "an SVE predicate register"},
   {AARCH64_OPND_CLASS_PRED_REG, "SVE_Pt", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Pt}, "an SVE predicate register"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_SHLIMM_PRED", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_tszh,FLD_SVE_imm5}, "a shift-left immediate operand"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_SHLIMM_UNPRED", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_tszh,FLD_imm5}, "a shift-left immediate operand"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_SHRIMM_PRED", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_tszh,FLD_SVE_imm5}, "a shift-right immediate operand"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_SHRIMM_UNPRED", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_tszh,FLD_imm5}, "a shift-right immediate operand"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_SIMM5", OPD_F_SEXT | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm5}, "a 5-bit signed immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_SIMM5B", OPD_F_SEXT | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm5b}, "a 5-bit signed immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_SIMM6", OPD_F_SEXT | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imms}, "a 6-bit signed immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_SIMM8", OPD_F_SEXT | OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm8}, "an 8-bit signed immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_UIMM3", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm3}, "a 3-bit unsigned immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_UIMM7", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm7}, "a 7-bit unsigned immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_UIMM8", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm8}, "an 8-bit unsigned immediate"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_UIMM8_53", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_imm5,FLD_imm3}, "an 8-bit unsigned immediate"},
   {AARCH64_OPND_CLASS_SVE_REG, "SVE_Za_5", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Za_5}, "an SVE vector register"},
   {AARCH64_OPND_CLASS_SVE_REG, "SVE_Za_16", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Za_16}, "an SVE vector register"},
   {AARCH64_OPND_CLASS_SVE_REG, "SVE_Zd", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Zd}, "an SVE vector register"},
index d0959b5b886a4f4621c7124464556bdc88e35cdf..b264bdb4f0a22df3dcffe5739cd0c03debbca073 100644 (file)
@@ -264,6 +264,7 @@ const aarch64_field fields[] =
     { 31,  1 },        /* b5: in the test bit and branch instructions.  */
     { 19,  5 },        /* b40: in the test bit and branch instructions.  */
     { 10,  6 },        /* scale: in the fixed-point scalar to fp converting inst.  */
+    { 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].  */
@@ -279,8 +280,16 @@ const aarch64_field fields[] =
     { 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].  */
+    { 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].  */
@@ -1374,9 +1383,10 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
                                  const aarch64_opcode *opcode,
                                  aarch64_operand_error *mismatch_detail)
 {
-  unsigned num, modifiers;
+  unsigned num, modifiers, shift;
   unsigned char size;
   int64_t imm, min_value, max_value;
+  uint64_t uvalue, mask;
   const aarch64_opnd_info *opnd = opnds + idx;
   aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
 
@@ -1977,6 +1987,10 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
        case AARCH64_OPND_UIMM7:
        case AARCH64_OPND_UIMM3_OP1:
        case AARCH64_OPND_UIMM3_OP2:
+       case AARCH64_OPND_SVE_UIMM3:
+       case AARCH64_OPND_SVE_UIMM7:
+       case AARCH64_OPND_SVE_UIMM8:
+       case AARCH64_OPND_SVE_UIMM8_53:
          size = get_operand_fields_width (get_operand_from_code (type));
          assert (size < 32);
          if (!value_fit_unsigned_field_p (opnd->imm.value, size))
@@ -1987,6 +2001,22 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
            }
          break;
 
+       case AARCH64_OPND_SIMM5:
+       case AARCH64_OPND_SVE_SIMM5:
+       case AARCH64_OPND_SVE_SIMM5B:
+       case AARCH64_OPND_SVE_SIMM6:
+       case AARCH64_OPND_SVE_SIMM8:
+         size = get_operand_fields_width (get_operand_from_code (type));
+         assert (size < 32);
+         if (!value_fit_signed_field_p (opnd->imm.value, size))
+           {
+             set_imm_out_of_range_error (mismatch_detail, idx,
+                                         -(1 << (size - 1)),
+                                         (1 << (size - 1)) - 1);
+             return 0;
+           }
+         break;
+
        case AARCH64_OPND_WIDTH:
          assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
                  && opnds[0].type == AARCH64_OPND_Rd);
@@ -2001,6 +2031,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
          break;
 
        case AARCH64_OPND_LIMM:
+       case AARCH64_OPND_SVE_LIMM:
          {
            int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
            uint64_t uimm = opnd->imm.value;
@@ -2171,6 +2202,90 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
            }
          break;
 
+       case AARCH64_OPND_SVE_AIMM:
+         min_value = 0;
+       sve_aimm:
+         assert (opnd->shifter.kind == AARCH64_MOD_LSL);
+         size = aarch64_get_qualifier_esize (opnds[0].qualifier);
+         mask = ~((uint64_t) -1 << (size * 4) << (size * 4));
+         uvalue = opnd->imm.value;
+         shift = opnd->shifter.amount;
+         if (size == 1)
+           {
+             if (shift != 0)
+               {
+                 set_other_error (mismatch_detail, idx,
+                                  _("no shift amount allowed for"
+                                    " 8-bit constants"));
+                 return 0;
+               }
+           }
+         else
+           {
+             if (shift != 0 && shift != 8)
+               {
+                 set_other_error (mismatch_detail, idx,
+                                  _("shift amount must be 0 or 8"));
+                 return 0;
+               }
+             if (shift == 0 && (uvalue & 0xff) == 0)
+               {
+                 shift = 8;
+                 uvalue = (int64_t) uvalue / 256;
+               }
+           }
+         mask >>= shift;
+         if ((uvalue & mask) != uvalue && (uvalue | ~mask) != uvalue)
+           {
+             set_other_error (mismatch_detail, idx,
+                              _("immediate too big for element size"));
+             return 0;
+           }
+         uvalue = (uvalue - min_value) & mask;
+         if (uvalue > 0xff)
+           {
+             set_other_error (mismatch_detail, idx,
+                              _("invalid arithmetic immediate"));
+             return 0;
+           }
+         break;
+
+       case AARCH64_OPND_SVE_ASIMM:
+         min_value = -128;
+         goto sve_aimm;
+
+       case AARCH64_OPND_SVE_INV_LIMM:
+         {
+           int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
+           uint64_t uimm = ~opnd->imm.value;
+           if (!aarch64_logical_immediate_p (uimm, esize, NULL))
+             {
+               set_other_error (mismatch_detail, idx,
+                                _("immediate out of range"));
+               return 0;
+             }
+         }
+         break;
+
+       case AARCH64_OPND_SVE_LIMM_MOV:
+         {
+           int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
+           uint64_t uimm = opnd->imm.value;
+           if (!aarch64_logical_immediate_p (uimm, esize, NULL))
+             {
+               set_other_error (mismatch_detail, idx,
+                                _("immediate out of range"));
+               return 0;
+             }
+           if (!aarch64_sve_dupm_mov_immediate_p (uimm, esize))
+             {
+               set_other_error (mismatch_detail, idx,
+                                _("invalid replicated MOV immediate"));
+               return 0;
+             }
+         }
+         break;
+
        case AARCH64_OPND_SVE_PATTERN_SCALED:
          assert (opnd->shifter.kind == AARCH64_MOD_MUL);
          if (!value_in_range_p (opnd->shifter.amount, 1, 16))
@@ -2180,6 +2295,27 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
            }
          break;
 
+       case AARCH64_OPND_SVE_SHLIMM_PRED:
+       case AARCH64_OPND_SVE_SHLIMM_UNPRED:
+         size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
+         if (!value_in_range_p (opnd->imm.value, 0, 8 * size - 1))
+           {
+             set_imm_out_of_range_error (mismatch_detail, idx,
+                                         0, 8 * size - 1);
+             return 0;
+           }
+         break;
+
+       case AARCH64_OPND_SVE_SHRIMM_PRED:
+       case AARCH64_OPND_SVE_SHRIMM_UNPRED:
+         size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
+         if (!value_in_range_p (opnd->imm.value, 1, 8 * size))
+           {
+             set_imm_out_of_range_error (mismatch_detail, idx, 1, 8 * size);
+             return 0;
+           }
+         break;
+
        default:
          break;
        }
@@ -2953,6 +3089,19 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_IMMR:
     case AARCH64_OPND_IMMS:
     case AARCH64_OPND_FBITS:
+    case AARCH64_OPND_SIMM5:
+    case AARCH64_OPND_SVE_SHLIMM_PRED:
+    case AARCH64_OPND_SVE_SHLIMM_UNPRED:
+    case AARCH64_OPND_SVE_SHRIMM_PRED:
+    case AARCH64_OPND_SVE_SHRIMM_UNPRED:
+    case AARCH64_OPND_SVE_SIMM5:
+    case AARCH64_OPND_SVE_SIMM5B:
+    case AARCH64_OPND_SVE_SIMM6:
+    case AARCH64_OPND_SVE_SIMM8:
+    case AARCH64_OPND_SVE_UIMM3:
+    case AARCH64_OPND_SVE_UIMM7:
+    case AARCH64_OPND_SVE_UIMM8:
+    case AARCH64_OPND_SVE_UIMM8_53:
       snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
       break;
 
@@ -3021,6 +3170,9 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_LIMM:
     case AARCH64_OPND_AIMM:
     case AARCH64_OPND_HALF:
+    case AARCH64_OPND_SVE_INV_LIMM:
+    case AARCH64_OPND_SVE_LIMM:
+    case AARCH64_OPND_SVE_LIMM_MOV:
       if (opnd->shifter.amount)
        snprintf (buf, size, "#0x%" PRIx64 ", lsl #%" PRIi64, opnd->imm.value,
                  opnd->shifter.amount);
@@ -3039,6 +3191,15 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
                  opnd->shifter.amount);
       break;
 
+    case AARCH64_OPND_SVE_AIMM:
+    case AARCH64_OPND_SVE_ASIMM:
+      if (opnd->shifter.amount)
+       snprintf (buf, size, "#%" PRIi64 ", lsl #%" PRIi64, opnd->imm.value,
+                 opnd->shifter.amount);
+      else
+       snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+      break;
+
     case AARCH64_OPND_FPIMM:
     case AARCH64_OPND_SIMD_FPIMM:
       switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
@@ -3967,6 +4128,33 @@ verify_ldpsw (const struct aarch64_opcode * opcode ATTRIBUTE_UNUSED,
   return TRUE;
 }
 
+/* Return true if VALUE cannot be moved into an SVE register using DUP
+   (with any element size, not just ESIZE) and if using DUPM would
+   therefore be OK.  ESIZE is the number of bytes in the immediate.  */
+
+bfd_boolean
+aarch64_sve_dupm_mov_immediate_p (uint64_t uvalue, int esize)
+{
+  int64_t svalue = uvalue;
+  uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
+
+  if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
+    return FALSE;
+  if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
+    {
+      svalue = (int32_t) uvalue;
+      if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
+       {
+         svalue = (int16_t) uvalue;
+         if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
+           return FALSE;
+       }
+    }
+  if ((svalue & 0xff) == 0)
+    svalue /= 256;
+  return svalue < -128 || svalue >= 128;
+}
+
 /* Include the opcode description table as well as the operand description
    table.  */
 #define VERIFIER(x) verify_##x
index e823146275531581932f40f0da35a7ee4bb942f6..087376e09c054f5f50ec003bab476cebf5d64b3f 100644 (file)
@@ -91,6 +91,7 @@ enum aarch64_field_kind
   FLD_b5,
   FLD_b40,
   FLD_scale,
+  FLD_SVE_N,
   FLD_SVE_Pd,
   FLD_SVE_Pg3,
   FLD_SVE_Pg4_5,
@@ -106,8 +107,16 @@ enum aarch64_field_kind
   FLD_SVE_Zm_16,
   FLD_SVE_Zn,
   FLD_SVE_Zt,
+  FLD_SVE_imm3,
   FLD_SVE_imm4,
+  FLD_SVE_imm5,
+  FLD_SVE_imm5b,
   FLD_SVE_imm6,
+  FLD_SVE_imm7,
+  FLD_SVE_imm8,
+  FLD_SVE_imm9,
+  FLD_SVE_immr,
+  FLD_SVE_imms,
   FLD_SVE_msz,
   FLD_SVE_pattern,
   FLD_SVE_prfop,
index 986cef6fe31a8da0f2d87b04abe04cfb9835537a..edb2d7936b2655d61164a260e32a4ccecb152933 100644 (file)
@@ -2761,6 +2761,8 @@ struct aarch64_opcode aarch64_opcode_table[] =
       "a 16-bit unsigned immediate")                                   \
     Y(IMMEDIATE, imm, "CCMP_IMM", 0, F(FLD_imm5),                      \
       "a 5-bit unsigned immediate")                                    \
+    Y(IMMEDIATE, imm, "SIMM5", OPD_F_SEXT, F(FLD_imm5),                        \
+      "a 5-bit signed immediate")                                      \
     Y(IMMEDIATE, imm, "NZCV", 0, F(FLD_nzcv),                          \
       "a flag bit specifier giving an alternative value for each flag")        \
     Y(IMMEDIATE, limm, "LIMM", 0, F(FLD_N,FLD_immr,FLD_imms),          \
@@ -2925,6 +2927,19 @@ struct aarch64_opcode aarch64_opcode_table[] =
     Y(ADDRESS, sve_addr_zz_uxtw, "SVE_ADDR_ZZ_UXTW", 0,                        \
       F(FLD_SVE_Zn,FLD_SVE_Zm_16),                                     \
       "an address with a vector register offset")                      \
+    Y(IMMEDIATE, sve_aimm, "SVE_AIMM", 0, F(FLD_SVE_imm9),             \
+      "a 9-bit unsigned arithmetic operand")                           \
+    Y(IMMEDIATE, sve_asimm, "SVE_ASIMM", 0, F(FLD_SVE_imm9),           \
+      "a 9-bit signed arithmetic operand")                             \
+    Y(IMMEDIATE, inv_limm, "SVE_INV_LIMM", 0,                          \
+      F(FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms),                          \
+      "an inverted 13-bit logical immediate")                          \
+    Y(IMMEDIATE, limm, "SVE_LIMM", 0,                                  \
+      F(FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms),                          \
+      "a 13-bit logical immediate")                                    \
+    Y(IMMEDIATE, sve_limm_mov, "SVE_LIMM_MOV", 0,                      \
+      F(FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms),                          \
+      "a 13-bit logical move immediate")                               \
     Y(IMMEDIATE, imm, "SVE_PATTERN", 0, F(FLD_SVE_pattern),            \
       "an enumeration value such as POW2")                             \
     Y(IMMEDIATE, sve_scale, "SVE_PATTERN_SCALED", 0,                   \
@@ -2947,6 +2962,30 @@ struct aarch64_opcode aarch64_opcode_table[] =
       "an SVE predicate register")                                     \
     Y(PRED_REG, regno, "SVE_Pt", 0, F(FLD_SVE_Pt),                     \
       "an SVE predicate register")                                     \
+    Y(IMMEDIATE, sve_shlimm, "SVE_SHLIMM_PRED", 0,                     \
+      F(FLD_SVE_tszh,FLD_SVE_imm5), "a shift-left immediate operand")  \
+    Y(IMMEDIATE, sve_shlimm, "SVE_SHLIMM_UNPRED", 0,                   \
+      F(FLD_SVE_tszh,FLD_imm5), "a shift-left immediate operand")      \
+    Y(IMMEDIATE, sve_shrimm, "SVE_SHRIMM_PRED", 0,                     \
+      F(FLD_SVE_tszh,FLD_SVE_imm5), "a shift-right immediate operand") \
+    Y(IMMEDIATE, sve_shrimm, "SVE_SHRIMM_UNPRED", 0,                   \
+      F(FLD_SVE_tszh,FLD_imm5), "a shift-right immediate operand")     \
+    Y(IMMEDIATE, imm, "SVE_SIMM5", OPD_F_SEXT, F(FLD_SVE_imm5),                \
+      "a 5-bit signed immediate")                                      \
+    Y(IMMEDIATE, imm, "SVE_SIMM5B", OPD_F_SEXT, F(FLD_SVE_imm5b),      \
+      "a 5-bit signed immediate")                                      \
+    Y(IMMEDIATE, imm, "SVE_SIMM6", OPD_F_SEXT, F(FLD_SVE_imms),                \
+      "a 6-bit signed immediate")                                      \
+    Y(IMMEDIATE, imm, "SVE_SIMM8", OPD_F_SEXT, F(FLD_SVE_imm8),                \
+      "an 8-bit signed immediate")                                     \
+    Y(IMMEDIATE, imm, "SVE_UIMM3", 0, F(FLD_SVE_imm3),                 \
+      "a 3-bit unsigned immediate")                                    \
+    Y(IMMEDIATE, imm, "SVE_UIMM7", 0, F(FLD_SVE_imm7),                 \
+      "a 7-bit unsigned immediate")                                    \
+    Y(IMMEDIATE, imm, "SVE_UIMM8", 0, F(FLD_SVE_imm8),                 \
+      "an 8-bit unsigned immediate")                                   \
+    Y(IMMEDIATE, imm, "SVE_UIMM8_53", 0, F(FLD_imm5,FLD_imm3),         \
+      "an 8-bit unsigned immediate")                                   \
     Y(SVE_REG, regno, "SVE_Za_5", 0, F(FLD_SVE_Za_5),                  \
       "an SVE vector register")                                                \
     Y(SVE_REG, regno, "SVE_Za_16", 0, F(FLD_SVE_Za_16),                        \