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


Teach parse_operands about VFP register lists.

zw

	* config/tc-arm.c (OP_REGLST, OP_VRSLST, OP_VRDLST): New operand parse
        codes.
	(parse_operands): Declare function-global scratch variable 'val', and
        use it throughout instead of block-local scratches.  Implement
	VRSLST and VRDLST.
	(do_vfp_reg2_from_sp2, do_vfp_sp2_from_reg, vfp_sp_ldstm, vfp_dp_ldstm):
	Use parse_operands.

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 38)
+++ gas/config/tc-arm.c	(revision 39)
@@ -4307,6 +4307,9 @@
 #define OP_CPSF    060  /* CPS flags */
 #define OP_ENDI    061  /* Endianness specifier */
 #define OP_PSR     062  /* CPSR/SPSR mask for msr */
+#define OP_REGLST  063	/* ARM register list */
+#define OP_VRSLST  064	/* VFP single-precision register list */
+#define OP_VRDLST  065	/* VFP double-precision register list */
 
 /* This-or-that operands.  All have bit 7 set.  */
 #define OP_RR_EX   100  /* ARM register or expression */
@@ -4357,6 +4360,7 @@
 parse_operands (char *str, const char *pattern)
 {
   int i;
+  int val;
   unsigned const char *p = pattern;
 
 #define po_char_or_fail(chr) do {		\
@@ -4365,30 +4369,29 @@
 } while (0)
 
 #define po_reg_or_fail(regtype) do {			\
-  int reg_ = reg_required_here (&str, -1, regtype);	\
-  if (reg_ == FAIL)					\
+  val = reg_required_here (&str, -1, regtype);		\
+  if (val == FAIL)					\
     {							\
       inst.error = _(reg_expected_msgs[regtype]);	\
       return FAIL;					\
     }							\
-  inst.operands[i].reg = reg_;				\
+  inst.operands[i].reg = val;				\
   inst.operands[i].isreg = 1;				\
 } while (0)
 
 #define po_reg_or_goto(regtype, label) do {	\
-  int reg_ = arm_reg_parse (&str, regtype);	\
-  if (reg_ == FAIL)				\
+  val = arm_reg_parse (&str, regtype);		\
+  if (val == FAIL)				\
     goto label;					\
 						\
-  inst.operands[i].reg = reg_;			\
+  inst.operands[i].reg = val;			\
   inst.operands[i].isreg = 1;			\
 } while (0)
 
 #define po_imm_or_fail(min, max, popt) do {				\
-  int imm_;								\
-  if (immediate_required_here (&str, &imm_, min, max, popt) == FAIL)	\
+  if (immediate_required_here (&str, &val, min, max, popt) == FAIL)	\
     return FAIL;							\
-  inst.operands[i].imm = imm_;						\
+  inst.operands[i].imm = val;						\
 } while (0)
 
   /* Check for a no-operand instruction, or an instruction with only
@@ -4534,15 +4537,15 @@
 	    return FAIL;
 	  if (inst.reloc.exp.X_op == O_symbol)
 	    {
-	      int reloc = parse_reloc (&str);
-	      if (reloc == -1)
+	      val = parse_reloc (&str);
+	      if (val == -1)
 		{
 		  inst.error = _("unrecognized relocation suffix");
 		  return FAIL;
 		}
-	      else if (reloc != BFD_RELOC_UNUSED)
+	      else if (val != BFD_RELOC_UNUSED)
 		{
-		  inst.operands[i].imm = reloc;
+		  inst.operands[i].imm = val;
 		  inst.operands[i].hasreloc = 1;
 		}
 	    }
@@ -4572,14 +4575,13 @@
 	    po_reg_or_fail (REG_TYPE_FN);
 	  else
 	    {
-	      int reg_;
 	      str++;
-	      reg_ = fpa_immediate (&str);
-	      if (reg_ == FAIL)
+	      val = fpa_immediate (&str);
+	      if (val == 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].reg = val;
 	      inst.operands[i].isreg = 1;
 	    }
 	  break;
@@ -4601,14 +4603,24 @@
 	  break;
 
 	case OP_(PSR):
-	  {
-	    int psrmask = parse_psr (&str);
-	    if (psrmask == FAIL)
-	      return FAIL;
-	    inst.operands[i].imm = psrmask;
-	  }
+	  if ((val = parse_psr (&str)) == FAIL)
+	    return FAIL;
+	  inst.operands[i].imm = val;
 	  break;
 
+	case OP_(VRSLST):
+	  val = vfp_parse_reg_list (&str, &inst.operands[i].reg, 0);
+	  goto vfp_reglist;
+
+	case OP_(VRDLST):
+	  val = vfp_parse_reg_list (&str, &inst.operands[i].reg, 1);
+
+	vfp_reglist:
+	  if (val == FAIL)
+	    return FAIL;
+	  inst.operands[i].imm = val;
+	  break;
+
 	default:
 	  as_fatal ("unhandled operand code %03o", *p);
 	}
@@ -7133,23 +7145,17 @@
 static void
 do_vfp_reg2_from_sp2 (char * str)
 {
-  int reg;
-
-  reg_or_fail (&str, 12, REG_TYPE_RN);
-  comma_or_fail (&str);
-
-  reg_or_fail (&str, 16, REG_TYPE_RN);
-  comma_or_fail (&str);
-
-  /* We require exactly two consecutive SP registers.  */
-  if (vfp_parse_reg_list (&str, &reg, 0) != 2)
+  if (parse_operands (str, OPERANDS3(RR,RR,VRSLST)))
+    return;
+  if (inst.operands[2].imm != 2)
     {
-      if (! inst.error)
-	inst.error = _("only two consecutive VFP SP registers allowed here");
+      inst.error = _("only two consecutive VFP SP registers allowed here");
+      return;
     }
