[binutils, ARM, 3/16] BF insns infrastructure with new bfd_reloc_code_real for fallba...
authorAndre Vieira <andre.simoesdiasvieira@arm.com>
Mon, 15 Apr 2019 10:06:30 +0000 (11:06 +0100)
committerAndre Vieira <andre.simoesdiasvieira@arm.com>
Mon, 15 Apr 2019 11:29:35 +0000 (12:29 +0100)
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.

This is the first infrastructure patch that adds a new bfd_reloc_code_real enum
for the fallback branch offset.
This is common for all such instructions and needs to be resolvable by the
assembler.

ChangeLog entries are as follows :
*** bfd/ChangeLog ***

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

* reloc.c (BFD_RELOC_THUMB_PCREL_BRANCH5): New enum.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.

*** gas/ChangeLog ***

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

* config/tc-arm.c (md_pcrel_from_section): New switch case
for BFD_RELOC_THUMB_PCREL_BRANCH5.
(v8_1_branch_value_check): New function to check branch
offsets.
(md_appdy_fix): New switch case for
BFD_RELOC_THUMB_PCREL_BRANCH5.
(tc_gen_reloc): Likewise.

*** opcodes/ChangeLog ***

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

* arm-dis.c (print_insn_thumb32): Updated to accept new %G pattern.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-arm.c
opcodes/ChangeLog
opcodes/arm-dis.c

index d9d1e9b3067f9f5b66e692e57a246360997c852f..bbb251a000fa98d063b6a3360356bcf1cb5588f8 100644 (file)
@@ -1,3 +1,9 @@
+2019-04-15  Sudakshina Das  <sudi.das@arm.com>
+
+       * reloc.c (BFD_RELOC_THUMB_PCREL_BRANCH5): New enum.
+       * bfd-in2.h: Regenerate.
+       * libbfd.h: Regenerate.
+
 2019-04-15  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        * archures.c (bfd_mach_arm_8_1M_MAIN): Define.
index 4f63fe50e6bf8003fb25beec9e64927a672e444b..3493d4f0de41cb184710248ce6664700bca78cca 100644 (file)
@@ -3564,6 +3564,9 @@ field in the instruction.  */
 /* ARM 26-bit pc-relative branch for B or conditional BL instruction.  */
   BFD_RELOC_ARM_PCREL_JUMP,
 
+/* ARM 5-bit pc-relative branch for Branch Future instructions.  */
+  BFD_RELOC_THUMB_PCREL_BRANCH5,
+
 /* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches.
 The lowest bit must be zero and is not stored in the instruction.
 Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an
index 36284d71a9bdb0237ad678027441ccf0fe880430..02daa29b433e390507fe91e7a045f43eb85d548d 100644 (file)
@@ -1529,6 +1529,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_THUMB_PCREL_BLX",
   "BFD_RELOC_ARM_PCREL_CALL",
   "BFD_RELOC_ARM_PCREL_JUMP",
+  "BFD_RELOC_THUMB_PCREL_BRANCH5",
   "BFD_RELOC_THUMB_PCREL_BRANCH7",
   "BFD_RELOC_THUMB_PCREL_BRANCH9",
   "BFD_RELOC_THUMB_PCREL_BRANCH12",
index e6446a78098602d91d3c7f4a0b20807b805bb829..a071dc75c0499192077da30aba8ee7fc3d62dacb 100644 (file)
@@ -3014,6 +3014,11 @@ ENUM
 ENUMDOC
   ARM 26-bit pc-relative branch for B or conditional BL instruction.
 
+ENUM
+  BFD_RELOC_THUMB_PCREL_BRANCH5
+ENUMDOC
+  ARM 5-bit pc-relative branch for Branch Future instructions.
+
 ENUM
   BFD_RELOC_THUMB_PCREL_BRANCH7
 ENUMX
index 483823ca11abe6987c404e4285d6928471a4e88a..02f28f24dc116bae102955735306a9f9e25428dc 100644 (file)
@@ -1,3 +1,13 @@
+2019-04-15  Sudakshina Das  <sudi.das@arm.com>
+
+       * config/tc-arm.c (md_pcrel_from_section): New switch case
+       for BFD_RELOC_THUMB_PCREL_BRANCH5.
+       (v8_1_branch_value_check): New function to check branch
+       offsets.
+       (md_appdy_fix): New switch case for
+       BFD_RELOC_THUMB_PCREL_BRANCH5.
+       (tc_gen_reloc): Likewise.
+
 2019-04-15  Andre Vieira  <andre.simoesdiasvieira@arm.com>
 
        * config/tc-arm.c (do_neon_movhf): Remove fp-armv8 check.
index 11d593c2626199d0dad4f4d81a276decb0300d3c..a13baa603486623836977d4c8f68ac283d02cbab 100644 (file)
@@ -235,6 +235,8 @@ static const arm_feature_set arm_ext_pan = ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN);
 static const arm_feature_set arm_ext_v8m = ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M);
 static const arm_feature_set arm_ext_v8m_main =
   ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN);
+static const arm_feature_set arm_ext_v8_1m_main =
+ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN);
 /* Instructions in ARMv8-M only found in M profile architectures.  */
 static const arm_feature_set arm_ext_v8m_m_only =
   ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M | ARM_EXT2_V8M_MAIN);
