public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Thumb32 assembler (11/69)
@ 2005-04-26  9:58 Zack Weinberg
  2005-04-26 17:36 ` Paul Brook
  0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2005-04-26  9:58 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 358 bytes --]


Almost all the calls to skip_whitespace in tc-arm.c are unnecessary,
because the input scrubber removes almost all the whitespace before
md_assemble gets called.  When it is necessary, it doesn't need to
loop.  The skip_whitespace call that used to appear at the beginning
of each and every ->parms function, which is necessary, is hoisted to
md_assemble.


[-- Attachment #2: Type: text/plain, Size: 303 bytes --]


	* tc-arm.c (skip_whitespace): No need to skip more than one space.
	Most calls to skip_whitespace / SKIP_WHITESPACE deleted, except ...
	(decode_shift): Must skip whitespace immediately after the
	shifter name.
	(do_sxtah): Similarly.
	(md_assemble): Skip whitespace before calling ->parms function.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 11.diff.txt --]
[-- Type: text/x-patch; name=11.diff.txt, Size: 33585 bytes --]

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 12)
+++ gas/config/tc-arm.c	(revision 13)
@@ -839,13 +839,11 @@
    value.  */
 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
 
-#define skip_whitespace(str)  while (*(str) == ' ') ++(str)
+#define skip_whitespace(str)  do { if (*(str) == ' ') ++(str); } while (0)
 
 static void
 end_of_line (char * str)
 {
-  skip_whitespace (str);
-
   if (*str != '\0' && !inst.error)
     inst.error = _("garbage following instruction");
 }
@@ -1145,8 +1143,6 @@
 {
   expressionS exp;
 
-  skip_whitespace (*str);
-
   if (is_immediate_prefix (**str))
     (*str)++;
   else if (!prefix_opt)
@@ -1187,7 +1183,6 @@
   expressionS exp;
   exp.X_op = O_illegal;
 
-  SKIP_WHITESPACE ();
   if (is_immediate_prefix (*input_line_pointer))
     {
       input_line_pointer++;
@@ -1498,8 +1493,6 @@
 	    {
 	      int reg;
 
-	      skip_whitespace (str);
-
 	      if ((reg = reg_required_here (& str, -1, REG_TYPE_RN)) == FAIL)
 		return FAIL;
 
@@ -1537,7 +1530,6 @@
 	  while (skip_past_comma (&str) != FAIL
 		 || (in_range = 1, *str++ == '-'));
 	  str--;
-	  skip_whitespace (str);
 
 	  if (*str++ != '}')
 	    {
@@ -1588,8 +1580,6 @@
 	    }
 	}
 
-      skip_whitespace (str);
-
       if (*str == '|' || *str == '+')
 	{
 	  str++;
@@ -1622,7 +1612,6 @@
     return FAIL;
 
   (*str)++;
-  skip_whitespace (*str);
 
   if (dp)
     {
@@ -1664,8 +1653,6 @@
       mask |= 1 << new_base;
       count++;
 
-      skip_whitespace (*str);
-
       if (**str == '-') /* We have the start of a range expression */
 	{
 	  int high_range;
@@ -1733,8 +1720,6 @@
   char * p;
   char   c;
 
-  skip_whitespace (* str);
-
   for (p = * str; ISALPHA (* p); p ++)
     ;
 
@@ -1950,8 +1935,6 @@
   int value;
   expressionS expr;
 
-  skip_whitespace (* str);
-
   if (reg_required_here (str, 0, REG_TYPE_RN) != FAIL)
     {
       if (skip_past_comma (str) == SUCCESS)
@@ -2037,8 +2020,6 @@
 static int
 fp_op2 (char ** str)
 {
-  skip_whitespace (* str);
-
   if (reg_required_here (str, 0, REG_TYPE_FN) != FAIL)
     return SUCCESS;
   else
@@ -2050,8 +2031,6 @@
 
 	  inst.error = NULL;
 
-	  skip_whitespace (* str);
-
 	  /* First try and match exact strings, this is to guarantee
 	     that some formats will work even for cross assembly.  */
 
@@ -2264,19 +2243,13 @@
   int    rn;
   int    pre_inc = 0;
 
-  skip_whitespace (str);
-
   if (* str == '[')
     {
       str++;
 
-      skip_whitespace (str);
-
       if ((rn = reg_required_here (&str, 16, REG_TYPE_RN)) == FAIL)
 	return FAIL;
 
-      skip_whitespace (str);
-
       if (* str == ']')
 	{
 	  str ++;
@@ -2289,8 +2262,6 @@
 	    }
 	  else 	      /* [Rn] */
 	    {
-	      skip_whitespace (str);
-
 	      if (* str == '!')
 		{
 		  str ++;
@@ -2314,16 +2285,12 @@
 	  if (ldst_extend_v4 (&str) == FAIL)
 	    return FAIL;
 
-	  skip_whitespace (str);
-
 	  if (* str ++ != ']')
 	    {
 	      inst.error = _("missing ]");
 	      return FAIL;
 	    }
 
-	  skip_whitespace (str);
-
 	  if (* str == '!')
 	    {
 	      str ++;
@@ -2492,7 +2459,6 @@
 {
   int processor;
 
-  skip_whitespace (*str);
   if ((processor = arm_reg_parse (str, REG_TYPE_CP)) == FAIL)
     {
       inst.error = reg_expected_msgs[REG_TYPE_CP];
@@ -2520,8 +2486,6 @@
 {
   int offset;
 
-  skip_whitespace (* str);
-
   if (! is_immediate_prefix (**str))
     {
       inst.error = _("immediate expression expected");
@@ -2574,19 +2538,14 @@
       int reg;
 
       p++;
-      skip_whitespace (p);
 
       if ((reg = reg_required_here (&p, 16, REG_TYPE_RN)) == FAIL)
 	return FAIL;
 
-      skip_whitespace (p);
-
       if (*p == ']')
 	{
 	  p++;
 
-	  skip_whitespace (p);
-
 	  if (*p == '\0')
 	    {
 	      /* As an extension to the official ARM syntax we allow:
@@ -2604,8 +2563,6 @@
 	      return FAIL;
 	    }
 
-	  skip_whitespace (p);
-
 	  if (*p == '#')
 	    {
 	      if (wb_ok)
@@ -2634,8 +2591,6 @@
 	      if (immediate_required_here (&p, &option, 0, 255, TRUE) == FAIL)
 		return FAIL;
 
-	      skip_whitespace (p);
-
 	      if (*p != '}')
 		{
 		  inst.error = _("'}' expected at end of 'option' field");
@@ -2669,16 +2624,12 @@
 	  if (cp_address_offset (& p) == FAIL)
 	    return FAIL;
 
-	  skip_whitespace (p);
-
 	  if (*p++ != ']')
 	    {
 	      inst.error = _("missing ]");
 	      return FAIL;
 	    }
 
-	  skip_whitespace (p);
-
 	  if (wb_ok && *p == '!')
 	    {
 	      if (reg == REG_PC)
@@ -2714,8 +2665,6 @@
 {
   int offset;
 
-  skip_whitespace (* str);
-
   if (! is_immediate_prefix (**str))
     {
       inst.error = _("immediate expression expected");
@@ -2762,13 +2711,10 @@
       int reg;
 
       p++;
-      skip_whitespace (p);
 
       if ((reg = reg_required_here (&p, 16, REG_TYPE_RN)) == FAIL)
         return FAIL;
 
-      skip_whitespace (p);
-
       if (*p == ']')
         {
           p++;
@@ -2805,16 +2751,12 @@
           if (cp_byte_address_offset (& p) == FAIL)
             return FAIL;
 
-          skip_whitespace (p);
-
           if (*p++ != ']')
             {
               inst.error = _("missing ]");
               return FAIL;
             }
 
-          skip_whitespace (p);
-
           if (*p == '!')
             {
               if (reg == REG_PC)
@@ -2875,8 +2817,6 @@
 
   int saw_a_flag = 0;
 
-  skip_whitespace (*str);
-
   /* Get the a, f and i flags.  */
   while (**str && **str != ',')
     {
@@ -2931,7 +2871,6 @@
 {
   int big_endian = 0;
 
-  skip_whitespace (str);
   if (strlen (str) < 2)
     inst.error = _("missing endian specifier");
   else if (strncasecmp (str, "BE", 2) == 0)
@@ -3067,7 +3006,6 @@
   char * name;
   char saved_char;
 
-  skip_whitespace (input_line_pointer);
   name = input_line_pointer;
 
   while (*input_line_pointer != 0
@@ -3405,8 +3343,6 @@
   end_name  = input_line_pointer;
   *end_name = delim;
 
-  SKIP_WHITESPACE ();
-
   if (*input_line_pointer != ',')
     {
       *end_name = 0;
@@ -3819,8 +3755,6 @@
   char *p;
   valueT highbit;
 
-  SKIP_WHITESPACE ();
-
   highbit = 0;
   if (*input_line_pointer == '1')
     highbit = 0x80000000;
@@ -3828,7 +3762,6 @@
     as_bad (_("expected 0 or 1"));
 
   input_line_pointer++;
-  SKIP_WHITESPACE ();
   if (*input_line_pointer != ',')
     as_bad (_("missing comma"));
   input_line_pointer++;
@@ -3955,8 +3888,6 @@
   if (unwind.personality_routine || unwind.personality_index != -1)
     as_bad (_("duplicate .personalityindex directive"));
 
-  SKIP_WHITESPACE ();
-
   expression (&exp);
 
   if (exp.X_op != O_constant
@@ -3983,13 +3914,11 @@
   if (unwind.personality_routine || unwind.personality_index != -1)
     as_bad (_("duplicate .personality directive"));
 
-  SKIP_WHITESPACE ();
   name = input_line_pointer;
   c = get_symbol_end ();
   p = input_line_pointer;
   unwind.personality_routine = symbol_find_or_make (name);
   *p = c;
-  SKIP_WHITESPACE ();
   demand_empty_rest_of_line ();
 }
 
@@ -4003,7 +3932,6 @@
   long range;
   int n;
 
-  SKIP_WHITESPACE ();
   range = reg_list (&input_line_pointer);
   if (range == FAIL)
     {
@@ -4180,7 +4108,6 @@
 	as_tsktsk (_("register list not in ascending order"));
       mask |= 1 << reg;
 
-      SKIP_WHITESPACE ();
       if (*input_line_pointer == '-')
 	{
 	  input_line_pointer++;
@@ -4201,7 +4128,6 @@
     }
   while (skip_past_comma (&input_line_pointer) != FAIL);
 
-  SKIP_WHITESPACE ();
   if (*input_line_pointer == '}')
     input_line_pointer++;
 
@@ -4315,7 +4241,6 @@
 	as_tsktsk (_("register list not in ascending order"));
       mask |= 1 << reg;
 
-      SKIP_WHITESPACE ();
       if (*input_line_pointer == '-')
 	{
 	  input_line_pointer++;
@@ -4336,7 +4261,6 @@
     }
   while (skip_past_comma (&input_line_pointer) != FAIL);
 
-  SKIP_WHITESPACE ();
   if (*input_line_pointer == '}')
     input_line_pointer++;
 
@@ -4370,7 +4294,6 @@
 
   /* Figure out what sort of save we have.  */
   peek = input_line_pointer;
-  skip_whitespace (peek);
 
   if (*peek == '{')
     {
@@ -4419,7 +4342,6 @@
   int reg;
   valueT op;
 
-  SKIP_WHITESPACE ();
   reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
   if (reg == FAIL)
     {
@@ -4531,7 +4453,6 @@
   unsigned char op[16];
   int count;
 
-  SKIP_WHITESPACE ();
   expression (&exp);
   if (exp.X_op == O_constant
       && skip_past_comma (&input_line_pointer) != FAIL)
@@ -4648,7 +4569,6 @@
   /* This is a pseudo-op of the form "adr rd, label" to be converted
      into a relative address of the form "add rd, pc, #label-.-8".  */
 
-  skip_whitespace (str);
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
   expression_or_fail (&inst.reloc.exp, &str);
@@ -4671,7 +4591,6 @@
      add rd, pc, #low(label-.-8)"
      add rd, rd, #high(label-.-8)"  */
 
-  skip_whitespace (str);
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
   expression_or_fail (&inst.reloc.exp, &str);
@@ -4690,7 +4609,6 @@
 static void
 do_arit (char * str)
 {
-  skip_whitespace (str);
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
   reg_or_fail (&str, 16, REG_TYPE_RN);
@@ -4731,7 +4649,6 @@
 static void
 do_bfc (char *str)
 {
-  skip_whitespace (str);
   reg_nonpc_or_fail (&str, 12);
   bfci_lsb_and_width (str);
 }
@@ -4742,7 +4659,6 @@
   int rm;
 
   /* Rd.  */
-  skip_whitespace (str);
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
 
@@ -4772,7 +4688,6 @@
   int lsb, width;
 
   /* Rd.  */
-  skip_whitespace (str);
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -4807,8 +4722,6 @@
 {
   int number = 0;
 
-  skip_whitespace (str);
-
   /* As a convenience we allow 'bkpt' without an operand.  */
   if (is_immediate_prefix (*str) || ISDIGIT (*str))
     if (immediate_required_here (&str, &number, 0, 0xffff, TRUE) == FAIL)
@@ -4919,7 +4832,6 @@
 {
   int reg;
 
-  skip_whitespace (str);
   note_reg_or_fail (reg, &str, 0, REG_TYPE_RN);
   end_of_line (str);
 
@@ -4941,7 +4853,6 @@
 {
   int rm;
 
-  skip_whitespace (str);
   rm = reg_required_here (&str, 0, REG_TYPE_RN);
 
   if (rm != FAIL)
@@ -4979,7 +4890,6 @@
 {
   int reg;
 
-  skip_whitespace (str);
   note_reg_or_fail (reg, &str, 0, REG_TYPE_RN);
   end_of_line (str);
 
@@ -4994,8 +4904,6 @@
 static void
 do_cdp (char * str)
 {
-  skip_whitespace (str);
-
   if (co_proc_number (&str) == FAIL)
     return;
   comma_or_fail (&str);
@@ -5027,8 +4935,6 @@
 static void
 do_clz (char * str)
 {
-  skip_whitespace (str);
-
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
   reg_nonpc_or_fail (&str, 0);
@@ -5038,8 +4944,6 @@
 static void
 do_cmp (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 16, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -5064,8 +4968,6 @@
 static void
 do_co_reg (char * str)
 {
-  skip_whitespace (str);
-
   if (co_proc_number (&str) == FAIL)
     return;
 
@@ -5109,8 +5011,6 @@
 static void
 do_co_reg2c (char * str)
 {
-  skip_whitespace (str);
-
   if (co_proc_number (& str) == FAIL)
     return;
 
@@ -5148,10 +5048,8 @@
   do_cps_flags (&str, /*thumb_p=*/0);
 
   if (skip_past_comma (&str) == SUCCESS)
-    {
-      skip_whitespace (str);
-      do_cps_mode (&str);
-    }
+    do_cps_mode (&str);
+
   end_of_line (str);
 }
 
@@ -5161,12 +5059,8 @@
   int base_reg;
   long range;
 
-  skip_whitespace (str);
-
   note_reg_nonpc_or_fail (base_reg, &str, 16);
 
-  skip_whitespace (str);
-
   if (*str == '!')
     {
       inst.instruction |= WRITE_BACK;
@@ -5225,8 +5119,6 @@
   int rd;
   int rn;
 
-  skip_whitespace (str);
-
   note_reg_or_fail (rd, &str, 12, REG_TYPE_RN);
 
   comma_or_fail (&str);
@@ -5279,14 +5171,11 @@
 static void
 do_ldrex (char * str)
 {
-  skip_whitespace (str);
-
   /* Parse Rd.  */
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
 
   /* Skip past '['.  */
-  skip_whitespace (str);
   if (*str != '[')
     {
       inst.error = BAD_ARGS;
@@ -5297,7 +5186,6 @@
   reg_nonpc_or_fail (&str, 16);
 
   /* Skip past ']'.  */
-  skip_whitespace (str);
   if (*str != ']')
     {
       inst.error = BAD_ARGS;
@@ -5314,8 +5202,6 @@
   int conflict_reg;
   int value;
 
-  skip_whitespace (str);
-
   note_reg_or_fail (conflict_reg, &str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -5325,15 +5211,11 @@
 
       str++;
 
-      skip_whitespace (str);
-
       note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
 
       /* Conflicts can occur on stores as well as loads.  */
       conflict_reg = (conflict_reg == reg);
 
-      skip_whitespace (str);
-
       if (*str == ']')
 	{
 	  str ++;
@@ -5351,7 +5233,6 @@
 	  else
 	    {
 	      /* [Rn]  */
-	      skip_whitespace (str);
 
 	      if (*str == '!')
 		{
@@ -5376,16 +5257,12 @@
 	  if (ldst_extend (&str) == FAIL)
 	    return;
 
-	  skip_whitespace (str);
-
 	  if (*str++ != ']')
 	    {
 	      inst.error = _("missing ]");
 	      return;
 	    }
 
-	  skip_whitespace (str);
-
 	  if (*str == '!')
 	    {
 	      if (conflict_reg)
@@ -5408,7 +5285,6 @@
       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
       str++;
 
-      skip_whitespace (str);
       expression_or_fail (&inst.reloc.exp, &str);
 
       if (inst.reloc.exp.X_op != O_constant
@@ -5484,7 +5360,6 @@
 {
   int conflict_reg;
 
-  skip_whitespace (str);
   note_reg_or_fail (conflict_reg, &str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -5494,7 +5369,6 @@
 
       str++;
 
-      skip_whitespace (str);
       note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
 
       /* ldrt/strt always use post-indexed addressing, so if the base is
@@ -5504,8 +5378,6 @@
 		 ? _("destination register same as write-back base")
 		 : _("source register same as write-back base"));
 
-      skip_whitespace (str);
-
       if (*str == ']')
 	{
 	  str ++;
@@ -5519,7 +5391,6 @@
 	  else
 	    {
 	      /* [Rn]  */
-	      skip_whitespace (str);
 
 	      /* Skip a write-back '!'.  */
 	      if (*str == '!')
@@ -5552,7 +5423,6 @@
   int conflict_reg;
   int value;
 
-  skip_whitespace (str);
   note_reg_or_fail (conflict_reg, &str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -5562,15 +5432,11 @@
 
       str++;
 
-      skip_whitespace (str);
-
       note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
 
       /* Conflicts can occur on stores as well as loads.  */
       conflict_reg = (conflict_reg == reg);
 
-      skip_whitespace (str);
-
       if (*str == ']')
 	{
 	  str ++;
@@ -5590,8 +5456,6 @@
 	      /* [Rn]  */
 	      inst.instruction |= HWOFFSET_IMM;
 
-	      skip_whitespace (str);
-
 	      if (*str == '!')
 		{
 		  if (conflict_reg)
@@ -5619,16 +5483,12 @@
 	  if (ldst_extend_v4 (&str) == FAIL)
 	    return;
 
-	  skip_whitespace (str);
-
 	  if (*str++ != ']')
 	    {
 	      inst.error = _("missing ]");
 	      return;
 	    }
 
-	  skip_whitespace (str);
-
 	  if (*str == '!')
 	    {
 	      if (conflict_reg)
@@ -5652,8 +5512,6 @@
       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
       str++;
 
-      skip_whitespace (str);
-
       expression_or_fail (&inst.reloc.exp, &str);
 
       if (inst.reloc.exp.X_op != O_constant
@@ -5729,8 +5587,6 @@
 {
   int conflict_reg;
 
-  skip_whitespace (str);
-
   note_reg_or_fail (conflict_reg, &str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -5740,7 +5596,6 @@
 
       str++;
 
-      skip_whitespace (str);
       note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
 
       /* ldrt/strt always use post-indexed addressing, so if the base is
@@ -5750,7 +5605,6 @@
 		 ? _("destination register same as write-back base")
 		 : _("source register same as write-back base"));
 
-      skip_whitespace (str);
       if (*str == ']')
 	{
 	  str ++;
@@ -5764,7 +5618,6 @@
 	  else
 	    {
 	      /* [Rn]  */
-	      skip_whitespace (str);
 
 	      /* Skip a write-back '!'.  */
 	      if (*str == '!')
@@ -5794,8 +5647,6 @@
   /* Co-processor register load/store.
      Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
 
-  skip_whitespace (str);
-
   if (co_proc_number (&str) == FAIL)
     return;
 
@@ -5817,7 +5668,6 @@
   int rd, rm;
 
   /* Only one format "rd, rm, rs, rn".  */
-  skip_whitespace (str);
 
   note_reg_nonpc_or_fail (rd, &str, 16);
   comma_or_fail (&str);
@@ -5852,8 +5702,6 @@
 static void
 do_mov (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -5874,7 +5722,6 @@
 {
   int val;
 
-  skip_whitespace (str);
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
   immediate_or_fail (&str, &val, 0, 65535, FALSE);
@@ -5889,13 +5736,9 @@
 do_mrs (char * str)
 {
   /* Only one syntax.  */
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
-  skip_whitespace (str);
-
   /* Lower case accepted for backwards compatibility.  */
   if (*str == 'c' || *str == 'C')
     ; /* SPSR bit is already clear.  */
@@ -5930,15 +5773,11 @@
 static void
 do_msr (char * str)
 {
-  skip_whitespace (str);
-
   if (psr_required_here (&str) == FAIL)
     return;
 
   comma_or_fail (&str);
 
-  skip_whitespace (str);
-
   if (reg_required_here (&str, 0, REG_TYPE_RN) != FAIL)
     {
       end_of_line (str);
@@ -5992,7 +5831,6 @@
   int rd, rm;
 
   /* Only one format "rd, rm, rs".  */
-  skip_whitespace (str);
 
   note_reg_nonpc_or_fail (rd, &str, 16);
   comma_or_fail (&str);
@@ -6019,8 +5857,6 @@
   int rdlo, rdhi, rm;
 
   /* Only one format "rdlo, rdhi, rm, rs".  */
-  skip_whitespace (str);
-
   note_reg_nonpc_or_fail (rdlo, &str, 12);
   comma_or_fail (&str);
 
@@ -6043,7 +5879,6 @@
 {
   int hint;
 
-  skip_whitespace (str);
   if (*str == '{')
     {
       str++;
@@ -6070,8 +5905,6 @@
 {
   int rm, rn;
 
-  skip_whitespace (str);
-
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
 
@@ -6129,8 +5962,6 @@
 {
   int rd;
 
-  skip_whitespace (str);
-
   if (* str != '[')
     {
       inst.error = _("'[' expected after PLD mnemonic");
@@ -6138,17 +5969,13 @@
     }
 
   ++str;
-  skip_whitespace (str);
 
   note_reg_or_fail (rd, &str, 16, REG_TYPE_RN);
 
-  skip_whitespace (str);
-
   if (*str == ']')
     {
       /* [Rn], ... ?  */
       ++str;
-      skip_whitespace (str);
 
       /* Post-indexed addressing is not allowed with PLD.  */
       if (skip_past_comma (&str) == SUCCESS)
@@ -6176,8 +6003,6 @@
       if (ldst_extend (&str) == FAIL)
 	return;
 
-      skip_whitespace (str);
-
       if (* str != ']')
 	{
 	  inst.error = _("missing ]");
@@ -6185,7 +6010,6 @@
 	}
 
       ++ str;
-      skip_whitespace (str);
 
       if (* str == '!') /* [Rn]! */
 	{
@@ -6206,8 +6030,6 @@
 static void
 do_qadd (char * str)
 {
-  skip_whitespace (str);
-
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
 
@@ -6226,8 +6048,6 @@
 static void
 do_qadd16 (char * str)
 {
-  skip_whitespace (str);
-
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
 
@@ -6241,7 +6061,6 @@
 static void
 do_rbit (char *str)
 {
-  skip_whitespace (str);
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -6258,8 +6077,6 @@
 static void
 do_rev (char * str)
 {
-  skip_whitespace (str);
-
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
 
@@ -6276,12 +6093,8 @@
 static void
 do_rfe (char * str)
 {
-  skip_whitespace (str);
-
   reg_nonpc_or_fail (&str, 16);
 
-  skip_whitespace (str);
-
   if (*str == '!')
     {
       inst.instruction |= WRITE_BACK;
@@ -6295,8 +6108,6 @@
 {
   int val;
 
-  skip_whitespace (str);
-
   /* Parse <Rd>, field.  */
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
@@ -6336,8 +6147,6 @@
 {
   int val;
 
-  skip_whitespace (str);
-
   /* Parse the <Rd> field.  */
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
@@ -6382,8 +6191,6 @@
 static void
 do_smi (char * str)
 {
-  skip_whitespace (str);
-
   /* Allow optional leading '#'.  */
   if (is_immediate_prefix (*str))
     str++;
@@ -6398,8 +6205,6 @@
 static void
 do_swi (char * str)
 {
-  skip_whitespace (str);
-
   /* Allow optional leading '#'.  */
   if (is_immediate_prefix (*str))
     str++;
@@ -6419,8 +6224,6 @@
 static void
 do_smla (char * str)
 {
-  skip_whitespace (str);
-
   reg_nonpc_or_fail (&str, 16);
   comma_or_fail (&str);
 
@@ -6445,8 +6248,6 @@
 {
   int rdlo, rdhi;
 
-  skip_whitespace (str);
-
   note_reg_nonpc_or_fail (rdlo, &str, 12);
   comma_or_fail (&str);
 
@@ -6471,7 +6272,6 @@
 static void
 do_smul (char * str)
 {
-  skip_whitespace (str);
   reg_nonpc_or_fail (&str, 16);
   comma_or_fail (&str);
 
@@ -6488,9 +6288,9 @@
 static void
 do_srs (char * str)
 {
-  char *exclam;
-  skip_whitespace (str);
-  exclam = strchr (str, '!');
+  /* This is necessary because the generic expression parser will
+     choke on "#16!".  */
+  char *exclam = strchr (str, '!');
   if (exclam)
     *exclam = '\0';
   do_cps_mode (&str);
@@ -6512,7 +6312,6 @@
   int rd, rm, rn;
 
   /* Parse Rd, Rm,.  */
-  skip_whitespace (str);
   note_reg_nonpc_or_fail (rd, &str, 12);
   comma_or_fail (&str);
 
@@ -6532,7 +6331,6 @@
       return;
     }
   str++;
-  skip_whitespace (str);
 
   /* Parse Rn.  */
   note_reg_nonpc_or_fail (rn, &str, 16);
@@ -6541,7 +6339,6 @@
       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
       return;
     }
-  skip_whitespace (str);
 
   /* Skip past ']'.  */
   if (*str != ']')
@@ -6559,26 +6356,20 @@
 {
   int reg;
 
-  skip_whitespace (str);
-
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
 
   reg_nonpc_or_fail (&str, 0);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL
-      || *str++ != '[')
+  if (*str++ != '[')
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  skip_whitespace (str);
-
   note_reg_nonpc_or_fail (reg, &str, 16);
 
-  skip_whitespace (str);
-
   if (*str++ != ']')
     {
       inst.error = _("missing ]");
@@ -6605,7 +6396,6 @@
   int rotation_sixteen_mask = 0x00000800;
   int rotation_twenty_four_mask = 0x00000c00;
 
-  skip_whitespace (str);
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
 
@@ -6625,7 +6415,6 @@
     }
 
   /* Move past 'ROR'.  */
-  skip_whitespace (str);
   if (strncasecmp (str, "ROR", 3) == 0)
     str += 3;
   else
@@ -6680,7 +6469,6 @@
   int rotation_sixteen_mask = 0x00000800;
   int rotation_twenty_four_mask = 0x00000c00;
 
-  skip_whitespace (str);
   reg_nonpc_or_fail (&str, 12);
   comma_or_fail (&str);
 
@@ -6697,7 +6485,6 @@
     }
 
   /* Move past 'ROR'.  */
-  skip_whitespace (str);
   if (strncasecmp (str, "ROR", 3) == 0)
     str += 3;
   else
@@ -6747,8 +6534,6 @@
 {
   int Rd, Rs, Rn = FAIL;
 
-  skip_whitespace (str);
-
   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
@@ -6913,8 +6698,6 @@
 {
   int Rd, Rb, Ro = FAIL;
 
-  skip_whitespace (str);
-
   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
@@ -6963,8 +6746,6 @@
       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
       str++;
 
-      skip_whitespace (str);
-
       expression_or_fail (& inst.reloc.exp, & str);
 
       end_of_line (str);
@@ -7113,8 +6894,6 @@
 {
   int Rd, Rs = FAIL;
 
-  skip_whitespace (str);
-
   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
@@ -7198,8 +6977,6 @@
 {
   int Rd, Rs, Rn = FAIL;
 
-  skip_whitespace (str);
-
   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
@@ -7311,7 +7088,6 @@
 
   /* This is a pseudo-op of the form "adr rd, label" to be converted
      into a relative address of the form "add rd, pc, #label-.-4".  */
-  skip_whitespace (str);
 
   /* Store Rd in temporary location inside instruction.  */
   if ((reg = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
@@ -7339,8 +7115,6 @@
 {
   int Rd, Rs, Rn;
 
-  skip_whitespace (str);
-
   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
       || skip_past_comma (&str) == FAIL
       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
@@ -7396,8 +7170,6 @@
 {
   int number = 0;
 
-  skip_whitespace (str);
-
   /* As a convenience we allow 'bkpt' without an operand.  */
   if (is_immediate_prefix (*str) || ISDIGIT (*str))
     if (immediate_required_here (&str, &number, 0, 255, TRUE) == FAIL)
@@ -7420,8 +7192,6 @@
 {
   int rm;
 
-  skip_whitespace (str);
-
   /* BLX(2) can be applied to any integer register.  */
   rm = thumb_reg (&str, THUMB_REG_ANY);
 
@@ -7490,8 +7260,6 @@
 {
   int reg;
 
-  skip_whitespace (str);
-
   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
     return;
 
@@ -7534,8 +7302,6 @@
   int Rb;
   long range;
 
-  skip_whitespace (str);
-
   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
     return;
 
@@ -7593,8 +7359,6 @@
 {
   int Rd, Rb, Ro;
 
-  skip_whitespace (str);
-
   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
       || skip_past_comma (&str) == FAIL
       || *str++ != '['
@@ -7642,8 +7406,6 @@
 {
   long range;
 
-  skip_whitespace (str);
-
   if ((range = reg_list (&str)) == FAIL)
     {
       if (! inst.error)
@@ -7716,8 +7478,6 @@
 static void
 do_t_swi (char * str)
 {
-  skip_whitespace (str);
-
   expression_or_fail (&inst.reloc.exp, &str);
 
   inst.reloc.type = BFD_RELOC_ARM_SWI;
@@ -7730,8 +7490,6 @@
 static void
 do_vfp_sp_monadic (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
   comma_or_fail (&str);
 
@@ -7742,8 +7500,6 @@
 static void
 do_vfp_dp_monadic (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
   comma_or_fail (&str);
 
@@ -7754,8 +7510,6 @@
 static void
 do_vfp_sp_dyadic (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
   comma_or_fail (&str);
 
@@ -7769,8 +7523,6 @@
 static void
 do_vfp_dp_dyadic (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
   comma_or_fail (&str);
 
@@ -7784,7 +7536,6 @@
 static void
 do_vfp_sp_compare_z (char * str)
 {
-  skip_whitespace (str);
   reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
   end_of_line (str);
 }
@@ -7792,7 +7543,6 @@
 static void
 do_vfp_dp_compare_z (char * str)
 {
-  skip_whitespace (str);
   reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
   end_of_line (str);
 }
@@ -7800,8 +7550,6 @@
 static void
 do_vfp_dp_sp_cvt (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
   comma_or_fail (&str);
 
@@ -7812,8 +7560,6 @@
 static void
 do_vfp_sp_dp_cvt (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
   comma_or_fail (&str);
 
@@ -7824,8 +7570,6 @@
 static void
 do_vfp_reg_from_sp (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -7838,8 +7582,6 @@
 {
   int reg;
 
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -7860,8 +7602,6 @@
 static void
 do_vfp_sp_from_reg (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Sn, REG_TYPE_SN);
   comma_or_fail (&str);
 
@@ -7876,8 +7616,6 @@
 {
   int reg;
 
-  skip_whitespace (str);
-
   /* We require exactly two consecutive SP registers.  */
   if (vfp_parse_reg_list (&str, &reg, 0) != 2)
     {
@@ -7897,8 +7635,6 @@
 static void
 do_vfp_reg_from_dp (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -7909,8 +7645,6 @@
 static void
 do_vfp_reg2_from_dp (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -7924,8 +7658,6 @@
 static void
 do_vfp_dp_from_reg (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Dn, REG_TYPE_DN);
   comma_or_fail (&str);
 
@@ -7936,8 +7668,6 @@
 static void
 do_vfp_dp_from_reg2 (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Dm, REG_TYPE_DN);
   comma_or_fail (&str);
 
@@ -7951,8 +7681,6 @@
 static void
 do_vfp_reg_from_ctrl (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -7965,8 +7693,6 @@
 static void
 do_vfp_ctrl_from_reg (char * str)
 {
-  skip_whitespace (str);
-
   if (vfp_psr_required_here (&str) == FAIL)
     return;
   comma_or_fail (&str);
@@ -7978,8 +7704,6 @@
 static void
 do_vfp_sp_ldst (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
   comma_or_fail (&str);
 
@@ -7992,8 +7716,6 @@
 static void
 do_vfp_dp_ldst (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
   comma_or_fail (&str);
 
@@ -8010,12 +7732,8 @@
   int count;
   int reg;
 
-  skip_whitespace (str);
-
   reg_or_fail (&str, 16, REG_TYPE_RN);
 
-  skip_whitespace (str);
-
   if (*str == '!')
     {
       inst.instruction |= WRITE_BACK;
@@ -8043,12 +7761,8 @@
   int count;
   int reg;
 
-  skip_whitespace (str);
-
   reg_or_fail (&str, 16, REG_TYPE_RN);
 
-  skip_whitespace (str);
-
   if (*str == '!')
     {
       inst.instruction |= WRITE_BACK;
@@ -8118,8 +7832,6 @@
   /* FP control registers.
      Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
 
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_RN);
   end_of_line (str);
 }
@@ -8127,8 +7839,6 @@
 static void
 do_fpa_cmp (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 16, REG_TYPE_FN);
   comma_or_fail (&str);
 
@@ -8141,8 +7851,6 @@
 static void
 do_fpa_monadic (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_FN);
   comma_or_fail (&str);
 
@@ -8155,8 +7863,6 @@
 static void
 do_fpa_dyadic (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_FN);
   comma_or_fail (&str);
 
@@ -8172,8 +7878,6 @@
 static void
 do_fpa_from_reg (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 16, REG_TYPE_FN);
   comma_or_fail (&str);
 
@@ -8184,8 +7888,6 @@
 static void
 do_fpa_to_reg (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_RN);
   comma_or_fail (&str);
 
@@ -8196,8 +7898,6 @@
 static void
 do_fpa_ldst (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_FN);
   comma_or_fail (&str);
 
@@ -8212,8 +7912,6 @@
 {
   int num_regs;
 
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_FN);
   comma_or_fail (&str);
 
@@ -8256,11 +7954,7 @@
 	}
 
       str++;
-      skip_whitespace (str);
-
       note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
-      skip_whitespace (str);
-
       if (*str != ']')
 	{
 	  inst.error = BAD_ARGS;
@@ -8335,8 +8029,6 @@
   inst_error = inst.error;
   if (!inst.error)
     inst.error = BAD_ARGS;
-  skip_whitespace (str);
-
   switch (insn_type)
     {
     case check_rd:
@@ -8606,8 +8298,6 @@
 static void
 do_iwmmxt_wldst (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_MMXWR);
   comma_or_fail (&str);
 
@@ -8622,8 +8312,6 @@
 {
   struct reg_entry *reg;
 
-  skip_whitespace (str);
-
   if ((reg = arm_reg_parse_multi (&str)) == NULL
       || (reg->type != REG_TYPE_MMXWR && reg->type != REG_TYPE_MMXWC))
     {
@@ -8708,7 +8396,6 @@
   shift0 = mode & 0xff;
   shift1 = (mode >> 8) & 0xff;
 
-  skip_whitespace (str);
   reg_or_fail (&str, shift0, reg0);
 
   comma_or_fail (&str);
@@ -8732,7 +8419,6 @@
   shift1 = (mode >> 8) & 0xff;
   shift2 = (mode >> 16) & 0xff;
 
-  skip_whitespace (str);
   reg_or_fail (&str, shift0, reg0);
 
   comma_or_fail (&str);
@@ -8762,7 +8448,6 @@
   shift2 = (mode >> 16) & 0xff;
   shift3 = (mode >> 24) & 0xff;
 
-  skip_whitespace (str);
   reg_or_fail (&str, shift0, reg0);
 
   comma_or_fail (&str);
@@ -8990,8 +8675,6 @@
 static void
 do_mav_dspsc_1 (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, -1, REG_TYPE_DSPSC);
   comma_or_fail (&str);
 
@@ -9003,8 +8686,6 @@
 static void
 do_mav_dspsc_2 (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, REG_TYPE_MVDX);
   comma_or_fail (&str);
 
@@ -9023,8 +8704,6 @@
 {
   int imm, neg = 0;
 
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, reg0);
   comma_or_fail (&str);
 
@@ -9033,8 +8712,6 @@
 
   /* Calculate the immediate operand.
      The operand is a 7bit signed number.  */
-  skip_whitespace (str);
-
   if (*str == '#')
     ++str;
 
@@ -9096,8 +8773,6 @@
 {
   int offset, negative;
 
-  skip_whitespace (str);
-
   reg_or_fail (&str, 12, reg0);
   comma_or_fail (&str);
   if (*str++ != '[')
@@ -9190,8 +8865,6 @@
 static void
 do_xsc_mia (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, -1, REG_TYPE_XSCALE);
   comma_or_fail (&str);
 
@@ -9209,8 +8882,6 @@
 static void
 do_xsc_mar (char * str)
 {
-  skip_whitespace (str);
-
   reg_or_fail (&str, -1, REG_TYPE_XSCALE);
   comma_or_fail (&str);
 
@@ -9231,8 +8902,6 @@
   int rdlo;
   int rdhi;
 
-  skip_whitespace (str);
-
   note_reg_nonpc_or_fail (rdlo, &str, 12);
   comma_or_fail (&str);
 
@@ -9343,8 +9012,6 @@
   memset (&inst, '\0', sizeof (inst));
   inst.reloc.type = BFD_RELOC_UNUSED;
 
-  skip_whitespace (str);
-
   /* Scan up to the end of the op-code, which must end in white space or
      end of string.  */
   for (p = str; *p != '\0'; p++)
@@ -9375,6 +9042,7 @@
 	  mapping_state (MAP_THUMB);
 	  inst.instruction = opcode->value;
 	  inst.size = opcode->size;
+	  skip_whitespace (p);
 	  opcode->parms (p);
 	  output_inst (str);
 	  return;
@@ -9398,6 +9066,7 @@
           mapping_state (MAP_ARM);
 	  inst.instruction = opcode->value;
 	  inst.size = INSN_SIZE;
+	  skip_whitespace (p);
 	  opcode->parms (p);
 	  output_inst (str);
 	  return;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (11/69)
  2005-04-26  9:58 Thumb32 assembler (11/69) Zack Weinberg
@ 2005-04-26 17:36 ` Paul Brook
  2005-04-28 10:39   ` Thumb32 assembler (11,58/69) Zack Weinberg
  0 siblings, 1 reply; 5+ messages in thread
From: Paul Brook @ 2005-04-26 17:36 UTC (permalink / raw)
  To: binutils; +Cc: Zack Weinberg

On Tuesday 26 April 2005 10:53, Zack Weinberg wrote:
> Almost all the calls to skip_whitespace in tc-arm.c are unnecessary,
> because the input scrubber removes almost all the whitespace before
> md_assemble gets called.  When it is necessary, it doesn't need to
> loop.  The skip_whitespace call that used to appear at the beginning
> of each and every ->parms function, which is necessary, is hoisted to
> md_assemble.

This (or something related) breaks libgcc builds. Reduced testcase below:

        .macro popret regs
        ldmia sp!, {\regs, pc}
        .endm
        .text
        popret "r4, r5"

foo.s: Assembler messages:
foo.s:5: Error: ARM register expected -- `ldmia sp!,{r4, r5,pc}'

