[ARM,4/16] BF insns infrastructure with array of relocs in struct arm_it

Message ID ba989ded-a8a4-534f-db20-b7ec9074a3d3@arm.com
State New
Headers show
Series
  • Add support for Armv8.1-M Mainline
Related show

Commit Message

Andre Vieira (lists) April 4, 2019, 1:34 p.m.
Hi

This patch is part of a series of patches to add support for ARMv8.1-M 
Mainline instructions to binutils.
This adds infrastructure for the Branch Future instructions (BF, BFX, 
BFL, BFLX, BFCSEL). These are the first instructions in ARM that
have more than one relocations in them. Their external relocations can 
be found in the 'ELF for the Arm Architecture - ABI 2019Q1' document on 
developer.arm.com (see 
https://developer.arm.com/docs/ihi0044/latest/elf-for-the-arm-architecture-abi-2019q1-documentation#aaelf32-table4-9)

This is the second infrastructure patch that adds support to allow up to 
3 relocations in an instruction. This is done by changing the
reloc member of struct arm_it to an array instead (relocs[3]). All the 
previous occurrences of reloc can now to referring to relocs[0].

Testing: Builds successfully and no regressions.

Thanks
Sudi


ChangeLog entries are as follows :

*** gas/ChangeLog ***

2019-04-04  Sudakshina Das  <sudi.das@arm.com>

	* config/tc-arm.c (ARM_IT_MAX_RELOCS): New macro.
	(arm_it): Member reloc renamed relocs and updated to an array.
	Rest: Replace all occurrences of reloc to relocs[0].

Patch

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index a13baa603486623836977d4c8f68ac283d02cbab..14d114adbeec62b11fa3bc7d4f7cb3cdd030bf8f 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -463,6 +463,7 @@  enum it_instruction_type
 
 /* The maximum number of operands we need.  */
 #define ARM_IT_MAX_OPERANDS 6
+#define ARM_IT_MAX_RELOCS 3
 
 struct arm_it
 {
@@ -487,7 +488,7 @@  struct arm_it
     bfd_reloc_code_real_type type;
     expressionS		     exp;
     int			     pc_rel;
-  } reloc;
+  } relocs[ARM_IT_MAX_RELOCS];
 
   enum it_instruction_type it_insn_type;
 
@@ -1791,15 +1792,15 @@  parse_reg_list (char ** strp)
 	    }
 	  else
 	    {
-	      if (inst.reloc.type != 0)
+	      if (inst.relocs[0].type != 0)
 		{
 		  inst.error = _("expression too complex");
 		  return FAIL;
 		}
 
-	      memcpy (&inst.reloc.exp, &exp, sizeof (expressionS));
-	      inst.reloc.type = BFD_RELOC_ARM_MULTI;
-	      inst.reloc.pc_rel = 0;
+	      memcpy (&inst.relocs[0].exp, &exp, sizeof (expressionS));
+	      inst.relocs[0].type = BFD_RELOC_ARM_MULTI;
+	      inst.relocs[0].pc_rel = 0;
 	    }
 	}
 
@@ -3249,7 +3250,7 @@  add_to_lit_pool (unsigned int nbytes)
     {
       imm1 = inst.operands[1].imm;
       imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
-	       : inst.reloc.exp.X_unsigned ? 0
+	       : inst.relocs[0].exp.X_unsigned ? 0
 	       : ((bfd_int64_t) inst.operands[1].imm) >> 32);
       if (target_big_endian)
 	{
@@ -3265,23 +3266,23 @@  add_to_lit_pool (unsigned int nbytes)
     {
       if (nbytes == 4)
 	{
-	  if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
-	      && (inst.reloc.exp.X_op == O_constant)
+	  if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
+	      && (inst.relocs[0].exp.X_op == O_constant)
 	      && (pool->literals[entry].X_add_number
-		  == inst.reloc.exp.X_add_number)
+		  == inst.relocs[0].exp.X_add_number)
 	      && (pool->literals[entry].X_md == nbytes)
 	      && (pool->literals[entry].X_unsigned
-		  == inst.reloc.exp.X_unsigned))
+		  == inst.relocs[0].exp.X_unsigned))
 	    break;
 
-	  if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
-	      && (inst.reloc.exp.X_op == O_symbol)
+	  if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
+	      && (inst.relocs[0].exp.X_op == O_symbol)
 	      && (pool->literals[entry].X_add_number
-		  == inst.reloc.exp.X_add_number)
+		  == inst.relocs[0].exp.X_add_number)
 	      && (pool->literals[entry].X_add_symbol
-		  == inst.reloc.exp.X_add_symbol)
+		  == inst.relocs[0].exp.X_add_symbol)
 	      && (pool->literals[entry].X_op_symbol
-		  == inst.reloc.exp.X_op_symbol)
+		  == inst.relocs[0].exp.X_op_symbol)
 	      && (pool->literals[entry].X_md == nbytes))
 	    break;
 	}
@@ -3291,11 +3292,11 @@  add_to_lit_pool (unsigned int nbytes)
 	       && (pool->literals[entry].X_op == O_constant)
 	       && (pool->literals[entry].X_add_number == (offsetT) imm1)
 	       && (pool->literals[entry].X_unsigned
-		   == inst.reloc.exp.X_unsigned)
+		   == inst.relocs[0].exp.X_unsigned)
 	       && (pool->literals[entry + 1].X_op == O_constant)
 	       && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
 	       && (pool->literals[entry + 1].X_unsigned
-		   == inst.reloc.exp.X_unsigned))
+		   == inst.relocs[0].exp.X_unsigned))
 	break;
 
       padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
@@ -3327,8 +3328,8 @@  add_to_lit_pool (unsigned int nbytes)
 
 	     We also check to make sure the literal operand is a
 	     constant number.  */
-	  if (!(inst.reloc.exp.X_op == O_constant
-	        || inst.reloc.exp.X_op == O_big))
+	  if (!(inst.relocs[0].exp.X_op == O_constant
+		|| inst.relocs[0].exp.X_op == O_big))
 	    {
 	      inst.error = _("invalid type for literal pool");
 	      return FAIL;
@@ -3341,7 +3342,7 @@  add_to_lit_pool (unsigned int nbytes)
 		  return FAIL;
 		}
 
-	      pool->literals[entry] = inst.reloc.exp;
+	      pool->literals[entry] = inst.relocs[0].exp;
 	      pool->literals[entry].X_op = O_constant;
 	      pool->literals[entry].X_add_number = 0;
 	      pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
@@ -3354,22 +3355,22 @@  add_to_lit_pool (unsigned int nbytes)
 	      return FAIL;
 	    }
 
-	  pool->literals[entry] = inst.reloc.exp;
+	  pool->literals[entry] = inst.relocs[0].exp;
 	  pool->literals[entry].X_op = O_constant;
 	  pool->literals[entry].X_add_number = imm1;
-	  pool->literals[entry].X_unsigned = inst.reloc.exp.X_unsigned;
+	  pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
 	  pool->literals[entry++].X_md = 4;
-	  pool->literals[entry] = inst.reloc.exp;
+	  pool->literals[entry] = inst.relocs[0].exp;
 	  pool->literals[entry].X_op = O_constant;
 	  pool->literals[entry].X_add_number = imm2;
-	  pool->literals[entry].X_unsigned = inst.reloc.exp.X_unsigned;
+	  pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
 	  pool->literals[entry].X_md = 4;
 	  pool->alignment = 3;
 	  pool->next_free_entry += 1;
 	}
       else
 	{
-	  pool->literals[entry] = inst.reloc.exp;
+	  pool->literals[entry] = inst.relocs[0].exp;
 	  pool->literals[entry].X_md = 4;
 	}
 
