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


Flesh out RR_EX, and use it for BLX; add a "register or immediate
zero" code, and use it for BFI.

zw

	* config/tc-arm.c (thumb_reg): Simplify.  Use BAD_HIREG.
	(OP_RRnpc_I0): New operand parse code.
	(parse_operands): Implement it and OP_RR_EX.
	(do_bfi): Use parse_operands.
	(do_t_blx): Likewise.  Assume inst.instruction is preloaded
	with BLX(2).
	(tinsns): Preload opcode and size fields for blx with BLX(2).

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 32)
+++ gas/config/tc-arm.c	(revision 33)
@@ -1262,20 +1262,11 @@
   if ((reg = reg_required_here (strp, -1, REG_TYPE_RN)) == FAIL)
     return FAIL;
 
-  switch (hi_lo)
+  if (hi_lo == THUMB_REG_LO && reg > 7)
     {
-    case THUMB_REG_LO:
-      if (reg > 7)
-	{
-	  inst.error = _("lo register required");
-	  return FAIL;
-	}
-      break;
-
-    default:
-      break;
+      inst.error = BAD_HIREG;
+      return FAIL;
     }
-
   return reg;
 }
 
@@ -4352,6 +4343,7 @@
 /* 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 */
 
 /* Optional operands.  All have the high bit set.  */
 #define OP_obI7    200  /* optional, prefix optional, immediate 0 .. 7 */
@@ -4555,7 +4547,17 @@
 
 	  /* Register or expression */
 	case OP_(RR_EX):
-	  abort ();
+	  {
+	    int reg_ = arm_reg_parse (&str, REG_TYPE_RN);
+	    if (reg_ != FAIL)
+	      {
+		inst.operands[i].reg = reg_;
+		inst.operands[i].isreg = 1;
+	      }
+	    else if (my_get_expression (&inst.reloc.exp, &str))
+		return FAIL;
+	  }
+	  break;
 
 	case OP_(oRL_iEX):
 	case OP_(RL_iEX):
@@ -4573,6 +4575,22 @@
 	    }
 	  break;
 
+	  /* Register or immediate */
+	case OP_(RRnpc_I0):
+	  {
+	    int reg_ = arm_reg_parse (&str, REG_TYPE_RN);
+	    if (reg_ != FAIL)
+	      {
+		inst.operands[i].reg = reg_;
+		inst.operands[i].isreg = 1;
+		if (reg_ == REG_PC)
+		  inst.error = BAD_PC;
+	      }
+	    else
+	      po_imm_or_fail (0, 0, FALSE);
+	  }
+	  break;
+
 	  /* Misc */
 	case OP_(CPSF):
 	  if (parse_cps_flags (&inst.operands[i].imm, &str))
@@ -4746,36 +4764,16 @@
 static void
 do_bfi (char *str)
 {
-  int rm, lsb, width, msb;
+  unsigned int msb;
+  if (parse_operands (str, OPERANDS4(RRnpc,RRnpc_I0,I31,I32)))
+    return;
 
-  /* Rd.  */
-  reg_nonpc_or_fail (&str, 12);
-  comma_or_fail (&str);
+  /* #0 in second position is alternative syntax for bfc, which is
+     the same instruction but with REG_PC in the Rm field.  */
+  if (!inst.operands[1].isreg)
+    inst.operands[1].reg = REG_PC;
 
-  /* Rm.  Accept #0 in this position as an alternative syntax for bfc.  */
-  if ((rm = reg_required_here (&str, 0, REG_TYPE_RN)) == FAIL)
-    {
-      int dummy;
-
-      inst.error = 0;
-      if (immediate_required_here (&str, &dummy, 0, 0, FALSE) == FAIL)
-	return;
-      inst.instruction |= 0x0000000f;  /* Rm = PC -> bfc, not bfi.  */
-    }
-
-  if (rm == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
-
-  comma_or_fail (&str);
-  immediate_or_fail (&str, &lsb, 0, 31, FALSE);
-  comma_or_fail (&str);
-  immediate_or_fail (&str, &width, 1, 32, FALSE);
-  end_of_line (str);
-
-  msb = width + lsb;
+  msb = inst.operands[2].imm + inst.operands[3].imm;
   if (msb > 32)
     {
       inst.error = _("bit-field extends past end of register");
@@ -4784,7 +4782,9 @@
 
   /* The instruction encoding stores the LSB and MSB,
      not the LSB and width.  */
-  inst.instruction |= (lsb << 7);
+  inst.instruction |= (inst.operands[0].reg << 12);
+  inst.instruction |= (inst.operands[1].reg << 0);
+  inst.instruction |= (inst.operands[2].imm << 7);
   inst.instruction |= (msb - 1) << 16;
 }
 
@@ -6901,30 +6901,20 @@
 static void
 do_t_blx (char * str)
 {
-  int rm;
+  if (parse_operands (str, OPERANDS1(RR_EX)))
+    return;
 
-  /* BLX(2) can be applied to any integer register.  */
-  rm = thumb_reg (&str, THUMB_REG_ANY);
-
-  if (rm != FAIL)
-    {
-      /* We have a register, so this is BLX(2).  */
-      inst.instruction = 0x4780;
-      inst.size = 2;
-      inst.instruction |= (rm << 3);
-    }
+  if (inst.operands[0].isreg)
+    /* We have a register, so this is BLX(2).  */
+    inst.instruction |= (inst.operands[0].reg << 3);
   else
     {
       /* No register.  This must be BLX(1).  */
-      expression_or_fail (&inst.reloc.exp, &str);
-
       inst.instruction = 0xf7ffeffe;
       inst.size = 4;
       inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BLX;
       inst.reloc.pc_rel = 1;
     }
-
-  end_of_line (str);
 }
 
 static void
@@ -9987,7 +9977,7 @@
   {"adr",       0x000f,         2,      ARM_EXT_V4T, do_t_adr},
   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_empty}, /* mov r8,r8  */
   /* Thumb v2 (ARMv5T).  */
-  {"blx",	0,		0,	ARM_EXT_V5T, do_t_blx},
+  {"blx",	0x4780,		2,	ARM_EXT_V5T, do_t_blx},
   {"bkpt",	0xbe00,		2,	ARM_EXT_V5T, do_t_bkpt},
 
   /* ARM V6.  */

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