Paul

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (11,58/69)
  2005-04-26 17:36 ` Paul Brook
@ 2005-04-28 10:39   ` Zack Weinberg
  2005-04-29 18:44     ` Paul Brook
  0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2005-04-28 10:39 UTC (permalink / raw)
  To: Paul Brook; +Cc: binutils


Paul Brook <paul@codesourcery.com> writes:
>
>         .macro popret regs
>         ldmia sp!, {\regs, pc}
>         .endm
>         .text
>         popret "r4, r5"
>
> foo.s: Assembler messages:
> foo.s:5: Error: ARM register expected -- `ldmia sp!,{r4, r5,pc}'

This turns out to be a bug in the generic macro code.  do_scrub_chars
needs to be applied to the result of macro expansion, because macro
expansion can generate lines that are not in canonical form.

Richard Earnshaw <rearnsha@gcc.gnu.org> writes:
> On Tue, 2005-04-26 at 17:32, Paul Brook wrote:
>> Unfortunately gcc (incorrectly) outputs the three argument form
>>     mul rd, rd, rm
>> I'll fix gcc, but I guess we want to support this for backwards
>> compatibility.
>
> The ARMv6 ARM says that all known implementations of v4t and later can
> handle any register overlap for MUL, so I'm inclined to just relax the
> compiler and assembler constraints entirely.