@@ -3385,13 +3386,13 @@  add_to_lit_pool (unsigned int nbytes)
     }
   else if (padding_slot_p)
     {
-      pool->literals[entry] = inst.reloc.exp;
+      pool->literals[entry] = inst.relocs[0].exp;
       pool->literals[entry].X_md = nbytes;
     }
 
-  inst.reloc.exp.X_op	      = O_symbol;
-  inst.reloc.exp.X_add_number = pool_size;
-  inst.reloc.exp.X_add_symbol = pool->symbol;
+  inst.relocs[0].exp.X_op	      = O_symbol;
+  inst.relocs[0].exp.X_add_number = pool_size;
+  inst.relocs[0].exp.X_add_symbol = pool->symbol;
 
   return SUCCESS;
 }
@@ -5212,7 +5213,7 @@  parse_shift (char **str, int i, enum parse_shift_mode mode)
 	  inst.operands[i].imm = reg;
 	  inst.operands[i].immisreg = 1;
 	}
-      else if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+      else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
 	return FAIL;
     }
   inst.operands[i].shift_kind = shift;
@@ -5244,8 +5245,8 @@  parse_shifter_operand (char **str, int i)
       inst.operands[i].isreg = 1;
 
       /* parse_shift will override this if appropriate */
-      inst.reloc.exp.X_op = O_constant;
-      inst.reloc.exp.X_add_number = 0;
+      inst.relocs[0].exp.X_op = O_constant;
+      inst.relocs[0].exp.X_add_number = 0;
 
       if (skip_past_comma (str) == FAIL)
 	return SUCCESS;
@@ -5254,7 +5255,7 @@  parse_shifter_operand (char **str, int i)
       return parse_shift (str, i, NO_SHIFT_RESTRICT);
     }
 
-  if (my_get_expression (&inst.reloc.exp, str, GE_IMM_PREFIX))
+  if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
     return FAIL;
 
   if (skip_past_comma (str) == SUCCESS)
@@ -5263,7 +5264,7 @@  parse_shifter_operand (char **str, int i)
       if (my_get_expression (&exp, str, GE_NO_PREFIX))
 	return FAIL;
 
-      if (exp.X_op != O_constant || inst.reloc.exp.X_op != O_constant)
+      if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
 	{
 	  inst.error = _("constant expression expected");
 	  return FAIL;
@@ -5275,19 +5276,20 @@  parse_shifter_operand (char **str, int i)
 	  inst.error = _("invalid rotation");
 	  return FAIL;
 	}
-      if (inst.reloc.exp.X_add_number < 0 || inst.reloc.exp.X_add_number > 255)
+      if (inst.relocs[0].exp.X_add_number < 0
+	  || inst.relocs[0].exp.X_add_number > 255)
 	{
 	  inst.error = _("invalid constant");
 	  return FAIL;
 	}
 
       /* Encode as specified.  */
-      inst.operands[i].imm = inst.reloc.exp.X_add_number | value << 7;
+      inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
       return SUCCESS;
     }
 
-  inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
-  inst.reloc.pc_rel = 0;
+  inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
+  inst.relocs[0].pc_rel = 0;
   return SUCCESS;
 }
 
@@ -5458,12 +5460,12 @@  parse_shifter_operand_group_reloc (char **str, int i)
 
       /* We now have the group relocation table entry corresponding to
 	 the name in the assembler source.  Next, we parse the expression.  */
-      if (my_get_expression (&inst.reloc.exp, str, GE_NO_PREFIX))
+      if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
 	return PARSE_OPERAND_FAIL_NO_BACKTRACK;
 
       /* Record the relocation type (always the ALU variant here).  */
-      inst.reloc.type = (bfd_reloc_code_real_type) entry->alu_code;
-      gas_assert (inst.reloc.type != 0);
+      inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
+      gas_assert (inst.relocs[0].type != 0);
 
       return PARSE_OPERAND_SUCCESS;
     }
