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 (34/69)


parse_operands conversion for some of the FPA instructions; also a
certain amount of whitespace tweaking.

zw

	* config/tc-arm.c (my_get_float_expression): Rename fpa_immediate.
	Fold in exact-string-match logic from fp_op2.  Return the
	pseudo-register number, not the index into the table.
	(fp_op2): Delete.
	(OP_RF_IF): New operand parse code.
	(parse_operand): Implement it.
	(do_fpa_cmp, do_fpa_monadic, do_fpa_dyadic): Use parse_operands.

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 35)
+++ gas/config/tc-arm.c	(revision 37)
@@ -877,11 +877,11 @@
   return 0;
 }
 
-/* Returns the index into fp_values of a floating point number,
-   or -1 if not in the table.  */
+/* Returns the pseudo-register number of an FPA immediate constant,
+   or FAIL if there isn't a valid constant here.  */
 
 static int
-my_get_float_expression (char ** str)
+fpa_immediate (char ** str)
 {
   LITTLENUM_TYPE words[MAX_LITTLENUMS];
   char *         save_in;
@@ -889,6 +889,27 @@
   int            i;
   int            j;
 
+  /* First try and match exact strings, this is to guarantee
+     that some formats will work even for cross assembly.  */
+
+  for (i = 0; fp_const[i]; i++)
+    {
+      if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
+	{
+	  char *start = *str;
+	  
+	  *str += strlen (fp_const[i]);
+	  if (is_end_of_line[(unsigned char) **str])
+	    return i + 8;
+	  *str = start;
+	}
+    }
+
+  /* Just because we didn't get a match doesn't mean that the constant
+     isn't valid, just that it is in a format that we don't
+     automatically recognize.  Try parsing it with the standard
+     expression routines.  */
+
   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
 
   /* Look for a raw floating point number.  */
@@ -906,7 +927,7 @@
 	  if (j == MAX_LITTLENUMS)
 	    {
 	      *str = save_in;
-	      return i;
+	      return i + 8;
 	    }
 	}
     }
@@ -935,7 +956,7 @@
 		{
 		  *str = input_line_pointer;
 		  input_line_pointer = save_in;
-		  return i;
+		  return i + 8;
 		}
 	    }
 	}
@@ -943,7 +964,8 @@
 
   *str = input_line_pointer;
   input_line_pointer = save_in;
-  return -1;
+  inst.error = _("invalid FPA immediate expression");
+  return FAIL;
 }
 
 /* We handle all bad expressions here, so that we can report the faulty
@@ -989,7 +1011,7 @@
       inst.error = _("immediate value out of range");
       return FAIL;
     }
-  
+
   *val = exp.X_add_number;
   return SUCCESS;
 }
@@ -1125,7 +1147,7 @@
 
   if (!reg)
     return NULL;
-  
+
   *ccp = p;
   return reg;
 }
@@ -1825,59 +1847,6 @@
     }
 }
 
-
-static int
-fp_op2 (char ** str)
-{
-  if (reg_required_here (str, 0, REG_TYPE_FN) != FAIL)
-    return SUCCESS;
-  else
-    {
-      /* Immediate expression.  */
-      if (*((*str)++) == '#')
-	{
-	  int i;
-
-	  inst.error = NULL;
-
-	  /* First try and match exact strings, this is to guarantee
-	     that some formats will work even for cross assembly.  */
-
-	  for (i = 0; fp_const[i]; i++)
-	    {
-	      if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
-		{
-		  char *start = *str;
-
-		  *str += strlen (fp_const[i]);
-		  if (is_end_of_line[(unsigned char) **str])
-		    {
-		      inst.instruction |= i + 8;
-		      return SUCCESS;
-		    }
-		  *str = start;
-		}
-	    }
-
-	  /* Just because we didn't get a match doesn't mean that the
-	     constant isn't valid, just that it is in a format that we
-	     don't automatically recognize.  Try parsing it with
-	     the standard expression routines.  */
-	  if ((i = my_get_float_expression (str)) >= 0)
-	    {
-	      inst.instruction |= i + 8;
-	      return SUCCESS;
-	    }
-
-	  inst.error = _("invalid floating point immediate expression");
-	  return FAIL;
-	}
-      inst.error =
-	_("floating point register or immediate expression expected");
-      return FAIL;
-    }
-}
-
 /* Parse an explicit relocation suffix on an expression.  This is
    either nothing, or a word in parentheses.  Note that if !OBJ_ELF,
    arm_reloc_hsh contains no entries, so this function can only
@@ -1888,7 +1857,7 @@
 {
   struct reloc_entry *r;
   char *p, *q;
-  
+
   if (**str != '(')
     return BFD_RELOC_UNUSED;
 
@@ -2624,7 +2593,7 @@
     {
       if (new->builtin)
 	as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
-      
+
       /* Only warn about a redefinition if it's not defined as the
 	 same register.  */
       else if (new->number != number || new->type != type)