Easily enough done.

The appended patch applies on top of the previous 69 patches; it fixes
the generic macro expansion bug, allows either source argument of
Thumb mul to equal the destination, and fixes a typo in the handling
of other commutative Thumb arithmetic instructions.  Dependencies on
as.h do not appear to be explicitly recorded in the Makefile, so
adding an #include of as.h to sb.c does not require a Makefile
update.  (Incidentally, "make DEP" doesn't work for me - DEPA contains
zillions of absolute paths, despite dep.sed supposedly filtering them.)

I am still working on the problem with 'ldr rd, label' at an
unaligned-modulo-4 address.  I thought I could use fx_pcrel to
distinguish between that and 'ldr rd, [pc, #4]', but the generic fixup
logic clears fx_pcrel, so another approach is necessary.

zw

gas:
        * sb.c: Include as.h.
        (sb_to_scrub, scrub_position, scrub_from_sb): New statics.
        (sb_scrub_and_add_sb): New interface.
        * sb.h: Declare sb_scrub_and_add_sb.
        * input-scrub.c (input_scrub_include_sb): Use it.

        * config/tc-arm.c (do_t_arit3c): Correct typo in expression.
        (do_t_mul): Allow dest to equal either source1 or source2 in
        16-bit form; do not complain about dest == source1 in any
        case.