@@ -5502,23 +5504,23 @@  parse_neon_alignment (char **str, int i)
 }
 
 /* Parse all forms of an ARM address expression.  Information is written
-   to inst.operands[i] and/or inst.reloc.
+   to inst.operands[i] and/or inst.relocs[0].
 
    Preindexed addressing (.preind=1):
 
-   [Rn, #offset]       .reg=Rn .reloc.exp=offset
+   [Rn, #offset]       .reg=Rn .relocs[0].exp=offset
    [Rn, +/-Rm]	       .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
    [Rn, +/-Rm, shift]  .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
-		       .shift_kind=shift .reloc.exp=shift_imm
+		       .shift_kind=shift .relocs[0].exp=shift_imm
 
    These three may have a trailing ! which causes .writeback to be set also.
 
    Postindexed addressing (.postind=1, .writeback=1):
 
-   [Rn], #offset       .reg=Rn .reloc.exp=offset
+   [Rn], #offset       .reg=Rn .relocs[0].exp=offset
    [Rn], +/-Rm	       .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
    [Rn], +/-Rm, shift  .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
-		       .shift_kind=shift .reloc.exp=shift_imm
+		       .shift_kind=shift .relocs[0].exp=shift_imm
 
    Unindexed addressing (.preind=0, .postind=0):
 
@@ -5527,11 +5529,11 @@  parse_neon_alignment (char **str, int i)
    Other:
 
    [Rn]{!}	       shorthand for [Rn,#0]{!}
-   =immediate	       .isreg=0 .reloc.exp=immediate
-   label	       .reg=PC .reloc.pc_rel=1 .reloc.exp=label
+   =immediate	       .isreg=0 .relocs[0].exp=immediate
+   label	       .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
 
   It is the caller's responsibility to check for addressing modes not
-  supported by the instruction, and to set inst.reloc.type.  */
+  supported by the instruction, and to set inst.relocs[0].type.  */
 
 static parse_operand_result
 parse_address_main (char **str, int i, int group_relocations,
@@ -5545,15 +5547,15 @@  parse_address_main (char **str, int i, int group_relocations,
       if (skip_past_char (&p, '=') == FAIL)
 	{
 	  /* Bare address - translate to PC-relative offset.  */
-	  inst.reloc.pc_rel = 1;
+	  inst.relocs[0].pc_rel = 1;
 	  inst.operands[i].reg = REG_PC;
 	  inst.operands[i].isreg = 1;
 	  inst.operands[i].preind = 1;
 
-	  if (my_get_expression (&inst.reloc.exp, &p, GE_OPT_PREFIX_BIG))
+	  if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
 	    return PARSE_OPERAND_FAIL;
 	}
-      else if (parse_big_immediate (&p, i, &inst.reloc.exp,
+      else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
 				    /*allow_symbol_p=*/TRUE))
 	return PARSE_OPERAND_FAIL;
 
@@ -5628,29 +5630,32 @@  parse_address_main (char **str, int i, int group_relocations,
 	      /* We now have the group relocation table entry corresponding to
 		 the name in the assembler source.  Next, we parse the
 		 expression.  */
-	      if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
+	      if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
 		return PARSE_OPERAND_FAIL_NO_BACKTRACK;
 
 	      /* Record the relocation type.  */
 	      switch (group_type)
 		{
 		  case GROUP_LDR:
-		    inst.reloc.type = (bfd_reloc_code_real_type) entry->ldr_code;
+		    inst.relocs[0].type
+			= (bfd_reloc_code_real_type) entry->ldr_code;
 		    break;
 
 		  case GROUP_LDRS:
-		    inst.reloc.type = (bfd_reloc_code_real_type) entry->ldrs_code;
+		    inst.relocs[0].type
+			= (bfd_reloc_code_real_type) entry->ldrs_code;
 		    break;
 
 		  case GROUP_LDC:
-		    inst.reloc.type = (bfd_reloc_code_real_type) entry->ldc_code;
+		    inst.relocs[0].type
+			= (bfd_reloc_code_real_type) entry->ldc_code;
 		    break;
 
 		  default:
 		    gas_assert (0);
 		}
 
-	      if (inst.reloc.type == 0)
+	      if (inst.relocs[0].type == 0)
 		{
 		  inst.error = _("this group relocation is not allowed on this instruction");
 		  return PARSE_OPERAND_FAIL_NO_BACKTRACK;
@@ -5660,11 +5665,11 @@  parse_address_main (char **str, int i, int group_relocations,
 	    {
 	      char *q = p;
 
-	      if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+	      if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
 		return PARSE_OPERAND_FAIL;
 	      /* If the offset is 0, find out if it's a +0 or -0.  */
-	      if (inst.reloc.exp.X_op == O_constant
-		  && inst.reloc.exp.X_add_number == 0)
+	      if (inst.relocs[0].exp.X_op == O_constant
+		  && inst.relocs[0].exp.X_add_number == 0)
 		{
 		  skip_whitespace (q);
 		  if (*q == '#')
@@ -5756,11 +5761,11 @@  parse_address_main (char **str, int i, int group_relocations,
 		  inst.operands[i].negative = 0;
 		  p--;
 		}
-	      if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+	      if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
 		return PARSE_OPERAND_FAIL;
 	      /* If the offset is 0, find out if it's a +0 or -0.  */
-	      if (inst.reloc.exp.X_op == O_constant
-		  && inst.reloc.exp.X_add_number == 0)
+	      if (inst.relocs[0].exp.X_op == O_constant
+		  && inst.relocs[0].exp.X_add_number == 0)
 		{
 		  skip_whitespace (q);
 		  if (*q == '#')
@@ -5780,8 +5785,8 @@  parse_address_main (char **str, int i, int group_relocations,
   if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
     {
       inst.operands[i].preind = 1;
-      inst.reloc.exp.X_op = O_constant;
-      inst.reloc.exp.X_add_number = 0;
+      inst.relocs[0].exp.X_op = O_constant;
+      inst.relocs[0].exp.X_add_number = 0;
     }
   *str = p;
   return PARSE_OPERAND_SUCCESS;
@@ -5809,28 +5814,28 @@  parse_half (char **str)
   p = *str;
   skip_past_char (&p, '#');
   if (strncasecmp (p, ":lower16:", 9) == 0)
-    inst.reloc.type = BFD_RELOC_ARM_MOVW;
+    inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
   else if (strncasecmp (p, ":upper16:", 9) == 0)
-    inst.reloc.type = BFD_RELOC_ARM_MOVT;
+    inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
 
-  if (inst.reloc.type != BFD_RELOC_UNUSED)
+  if (inst.relocs[0].type != BFD_RELOC_UNUSED)
     {
       p += 9;
       skip_whitespace (p);
     }
 
-  if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
+  if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
     return FAIL;
 
-  if (inst.reloc.type == BFD_RELOC_UNUSED)
+  if (inst.relocs[0].type == BFD_RELOC_UNUSED)
     {
-      if (inst.reloc.exp.X_op != O_constant)
+      if (inst.relocs[0].exp.X_op != O_constant)
 	{
 	  inst.error = _("constant expression expected");
 	  return FAIL;
 	}
-      if (inst.reloc.exp.X_add_number < 0
-	  || inst.reloc.exp.X_add_number > 0xffff)
+      if (inst.relocs[0].exp.X_add_number < 0
+	  || inst.relocs[0].exp.X_add_number > 0xffff)
 	{
 	  inst.error = _("immediate value out of range");
 	  return FAIL;
@@ -6257,7 +6262,7 @@  parse_tb (char **str)
     {
       if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
 	return FAIL;
-      if (inst.reloc.exp.X_add_number != 1)
+      if (inst.relocs[0].exp.X_add_number != 1)
 	{
 	  inst.error = _("invalid shift");
 	  return FAIL;
@@ -6587,6 +6592,7 @@  enum operand_parse_code
   OP_EXP,	/* arbitrary expression */
   OP_EXPi,	/* same, with optional immediate prefix */
   OP_EXPr,	/* same, with optional relocation suffix */
+  OP_EXPs,	/* same, with optional non-first operand relocation suffix */
   OP_HALF,	/* 0 .. 65535 or low/high reloc.  */
   OP_IROT1,	/* VCADD rotate immediate: 90, 270.  */
   OP_IROT2,	/* VCMLA rotate immediate: 0, 90, 180, 270.  */
@@ -6995,19 +7001,19 @@  parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 
 	  /* Expressions */
 	case OP_EXPi:	EXPi:
-	  po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
+	  po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
 					      GE_OPT_PREFIX));
 	  break;
 
 	case OP_EXP:
-	  po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
+	  po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
 					      GE_NO_PREFIX));
 	  break;
 
 	case OP_EXPr:	EXPr:
-	  po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
+	  po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
 					      GE_NO_PREFIX));
-	  if (inst.reloc.exp.X_op == O_symbol)
+	  if (inst.relocs[0].exp.X_op == O_symbol)
 	    {
 	      val = parse_reloc (&str);
 	      if (val == -1)
@@ -7023,6 +7029,20 @@  parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	    }
 	  break;
 
+	case OP_EXPs:
+	  po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
+					      GE_NO_PREFIX));
+	  if (inst.relocs[i].exp.X_op == O_symbol)
+	    {
+	      inst.operands[i].hasreloc = 1;
+	    }
+	  else if (inst.relocs[i].exp.X_op == O_constant)
+	    {
+	      inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
+	      inst.operands[i].hasreloc = 0;
+	    }
+	  break;
+
 	  /* Operand for MOVW or MOVT.  */
 	case OP_HALF:
 	  po_misc_or_fail (parse_half (&str));
@@ -7543,7 +7563,7 @@  encode_arm_shift (int i)
 	  inst.instruction |= inst.operands[i].imm << 8;
 	}
       else
-	inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+	inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
     }
 }
 
@@ -7558,7 +7578,7 @@  encode_arm_shifter_operand (int i)
   else
     {
       inst.instruction |= INST_IMMEDIATE;
-      if (inst.reloc.type != BFD_RELOC_ARM_IMMEDIATE)
+      if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
 	inst.instruction |= inst.operands[i].imm;
     }
 }
@@ -7633,13 +7653,13 @@  encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
 	  else
 	    {
 	      inst.instruction |= inst.operands[i].shift_kind << 5;
-	      inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+	      inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
 	    }
 	}
     }
-  else /* immediate offset in inst.reloc */
+  else /* immediate offset in inst.relocs[0] */
     {
-      if (is_pc && !inst.reloc.pc_rel)
+      if (is_pc && !inst.relocs[0].pc_rel)
 	{
 	  const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
 
@@ -7656,12 +7676,12 @@  encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
 	    as_tsktsk (_("use of PC in this instruction is deprecated"));
 	}
 
-      if (inst.reloc.type == BFD_RELOC_UNUSED)
+      if (inst.relocs[0].type == BFD_RELOC_UNUSED)
 	{
 	  /* Prefer + for zero encoded value.  */
 	  if (!inst.operands[i].negative)
 	    inst.instruction |= INDEX_UP;
-	  inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
+	  inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
 	}
     }
 }
@@ -7693,19 +7713,19 @@  encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
       if (!inst.operands[i].negative)
 	inst.instruction |= INDEX_UP;
     }
