This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Thumb32 assembler (14/69)


Simplification of the handling of PSR codes.  The hash table now
contains only the suffix; the initial [CS]PSR_? is parsed by hand.
This halves the size of the static table, since it no longer needs
separate entries for CPSR_foo and SPSR_foo.

zw

	* config/tc-arm.c (struct asm_psr): Remove cpsr field.
	(PSR_c, PSR_x, PSR_s, PSR_f): Incorporate PSR_SHIFT into values.
	(PSR_SHIFT): Delete.
	(psrs): Move next to register table.  Remove all SPSR entries.
	Remove entry for "CPSR" alone.  Remove ->cpsr column.  Remove
	CPSR_ prefix from all entries.
	(arm_psr_parse): Fold into psr_required_here.  Do not include
	prefix in text passed to hash lookup.  Use hash_find_n.
	Distinguish between CPSR_ and SPSR_ entries here, and handle
	unsuffixed CPSR/SPSR without a hash lookup.

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 15)
+++ gas/config/tc-arm.c	(revision 16)
@@ -320,162 +320,19 @@
 struct asm_psr
 {
   const char *template;
-  bfd_boolean cpsr;
   unsigned long field;
 };
 
 /* The bit that distinguishes CPSR and SPSR.  */
 #define SPSR_BIT   (1 << 22)
 
-/* How many bits to shift the PSR_xxx bits up by.  */
-#define PSR_SHIFT  16
+/* The individual PSR flag bits.  */
+#define PSR_c   (1 << 16)
+#define PSR_x   (1 << 17)
+#define PSR_s   (1 << 18)
+#define PSR_f   (1 << 19)
 
-#define PSR_c   (1 << 0)
-#define PSR_x   (1 << 1)
-#define PSR_s   (1 << 2)
-#define PSR_f   (1 << 3)
 