gas/testsuite:
        * gas/arm/tcompat2.s: Test both dest==source1 and dest==source2 
        for commutative arithmetic instructions.
        * gas/arm/tcompat2.d: Update to match.
        * gas/arm/t16-bad.l: Adjust expected diagnostic.
        * gas/arm/macro1.s, gas/arm/macro1.d: New test pair.
        * gas/arm/arm.exp: Run it.

===================================================================
Index: gas/sb.c
--- gas/sb.c	(revision 84)
+++ gas/sb.c	(working copy)
@@ -33,6 +33,7 @@
 #endif
 #include "libiberty.h"
 #include "sb.h"
+#include "as.h"
 
 /* These routines are about manipulating strings.
 
@@ -121,6 +122,37 @@ sb_add_sb (sb *ptr, sb *s)
   ptr->len += s->len;
 }
 
+/* helper for below */
+static sb *sb_to_scrub;
+static char *scrub_position;
+static int
+scrub_from_sb (char *buf, int buflen)
+{
+  int copy;
+  copy = sb_to_scrub->len - (scrub_position - sb_to_scrub->ptr);
+  if (copy > buflen)
+    copy = buflen;
+  memcpy (buf, scrub_position, copy);
+  scrub_position += copy;
+  return copy;
+}
+
+/* run the sb at s through do_scrub_chars and add the result to the sb
+   at ptr */
+
+void
+sb_scrub_and_add_sb (sb *ptr, sb *s)
+{
+  sb_to_scrub = s;
+  scrub_position = s->ptr;
+  
+  sb_check (ptr, s->len);
+  ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, s->len);
+
+  sb_to_scrub = 0;
+  scrub_position = 0;
+}
+
 /* make sure that the sb at ptr has room for another len characters,
    and grow it if it doesn't.  */
 