@@ -4287,64 +4256,65 @@
    the macros below.  Never refer to these constants except via the
    macros below.  */
 
-#define OP_stop	   000	/* end of line */
+#define OP_stop    000  /* end of line */
 
-#define OP_RR	   001	/* ARM register */			   
-#define OP_RRnpc   002	/* ARM register, not r15 */
-#define OP_bRRnpc  003	/* ARM register, not r15, in square brackets */
-#define OP_RCP	   004	/* Coprocessor number */		   
-#define OP_RCN	   005	/* Coprocessor register */		   
-#define OP_RF	   006	/* FPA register */			   
-#define OP_RVS	   007	/* VFP single precision register */	   
-#define OP_RVD	   010	/* VFP double precision register */	   
-#define OP_RVC	   011	/* VFP control register */		   
-#define OP_RMF	   012	/* Maverick F register */		   
-#define OP_RMD	   013	/* Maverick D register */		   
-#define OP_RMFX	   014	/* Maverick FX register */		   
-#define OP_RMDX	   015	/* Maverick DX register */		   
-#define OP_RMAX	   016	/* Maverick AX register */		   
-#define OP_RMDS	   017	/* Maverick DSPSC register */	   
-#define OP_RIWR	   020	/* iWMMXt wR register */		   
-#define OP_RIWC	   021	/* iWMMXt wC register */		   
-#define OP_RIWG	   022	/* iWMMXt wCG register */		   
-#define OP_RXA	   023  /* XScale accumulator register */
+#define OP_RR      001  /* ARM register */
+#define OP_RRnpc   002  /* ARM register, not r15 */
+#define OP_bRRnpc  003  /* ARM register, not r15, in square brackets */
+#define OP_RCP     004  /* Coprocessor number */
+#define OP_RCN     005  /* Coprocessor register */
+#define OP_RF      006  /* FPA register */
+#define OP_RVS     007  /* VFP single precision register */
+#define OP_RVD     010  /* VFP double precision register */
+#define OP_RVC     011  /* VFP control register */
+#define OP_RMF     012  /* Maverick F register */
+#define OP_RMD     013  /* Maverick D register */
+#define OP_RMFX    014  /* Maverick FX register */
+#define OP_RMDX    015  /* Maverick DX register */
+#define OP_RMAX    016  /* Maverick AX register */
+#define OP_RMDS    017  /* Maverick DSPSC register */
+#define OP_RIWR    020  /* iWMMXt wR register */
+#define OP_RIWC    021  /* iWMMXt wC register */
+#define OP_RIWG    022  /* iWMMXt wCG register */
+#define OP_RXA     023  /* XScale accumulator register */
 
-#define OP_EXP	   024	/* arbitrary expression */
-#define OP_iEXP	   025	/* same, with optional immediate prefix */
-#define OP_EXPr	   026	/* same, with optional relocation suffix */
+#define OP_EXP     024  /* arbitrary expression */
+#define OP_iEXP    025  /* same, with optional immediate prefix */
+#define OP_EXPr    026  /* same, with optional relocation suffix */
 
-#define OP_I0	   027	/* immediate value 0 */
+#define OP_I0      027  /* immediate value 0 */
 #define OP_I4      030  /*                 1 .. 4 */
-#define OP_I7	   031  /*                 0 .. 7 */
-#define OP_I15	   032  /*                 0 .. 15 */
-#define OP_I16	   033  /*                 1 .. 16 */
-#define OP_I31	   034	/*                 0 .. 31 */
-#define OP_I32	   035	/*                 1 .. 32 */
-#define OP_Is63	   036  /*               -64 .. 63 */
-#define OP_I255	   037	/*                 0 .. 255 */
+#define OP_I7      031  /*                 0 .. 7 */
+#define OP_I15     032  /*                 0 .. 15 */
+#define OP_I16     033  /*                 1 .. 16 */
+#define OP_I31     034  /*                 0 .. 31 */
+#define OP_I32     035  /*                 1 .. 32 */
+#define OP_Is63    036  /*               -64 .. 63 */
+#define OP_I255    037  /*                 0 .. 255 */
 #define OP_Iffff   040 /*                 0 .. 65535 */
 