@@ -843,6 +845,7 @@ struct asm_opcode
 #define BAD_THUMB32    _("instruction not supported in Thumb16 mode")
 #define BAD_ADDR_MODE   _("instruction does not accept this addressing mode");
 #define BAD_BRANCH     _("branch must be last instruction in IT block")
+#define BAD_BRANCH_OFF _("branch out of range or not a multiple of 2")
 #define BAD_NOT_IT     _("instruction not allowed in IT block")
 #define BAD_FPU                _("selected FPU does not support instruction")
 #define BAD_OUT_IT     _("thumb conditional instruction should be in IT block")
@@ -13272,6 +13275,26 @@ do_t_usat16 (void)
   inst.instruction |= Rn << 16;
 }
 
+/* Checking the range of the branch offset (VAL) with NBITS bits
+   and IS_SIGNED signedness.  Also checks the LSB to be 0.  */
+static int
+v8_1_branch_value_check (int val, int nbits, int is_signed)
+{
+  gas_assert (nbits > 0 && nbits <= 32);
+  if (is_signed)
+    {
+      int cmp = (1 << (nbits - 1));
+      if ((val < -cmp) || (val >= cmp) || (val & 0x01))
+       return FAIL;
+    }
+  else
+    {
+      if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
+       return FAIL;
+    }
+    return SUCCESS;
+}
+
 /* Neon instruction encoder helpers.  */
 
 /* Encodings for the different types for various Neon opcodes.  */
@@ -22791,6 +22814,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
       return (base + 4) & ~3;
 
       /* Thumb branches are simply offset by +4.  */
+    case BFD_RELOC_THUMB_PCREL_BRANCH5:
     case BFD_RELOC_THUMB_PCREL_BRANCH7:
     case BFD_RELOC_THUMB_PCREL_BRANCH9:
     case BFD_RELOC_THUMB_PCREL_BRANCH12:
@@ -24669,6 +24693,30 @@ md_apply_fix (fixS *   fixP,
        }
       break;
 
+    case BFD_RELOC_THUMB_PCREL_BRANCH5:
+      if (fixP->fx_addsy
+         && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+         && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
+         && ARM_IS_FUNC (fixP->fx_addsy)
+         && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
+       {
+         /* Force a relocation for a branch 5 bits wide.  */
+         fixP->fx_done = 0;
+       }
+      if (v8_1_branch_value_check (value, 5, FALSE) == FAIL)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     BAD_BRANCH_OFF);
+
+      if (fixP->fx_done || !seg->use_rela_p)
+       {
+         addressT boff = value >> 1;
+
+         newval  = md_chars_to_number (buf, THUMB_SIZE);
+         newval |= (boff << 7);
+         md_number_to_chars (buf, newval, THUMB_SIZE);
+       }
+      break;
+
     case BFD_RELOC_ARM_V4BX:
       /* This will need to go in the object file.  */
       fixP->fx_done = 0;
@@ -24880,6 +24928,12 @@ tc_gen_reloc (asection *section, fixS *fixp)
                    _("ADRL used for a symbol not defined in the same file"));
       return NULL;
 
+    case BFD_RELOC_THUMB_PCREL_BRANCH5:
+      as_bad_where (fixp->fx_file, fixp->fx_line,
+                   _("%s used for a symbol not defined in the same file"),
+                   bfd_get_reloc_code_name (fixp->fx_r_type));
+      return NULL;
+
     case BFD_RELOC_ARM_OFFSET_IMM:
       if (section->use_rela_p)
        {
index 5027e9a573fb6b7db4b749d94e1068a363f2caa6..fc9697b83d8247c3f62981570c8dbc55755e8aa8 100644 (file)
@@ -1,3 +1,7 @@
+2019-04-15  Sudakshina Das  <sudi.das@arm.com>
+
+       * arm-dis.c (print_insn_thumb32): Updated to accept new %G pattern.
+
 2019-04-15  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        * arm-dis.c (select_arm_features): Add logic for Armv8.1-M Mainline.
index e38296edea95749ebfc313c423d2e8147032ba27..0ed893b01acdabe33ddb24de10303cecf6be95e5 100644 (file)
@@ -2713,6 +2713,7 @@ static const struct opcode16 thumb_opcodes[] =
 
        %E              print the lsb and width fields of a bfc/bfi instruction
        %F              print the lsb and width fields of a sbfx/ubfx instruction
+       %G              print a fallback offset for Branch Future instructions
        %b              print a conditional branch offset
        %B              print an unconditional branch offset
        %s              print the shift field of an SSAT instruction
@@ -5862,6 +5863,13 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                }
                break;
 
+             case 'G':
+               {
+                 unsigned int boff = (((given & 0x07800000) >> 23) << 1);
+                 func (stream, "%x", boff);
+               }
+               break;
+
              case 'b':
                {
                  unsigned int S = (given & 0x04000000u) >> 26;