-static const struct asm_psr psrs[] =
-{
-  {"CPSR",	TRUE,  PSR_c | PSR_f},
-  {"CPSR_all",	TRUE,  PSR_c | PSR_f},
-  {"SPSR",	FALSE, PSR_c | PSR_f},
-  {"SPSR_all",	FALSE, PSR_c | PSR_f},
-  {"CPSR_flg",	TRUE,  PSR_f},
-  {"CPSR_f",    TRUE,  PSR_f},
-  {"SPSR_flg",	FALSE, PSR_f},
-  {"SPSR_f",    FALSE, PSR_f},
-  {"CPSR_c",	TRUE,  PSR_c},
-  {"CPSR_ctl",	TRUE,  PSR_c},
-  {"SPSR_c",	FALSE, PSR_c},
-  {"SPSR_ctl",	FALSE, PSR_c},
-  {"CPSR_x",    TRUE,  PSR_x},
-  {"CPSR_s",    TRUE,  PSR_s},
-  {"SPSR_x",    FALSE, PSR_x},
-  {"SPSR_s",    FALSE, PSR_s},
-  /* Combinations of flags.  */
-  {"CPSR_fs",	TRUE, PSR_f | PSR_s},
-  {"CPSR_fx",	TRUE, PSR_f | PSR_x},
-  {"CPSR_fc",	TRUE, PSR_f | PSR_c},
-  {"CPSR_sf",	TRUE, PSR_s | PSR_f},
-  {"CPSR_sx",	TRUE, PSR_s | PSR_x},
-  {"CPSR_sc",	TRUE, PSR_s | PSR_c},
-  {"CPSR_xf",	TRUE, PSR_x | PSR_f},
-  {"CPSR_xs",	TRUE, PSR_x | PSR_s},
-  {"CPSR_xc",	TRUE, PSR_x | PSR_c},
-  {"CPSR_cf",	TRUE, PSR_c | PSR_f},
-  {"CPSR_cs",	TRUE, PSR_c | PSR_s},
-  {"CPSR_cx",	TRUE, PSR_c | PSR_x},
-  {"CPSR_fsx",	TRUE, PSR_f | PSR_s | PSR_x},
-  {"CPSR_fsc",	TRUE, PSR_f | PSR_s | PSR_c},
-  {"CPSR_fxs",	TRUE, PSR_f | PSR_x | PSR_s},
-  {"CPSR_fxc",	TRUE, PSR_f | PSR_x | PSR_c},
-  {"CPSR_fcs",	TRUE, PSR_f | PSR_c | PSR_s},
-  {"CPSR_fcx",	TRUE, PSR_f | PSR_c | PSR_x},
-  {"CPSR_sfx",	TRUE, PSR_s | PSR_f | PSR_x},
-  {"CPSR_sfc",	TRUE, PSR_s | PSR_f | PSR_c},
-  {"CPSR_sxf",	TRUE, PSR_s | PSR_x | PSR_f},
-  {"CPSR_sxc",	TRUE, PSR_s | PSR_x | PSR_c},
-  {"CPSR_scf",	TRUE, PSR_s | PSR_c | PSR_f},
-  {"CPSR_scx",	TRUE, PSR_s | PSR_c | PSR_x},
-  {"CPSR_xfs",	TRUE, PSR_x | PSR_f | PSR_s},
-  {"CPSR_xfc",	TRUE, PSR_x | PSR_f | PSR_c},
-  {"CPSR_xsf",	TRUE, PSR_x | PSR_s | PSR_f},
-  {"CPSR_xsc",	TRUE, PSR_x | PSR_s | PSR_c},
-  {"CPSR_xcf",	TRUE, PSR_x | PSR_c | PSR_f},
-  {"CPSR_xcs",	TRUE, PSR_x | PSR_c | PSR_s},
-  {"CPSR_cfs",	TRUE, PSR_c | PSR_f | PSR_s},
-  {"CPSR_cfx",	TRUE, PSR_c | PSR_f | PSR_x},
-  {"CPSR_csf",	TRUE, PSR_c | PSR_s | PSR_f},
-  {"CPSR_csx",	TRUE, PSR_c | PSR_s | PSR_x},
-  {"CPSR_cxf",	TRUE, PSR_c | PSR_x | PSR_f},
-  {"CPSR_cxs",	TRUE, PSR_c | PSR_x | PSR_s},
-  {"CPSR_fsxc",	TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
-  {"CPSR_fscx",	TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
-  {"CPSR_fxsc",	TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
-  {"CPSR_fxcs",	TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
-  {"CPSR_fcsx",	TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
-  {"CPSR_fcxs",	TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
-  {"CPSR_sfxc",	TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
-  {"CPSR_sfcx",	TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
-  {"CPSR_sxfc",	TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
-  {"CPSR_sxcf",	TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
-  {"CPSR_scfx",	TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
-  {"CPSR_scxf",	TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
-  {"CPSR_xfsc",	TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
-  {"CPSR_xfcs",	TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
-  {"CPSR_xsfc",	TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
-  {"CPSR_xscf",	TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
-  {"CPSR_xcfs",	TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
-  {"CPSR_xcsf",	TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
-  {"CPSR_cfsx",	TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
-  {"CPSR_cfxs",	TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
-  {"CPSR_csfx",	TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
-  {"CPSR_csxf",	TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
-  {"CPSR_cxfs",	TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
-  {"CPSR_cxsf",	TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
-  {"SPSR_fs",	FALSE, PSR_f | PSR_s},
-  {"SPSR_fx",	FALSE, PSR_f | PSR_x},
-  {"SPSR_fc",	FALSE, PSR_f | PSR_c},
-  {"SPSR_sf",	FALSE, PSR_s | PSR_f},
-  {"SPSR_sx",	FALSE, PSR_s | PSR_x},
-  {"SPSR_sc",	FALSE, PSR_s | PSR_c},
-  {"SPSR_xf",	FALSE, PSR_x | PSR_f},
-  {"SPSR_xs",	FALSE, PSR_x | PSR_s},
-  {"SPSR_xc",	FALSE, PSR_x | PSR_c},
-  {"SPSR_cf",	FALSE, PSR_c | PSR_f},
-  {"SPSR_cs",	FALSE, PSR_c | PSR_s},
-  {"SPSR_cx",	FALSE, PSR_c | PSR_x},
-  {"SPSR_fsx",	FALSE, PSR_f | PSR_s | PSR_x},
-  {"SPSR_fsc",	FALSE, PSR_f | PSR_s | PSR_c},
-  {"SPSR_fxs",	FALSE, PSR_f | PSR_x | PSR_s},
-  {"SPSR_fxc",	FALSE, PSR_f | PSR_x | PSR_c},
-  {"SPSR_fcs",	FALSE, PSR_f | PSR_c | PSR_s},
-  {"SPSR_fcx",	FALSE, PSR_f | PSR_c | PSR_x},
-  {"SPSR_sfx",	FALSE, PSR_s | PSR_f | PSR_x},
-  {"SPSR_sfc",	FALSE, PSR_s | PSR_f | PSR_c},
-  {"SPSR_sxf",	FALSE, PSR_s | PSR_x | PSR_f},
-  {"SPSR_sxc",	FALSE, PSR_s | PSR_x | PSR_c},
-  {"SPSR_scf",	FALSE, PSR_s | PSR_c | PSR_f},
-  {"SPSR_scx",	FALSE, PSR_s | PSR_c | PSR_x},
-  {"SPSR_xfs",	FALSE, PSR_x | PSR_f | PSR_s},
-  {"SPSR_xfc",	FALSE, PSR_x | PSR_f | PSR_c},
-  {"SPSR_xsf",	FALSE, PSR_x | PSR_s | PSR_f},
-  {"SPSR_xsc",	FALSE, PSR_x | PSR_s | PSR_c},
-  {"SPSR_xcf",	FALSE, PSR_x | PSR_c | PSR_f},
-  {"SPSR_xcs",	FALSE, PSR_x | PSR_c | PSR_s},
-  {"SPSR_cfs",	FALSE, PSR_c | PSR_f | PSR_s},
-  {"SPSR_cfx",	FALSE, PSR_c | PSR_f | PSR_x},
-  {"SPSR_csf",	FALSE, PSR_c | PSR_s | PSR_f},
-  {"SPSR_csx",	FALSE, PSR_c | PSR_s | PSR_x},
-  {"SPSR_cxf",	FALSE, PSR_c | PSR_x | PSR_f},
-  {"SPSR_cxs",	FALSE, PSR_c | PSR_x | PSR_s},
-  {"SPSR_fsxc",	FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
-  {"SPSR_fscx",	FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
-  {"SPSR_fxsc",	FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
-  {"SPSR_fxcs",	FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
-  {"SPSR_fcsx",	FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
-  {"SPSR_fcxs",	FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
-  {"SPSR_sfxc",	FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
-  {"SPSR_sfcx",	FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
-  {"SPSR_sxfc",	FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
-  {"SPSR_sxcf",	FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
-  {"SPSR_scfx",	FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
-  {"SPSR_scxf",	FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
-  {"SPSR_xfsc",	FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
-  {"SPSR_xfcs",	FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
-  {"SPSR_xsfc",	FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
-  {"SPSR_xscf",	FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
-  {"SPSR_xcfs",	FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
-  {"SPSR_xcsf",	FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
-  {"SPSR_cfsx",	FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
-  {"SPSR_cfxs",	FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
-  {"SPSR_csfx",	FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
-  {"SPSR_csxf",	FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
-  {"SPSR_cxfs",	FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
-  {"SPSR_cxsf",	FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
-};
-
 enum iwmmxt_insn_type
 {
   check_rd,
@@ -2319,74 +2176,67 @@
 /* Miscellaneous: PSR flags, endian specifiers, coprocessor
    operands. */
 
-static const struct asm_psr *
-arm_psr_parse (char ** ccp)
+/* Parse the input looking for a PSR flag.  */
+static int
+psr_required_here (char **str)
 {
-  char * start = * ccp;
-  char   c;
-  char * p;
-  const struct asm_psr * psr;
+  char *p;
+  bfd_boolean is_spsr;
+  unsigned long psr_field;
 
-  p = start;
-
-  /* Skip to the end of the next word in the input stream.  */
-  do
-    {
-      c = *p++;
-    }
-  while (ISALPHA (c) || c == '_');
-
-  /* Terminate the word.  */
-  *--p = 0;
-
   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
      feature for ease of use and backwards compatibility.  */
-  if (!strncmp (start, "cpsr", 4))
-    strncpy (start, "CPSR", 4);
-  else if (!strncmp (start, "spsr", 4))
-    strncpy (start, "SPSR", 4);
+  p = *str;
+  if (*p == 's' || *p == 'S')
+    is_spsr = TRUE;
+  else if (*p == 'c' || *p == 'C')
+    is_spsr = FALSE;
+  else
+    goto error;
 
-  /* Now locate the word in the psr hash table.  */
-  psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
+  p++;
+  if (strncasecmp (p, "PSR", 3) != 0)
+    goto error;
+  p += 3;
 
-  /* Restore the input stream.  */
-  *p = c;
+  if (*p == '_')
+    {
+      /* A suffix follows.  */
+      const struct asm_psr *psr;
+      char *start;
 
-  /* If we found a valid match, advance the
-     stream pointer past the end of the word.  */
-  *ccp = p;
+      p++;
+      start = p;
 
-  return psr;
-}
+      do
+	p++;
+      while (ISALNUM (*p) || *p == '_');
 
-/* Parse the input looking for a PSR flag.  */
+      psr = hash_find_n (arm_psr_hsh, start, p - start);
+      if (!psr)
+	goto error;
 
-static int
-psr_required_here (char ** str)
-{
-  char * start = * str;
-  const struct asm_psr * psr;
-
-  psr = arm_psr_parse (str);
-
-  if (psr)
+      psr_field = psr->field;
+    }
+  else
     {
-      /* If this is the SPSR that is being modified, set the R bit.  */
-      if (! psr->cpsr)
-	inst.instruction |= SPSR_BIT;
+      if (ISALNUM (*p))
+	goto error;    /* Garbage after "[CS]PSR".  */
 
-      /* Set the psr flags in the MSR instruction.  */
-      inst.instruction |= psr->field << PSR_SHIFT;
-
-      return SUCCESS;
+      psr_field = (PSR_c | PSR_f);
     }
 
-  /* In the few cases where we might be able to accept
-     something else this error can be overridden.  */
-  inst.error = _("flag for {c}psr instruction expected");
+  /* If this is the SPSR that is being modified, set the R bit.  */
+  if (is_spsr)
+    inst.instruction |= SPSR_BIT;
 
-  /* Restore the start point.  */
-  *str = start;
+  /* Set the psr flags in the MSR instruction.  */
+  inst.instruction |= psr_field;
+  *str = p;
+  return SUCCESS;
+
+ error:
+  inst.error = _("flag for {c}psr instruction expected");
   return FAIL;
 }
 
@@ -9191,6 +9041,85 @@
 #undef REGNUM
 #undef REGSET
 
+/* Table of all PSR suffixes.  Bare "CPSR" and "SPSR" are handled
+   within psr_required_here.  */
+static const struct asm_psr psrs[] =
+{
+  /* Backward compatibility notation.  Note that "all" is no longer
+     truly all possible PSR bits.  */
+  {"all",  PSR_c | PSR_f},
+  {"flg",  PSR_f},
+  {"ctl",  PSR_c},
+
+  /* Individual flags.  */
+  {"f",    PSR_f},
+  {"c",	   PSR_c},
+  {"x",    PSR_x},
+  {"s",    PSR_s},
+  /* Combinations of flags.  */
+  {"fs",   PSR_f | PSR_s},
+  {"fx",   PSR_f | PSR_x},
+  {"fc",   PSR_f | PSR_c},
+  {"sf",   PSR_s | PSR_f},
+  {"sx",   PSR_s | PSR_x},
+  {"sc",   PSR_s | PSR_c},
+  {"xf",   PSR_x | PSR_f},
+  {"xs",   PSR_x | PSR_s},
+  {"xc",   PSR_x | PSR_c},
+  {"cf",   PSR_c | PSR_f},
+  {"cs",   PSR_c | PSR_s},
+  {"cx",   PSR_c | PSR_x},
+  {"fsx",  PSR_f | PSR_s | PSR_x},
+  {"fsc",  PSR_f | PSR_s | PSR_c},
+  {"fxs",  PSR_f | PSR_x | PSR_s},
+  {"fxc",  PSR_f | PSR_x | PSR_c},
+  {"fcs",  PSR_f | PSR_c | PSR_s},
+  {"fcx",  PSR_f | PSR_c | PSR_x},
+  {"sfx",  PSR_s | PSR_f | PSR_x},
+  {"sfc",  PSR_s | PSR_f | PSR_c},
+  {"sxf",  PSR_s | PSR_x | PSR_f},
+  {"sxc",  PSR_s | PSR_x | PSR_c},
+  {"scf",  PSR_s | PSR_c | PSR_f},
+  {"scx",  PSR_s | PSR_c | PSR_x},
+  {"xfs",  PSR_x | PSR_f | PSR_s},
+  {"xfc",  PSR_x | PSR_f | PSR_c},
+  {"xsf",  PSR_x | PSR_s | PSR_f},
+  {"xsc",  PSR_x | PSR_s | PSR_c},
+  {"xcf",  PSR_x | PSR_c | PSR_f},
+  {"xcs",  PSR_x | PSR_c | PSR_s},
+  {"cfs",  PSR_c | PSR_f | PSR_s},
+  {"cfx",  PSR_c | PSR_f | PSR_x},
+  {"csf",  PSR_c | PSR_s | PSR_f},
+  {"csx",  PSR_c | PSR_s | PSR_x},
+  {"cxf",  PSR_c | PSR_x | PSR_f},
+  {"cxs",  PSR_c | PSR_x | PSR_s},
+  {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
+  {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
+  {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
+  {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
+  {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
+  {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
+  {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
+  {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
+  {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
+  {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
+  {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
+  {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
+  {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
+  {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
+  {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
+  {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
+  {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
+  {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
+  {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
+  {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
+  {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
+  {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
+  {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
+  {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
+};
+
+
 static const struct asm_opcode insns[] =
 {
   /* Core ARM Instructions.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]