-  vfp_sp_encode_reg (reg, VFP_REG_Sm);
 
-  end_of_line (str);
+  inst.instruction |= (inst.operands[0].reg << 12);
+  inst.instruction |= (inst.operands[1].reg << 16);
+  vfp_sp_encode_reg (inst.operands[2].reg, VFP_REG_Sm);
 }
 
 static void
@@ -7165,22 +7171,17 @@
 static void
 do_vfp_sp2_from_reg2 (char * str)
 {
-  int reg;
-
-  /* We require exactly two consecutive SP registers.  */
-  if (vfp_parse_reg_list (&str, &reg, 0) != 2)
+  if (parse_operands (str, OPERANDS3(VRSLST,RR,RR)))
+    return;
+  if (inst.operands[0].imm != 2)
     {
-      if (! inst.error)
-	inst.error = _("only two consecutive VFP SP registers allowed here");
+      inst.error = _("only two consecutive VFP SP registers allowed here");
+      return;
     }
-  vfp_sp_encode_reg (reg, VFP_REG_Sm);
-  comma_or_fail (&str);
 
-  reg_or_fail (&str, 12, REG_TYPE_RN);
-  comma_or_fail (&str);
-
-  reg_or_fail (&str, 16, REG_TYPE_RN);
-  end_of_line (str);
+  vfp_sp_encode_reg (inst.operands[0].reg, VFP_REG_Sm);
+  inst.instruction |= (inst.operands[1].reg << 12);
+  inst.instruction |= (inst.operands[2].reg << 16);
 }
 
 static void
@@ -7273,62 +7274,44 @@
 static void
 vfp_sp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
 {
-  int count;
-  int reg;
-
-  reg_or_fail (&str, 16, REG_TYPE_RN);
-
-  if (*str == '!')
-    {
-      inst.instruction |= WRITE_BACK;
-      str++;
-    }
+  if (parse_operands (str, OPERANDS2(RRw,VRSLST)))
+    return;
+  if (inst.operands[0].writeback)
+    inst.instruction |= WRITE_BACK;
   else if (ldstm_type != VFP_LDSTMIA)
     {
       inst.error = _("this addressing mode requires base-register writeback");
       return;
     }
 
-  comma_or_fail (&str);
-
-  if ((count = vfp_parse_reg_list (&str, &reg, 0)) == FAIL)
-    return;
-  end_of_line (str);
-
-  vfp_sp_encode_reg (reg, VFP_REG_Sd);
-  inst.instruction |= count;
+  inst.instruction |= inst.operands[0].reg << 16;
+  vfp_sp_encode_reg (inst.operands[1].reg, VFP_REG_Sd);
+  inst.instruction |= inst.operands[1].imm;
 }
 
 static void
 vfp_dp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
 {
   int count;
-  int reg;
 
-  reg_or_fail (&str, 16, REG_TYPE_RN);
-
-  if (*str == '!')
-    {
-      inst.instruction |= WRITE_BACK;
-      str++;
-    }
+  if (parse_operands (str, OPERANDS2(RRw,VRDLST)))
+    return;
+  if (inst.operands[0].writeback)
+    inst.instruction |= WRITE_BACK;
   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
     {
       inst.error = _("this addressing mode requires base-register writeback");
       return;
     }
 
-  comma_or_fail (&str);
+  inst.instruction |= inst.operands[0].reg << 16;
+  inst.instruction |= inst.operands[1].reg << 12;
 
-  if ((count = vfp_parse_reg_list (&str, &reg, 1)) == FAIL)
-    return;
-
-  count <<= 1;
+  count = inst.operands[1].imm << 1;
   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
     count += 1;
 
-  inst.instruction |= (reg << 12) | count;
-  end_of_line (str);
+  inst.instruction |= count;
 }
 
 static void

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