-#define OP_bI7	   041  /* immediate, prefix optional, 0 .. 7 */
+#define OP_bI7     041  /* immediate, prefix optional, 0 .. 7 */
 #define OP_bI15    042  /*                             0 .. 15 */
 #define OP_bI31    043  /*                             0 .. 31 */
 
-#define OP_I31w	   050  /* 0 .. 31, optional trailing ! */
-#define OP_RRw	   051  /* ARM register, not the PC, optional trailing ! */
+#define OP_I31w    050  /* 0 .. 31, optional trailing ! */
+#define OP_RRw     051  /* ARM register, not the PC, optional trailing ! */
 
-#define OP_RL	   052	/* Thumb low register */
-#define OP_RLlb	   053  /* Thumb low register, leading [ */
-#define OP_RLtb	   054	/* Thumb low register. trailing ] */
+#define OP_RL      052  /* Thumb low register */
+#define OP_RLlb    053  /* Thumb low register, leading [ */
+#define OP_RLtb    054  /* Thumb low register. trailing ] */
 
-#define OP_CPSF	   060  /* CPS flags */
-#define OP_ENDI	   061	/* Endianness specifier */
+#define OP_CPSF    060  /* CPS flags */
+#define OP_ENDI    061  /* Endianness specifier */
 #define OP_PSR     062  /* CPSR/SPSR mask for msr */
 
 /* This-or-that operands.  All have bit 7 set.  */
-#define OP_RR_EX   100	/* ARM register or expression */
-#define OP_RL_iEX  101	/* Thumb low register or expression with imm prefix */
-#define OP_RRnpc_I0 102	/* ARM register or literal 0 */
+#define OP_RR_EX   100  /* ARM register or expression */
+#define OP_RL_iEX  101  /* Thumb low register or expression with imm prefix */
+#define OP_RRnpc_I0 102 /* ARM register or literal 0 */
 #define OP_RR_EXr  103  /* ARM register or expression with opt. reloc suff. */
 #define OP_RR_iEX  104  /* ARM register or expression with imm prefix */
+#define OP_RF_IF   105  /* FPA register or immediate */
 
 /* Optional operands.  All have the high bit set.  */
 #define OP_obI7    200  /* optional, prefix optional, immediate 0 .. 7 */
@@ -4353,10 +4323,10 @@
 #define OP_obIffff 203  /*                                      0 .. 65535 */
 #define OP_ocI255  204  /* optional, curly-brace enclosed, imm  0 .. 255 */
 
-#define OP_oROR	   210  /* optional rotate right 0/8/16/24 */
-#define OP_oRL	   211  /* optional Thumb low register */
+#define OP_oROR    210  /* optional rotate right 0/8/16/24 */
+#define OP_oRL     211  /* optional Thumb low register */
 
-#define OP_oRL_iEX 300	/* optional Thumb low reg or expression */
+#define OP_oRL_iEX 300  /* optional Thumb low reg or expression */
 
 /* Macro for referring to one of the above constants as a number.
    Should appear solely in parse_operands().  */
@@ -4484,7 +4454,7 @@
 	  if (inst.operands[i].reg > 7)
 	    inst.error = BAD_HIREG;
 	  break;
-	  
+
 	case OP_(RLlb):
 	  po_char_or_fail ('[');
 	  po_reg_or_fail (REG_TYPE_RN);
@@ -4498,7 +4468,7 @@
 	  if (inst.operands[i].reg > 7)
 	    inst.error = BAD_HIREG;
 	  break;
-	  
+
 	  /* Immediates */
 	I0:
 	case OP_(I0):	 po_imm_or_fail (  0,      0, FALSE);	break;
@@ -4544,14 +4514,14 @@
 	      str = s;
 	  }
 	  break;
-	  
+
 	  /* Expressions */
 	case OP_(iEXP):
 	iEXP:
 	  if (is_immediate_prefix (*str))
 	    str++;
 	  /* fall through */
-	  
+
 	case OP_(EXP):
 	EXP:
 	  if (my_get_expression (&inst.reloc.exp, &str))
@@ -4597,6 +4567,23 @@
 	    inst.error = BAD_PC;
 	  break;
 
+	case OP_(RF_IF):
+	  if (!is_immediate_prefix (*str))
+	    po_reg_or_fail (REG_TYPE_FN);
+	  else
+	    {
+	      int reg_;
+	      str++;
+	      reg_ = fpa_immediate (&str);
+	      if (reg_ == FAIL)
+		return FAIL;
+	      /* FPA immediates are encoded as registers 8-15.
+	         fpa_immediate has already applied the offset.  */
+	      inst.operands[i].reg = reg_;
+	      inst.operands[i].isreg = 1;
+	    }
+	  break;
+
 	  /* Misc */
 	case OP_(CPSF):
 	  if (parse_cps_flags (&inst.operands[i].imm, &str))