===================================================================
Index: gas/sb.h
--- gas/sb.h	(revision 84)
+++ gas/sb.h	(working copy)
@@ -82,6 +82,7 @@ extern void sb_build (sb *, int);
 extern void sb_new (sb *);
 extern void sb_kill (sb *);
 extern void sb_add_sb (sb *, sb *);
+extern void sb_scrub_and_add_sb (sb *, sb *);
 extern void sb_reset (sb *);
 extern void sb_add_char (sb *, int);
 extern void sb_add_string (sb *, const char *);
===================================================================
Index: gas/input-scrub.c
--- gas/input-scrub.c	(revision 84)
+++ gas/input-scrub.c	(working copy)
@@ -280,7 +280,7 @@ input_scrub_include_sb (sb *from, char *
       /* Add the sentinel required by read.c.  */
       sb_add_char (&from_sb, '\n');
     }
-  sb_add_sb (&from_sb, from);
+  sb_scrub_and_add_sb (&from_sb, from);
   sb_index = 1;
 
   /* These variables are reset by input_scrub_push.  Restore them
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 84)
+++ gas/config/tc-arm.c	(working copy)
@@ -6025,7 +6025,7 @@ do_t_arit3c (void)
       if (Rd == Rs)
 	inst.instruction |= Rn << 3;
       else if (Rd == Rn)
-	inst.instruction |= Rn << 3;
+	inst.instruction |= Rs << 3;
       else
 	constraint (1, _("dest must overlap one source register"));
     }
@@ -6735,15 +6735,18 @@ do_t_mul (void)
     {
       constraint (!thumb32_mode
 		  && inst.instruction == T_MNEM_muls, BAD_THUMB32);
-      constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7, BAD_HIREG);
-      constraint (inst.operands[0].reg != inst.operands[2].reg,
-		  _("dest and source2 must be the same register"));
-      if (inst.operands[0].reg == inst.operands[1].reg)
-	as_tsktsk (_("dest and source must be different in MUL"));
+      constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
+		  BAD_HIREG);
 
       inst.instruction = THUMB_OP16 (inst.instruction);
       inst.instruction |= inst.operands[0].reg;
-      inst.instruction |= inst.operands[1].reg << 3;
+
+      if (inst.operands[0].reg == inst.operands[1].reg)
+	inst.instruction |= inst.operands[2].reg << 3;
+      else if (inst.operands[0].reg == inst.operands[2].reg)
+	inst.instruction |= inst.operands[1].reg << 3;
+      else
+	constraint (1, _("dest must overlap one source register"));
     }
 }
 
===================================================================
Index: gas/testsuite/gas/arm/tcompat2.s
--- gas/testsuite/gas/arm/tcompat2.s	(revision 84)
+++ gas/testsuite/gas/arm/tcompat2.s	(working copy)
@@ -1,13 +1,27 @@
 	@ Three-argument forms of Thumb arithmetic instructions.
+	@ Commutative instructions allow either the second or third
+	@ operand to equal the first.
+
 	.text
 	.global m
 	.thumb_func
 m:
 	adc	r0,r0,r1
+	adc	r0,r1,r0
+
 	and	r0,r0,r1
-	bic	r0,r0,r1
+	and	r0,r1,r0
+
 	eor	r0,r0,r1
+	eor	r0,r1,r0
+
+	mul	r0,r0,r1
 	mul	r0,r1,r0
+
 	orr	r0,r0,r1
+	orr	r0,r1,r0
+
+	bic	r0,r0,r1
+
 	sbc	r0,r0,r1
-	nop
+
===================================================================
Index: gas/testsuite/gas/arm/tcompat2.d
--- gas/testsuite/gas/arm/tcompat2.d	(revision 84)
+++ gas/testsuite/gas/arm/tcompat2.d	(working copy)
@@ -9,10 +9,14 @@
 Disassembly of section .text:
 
 0+00 <[^>]*> 4148 *	adcs	r0, r1
-0+02 <[^>]*> 4008 *	ands	r0, r1
-0+04 <[^>]*> 4388 *	bics	r0, r1
-0+06 <[^>]*> 4048 *	eors	r0, r1
-0+08 <[^>]*> 4348 *	muls	r0, r1
-0+0a <[^>]*> 4308 *	orrs	r0, r1
-0+0c <[^>]*> 4188 *	sbcs	r0, r1
-0+0e <[^>]*> 46c0 *	nop			\(mov r8, r8\)
+0+02 <[^>]*> 4148 *	adcs	r0, r1
+0+04 <[^>]*> 4008 *	ands	r0, r1
+0+06 <[^>]*> 4008 *	ands	r0, r1
+0+08 <[^>]*> 4048 *	eors	r0, r1
+0+0a <[^>]*> 4048 *	eors	r0, r1
+0+0c <[^>]*> 4348 *	muls	r0, r1
+0+0e <[^>]*> 4348 *	muls	r0, r1
+0+10 <[^>]*> 4308 *	orrs	r0, r1
+0+12 <[^>]*> 4308 *	orrs	r0, r1
+0+14 <[^>]*> 4388 *	bics	r0, r1
+0+16 <[^>]*> 4188 *	sbcs	r0, r1
===================================================================
Index: gas/testsuite/gas/arm/t16-bad.l
--- gas/testsuite/gas/arm/t16-bad.l	(revision 84)
+++ gas/testsuite/gas/arm/t16-bad.l	(working copy)
@@ -70,7 +70,7 @@
 [^:]*:53: Error: unshifted register required -- `sbc r0,#12'
 [^:]*:53: Error: unshifted register required -- `sbc r0,r1,lsl#2'
 [^:]*:53: Error: unshifted register required -- `sbc r0,r1,lsl r3'
-[^:]*:54: Error: dest and source2 must be the same register -- `mul r1,r2,r3'
+[^:]*:54: Error: dest must overlap one source register -- `mul r1,r2,r3'
 [^:]*:54: Error: lo register required -- `mul r8,r0'
 [^:]*:54: Error: lo register required -- `mul r0,r8'
 [^:]*:62: Error: lo register required -- `asr r8,r0,#12'
===================================================================
Index: gas/testsuite/gas/arm/macro1.d
--- gas/testsuite/gas/arm/macro1.d	(revision 0)
+++ gas/testsuite/gas/arm/macro1.d	(revision 0)
@@ -0,0 +1,9 @@
+# name: Macro scrubbing
+# as:
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+[^:]+: +file format .*arm.*
+
+Disassembly of section .text:
+
+0+0 <[^>]*> e8bd8030 ?	ldmia	sp!, {r4, r5, pc}
===================================================================
Index: gas/testsuite/gas/arm/macro1.s
--- gas/testsuite/gas/arm/macro1.s	(revision 0)
+++ gas/testsuite/gas/arm/macro1.s	(revision 0)
@@ -0,0 +1,6 @@
+	@ Test that macro expansions are properly scrubbed.
+	.macro popret regs
+	ldmia sp!, {\regs, pc}
+	.endm
+	.text
+	popret "r4, r5"
===================================================================
Index: gas/testsuite/gas/arm/arm.exp
--- gas/testsuite/gas/arm/arm.exp	(revision 84)
+++ gas/testsuite/gas/arm/arm.exp	(working copy)
@@ -55,6 +55,7 @@ if {[istarget *arm*-*-*] || [istarget "x
     run_dump_test "tcompat"
     run_dump_test "tcompat2"
     run_dump_test "iwmmxt"
+    run_dump_test "macro1"
     
     run_errors_test "vfp-bad" "-mfpu=vfp" "VFP errors"
     run_errors_test "req" "-mcpu=arm7m" ".req errors"

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (11,58/69)
  2005-04-28 10:39   ` Thumb32 assembler (11,58/69) Zack Weinberg
@ 2005-04-29 18:44     ` Paul Brook
  2005-04-29 19:20       ` Zack Weinberg
  0 siblings, 1 reply; 5+ messages in thread
From: Paul Brook @ 2005-04-29 18:44 UTC (permalink / raw)
  To: binutils; +Cc: Zack Weinberg

> gas:
>         * sb.c: Include as.h.
>         (sb_to_scrub, scrub_position, scrub_from_sb): New statics.
>         (sb_scrub_and_add_sb): New interface.
>         * sb.h: Declare sb_scrub_and_add_sb.
>         * input-scrub.c (input_scrub_include_sb): Use it.
>
>         * config/tc-arm.c (do_t_arit3c): Correct typo in expression.
>         (do_t_mul): Allow dest to equal either source1 or source2 in
>         16-bit form; do not complain about dest == source1 in any
>         case.
>
> gas/testsuite:
>         * gas/arm/tcompat2.s: Test both dest==source1 and dest==source2
>         for commutative arithmetic instructions.
>         * gas/arm/tcompat2.d: Update to match.
>         * gas/arm/t16-bad.l: Adjust expected diagnostic.
>         * gas/arm/macro1.s, gas/arm/macro1.d: New test pair.
>         * gas/arm/arm.exp: Run it.

I can't comment on the input scrubbing bits, except they seem to work.
The arm bits look ok.

Please apply to binutils-csl-arm-2005q1-branch

Paul

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (11,58/69)
  2005-04-29 18:44     ` Paul Brook
@ 2005-04-29 19:20       ` Zack Weinberg
  0 siblings, 0 replies; 5+ messages in thread
From: Zack Weinberg @ 2005-04-29 19:20 UTC (permalink / raw)
  To: Paul Brook; +Cc: binutils

Paul Brook <paul@codesourcery.com> writes:

> Please apply to binutils-csl-arm-2005q1-branch

Done.

zw

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-04-29 17:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-04-26  9:58 Thumb32 assembler (11/69) Zack Weinberg
2005-04-26 17:36 ` Paul Brook
2005-04-28 10:39   ` Thumb32 assembler (11,58/69) Zack Weinberg
2005-04-29 18:44     ` Paul Brook
2005-04-29 19:20       ` Zack Weinberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).