-  else /* immediate offset in inst.reloc */
+  else /* immediate offset in inst.relocs[0] */
     {
-      constraint ((inst.operands[i].reg == REG_PC && !inst.reloc.pc_rel
+      constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
 		   && inst.operands[i].writeback),
 		  BAD_PC_WRITEBACK);
       inst.instruction |= HWOFFSET_IMM;
-      if (inst.reloc.type == BFD_RELOC_UNUSED)
+      if (inst.relocs[0].type == BFD_RELOC_UNUSED)
 	{
 	  /* Prefer + for zero encoded value.  */
 	  if (!inst.operands[i].negative)
 	    inst.instruction |= INDEX_UP;
 
-	  inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
+	  inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
 	}
     }
 }
@@ -7958,7 +7978,7 @@  enum lit_type
 
 static void do_vfp_nsyn_opcode (const char *);
 
-/* inst.reloc.exp describes an "=expr" load pseudo-operation.
+/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
    Determine whether it can be performed with a move instruction; if
    it can, convert inst.instruction to that move instruction and
    return TRUE; if it can't, convert inst.instruction to a literal-pool
@@ -7985,28 +8005,28 @@  move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
       return TRUE;
     }
 
-  if (inst.reloc.exp.X_op != O_constant
-      && inst.reloc.exp.X_op != O_symbol
-      && inst.reloc.exp.X_op != O_big)
+  if (inst.relocs[0].exp.X_op != O_constant
+      && inst.relocs[0].exp.X_op != O_symbol
+      && inst.relocs[0].exp.X_op != O_big)
     {
       inst.error = _("constant expression expected");
       return TRUE;
     }
 
-  if (inst.reloc.exp.X_op == O_constant
-      || inst.reloc.exp.X_op == O_big)
+  if (inst.relocs[0].exp.X_op == O_constant
+      || inst.relocs[0].exp.X_op == O_big)
     {
 #if defined BFD_HOST_64_BIT
       bfd_int64_t v;
 #else
       offsetT v;
 #endif
-      if (inst.reloc.exp.X_op == O_big)
+      if (inst.relocs[0].exp.X_op == O_big)
 	{
 	  LITTLENUM_TYPE w[X_PRECISION];
 	  LITTLENUM_TYPE * l;
 
-	  if (inst.reloc.exp.X_add_number == -1)
+	  if (inst.relocs[0].exp.X_add_number == -1)
 	    {
 	      gen_to_words (w, X_PRECISION, E_PRECISION);
 	      l = w;
@@ -8030,7 +8050,7 @@  move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
 #endif
 	}
       else
-	v = inst.reloc.exp.X_add_number;
+	v = inst.relocs[0].exp.X_add_number;
 
       if (!inst.operands[i].issingle)
 	{
@@ -8119,7 +8139,7 @@  move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
 	      unsigned immlo = inst.operands[1].imm;
 	      unsigned immhi = inst.operands[1].regisimm
 		? inst.operands[1].reg
-		: inst.reloc.exp.X_unsigned
+		: inst.relocs[0].exp.X_unsigned
 		? 0
 		: ((bfd_int64_t)((int) immlo)) >> 32;
 	      int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
@@ -8194,8 +8214,8 @@  move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
   inst.operands[1].reg = REG_PC;
   inst.operands[1].isreg = 1;
   inst.operands[1].preind = 1;
-  inst.reloc.pc_rel = 1;
-  inst.reloc.type = (thumb_p
+  inst.relocs[0].pc_rel = 1;
+  inst.relocs[0].type = (thumb_p
 		     ? BFD_RELOC_ARM_THUMB_OFFSET
 		     : (mode_3
 			? BFD_RELOC_ARM_HWLITERAL
@@ -8262,15 +8282,15 @@  encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
     }
 
   if (reloc_override)
-    inst.reloc.type = (bfd_reloc_code_real_type) reloc_override;
-  else if ((inst.reloc.type < BFD_RELOC_ARM_ALU_PC_G0_NC
-	    || inst.reloc.type > BFD_RELOC_ARM_LDC_SB_G2)
-	   && inst.reloc.type != BFD_RELOC_ARM_LDR_PC_G0)
+    inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
+  else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
+	    || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
+	   && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
     {
       if (thumb_mode)
-	inst.reloc.type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
+	inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
       else
-	inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+	inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
     }
 
   /* Prefer + for zero encoded value.  */
@@ -8389,9 +8409,9 @@  static void
 do_rm_rd_rn (void)
 {
   constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
-  constraint (((inst.reloc.exp.X_op != O_constant
-		&& inst.reloc.exp.X_op != O_illegal)
-	       || inst.reloc.exp.X_add_number != 0),
+  constraint (((inst.relocs[0].exp.X_op != O_constant
+		&& inst.relocs[0].exp.X_op != O_illegal)
+	       || inst.relocs[0].exp.X_add_number != 0),
 	      BAD_ADDR_MODE);
   inst.instruction |= inst.operands[0].reg;
   inst.instruction |= inst.operands[1].reg << 12;
@@ -8425,16 +8445,16 @@  do_adr (void)
 
   /* Frag hacking will turn this into a sub instruction if the offset turns
      out to be negative.  */
-  inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
-  inst.reloc.pc_rel = 1;
-  inst.reloc.exp.X_add_number -= 8;
+  inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
+  inst.relocs[0].pc_rel = 1;
+  inst.relocs[0].exp.X_add_number -= 8;
 
   if (support_interwork
-      && inst.reloc.exp.X_op == O_symbol
-      && inst.reloc.exp.X_add_symbol != NULL
-      && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
-      && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
-    inst.reloc.exp.X_add_number |= 1;
+      && inst.relocs[0].exp.X_op == O_symbol
+      && inst.relocs[0].exp.X_add_symbol != NULL
+      && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
+      && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
+    inst.relocs[0].exp.X_add_number |= 1;
 }
 
 /* This is a pseudo-op of the form "adrl rd, label" to be converted
@@ -8449,24 +8469,24 @@  do_adrl (void)
 
   /* Frag hacking will turn this into a sub instruction if the offset turns
      out to be negative.  */
-  inst.reloc.type	       = BFD_RELOC_ARM_ADRL_IMMEDIATE;
-  inst.reloc.pc_rel	       = 1;
+  inst.relocs[0].type	       = BFD_RELOC_ARM_ADRL_IMMEDIATE;
+  inst.relocs[0].pc_rel	       = 1;
   inst.size		       = INSN_SIZE * 2;
-  inst.reloc.exp.X_add_number -= 8;
+  inst.relocs[0].exp.X_add_number -= 8;
 
   if (support_interwork
-      && inst.reloc.exp.X_op == O_symbol
-      && inst.reloc.exp.X_add_symbol != NULL
-      && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
-      && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
-    inst.reloc.exp.X_add_number |= 1;
+      && inst.relocs[0].exp.X_op == O_symbol
+      && inst.relocs[0].exp.X_add_symbol != NULL
+      && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
+      && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
+    inst.relocs[0].exp.X_add_number |= 1;
 }
 
 static void
 do_arit (void)
 {
-  constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
-	      && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+  constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+	      && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
 	      THUMB1_RELOC_ONLY);
   if (!inst.operands[1].present)
     inst.operands[1].reg = inst.operands[0].reg;
@@ -8551,13 +8571,13 @@  encode_branch (int default_reloc)
       constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
 		  && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
 		  _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
-      inst.reloc.type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
+      inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
 	? BFD_RELOC_ARM_PLT32
 	: thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
     }
   else
-    inst.reloc.type = (bfd_reloc_code_real_type) default_reloc;
-  inst.reloc.pc_rel = 1;
+    inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
+  inst.relocs[0].pc_rel = 1;
 }
 
 static void