@@ -4621,7 +4608,7 @@
 	    inst.operands[i].imm = psrmask;
 	  }
 	  break;
-	  
+
 	default:
 	  as_fatal ("unhandled operand code %03o", *p);
 	}
@@ -4687,7 +4674,7 @@
 static void
 do_empty (char * str)
 {
-  parse_operands (str, OPERANDS0 ());
+  parse_operands (str, OPERANDS0());
 }
 
 /* ARM instructions, in alphabetical order by function name (except
@@ -4700,7 +4687,7 @@
 static void
 do_adr (char * str)
 {
-  if (parse_operands (str, OPERANDS2 (RR, EXP)) == FAIL)
+  if (parse_operands (str, OPERANDS2(RR,EXP)) == FAIL)
     return;
 
   inst.instruction |= (inst.operands[0].reg << 12);  /* Rd */
@@ -4722,7 +4709,7 @@
 static void
 do_adrl (char * str)
 {
-  if (parse_operands (str, OPERANDS2 (RR, EXP)) == FAIL)
+  if (parse_operands (str, OPERANDS2(RR,EXP)) == FAIL)
     return;
 
   inst.instruction |= (inst.operands[0].reg << 12);  /* Rd */
@@ -4911,7 +4898,7 @@
 static void
 do_bx (char * str)
 {
-  if (parse_operands (str, OPERANDS1 (RR)) == FAIL)
+  if (parse_operands (str, OPERANDS1(RR)) == FAIL)
     return;
 
   if (inst.operands[0].reg == REG_PC)
@@ -4926,7 +4913,7 @@
 static void
 do_bxj (char * str)
 {
-  if (parse_operands (str, OPERANDS1 (RR)) == FAIL)
+  if (parse_operands (str, OPERANDS1(RR)) == FAIL)
     return;
 
   if (inst.operands[0].reg == REG_PC)
@@ -4960,7 +4947,7 @@
 static void
 do_clz (char * str)
 {
-  if (parse_operands (str, OPERANDS2 (RRnpc,RRnpc)) == FAIL)
+  if (parse_operands (str, OPERANDS2(RRnpc,RRnpc)) == FAIL)
     return;
 
   inst.instruction |= (inst.operands[0].reg << 12);
@@ -5170,7 +5157,7 @@
 static void
 do_ldrex (char * str)
 {
-  if (parse_operands (str, OPERANDS2(RRnpc, bRRnpc)))
+  if (parse_operands (str, OPERANDS2(RRnpc,bRRnpc)))
     return;
 
   inst.instruction |= (inst.operands[0].reg << 12);
@@ -5650,7 +5637,7 @@
   inst.instruction |= (inst.operands[1].reg << 0);
   inst.instruction |= (inst.operands[2].reg << 8);
   inst.instruction |= (inst.operands[3].reg << 12);
-  
+
   /* This restriction does not apply to mls (nor to mla in v6, but
      that's hard to detect at present).  */
   if (inst.operands[0].reg == inst.operands[1].reg && !is_mls)
@@ -6134,7 +6121,7 @@
   inst.instruction |= (inst.operands[1].reg << 16);
   inst.instruction |= (inst.operands[2].reg << 0);
   inst.instruction |= (inst.operands[3].reg << 8);
-  
+
   if (inst.operands[0].reg == inst.operands[1].reg)
     as_tsktsk (_("rdhi and rdlo must be different"));
 }
@@ -6742,7 +6729,7 @@
 {
   if (parse_operands (str, OPERANDS2(RL,EXP)))
     return;
-  
+
   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
   inst.reloc.pc_rel = 1;
@@ -7415,40 +7402,32 @@
 static void
 do_fpa_cmp (char * str)
 {
-  reg_or_fail (&str, 16, REG_TYPE_FN);
-  comma_or_fail (&str);
-
-  if (fp_op2 (&str) == FAIL)
+  if (parse_operands (str, OPERANDS2(RF,RF_IF)))
     return;
 
-  end_of_line (str);
+  inst.instruction |= inst.operands[0].reg << 16;
+  inst.instruction |= inst.operands[1].reg;
 }
 
 static void
 do_fpa_monadic (char * str)
 {
-  reg_or_fail (&str, 12, REG_TYPE_FN);
-  comma_or_fail (&str);
-
-  if (fp_op2 (&str) == FAIL)
+  if (parse_operands (str, OPERANDS2(RF,RF_IF)))
     return;
 
-  end_of_line (str);
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg;
 }
 
 static void
 do_fpa_dyadic (char * str)
 {
-  reg_or_fail (&str, 12, REG_TYPE_FN);
-  comma_or_fail (&str);
-
-  reg_or_fail (&str, 16, REG_TYPE_FN);
-  comma_or_fail (&str);
-
-  if (fp_op2 (&str) == FAIL)
+  if (parse_operands (str, OPERANDS3(RF,RF,RF_IF)))
     return;
 
-  end_of_line (str);
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= inst.operands[2].reg;
 }
 
 static void
@@ -7456,7 +7435,7 @@
 {
   if (parse_operands (str, OPERANDS2(RF,RR)))
     return;
-  
+
   inst.instruction |= (inst.operands[0].reg << 16);
   inst.instruction |= (inst.operands[1].reg << 12);
 }
@@ -7466,7 +7445,7 @@
 {
   if (parse_operands (str, OPERANDS2(RR,RF)))
     return;
-  
+
   inst.instruction |= (inst.operands[0].reg << 12);
   inst.instruction |= (inst.operands[1].reg << 0);
 }
@@ -7599,7 +7578,7 @@
 {
   if (parse_operands (str, OPERANDS2(RR,RIWR)))
     return;
-  
+
   inst.instruction |= (inst.operands[0].reg << 12);
   inst.instruction |= (inst.operands[1].reg << 16);
 }
@@ -7641,7 +7620,7 @@
 {
   if (parse_operands (str, OPERANDS2(RIWC,RR)))
     return;
-  
+
   inst.instruction |= (inst.operands[0].reg << 16);
   inst.instruction |= (inst.operands[1].reg << 12);
 }
@@ -7651,7 +7630,7 @@
 {
   if (parse_operands (str, OPERANDS3(RIWR,RR,RR)))
     return;
-  
+
   inst.instruction |= (inst.operands[0].reg << 0);
   inst.instruction |= (inst.operands[1].reg << 12);
   inst.instruction |= (inst.operands[2].reg << 16);
@@ -7662,7 +7641,7 @@
 {
   if (parse_operands (str, OPERANDS3(RIWR,RR,RR)))
     return;
-  
+
   inst.instruction |= (inst.operands[0].reg << 5);
   inst.instruction |= (inst.operands[1].reg << 0);
   inst.instruction |= (inst.operands[2].reg << 12);
@@ -7673,7 +7652,7 @@
 {
   if (parse_operands (str, OPERANDS2(RR,RIWR)))
     return;
-  
+
   inst.instruction |= (inst.operands[0].reg << 12);
   inst.instruction |= (inst.operands[1].reg << 16);
 
@@ -7684,7 +7663,7 @@
 {
   if (parse_operands (str, OPERANDS2(RR,RIWC)))
     return;
-  
+
   inst.instruction |= (inst.operands[0].reg << 12);
   inst.instruction |= (inst.operands[1].reg << 16);
 }
@@ -7694,7 +7673,7 @@
 {
   if (parse_operands (str, OPERANDS3(RR,RR,RIWR)))
     return;
-  
+
   inst.instruction |= (inst.operands[0].reg << 12);
   inst.instruction |= (inst.operands[1].reg << 16);
   inst.instruction |= (inst.operands[2].reg << 0);
@@ -8586,11 +8565,11 @@
   /* VFP control registers.  */
   REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
   REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
-  
+
   /* Maverick DSP coprocessor registers.  */
   REGSET(mvf,MVF),  REGSET(mvd,MVD),  REGSET(mvfx,MVFX),  REGSET(mvdx,MVDX),
   REGSET(MVF,MVF),  REGSET(MVD,MVD),  REGSET(MVFX,MVFX),  REGSET(MVDX,MVDX),
-  
+
   REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
   REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
   REGDEF(dspsc,0,DSPSC),
@@ -10302,7 +10281,7 @@
   flags = SHF_ALLOC;
   linkonce = 0;
   group_name = 0;
-  
+
   /* Handle COMDAT group.  */
   if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
     {
@@ -10622,7 +10601,7 @@
       /* This will need to go in the object file.  */
       fixP->fx_done = 0;
       break;
-  
+
     case BFD_RELOC_ARM_IMMEDIATE:
       /* We claim that this fixup has been processed here,
 	 even if in fact we generate an error because we do
@@ -11833,7 +11812,7 @@
     }
   else if (mfpu_opt == -1)
     {
-#if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS)) 
+#if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS))
       /* Some environments specify a default FPU.  If they don't, infer it
 	 from the processor.  */
       if (mcpu_fpu_opt != -1)

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