> -----Original Message-----
> From: Richard Earnshaw (foss) <[email protected]>
> Sent: 06 October 2026 15:00
> To: Tamar Christina <[email protected]>; [email protected]
> Cc: nd <[email protected]>; [email protected]; Alex Coplan
> <[email protected]>; [email protected]; Wilco Dijkstra
> <[email protected]>; Alice Carlotti <[email protected]>
> Subject: Re: [patch][gcc 2/5]AArch64: route print operands through a shared
> lookup table
> 
> On 28/09/2026 08:17, Tamar Christina wrote:
> > The previous patch gives the middle end a way to pass named output
> > modifiers to targets.  This patch teaches AArch64 to use that mechanism
> > without changing the meaning of the existing one-letter modifiers.
> >
> > AArch64 used to dispatch print operands directly from the raw character in
> > a large switch.  That made sense when the modifier could only be a single
> > letter, but it does not give us a natural place to say that a named
> > modifier is internal-only or to attach small pieces of data to a modifier.
> >
> > This patch moves the AArch64 print operand selection into a small lookup
> > table.  The existing public modifiers, such as %w0, %x0 and %c0, are
> > registered under their current names and continue to work for user asm and
> > machine descriptions.  The table also records whether a modifier is
> > available to user asm, and has an extra field that later patches use for
> > small constants such as a lane count.
> >
> > So for the old form:
> >
> >   %w0
> >
> > the hook still ends up selecting the existing W-register printing
> > behaviour.  For the new form:
> >
> >   %[SOME_TARGET_NAME]0
> >
> > the hook asks the middle end for the bracketed name and performs the same
> > table lookup.  Unknown names, or internal-only names used from user asm,
> > are rejected with the normal output operand diagnostic.
> >
> > There should be no intended assembly output change from this patch by
> > itself.  It is the AArch64 plumbing needed by the following cleanups.
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu,
> > arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> > -m32, -m64 and no issues.
> >
> > OK for master?
> >
> > Thanks,
> > Tamar
> >
> > gcc/ChangeLog:
> >
> >     * config/aarch64/aarch64.cc (aarch64_print_operands): New enum.
> >     (aarch64_print_operand_info): New structure.
> >     (operands_cache): New hash map.
> >     (operands_cache_initializer): New helper.
> >     (aarch64_lookup_operand): New overloads.
> >     (aarch64_print_operand): Dispatch via aarch64_print_operands.
> >
> > ---
> > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> > index
> 13a63a936d5956c1ef38d2314f0e618d31e918e9..438c109596e9a2c8483e
> dd5cf98a57358f2fae22 100644
> > --- a/gcc/config/aarch64/aarch64.cc
> > +++ b/gcc/config/aarch64/aarch64.cc
> > @@ -13178,67 +13178,217 @@ sizetochar (int size)
> >      }
> >  }
> >
> > +/* Print operands supported by AArch64.  */
> > +typedef enum aarch64_print_operands {
> > +  /* An integer or symbol address without a preceding # sign.  */
> > +  A64_PRINT_constants,
> > +  /* Print the sign/zero-extend size as a character 8->b, 16->h, 32->w.  
> > Can
> > +     also be used for masks: 0xff->b, 0xffff->h, 0xffffffff->w.  */
> > +  A64_PRINT_extended,
> > +  /* Prints N such that 2^N == X (X must be power of 2 and const int). */
> > +  A64_PRINT_power2n,
> > +  /* Print the number of non-zero bits in X (a const_int).  */
> > +  A64_PRINT_num_nonzero,
> > +  /* Print the higher numbered register of a pair (TImode) of regs.  */
> > +  A64_PRINT_hi_regpair,
> > +  /* If the operand is a duplicated vector constant, replace it with the
> > +     duplicated scalar.  If the operand is then a floating-point constant,
> > +     replace it with the integer bit representation.  Print the transformed
> > +     constant as a signed decimal number.  */
> > +  A64_PRINT_dup_or_int,
> > +  /* Print a condition (eq, ne, etc).  */
> > +  A64_PRINT_cc_code,
> > +  /* Same as 'm', but invert condition.  */
> > +  A64_PRINT_inv_cc_code,
> > +  /* Take the duplicated element in a vector constant and print the 
> > negative
> > +     of it in decimal.  */
> > +  A64_PRINT_neg_dup_const,
> > +  /* Print a scalar FP/SIMD register name.  */
> > +  A64_PRINT_scalar_b_reg,
> > +  /* Print a scalar FP/SIMD register name.  */
> > +  A64_PRINT_scalar_h_reg,
> > +  /* Print a scalar FP/SIMD register name.  */
> > +  A64_PRINT_scalar_s_reg,
> > +  /* Print a scalar FP/SIMD register name.  */
> > +  A64_PRINT_scalar_d_reg,
> > +  /* Print a scalar FP/SIMD register name.  */
> > +  A64_PRINT_simd_q_reg,
> > +  /* Same for SVE registers.  ('z' was already taken.) Note that it is not
> > +     necessary to use %Z for operands that have SVE modes.  The convention
> is to
> > +     use %Z only for non-SVE (or potentially non-SVE) modes.  */
> > +  A64_PRINT_sve_reg,
> > +  /* Print a FP/SIMD register name for a register list.  The register 
> > printed is
> > +     the FP/SIMD register name of X + 0/1/2/3 for S/T/U/V.  */
> > +  A64_PRINT_simd_reg_plus_0,
> > +  /* Print a FP/SIMD register name for a register list.  The register 
> > printed is
> > +     the FP/SIMD register name of X + 0/1/2/3 for S/T/U/V.  */
> > +  A64_PRINT_simd_reg_plus_1,
> > +  /* Print a FP/SIMD register name for a register list.  The register 
> > printed is
> > +     the FP/SIMD register name of X + 0/1/2/3 for S/T/U/V.  */
> > +  A64_PRINT_simd_reg_plus_2,
> > +  /* Print a FP/SIMD register name for a register list.  The register 
> > printed is
> > +     the FP/SIMD register name of X + 0/1/2/3 for S/T/U/V.  */
> > +  A64_PRINT_simd_reg_plus_3,
> > +  /* Print a scalar Integer/FP/SIMD register name + 1.  */
> > +  A64_PRINT_scalar_intreg_plus_1,
> > +  /* Print bottom 16 bits of integer constant in hex.  */
> > +  A64_PRINT_bottom_16bits,
> > +  /* Take the duplicated element in a vector constant and print it in hex. 
> >  */
> > +  A64_PRINT_dup_as_hex,
> > +  /* Take the duplicated element in a vector constant and print it as an
> > +     unsigned integer, in decimal.  */
> > +  A64_PRINT_dup_as_unsigned_dec,
> > +  /* Print a general register name or the zero register (32-bit or 
> > 64-bit).  */
> > +  A64_PRINT_gpr_w,
> > +  /* Print a general register name or the zero register (32-bit or 
> > 64-bit).  */
> > +  A64_PRINT_gpr_x,
> > +  /* Print a normal operand, if it's a general register, then we assume
> > +     DImode.  */
> > +  A64_PRINT_operand,
> > +  /* Output address constant representing the first argument of X,
> specifying a
> > +     relocation offset if appropriate.  */
> > +  A64_PRINT_output_addr,
> > +  /* Output constant address specified by X with a relocation offset if
> > +     appropriate.  */
> > +  A64_PRINT_output_const_addr,
> > +  /* Prints address of X, specifying a PC relative relocation mode if
> > +     appropriate.  */
> > +  A64_PRINT_output_addr_or_reloc,
> > +  /* Print NZCV for conditional compare instructions.  */
> > +  A64_PRINT_cond_cc_code,
> > +  /* Print a predicate register as pn<N> rather than p<N>.  */
> > +  A64_PRINT_pred_reg,
> > +  /* Output address of LDP or STP - this is used for some LDP/STPs which
> don't
> > +     use a PARALLEL in their pattern (so the mode needs to be adjusted).  
> > */
> > +  A64_PRINT_addr_ldp_stp_np,
> > +  /* Output address of a typical LDP or STP.  */
> > +  A64_PRINT_addr_ldp_stp,
> 
> It would be nice, I think, if this list could be generated by parsing ...
> 
> > +  /* Unknown print operand.  */
> > +  A64_PRINT_UNKNOWN
> > +} aarch64_print_operands_t;
> > +
> > +struct aarch64_print_operand_info
> > +{
> > +  aarch64_print_operands_t code;
> > +  bool user_p;
> > +  void *extra;
> > +};
> > +
> > +static hash_map<nofree_string_hash, aarch64_print_operand_info>
> operands_cache;
> > +
> > +struct operands_cache_initializer
> > +{
> > +  void add (const char *token, aarch64_print_operands_t code,
> > +       bool user_p = true, void *extra = nullptr)
> > +  {
> > +    operands_cache.put (token, { code, user_p, extra });
> > +  }
> > +
> > +  operands_cache_initializer ()
> > +  {
> > +#define DEF_PUBLIC_OPERAND(NAME, CODE) add (#NAME, CODE)
> > +#define DEF_PRIVATE_OPERAND(NAME, CODE) add (#NAME, CODE, false)
> > +#define DEF_PUBLIC_OPERAND_EXT(NAME, CODE, EXTRA) \
> > +  add (#NAME, CODE, true, (void *) (uintptr_t) (EXTRA))
> > +#define DEF_PRIVATE_OPERAND_EXT(NAME, CODE, EXTRA) \
> > +  add (#NAME, CODE, false, (void *) (uintptr_t) (EXTRA))
> > +
> 
> ... these DEF rules so that we can avoid some replication.

That's do-able, I think I'd have to move them to e.g. an 
aarch64-print-operands.def
file, but maybe for the best anyway? Splits up this huge file anyway.

> 
> > +    DEF_PUBLIC_OPERAND (A, A64_PRINT_output_addr);
> > +    DEF_PUBLIC_OPERAND (b, A64_PRINT_scalar_b_reg);
> > +    DEF_PUBLIC_OPERAND (c, A64_PRINT_constants);
> > +    DEF_PUBLIC_OPERAND (C, A64_PRINT_dup_as_hex);
> > +    DEF_PUBLIC_OPERAND (d, A64_PRINT_scalar_d_reg);
> > +    DEF_PUBLIC_OPERAND (D, A64_PRINT_dup_as_unsigned_dec);
> > +    DEF_PUBLIC_OPERAND (e, A64_PRINT_extended);
> > +    DEF_PUBLIC_OPERAND (p, A64_PRINT_power2n);
> > +    DEF_PUBLIC_OPERAND (P, A64_PRINT_num_nonzero);
> > +    DEF_PUBLIC_OPERAND (H, A64_PRINT_hi_regpair);
> > +    DEF_PUBLIC_OPERAND (I, A64_PRINT_dup_or_int);
> > +    DEF_PUBLIC_OPERAND (m, A64_PRINT_cc_code);
> > +    DEF_PUBLIC_OPERAND (M, A64_PRINT_inv_cc_code);
> > +    DEF_PUBLIC_OPERAND (N, A64_PRINT_neg_dup_const);
> > +    DEF_PUBLIC_OPERAND (h, A64_PRINT_scalar_h_reg);
> > +    DEF_PUBLIC_OPERAND (q, A64_PRINT_simd_q_reg);
> > +    DEF_PUBLIC_OPERAND (Z, A64_PRINT_sve_reg);
> > +    DEF_PUBLIC_OPERAND (s, A64_PRINT_scalar_s_reg);
> > +    DEF_PUBLIC_OPERAND (S, A64_PRINT_simd_reg_plus_0);
> > +    DEF_PUBLIC_OPERAND (T, A64_PRINT_simd_reg_plus_1);
> > +    DEF_PUBLIC_OPERAND (U, A64_PRINT_simd_reg_plus_2);
> > +    DEF_PUBLIC_OPERAND (V, A64_PRINT_simd_reg_plus_3);
> > +    DEF_PUBLIC_OPERAND (R, A64_PRINT_scalar_intreg_plus_1);
> > +    DEF_PUBLIC_OPERAND (w, A64_PRINT_gpr_w);
> > +    DEF_PUBLIC_OPERAND (L, A64_PRINT_output_const_addr);
> > +    DEF_PUBLIC_OPERAND (G, A64_PRINT_output_addr_or_reloc);
> > +    DEF_PUBLIC_OPERAND (k, A64_PRINT_cond_cc_code);
> > +    DEF_PUBLIC_OPERAND (K, A64_PRINT_pred_reg);
> > +    DEF_PUBLIC_OPERAND (x, A64_PRINT_gpr_x);
> > +    DEF_PUBLIC_OPERAND (X, A64_PRINT_bottom_16bits);
> > +    DEF_PUBLIC_OPERAND (y, A64_PRINT_addr_ldp_stp_np);
> > +    DEF_PUBLIC_OPERAND (z, A64_PRINT_addr_ldp_stp);
> > +
> > +#undef DEF_PUBLIC_OPERAND
> > +#undef DEF_PRIVATE_OPERAND
> > +#undef DEF_PUBLIC_OPERAND_EXT
> > +#undef DEF_PRIVATE_OPERAND_EXT
> > +  }
> > +};
> > +
> > +/* Force the static initialization.  */
> > +static operands_cache_initializer init_operands_cache;
> > +
> > +/* Perform lookup of print operand based on TOKEN.  */
> > +static aarch64_print_operand_info
> > +aarch64_lookup_operand (const char *token)
> > +{
> > +  if (auto e = operands_cache.get (token))
> > +    return *e;
> > +
> > +  return { A64_PRINT_UNKNOWN, false, nullptr };
> > +}
> > +
> > +/* Perform lookup of print operand based on legacy single-character CODE,
> > +   recording the printable form in TOKEN for diagnostics.  */
> > +
> > +static aarch64_print_operand_info
> > +aarch64_lookup_operand (int code, std::string &token)
> > +{
> > +  /* CODE 0 is the default operand syntax.  */
> > +  if (code == 0)
> > +    return { A64_PRINT_operand, true, nullptr };
> > +
> > +  if (code > UCHAR_MAX)
> > +    {
> > +      const char *name = output_operand_modifier_name (code);
> > +      if (!name)
> > +   return { A64_PRINT_UNKNOWN, false, nullptr };
> > +      token = name;
> > +      if (auto e = operands_cache.get (token.c_str ()))
> > +   {
> > +     if (output_operand_modifier_user_p (code) && !e->user_p)
> > +       return { A64_PRINT_UNKNOWN, false, nullptr };
> > +     return *e;
> > +   }
> > +      return { A64_PRINT_UNKNOWN, false, nullptr };
> > +    }
> > +
> > +  token += (char) code;
> > +  return aarch64_lookup_operand (token.c_str ());
> > +}
> > +
> >  /* Print operand X to file F in a target specific manner according to CODE.
> > -   The acceptable formatting commands given by CODE are:
> > -     'c':          An integer or symbol address without a preceding #
> > -                   sign.
> > -     'C':          Take the duplicated element in a vector constant
> > -                   and print it in hex.
> > -     'D':          Take the duplicated element in a vector constant
> > -                   and print it as an unsigned integer, in decimal.
> > -     'e':          Print the sign/zero-extend size as a character 8->b,
> > -                   16->h, 32->w.  Can also be used for masks:
> > -                   0xff->b, 0xffff->h, 0xffffffff->w.
> > -     'I':          If the operand is a duplicated vector constant,
> > -                   replace it with the duplicated scalar.  If the
> > -                   operand is then a floating-point constant, replace
> > -                   it with the integer bit representation.  Print the
> > -                   transformed constant as a signed decimal number.
> > -     'p':          Prints N such that 2^N == X (X must be power of 2 and
> > -                   const int).
> > -     'P':          Print the number of non-zero bits in X (a const_int).
> > -     'H':          Print the higher numbered register of a pair (TImode)
> > -                   of regs.
> > -     'm':          Print a condition (eq, ne, etc).
> > -     'M':          Same as 'm', but invert condition.
> > -     'N':          Take the duplicated element in a vector constant
> > -                   and print the negative of it in decimal.
> > -     'b/h/s/d/q':  Print a scalar FP/SIMD register name.
> > -     'Z':          Same for SVE registers.  ('z' was already taken.)
> > -                   Note that it is not necessary to use %Z for operands
> > -                   that have SVE modes.  The convention is to use %Z
> > -                   only for non-SVE (or potentially non-SVE) modes.
> > -     'S/T/U/V':            Print a FP/SIMD register name for a register 
> > list.
> > -                   The register printed is the FP/SIMD register name
> > -                   of X + 0/1/2/3 for S/T/U/V.
> > -     'R':          Print a scalar Integer/FP/SIMD register name + 1.
> > -     'X':          Print bottom 16 bits of integer constant in hex.
> > -     'w/x':                Print a general register name or the zero 
> > register
> > -                   (32-bit or 64-bit).
> > -     '0':          Print a normal operand, if it's a general register,
> > -                   then we assume DImode.
> > -     'k':          Print NZCV for conditional compare instructions.
> > -     'K':          Print a predicate register as pn<N> rather than p<N>
> > -     'A':          Output address constant representing the first
> > -                   argument of X, specifying a relocation offset
> > -                   if appropriate.
> > -     'L':          Output constant address specified by X
> > -                   with a relocation offset if appropriate.
> > -     'G':          Prints address of X, specifying a PC relative
> > -                   relocation mode if appropriate.
> > -     'y':          Output address of LDP or STP - this is used for
> > -                   some LDP/STPs which don't use a PARALLEL in their
> > -                   pattern (so the mode needs to be adjusted).
> > -     'z':          Output address of a typical LDP or STP.  */
> > +   The acceptable formatting commands given by CODE are documented on
> the
> > +   enum aarch64_print_operands.  */
> >
> >  static void
> > -aarch64_print_operand (FILE *f, rtx x, const char * const *p)
> 
> ??? Is your baseline correct?  My source tree shows
> aarch64_print_operand (FILE *f, rtx x, int code)
> ie, this doesn't change.
> 

Ugh. Must have forgotten to update the patch before posting.
It's correct locally.

Will fix in V2.

Thanks,
Tamar

> > +aarch64_print_operand (FILE *f, rtx x, int code)
> >  {
> >    rtx elt;
> > -  int code = p ? (unsigned char)**p : 0;
> > -  switch (code)
> > +  std::string token;
> > +  aarch64_print_operand_info print_info = aarch64_lookup_operand (code,
> token);
> > +  aarch64_print_operands_t print_code = print_info.code;
> > +  switch (print_code)
> >      {
> > -    case 'c':
> > +    case A64_PRINT_constants:
> >        if (CONST_INT_P (x))
> >     fprintf (f, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
> >        else
> > @@ -13248,16 +13398,18 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >       if (SYMBOL_REF_P (base))
> >         output_addr_const (f, x);
> >       else
> > -       output_operand_lossage ("unsupported operand for code '%c'",
> code);
> > +       output_operand_lossage ("unsupported operand for code '%%%s'",
> > +                               token.c_str ());
> >     }
> >        break;
> >
> > -    case 'e':
> > +    case A64_PRINT_extended:
> >        {
> >     x = unwrap_const_vec_duplicate (x);
> >     if (!CONST_INT_P (x))
> >       {
> > -       output_operand_lossage ("invalid operand for '%%%c'", code);
> > +       output_operand_lossage ("invalid operand for '%%%s'",
> > +                               token.c_str ());
> >         return;
> >       }
> >
> > @@ -13270,19 +13422,21 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >       fputc ('w', f);
> >     else
> >       {
> > -       output_operand_lossage ("invalid operand for '%%%c'", code);
> > +       output_operand_lossage ("invalid operand for '%%%s'",
> > +                               token.c_str ());
> >         return;
> >       }
> >        }
> >        break;
> >
> > -    case 'p':
> > +    case A64_PRINT_power2n:
> >        {
> >     int n;
> >
> >     if (!CONST_INT_P (x) || (n = exact_log2 (INTVAL (x))) < 0)
> >       {
> > -       output_operand_lossage ("invalid operand for '%%%c'", code);
> > +       output_operand_lossage ("invalid operand for '%%%s'",
> > +                               token.c_str ());
> >         return;
> >       }
> >
> > @@ -13290,17 +13444,18 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >        }
> >        break;
> >
> > -    case 'P':
> > +    case A64_PRINT_num_nonzero:
> >        if (!CONST_INT_P (x))
> >     {
> > -     output_operand_lossage ("invalid operand for '%%%c'", code);
> > +     output_operand_lossage ("invalid operand for '%%%s'",
> > +                             token.c_str ());
> >       return;
> >     }
> >
> >        asm_fprintf (f, "%u", popcount_hwi (INTVAL (x)));
> >        break;
> >
> > -    case 'H':
> > +    case A64_PRINT_hi_regpair:
> >        if (x == const0_rtx)
> >     {
> >       asm_fprintf (f, "xzr");
> > @@ -13309,47 +13464,50 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >
> >        if (!REG_P (x) || !GP_REGNUM_P (REGNO (x) + 1))
> >     {
> > -     output_operand_lossage ("invalid operand for '%%%c'", code);
> > +     output_operand_lossage ("invalid operand for '%%%s'",
> > +                             token.c_str ());
> >       return;
> >     }
> >
> >        asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]);
> >        break;
> >
> > -    case 'I':
> > +    case A64_PRINT_dup_or_int:
> >        {
> >     x = aarch64_bit_representation (unwrap_const_vec_duplicate (x));
> >     if (CONST_INT_P (x))
> >       asm_fprintf (f, "%wd", INTVAL (x));
> >     else
> >       {
> > -       output_operand_lossage ("invalid operand for '%%%c'", code);
> > +       output_operand_lossage ("invalid operand for '%%%s'",
> > +                               token.c_str ());
> >         return;
> >       }
> >     break;
> >        }
> >
> > -    case 'M':
> > -    case 'm':
> > +    case A64_PRINT_inv_cc_code:
> > +    case A64_PRINT_cc_code:
> >        {
> >          int cond_code;
> >     /* CONST_TRUE_RTX means al/nv (al is the default, don't print it).  */
> >     if (x == const_true_rtx)
> >       {
> > -       if (code == 'M')
> > +       if (token == "M")
> >           fputs ("nv", f);
> >         return;
> >       }
> >
> >          if (!COMPARISON_P (x))
> >       {
> > -       output_operand_lossage ("invalid operand for '%%%c'", code);
> > +       output_operand_lossage ("invalid operand for '%%%s'",
> > +                               token.c_str ());
> >         return;
> >       }
> >
> >          cond_code = aarch64_get_condition_code (x);
> >          gcc_assert (cond_code >= 0);
> > -   if (code == 'M')
> > +   if (token == "M")
> >       cond_code = AARCH64_INVERSE_CONDITION_CODE (cond_code);
> >     if (GET_MODE (XEXP (x, 0)) == CC_NZCmode)
> >       fputs (aarch64_sve_condition_codes[cond_code], f);
> > @@ -13358,7 +13516,7 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >        }
> >        break;
> >
> > -    case 'N':
> > +    case A64_PRINT_neg_dup_const:
> >        if (!const_vec_duplicate_p (x, &elt))
> >     {
> >       output_operand_lossage ("invalid vector constant");
> > @@ -13377,39 +13535,46 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >     }
> >        break;
> >
> > -    case 'b':
> > -    case 'h':
> > -    case 's':
> > -    case 'd':
> > -    case 'q':
> > -    case 'Z':
> > -      code = TOLOWER (code);
> > -      if (!REG_P (x) || !FP_REGNUM_P (REGNO (x)))
> > -   {
> > -     output_operand_lossage ("incompatible floating point / vector
> register operand for '%%%c'", code);
> > -     return;
> > -   }
> > -      asm_fprintf (f, "%c%d", code, REGNO (x) - V0_REGNUM);
> > +    case A64_PRINT_scalar_b_reg:
> > +    case A64_PRINT_scalar_h_reg:
> > +    case A64_PRINT_scalar_s_reg:
> > +    case A64_PRINT_scalar_d_reg:
> > +    case A64_PRINT_simd_q_reg:
> > +    case A64_PRINT_sve_reg:
> > +      {
> > +   int code = TOLOWER (token[0]);
> > +   if (!REG_P (x) || !FP_REGNUM_P (REGNO (x)))
> > +     {
> > +       output_operand_lossage ("incompatible floating point / vector
> register operand for '%%%s'",
> > +                               token.c_str ());
> > +       return;
> > +     }
> > +   asm_fprintf (f, "%c%d", code, REGNO (x) - V0_REGNUM);
> > +      }
> >        break;
> >
> > -    case 'S':
> > -    case 'T':
> > -    case 'U':
> > -    case 'V':
> > -      if (!REG_P (x) || (!FP_REGNUM_P (REGNO (x)) && !PR_REGNUM_P
> (REGNO (x))))
> > -   {
> > -     output_operand_lossage ("incompatible operand for '%%%c'", code);
> > -     return;
> > -   }
> > -      if (PR_REGNUM_P (REGNO (x)))
> > -   asm_fprintf (f, "p%d", REGNO (x) - P0_REGNUM + (code - 'S'));
> > -      else
> > -   asm_fprintf (f, "%c%d",
> > -                aarch64_sve_data_mode_p (GET_MODE (x)) ? 'z' : 'v',
> > -                REGNO (x) - V0_REGNUM + (code - 'S'));
> > +    case A64_PRINT_simd_reg_plus_0:
> > +    case A64_PRINT_simd_reg_plus_1:
> > +    case A64_PRINT_simd_reg_plus_2:
> > +    case A64_PRINT_simd_reg_plus_3:
> > +      {
> > +   int code = token[0];
> > +   if (!REG_P (x)
> > +       || (!FP_REGNUM_P (REGNO (x)) && !PR_REGNUM_P (REGNO (x))))
> > +     {
> > +       output_operand_lossage ("incompatible operand for '%%%c'",
> code);
> > +       return;
> > +     }
> > +   if (PR_REGNUM_P (REGNO (x)))
> > +     asm_fprintf (f, "p%d", REGNO (x) - P0_REGNUM + (code - 'S'));
> > +   else
> > +     asm_fprintf (f, "%c%d",
> > +                  aarch64_sve_data_mode_p (GET_MODE (x)) ? 'z' : 'v',
> > +                  REGNO (x) - V0_REGNUM + (code - 'S'));
> > +      }
> >        break;
> >
> > -    case 'R':
> > +    case A64_PRINT_scalar_intreg_plus_1:
> >        if (REG_P (x) && FP_REGNUM_P (REGNO (x))
> >       && (aarch64_advsimd_partial_struct_mode_p (GET_MODE (x))))
> >     asm_fprintf (f, "d%d", REGNO (x) - V0_REGNUM + 1);
> > @@ -13418,25 +13583,26 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >        else if (REG_P (x) && GP_REGNUM_P (REGNO (x)))
> >     asm_fprintf (f, "x%d", REGNO (x) - R0_REGNUM + 1);
> >        else
> > -   output_operand_lossage ("incompatible register operand for
> '%%%c'",
> > -                           code);
> > +   output_operand_lossage ("incompatible register operand for
> '%%%s'",
> > +                           token.c_str ());
> >        break;
> >
> > -    case 'X':
> > +    case A64_PRINT_bottom_16bits:
> >        if (!CONST_INT_P (x))
> >     {
> > -     output_operand_lossage ("invalid operand for '%%%c'", code);
> > +     output_operand_lossage ("invalid operand for '%%%s'", token.c_str
> ());
> >       return;
> >     }
> >        asm_fprintf (f, "0x%wx", UINTVAL (x) & 0xffff);
> >        break;
> >
> > -    case 'C':
> > +    case A64_PRINT_dup_as_hex:
> >        {
> >     /* Print a replicated constant in hex.  */
> >     if (!const_vec_duplicate_p (x, &elt) || !CONST_INT_P (elt))
> >       {
> > -       output_operand_lossage ("invalid operand for '%%%c'", code);
> > +       output_operand_lossage ("invalid operand for '%%%s'",
> > +                               token.c_str ());
> >         return;
> >       }
> >     scalar_mode inner_mode = GET_MODE_INNER (GET_MODE (x));
> > @@ -13444,13 +13610,14 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >        }
> >        break;
> >
> > -    case 'D':
> > +    case A64_PRINT_dup_as_unsigned_dec:
> >        {
> >     /* Print a replicated constant in decimal, treating it as
> >        unsigned.  */
> >     if (!const_vec_duplicate_p (x, &elt) || !CONST_INT_P (elt))
> >       {
> > -       output_operand_lossage ("invalid operand for '%%%c'", code);
> > +       output_operand_lossage ("invalid operand for '%%%s'",
> > +                               token.c_str ());
> >         return;
> >       }
> >     scalar_mode inner_mode = GET_MODE_INNER (GET_MODE (x));
> > @@ -13458,29 +13625,29 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >        }
> >        break;
> >
> > -    case 'w':
> > -    case 'x':
> > +    case A64_PRINT_gpr_w:
> > +    case A64_PRINT_gpr_x:
> >        if (aarch64_const_zero_rtx_p (x))
> >     {
> > -     asm_fprintf (f, "%czr", code);
> > +     asm_fprintf (f, "%czr", token[0]);
> >       break;
> >     }
> >
> >        if (REG_P (x) && GP_REGNUM_P (REGNO (x)))
> >     {
> > -     asm_fprintf (f, "%c%d", code, REGNO (x) - R0_REGNUM);
> > +     asm_fprintf (f, "%c%d", token[0], REGNO (x) - R0_REGNUM);
> >       break;
> >     }
> >
> >        if (REG_P (x) && REGNO (x) == SP_REGNUM)
> >     {
> > -     asm_fprintf (f, "%ssp", code == 'w' ? "w" : "");
> > +     asm_fprintf (f, "%ssp", token == "w" ? "w" : "");
> >       break;
> >     }
> >
> >        /* Fall through */
> >
> > -    case 0:
> > +    case A64_PRINT_operand:
> >        if (x == NULL)
> >     {
> >       output_operand_lossage ("missing operand");
> > @@ -13581,7 +13748,7 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >     }
> >        break;
> >
> > -    case 'A':
> > +    case A64_PRINT_output_addr:
> >        if (GET_CODE (x) == HIGH)
> >     x = XEXP (x, 0);
> >
> > @@ -13617,7 +13784,7 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >        output_addr_const (asm_out_file, x);
> >        break;
> >
> > -    case 'L':
> > +    case A64_PRINT_output_const_addr:
> >        switch (aarch64_classify_symbolic_expression (x))
> >     {
> >     case SYMBOL_SMALL_GOT_4G:
> > @@ -13658,7 +13825,7 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >        output_addr_const (asm_out_file, x);
> >        break;
> >
> > -    case 'G':
> > +    case A64_PRINT_output_addr_or_reloc:
> >        switch (aarch64_classify_symbolic_expression (x))
> >     {
> >     case SYMBOL_TLSLE24:
> > @@ -13670,13 +13837,14 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >        output_addr_const (asm_out_file, x);
> >        break;
> >
> > -    case 'k':
> > +    case A64_PRINT_cond_cc_code:
> >        {
> >     HOST_WIDE_INT cond_code;
> >
> >     if (!CONST_INT_P (x))
> >       {
> > -       output_operand_lossage ("invalid operand for '%%%c'", code);
> > +       output_operand_lossage ("invalid operand for '%%%s'",
> > +                               token.c_str ());
> >         return;
> >       }
> >
> > @@ -13686,40 +13854,43 @@ aarch64_print_operand (FILE *f, rtx x, const
> char * const *p)
> >        }
> >        break;
> >
> > -    case 'K':
> > +    case A64_PRINT_pred_reg:
> >        if (!REG_P (x) || !PR_REGNUM_P (REGNO (x)))
> >     {
> > -     output_operand_lossage ("invalid operand for '%%%c'", code);
> > +     output_operand_lossage ("invalid operand for '%%%s'", token.c_str
> ());
> >       return;
> >     }
> >        asm_fprintf (f, "pn%d", REGNO (x) - P0_REGNUM);
> >        break;
> >
> > -    case 'y':
> > -    case 'z':
> > +    case A64_PRINT_addr_ldp_stp_np:
> > +    case A64_PRINT_addr_ldp_stp:
> >        {
> >     machine_mode mode = GET_MODE (x);
> >
> >     if (!MEM_P (x)
> > -       || (code == 'y'
> > +       || (token == "y"
> >             && maybe_ne (GET_MODE_SIZE (mode), 8)
> >             && maybe_ne (GET_MODE_SIZE (mode), 16)
> >             && maybe_ne (GET_MODE_SIZE (mode), 32)))
> >       {
> > -       output_operand_lossage ("invalid operand for '%%%c'", code);
> > +       output_operand_lossage ("invalid operand for '%%%s'",
> > +                               token.c_str ());
> >         return;
> >       }
> >
> >     if (!aarch64_print_address_internal (f, mode, XEXP (x, 0),
> > -                                       code == 'y'
> > +                                       token == "y"
> >                                         ? ADDR_QUERY_LDP_STP_N
> >                                         : ADDR_QUERY_LDP_STP))
> > -     output_operand_lossage ("invalid operand prefix '%%%c'", code);
> > +     output_operand_lossage ("invalid operand prefix '%%%s'",
> > +                             token.c_str ());
> >        }
> >        break;
> >
> >      default:
> > -      output_operand_lossage ("invalid operand prefix '%%%c'", code);
> > +      output_operand_lossage ("invalid operand prefix '%%%s'",
> > +                         token.c_str ());
> >        return;
> >      }
> >  }
> >
> >

Reply via email to