@@ -8641,7 +8661,7 @@  do_bx (void)
     want_reloc = FALSE;
 
   if (want_reloc)
-    inst.reloc.type = BFD_RELOC_ARM_V4BX;
+    inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
 }
 
 
@@ -9010,15 +9030,15 @@  do_ldrex (void)
 	      || (inst.operands[1].reg == REG_PC),
 	      BAD_ADDR_MODE);
 
-  constraint (inst.reloc.exp.X_op != O_constant
-	      || inst.reloc.exp.X_add_number != 0,
+  constraint (inst.relocs[0].exp.X_op != O_constant
+	      || inst.relocs[0].exp.X_add_number != 0,
 	      _("offset must be zero in ARM encoding"));
 
   constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
 
   inst.instruction |= inst.operands[0].reg << 12;
   inst.instruction |= inst.operands[1].reg << 16;
-  inst.reloc.type = BFD_RELOC_UNUSED;
+  inst.relocs[0].type = BFD_RELOC_UNUSED;
 }
 
 static void
@@ -9045,7 +9065,7 @@  check_ldr_r15_aligned (void)
   constraint (!(inst.operands[1].immisreg)
 	      && (inst.operands[0].reg == REG_PC
 	      && inst.operands[1].reg == REG_PC
-	      && (inst.reloc.exp.X_add_number & 0x3)),
+	      && (inst.relocs[0].exp.X_add_number & 0x3)),
 	      _("ldr to register 15 must be 4-byte aligned"));
 }
 
@@ -9067,8 +9087,8 @@  do_ldstt (void)
      reject [Rn,...].  */
   if (inst.operands[1].preind)
     {
-      constraint (inst.reloc.exp.X_op != O_constant
-		  || inst.reloc.exp.X_add_number != 0,
+      constraint (inst.relocs[0].exp.X_op != O_constant
+		  || inst.relocs[0].exp.X_add_number != 0,
 		  _("this instruction requires a post-indexed address"));
 
       inst.operands[1].preind = 0;
@@ -9099,8 +9119,8 @@  do_ldsttv4 (void)
      reject [Rn,...].  */
   if (inst.operands[1].preind)
     {
-      constraint (inst.reloc.exp.X_op != O_constant
-		  || inst.reloc.exp.X_add_number != 0,
+      constraint (inst.relocs[0].exp.X_op != O_constant
+		  || inst.relocs[0].exp.X_add_number != 0,
 		  _("this instruction requires a post-indexed address"));
 
       inst.operands[1].preind = 0;
@@ -9139,8 +9159,8 @@  do_mlas (void)
 static void
 do_mov (void)
 {
-  constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
-	      && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+  constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+	      && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
 	      THUMB1_RELOC_ONLY);
   inst.instruction |= inst.operands[0].reg << 12;
   encode_arm_shifter_operand (1);
@@ -9154,14 +9174,14 @@  do_mov16 (void)
   bfd_boolean top;
 
   top = (inst.instruction & 0x00400000) != 0;
-  constraint (top && inst.reloc.type == BFD_RELOC_ARM_MOVW,
+  constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
 	      _(":lower16: not allowed in this instruction"));
-  constraint (!top && inst.reloc.type == BFD_RELOC_ARM_MOVT,
+  constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
 	      _(":upper16: not allowed in this instruction"));
   inst.instruction |= inst.operands[0].reg << 12;
-  if (inst.reloc.type == BFD_RELOC_UNUSED)
+  if (inst.relocs[0].type == BFD_RELOC_UNUSED)
     {
-      imm = inst.reloc.exp.X_add_number;
+      imm = inst.relocs[0].exp.X_add_number;
       /* The value is in two pieces: 0:11, 16:19.  */
       inst.instruction |= (imm & 0x00000fff);
       inst.instruction |= (imm & 0x0000f000) << 4;
@@ -9296,8 +9316,8 @@  do_msr (void)
   else
     {
       inst.instruction |= INST_IMMEDIATE;
-      inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
-      inst.reloc.pc_rel = 0;
+      inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
+      inst.relocs[0].pc_rel = 0;
     }
 }
 
@@ -9537,28 +9557,28 @@  do_shift (void)
 		  _("extraneous shift as part of operand to shift insn"));
     }
   else
-    inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+    inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
 }
 
 static void
 do_smc (void)
 {
-  inst.reloc.type = BFD_RELOC_ARM_SMC;
-  inst.reloc.pc_rel = 0;
+  inst.relocs[0].type = BFD_RELOC_ARM_SMC;
+  inst.relocs[0].pc_rel = 0;
 }
 
 static void
 do_hvc (void)
 {
-  inst.reloc.type = BFD_RELOC_ARM_HVC;
-  inst.reloc.pc_rel = 0;
+  inst.relocs[0].type = BFD_RELOC_ARM_HVC;
+  inst.relocs[0].pc_rel = 0;
 }
 
 static void
 do_swi (void)
 {
-  inst.reloc.type = BFD_RELOC_ARM_SWI;
-  inst.reloc.pc_rel = 0;
+  inst.relocs[0].type = BFD_RELOC_ARM_SWI;
+  inst.relocs[0].pc_rel = 0;
 }
 
 static void
@@ -9660,14 +9680,14 @@  do_strex (void)
   constraint (inst.operands[0].reg == inst.operands[1].reg
 	      || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
 
-  constraint (inst.reloc.exp.X_op != O_constant
-	      || inst.reloc.exp.X_add_number != 0,
+  constraint (inst.relocs[0].exp.X_op != O_constant
+	      || inst.relocs[0].exp.X_add_number != 0,
 	      _("offset must be zero in ARM encoding"));
 
   inst.instruction |= inst.operands[0].reg << 12;
   inst.instruction |= inst.operands[1].reg;
   inst.instruction |= inst.operands[2].reg << 16;
-  inst.reloc.type = BFD_RELOC_UNUSED;
+  inst.relocs[0].type = BFD_RELOC_UNUSED;
 }
 
 static void
@@ -10054,15 +10074,15 @@  do_fpa_ldmstm (void)
 	 [Rn]{!}.  The instruction does not really support stacking or
 	 unstacking, so we have to emulate these by setting appropriate
 	 bits and offsets.  */
-      constraint (inst.reloc.exp.X_op != O_constant
-		  || inst.reloc.exp.X_add_number != 0,
+      constraint (inst.relocs[0].exp.X_op != O_constant
+		  || inst.relocs[0].exp.X_add_number != 0,
 		  _("this instruction does not support indexing"));
 
       if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
-	inst.reloc.exp.X_add_number = 12 * inst.operands[1].imm;
+	inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
 
       if (!(inst.instruction & INDEX_UP))
-	inst.reloc.exp.X_add_number = -inst.reloc.exp.X_add_number;
+	inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
 
       if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
 	{
@@ -10182,7 +10202,7 @@  do_iwmmxt_wldstd (void)
       if (inst.operands[1].writeback)
 	inst.instruction |= WRITE_BACK;
       inst.instruction |= inst.operands[1].reg << 16;
-      inst.instruction |= inst.reloc.exp.X_add_number << 4;
+      inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
       inst.instruction |= inst.operands[1].imm;
     }
   else
@@ -10354,7 +10374,7 @@  do_xsc_mra (void)
 static void
 encode_thumb32_shifted_operand (int i)
 {
-  unsigned int value = inst.reloc.exp.X_add_number;
+  unsigned int value = inst.relocs[0].exp.X_add_number;
   unsigned int shift = inst.operands[i].shift_kind;
 
   constraint (inst.operands[i].immisreg,
@@ -10364,7 +10384,7 @@  encode_thumb32_shifted_operand (int i)
     inst.instruction |= SHIFT_ROR << 4;
   else
     {
-      constraint (inst.reloc.exp.X_op != O_constant,
+      constraint (inst.relocs[0].exp.X_op != O_constant,
 		  _("expression too complex"));
 
       constraint (value > 32
@@ -10416,14 +10436,14 @@  encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
       inst.instruction |= inst.operands[i].imm;
       if (inst.operands[i].shifted)
 	{
-	  constraint (inst.reloc.exp.X_op != O_constant,
+	  constraint (inst.relocs[0].exp.X_op != O_constant,
 		      _("expression too complex"));
-	  constraint (inst.reloc.exp.X_add_number < 0
-		      || inst.reloc.exp.X_add_number > 3,
+	  constraint (inst.relocs[0].exp.X_add_number < 0
+		      || inst.relocs[0].exp.X_add_number > 3,
 		      _("shift out of range"));
-	  inst.instruction |= inst.reloc.exp.X_add_number << 4;
+	  inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
 	}
-      inst.reloc.type = BFD_RELOC_UNUSED;
+      inst.relocs[0].type = BFD_RELOC_UNUSED;
     }
   else if (inst.operands[i].preind)
     {
@@ -10445,7 +10465,7 @@  encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
 	  if (inst.operands[i].writeback)
 	    inst.instruction |= 0x00000100;
 	}
-      inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
+      inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
     }
   else if (inst.operands[i].postind)
     {
@@ -10457,7 +10477,7 @@  encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
 	inst.instruction |= 0x00200000;
       else
 	inst.instruction |= 0x00000900;
-      inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
+      inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
     }
   else /* unindexed - only for coprocessor */
     inst.error = _("instruction does not accept unindexed addressing");
@@ -10589,7 +10609,7 @@  do_t_add_sub_w (void)
     reject_bad_reg (Rd);
 
   inst.instruction |= (Rn << 16) | (Rd << 8);
-  inst.reloc.type = BFD_RELOC_ARM_T32_IMM12;
+  inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
 }
 
 /* Parse an add or subtract instruction.  We get here with inst.instruction
@@ -10651,11 +10671,12 @@  do_t_add_sub (void)
 		{
 		  inst.instruction = THUMB_OP16(opcode);
 		  inst.instruction |= (Rd << 4) | Rs;
-		  if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
-		      || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
+		  if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+		      || (inst.relocs[0].type
+			  > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
 		  {
 		    if (inst.size_req == 2)
-		      inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+		      inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
 		    else
 		      inst.relax = opcode;
 		  }
@@ -10666,29 +10687,31 @@  do_t_add_sub (void)
 	  if (inst.size_req == 4
 	      || (inst.size_req != 2 && !opcode))
 	    {
-	      constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
-			  && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+	      constraint ((inst.relocs[0].type
+			   >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
+			  && (inst.relocs[0].type
+			      <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
 			  THUMB1_RELOC_ONLY);
 	      if (Rd == REG_PC)
 		{
 		  constraint (add, BAD_PC);
 		  constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
 			     _("only SUBS PC, LR, #const allowed"));
-		  constraint (inst.reloc.exp.X_op != O_constant,
+		  constraint (inst.relocs[0].exp.X_op != O_constant,
 			      _("expression too complex"));
-		  constraint (inst.reloc.exp.X_add_number < 0
-			      || inst.reloc.exp.X_add_number > 0xff,
+		  constraint (inst.relocs[0].exp.X_add_number < 0
+			      || inst.relocs[0].exp.X_add_number > 0xff,
 			     _("immediate value out of range"));
 		  inst.instruction = T2_SUBS_PC_LR
-				     | inst.reloc.exp.X_add_number;
-		  inst.reloc.type = BFD_RELOC_UNUSED;
+				     | inst.relocs[0].exp.X_add_number;
+		  inst.relocs[0].type = BFD_RELOC_UNUSED;
 		  return;
 		}
 	      else if (Rs == REG_PC)
 		{
 		  /* Always use addw/subw.  */
 		  inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
-		  inst.reloc.type = BFD_RELOC_ARM_T32_IMM12;
+		  inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
 		}
 	      else
 		{
@@ -10696,9 +10719,9 @@  do_t_add_sub (void)
 		  inst.instruction = (inst.instruction & 0xe1ffffff)
 				     | 0x10000000;
 		  if (flags)
-		    inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+		    inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
 		  else
-		    inst.reloc.type = BFD_RELOC_ARM_T32_ADD_IMM;
+		    inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
 		}
 	      inst.instruction |= Rd << 8;
 	      inst.instruction |= Rs << 16;
@@ -10706,7 +10729,7 @@  do_t_add_sub (void)
 	}
       else
 	{
-	  unsigned int value = inst.reloc.exp.X_add_number;
+	  unsigned int value = inst.relocs[0].exp.X_add_number;
 	  unsigned int shift = inst.operands[2].shift_kind;
 
 	  Rn = inst.operands[2].reg;
@@ -10782,7 +10805,7 @@  do_t_add_sub (void)
 	  inst.instruction = (inst.instruction == T_MNEM_add
 			      ? 0x0000 : 0x8000);
 	  inst.instruction |= (Rd << 4) | Rs;
-	  inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+	  inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
 	  return;
 	}
 
@@ -10833,24 +10856,24 @@  do_t_adr (void)
       /* Generate a 32-bit opcode.  */
       inst.instruction = THUMB_OP32 (inst.instruction);
       inst.instruction |= Rd << 8;
-      inst.reloc.type = BFD_RELOC_ARM_T32_ADD_PC12;
-      inst.reloc.pc_rel = 1;
+      inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
+      inst.relocs[0].pc_rel = 1;
     }
   else
     {
       /* Generate a 16-bit opcode.  */
       inst.instruction = THUMB_OP16 (inst.instruction);
-      inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
-      inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
-      inst.reloc.pc_rel = 1;
+      inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
+      inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust.  */
+      inst.relocs[0].pc_rel = 1;
       inst.instruction |= Rd << 4;
     }
 
-  if (inst.reloc.exp.X_op == O_symbol
-      && inst.reloc.exp.X_add_symbol != NULL
-      && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
-      && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
-    inst.reloc.exp.X_add_number += 1;
+  if (inst.relocs[0].exp.X_op == O_symbol
+      && inst.relocs[0].exp.X_add_symbol != NULL
+      && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
+      && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
+    inst.relocs[0].exp.X_add_number += 1;
 }
 
 /* Arithmetic instructions for which there is just one 16-bit
@@ -10885,7 +10908,7 @@  do_t_arit3 (void)
 	  inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
 	  inst.instruction |= Rd << 8;
 	  inst.instruction |= Rs << 16;
-	  inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+	  inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
 	}
       else
 	{
@@ -10973,7 +10996,7 @@  do_t_arit3c (void)
 	  inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
 	  inst.instruction |= Rd << 8;
 	  inst.instruction |= Rs << 16;
-	  inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+	  inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
 	}
       else
 	{
@@ -11166,7 +11189,7 @@  do_t_branch (void)
       && (inst.size_req == 4
 	  || (inst.size_req != 2
 	      && (inst.operands[0].hasreloc
-		  || inst.reloc.exp.X_op == O_constant))))
+		  || inst.relocs[0].exp.X_op == O_constant))))
     {
       inst.instruction = THUMB_OP32(opcode);
       if (cond == COND_ALWAYS)
@@ -11196,8 +11219,8 @@  do_t_branch (void)
       if (unified_syntax && inst.size_req != 2)
 	inst.relax = opcode;
     }
-  inst.reloc.type = reloc;
-  inst.reloc.pc_rel = 1;
+  inst.relocs[0].type = reloc;
+  inst.relocs[0].pc_rel = 1;
 }
 
 /* Actually do the work for Thumb state bkpt and hlt.  The only difference
@@ -11241,20 +11264,20 @@  do_t_branch23 (void)
      the branch encoding is now needed to deal with TLSCALL relocs.
      So if we see a PLT reloc now, put it back to how it used to be to
      keep the preexisting behaviour.  */
-  if (inst.reloc.type == BFD_RELOC_ARM_PLT32)
-    inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
+  if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
+    inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
 
 #if defined(OBJ_COFF)
   /* If the destination of the branch is a defined symbol which does not have
      the THUMB_FUNC attribute, then we must be calling a function which has
      the (interfacearm) attribute.  We look for the Thumb entry point to that
      function and change the branch to refer to that function instead.	*/
-  if (	 inst.reloc.exp.X_op == O_symbol
-      && inst.reloc.exp.X_add_symbol != NULL
-      && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
-      && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
-    inst.reloc.exp.X_add_symbol =
-      find_real_start (inst.reloc.exp.X_add_symbol);
+  if (	 inst.relocs[0].exp.X_op == O_symbol
+      && inst.relocs[0].exp.X_add_symbol != NULL
+      && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
+      && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
+    inst.relocs[0].exp.X_add_symbol
+      = find_real_start (inst.relocs[0].exp.X_add_symbol);
 #endif
 }
 
@@ -11362,8 +11385,8 @@  do_t_cbz (void)
   set_it_insn_type (OUTSIDE_IT_INSN);
   constraint (inst.operands[0].reg > 7, BAD_HIREG);
   inst.instruction |= inst.operands[0].reg;
-  inst.reloc.pc_rel = 1;
-  inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH7;
+  inst.relocs[0].pc_rel = 1;
+  inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
 }
 
 static void
@@ -11511,7 +11534,7 @@  static void
 do_t_ldmstm (void)
 {
   /* This really doesn't seem worth it.  */
-  constraint (inst.reloc.type != BFD_RELOC_UNUSED,
+  constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
 	      _("expression too complex"));
   constraint (inst.operands[1].writeback,
 	      _("Thumb load/store multiple does not support {reglist}^"));
@@ -11648,7 +11671,7 @@  do_t_ldrex (void)
 
   inst.instruction |= inst.operands[0].reg << 12;
   inst.instruction |= inst.operands[1].reg << 16;
-  inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_U8;
+  inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
 }
 
 static void
@@ -11718,7 +11741,7 @@  do_t_ldst (void)
 		{
 		  if (Rn == REG_PC)
 		    {
-		      if (inst.reloc.pc_rel)
+		      if (inst.relocs[0].pc_rel)
 			opcode = T_MNEM_ldr_pc2;
 		      else
 			opcode = T_MNEM_ldr_pc;
@@ -11739,7 +11762,7 @@  do_t_ldst (void)
 		}
 	      inst.instruction |= THUMB_OP16 (opcode);
 	      if (inst.size_req == 2)
-		inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+		inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
 	      else
 		inst.relax = opcode;
 	      return;
@@ -11818,7 +11841,7 @@  do_t_ldst (void)
 	inst.instruction = T_OPCODE_STR_SP;
 
       inst.instruction |= inst.operands[0].reg << 8;
-      inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+      inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
       return;
     }
 
@@ -11828,7 +11851,7 @@  do_t_ldst (void)
       /* Immediate offset.  */
       inst.instruction |= inst.operands[0].reg;
       inst.instruction |= inst.operands[1].reg << 3;
-      inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+      inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
       return;
     }
 
@@ -12026,25 +12049,27 @@  do_t_mov_cmp (void)
 	    {
 	      inst.instruction = THUMB_OP16 (opcode);
 	      inst.instruction |= Rn << 8;
-	      if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
-		  || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
+	      if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+		  || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
 		{
 		  if (inst.size_req == 2)
-		    inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+		    inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
 		  else
 		    inst.relax = opcode;
 		}
 	    }
 	  else
 	    {
-	      constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
-			  && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+	      constraint ((inst.relocs[0].type
+			   >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
+			  && (inst.relocs[0].type
+			      <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
 			  THUMB1_RELOC_ONLY);
 
 	      inst.instruction = THUMB_OP32 (inst.instruction);
 	      inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
 	      inst.instruction |= Rn << r0off;
-	      inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+	      inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
 	    }
 	}
       else if (inst.operands[1].shifted && inst.operands[1].immisreg
@@ -12131,7 +12156,7 @@  do_t_mov_cmp (void)
 	    {
 	      inst.instruction |= Rn;
 	      inst.instruction |= Rm << 3;
-	      inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+	      inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
 	    }
 	  else
 	    {
@@ -12222,7 +12247,7 @@  do_t_mov_cmp (void)
       constraint (Rn > 7,
 		  _("only lo regs allowed with immediate"));
       inst.instruction |= Rn << 8;
-      inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+      inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
     }
 }
 
@@ -12234,24 +12259,24 @@  do_t_mov16 (void)
   bfd_boolean top;
 
   top = (inst.instruction & 0x00800000) != 0;
-  if (inst.reloc.type == BFD_RELOC_ARM_MOVW)
+  if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
     {
       constraint (top, _(":lower16: not allowed in this instruction"));
-      inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVW;
+      inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
     }
-  else if (inst.reloc.type == BFD_RELOC_ARM_MOVT)
+  else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
     {
       constraint (!top, _(":upper16: not allowed in this instruction"));
-      inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVT;
+      inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
     }
 
   Rd = inst.operands[0].reg;
   reject_bad_reg (Rd);
 
   inst.instruction |= Rd << 8;
-  if (inst.reloc.type == BFD_RELOC_UNUSED)
+  if (inst.relocs[0].type == BFD_RELOC_UNUSED)
     {
-      imm = inst.reloc.exp.X_add_number;
+      imm = inst.relocs[0].exp.X_add_number;
       inst.instruction |= (imm & 0xf000) << 4;
       inst.instruction |= (imm & 0x0800) << 15;
       inst.instruction |= (imm & 0x0700) << 4;
@@ -12301,7 +12326,7 @@  do_t_mvn_tst (void)
 	    inst.instruction = THUMB_OP32 (inst.instruction);
 	  inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
 	  inst.instruction |= Rn << r0off;
-	  inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+	  inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
 	}
       else
 	{
@@ -12613,7 +12638,7 @@  do_t_orn (void)
   if (!inst.operands[2].isreg)
     {
       inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
-      inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+      inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
     }
   else
     {
@@ -12647,8 +12672,8 @@  do_t_pkhbt (void)
   inst.instruction |= Rm;
   if (inst.operands[3].present)
     {
-      unsigned int val = inst.reloc.exp.X_add_number;
-      constraint (inst.reloc.exp.X_op != O_constant,
+      unsigned int val = inst.relocs[0].exp.X_add_number;
+      constraint (inst.relocs[0].exp.X_op != O_constant,
 		  _("expression too complex"));
       inst.instruction |= (val & 0x1c) << 10;
       inst.instruction |= (val & 0x03) << 6;
@@ -12688,7 +12713,7 @@  do_t_push_pop (void)
 
   constraint (inst.operands[0].writeback,
 	      _("push/pop do not support {reglist}^"));
-  constraint (inst.reloc.type != BFD_RELOC_UNUSED,
+  constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
 	      _("expression too complex"));
 
   mask = inst.operands[0].imm;
@@ -12806,15 +12831,15 @@  do_t_rsb (void)
       if (inst.size_req == 4 || !unified_syntax)
 	narrow = FALSE;
 
-      if (inst.reloc.exp.X_op != O_constant
-	  || inst.reloc.exp.X_add_number != 0)
+      if (inst.relocs[0].exp.X_op != O_constant
+	  || inst.relocs[0].exp.X_add_number != 0)
 	narrow = FALSE;
 
       /* Turn rsb #0 into 16-bit neg.  We should probably do this via
 	 relaxation, but it doesn't seem worth the hassle.  */
       if (narrow)
 	{
-	  inst.reloc.type = BFD_RELOC_UNUSED;
+	  inst.relocs[0].type = BFD_RELOC_UNUSED;
 	  inst.instruction = THUMB_OP16 (T_MNEM_negs);
 	  inst.instruction |= Rs << 3;
 	  inst.instruction |= Rd;
@@ -12822,7 +12847,7 @@  do_t_rsb (void)
       else
 	{
 	  inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
-	  inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+	  inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
 	}
     }
   else
@@ -12906,7 +12931,7 @@  do_t_shift (void)
 	      inst.instruction |= inst.operands[0].reg << 8;
 	      encode_thumb32_shifted_operand (1);
 	      /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup.  */
-	      inst.reloc.type = BFD_RELOC_UNUSED;
+	      inst.relocs[0].type = BFD_RELOC_UNUSED;
 	    }
 	}
       else
@@ -12938,7 +12963,7 @@  do_t_shift (void)
 		case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
 		default: abort ();
 		}
-	      inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+	      inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
 	      inst.instruction |= inst.operands[0].reg;
 	      inst.instruction |= inst.operands[1].reg << 3;
 	    }
@@ -12982,7 +13007,7 @@  do_t_shift (void)
 	    case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
 	    default: abort ();
 	    }
-	  inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+	  inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
 	  inst.instruction |= inst.operands[0].reg;
 	  inst.instruction |= inst.operands[1].reg << 3;
 	}
@@ -13028,12 +13053,12 @@  do_t_simd2 (void)
 static void
 do_t_smc (void)
 {
-  unsigned int value = inst.reloc.exp.X_add_number;
+  unsigned int value = inst.relocs[0].exp.X_add_number;
   constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
 	      _("SMC is not permitted on this architecture"));
-  constraint (inst.reloc.exp.X_op != O_constant,
+  constraint (inst.relocs[0].exp.X_op != O_constant,
 	      _("expression too complex"));
-  inst.reloc.type = BFD_RELOC_UNUSED;
+  inst.relocs[0].type = BFD_RELOC_UNUSED;
   inst.instruction |= (value & 0xf000) >> 12;
   inst.instruction |= (value & 0x0ff0);
   inst.instruction |= (value & 0x000f) << 16;
@@ -13044,9 +13069,9 @@  do_t_smc (void)
 static void
 do_t_hvc (void)
 {
-  unsigned int value = inst.reloc.exp.X_add_number;
+  unsigned int value = inst.relocs[0].exp.X_add_number;
 
-  inst.reloc.type = BFD_RELOC_UNUSED;
+  inst.relocs[0].type = BFD_RELOC_UNUSED;
   inst.instruction |= (value & 0x0fff);
   inst.instruction |= (value & 0xf000) << 4;
 }
@@ -13068,11 +13093,11 @@  do_t_ssat_usat (int bias)
 
   if (inst.operands[3].present)
     {
-      offsetT shift_amount = inst.reloc.exp.X_add_number;
+      offsetT shift_amount = inst.relocs[0].exp.X_add_number;
 
-      inst.reloc.type = BFD_RELOC_UNUSED;
+      inst.relocs[0].type = BFD_RELOC_UNUSED;
 
-      constraint (inst.reloc.exp.X_op != O_constant,
+      constraint (inst.relocs[0].exp.X_op != O_constant,
 		  _("expression too complex"));
 
       if (shift_amount != 0)
@@ -13125,7 +13150,7 @@  do_t_strex (void)
   inst.instruction |= inst.operands[0].reg << 8;
   inst.instruction |= inst.operands[1].reg << 12;
   inst.instruction |= inst.operands[2].reg << 16;
-  inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_U8;
+  inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
 }
 
 static void
@@ -13203,7 +13228,7 @@  do_t_sxth (void)
 static void
 do_t_swi (void)
 {
-  inst.reloc.type = BFD_RELOC_ARM_SWI;
+  inst.relocs[0].type = BFD_RELOC_ARM_SWI;
 }
 
 static void
@@ -17360,8 +17385,8 @@  do_neon_ldx_stx (void)
   else
     {
       constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
-      constraint (inst.reloc.exp.X_op != O_constant
-		  || inst.reloc.exp.X_add_number != 0,
+      constraint (inst.relocs[0].exp.X_op != O_constant
+		  || inst.relocs[0].exp.X_add_number != 0,
 		  BAD_ADDR_MODE);
 
       if (inst.operands[1].writeback)
@@ -17584,8 +17609,9 @@  do_vcmla (void)
 {
   constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
 	      _(BAD_FPU));
-  constraint (inst.reloc.exp.X_op != O_constant, _("expression too complex"));
-  unsigned rot = inst.reloc.exp.X_add_number;
+  constraint (inst.relocs[0].exp.X_op != O_constant,
+	      _("expression too complex"));
+  unsigned rot = inst.relocs[0].exp.X_add_number;
   constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
 	      _("immediate out of range"));
   rot /= 90;
@@ -17625,8 +17651,9 @@  do_vcadd (void)
 {
   constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
 	      _(BAD_FPU));
-  constraint (inst.reloc.exp.X_op != O_constant, _("expression too complex"));
-  unsigned rot = inst.reloc.exp.X_add_number;
+  constraint (inst.relocs[0].exp.X_op != O_constant,
+	      _("expression too complex"));
+  unsigned rot = inst.relocs[0].exp.X_add_number;
   constraint (rot != 90 && rot != 270, _("immediate out of range"));
   enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
   unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
@@ -17976,18 +18003,18 @@  output_relax_insn (void)
      start of the instruction.  */
   dwarf2_emit_insn (0);
 
-  switch (inst.reloc.exp.X_op)
+  switch (inst.relocs[0].exp.X_op)
     {
     case O_symbol:
-      sym = inst.reloc.exp.X_add_symbol;
-      offset = inst.reloc.exp.X_add_number;
+      sym = inst.relocs[0].exp.X_add_symbol;
+      offset = inst.relocs[0].exp.X_add_number;
       break;
     case O_constant:
       sym = NULL;
-      offset = inst.reloc.exp.X_add_number;
+      offset = inst.relocs[0].exp.X_add_number;
       break;
     default:
-      sym = make_expr_symbol (&inst.reloc.exp);
+      sym = make_expr_symbol (&inst.relocs[0].exp);
       offset = 0;
       break;
   }
@@ -18043,10 +18070,14 @@  output_inst (const char * str)
   else
     md_number_to_chars (to, inst.instruction, inst.size);
 
-  if (inst.reloc.type != BFD_RELOC_UNUSED)
-    fix_new_arm (frag_now, to - frag_now->fr_literal,
-		 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
-		 inst.reloc.type);
+  int r;
+  for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
+    {
+      if (inst.relocs[r].type != BFD_RELOC_UNUSED)
+	fix_new_arm (frag_now, to - frag_now->fr_literal,
+		     inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
+		     inst.relocs[r].type);
+    }
 
   dwarf2_emit_insn (inst.size);
 }
@@ -18771,7 +18802,9 @@  md_assemble (char *str)
     }
 
   memset (&inst, '\0', sizeof (inst));
-  inst.reloc.type = BFD_RELOC_UNUSED;
+  int r;
+  for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
+    inst.relocs[r].type = BFD_RELOC_UNUSED;
 
   opcode = opcode_lookup (&p);
   if (!opcode)