Skip to content

Commit e12437d

Browse files
committed
[binutils, ARM, 3/16] BF insns infrastructure with new bfd_reloc_code_real for fallback branch
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 <[email protected]> * reloc.c (BFD_RELOC_THUMB_PCREL_BRANCH5): New enum. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. *** gas/ChangeLog *** 2019-04-15 Sudakshina Das <[email protected]> * 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 <[email protected]> * arm-dis.c (print_insn_thumb32): Updated to accept new %G pattern.
1 parent e099158 commit e12437d

File tree

8 files changed

+91
-0
lines changed

8 files changed

+91
-0
lines changed

bfd/ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2019-04-15 Sudakshina Das <[email protected]>
2+
3+
* reloc.c (BFD_RELOC_THUMB_PCREL_BRANCH5): New enum.
4+
* bfd-in2.h: Regenerate.
5+
* libbfd.h: Regenerate.
6+
17
2019-04-15 Thomas Preud'homme <[email protected]>
28

39
* archures.c (bfd_mach_arm_8_1M_MAIN): Define.

bfd/bfd-in2.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3564,6 +3564,9 @@ field in the instruction. */
35643564
/* ARM 26-bit pc-relative branch for B or conditional BL instruction. */
35653565
BFD_RELOC_ARM_PCREL_JUMP,
35663566

3567+
/* ARM 5-bit pc-relative branch for Branch Future instructions. */
3568+
BFD_RELOC_THUMB_PCREL_BRANCH5,
3569+
35673570
/* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches.
35683571
The lowest bit must be zero and is not stored in the instruction.
35693572
Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an

bfd/libbfd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
15291529
"BFD_RELOC_THUMB_PCREL_BLX",
15301530
"BFD_RELOC_ARM_PCREL_CALL",
15311531
"BFD_RELOC_ARM_PCREL_JUMP",
1532+
"BFD_RELOC_THUMB_PCREL_BRANCH5",
15321533
"BFD_RELOC_THUMB_PCREL_BRANCH7",
15331534
"BFD_RELOC_THUMB_PCREL_BRANCH9",
15341535
"BFD_RELOC_THUMB_PCREL_BRANCH12",

bfd/reloc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,6 +3014,11 @@ ENUM
30143014
ENUMDOC
30153015
ARM 26-bit pc-relative branch for B or conditional BL instruction.
30163016
3017+
ENUM
3018+
BFD_RELOC_THUMB_PCREL_BRANCH5
3019+
ENUMDOC
3020+
ARM 5-bit pc-relative branch for Branch Future instructions.
3021+
30173022
ENUM
30183023
BFD_RELOC_THUMB_PCREL_BRANCH7
30193024
ENUMX

gas/ChangeLog

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2019-04-15 Sudakshina Das <[email protected]>
2+
3+
* config/tc-arm.c (md_pcrel_from_section): New switch case
4+
for BFD_RELOC_THUMB_PCREL_BRANCH5.
5+
(v8_1_branch_value_check): New function to check branch
6+
offsets.
7+
(md_appdy_fix): New switch case for
8+
BFD_RELOC_THUMB_PCREL_BRANCH5.
9+
(tc_gen_reloc): Likewise.
10+
111
2019-04-15 Andre Vieira <[email protected]>
212

313
* config/tc-arm.c (do_neon_movhf): Remove fp-armv8 check.

gas/config/tc-arm.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ static const arm_feature_set arm_ext_pan = ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN);
235235
static const arm_feature_set arm_ext_v8m = ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M);
236236
static const arm_feature_set arm_ext_v8m_main =
237237
ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN);
238+
static const arm_feature_set arm_ext_v8_1m_main =
239+
ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN);
238240
/* Instructions in ARMv8-M only found in M profile architectures. */
239241
static const arm_feature_set arm_ext_v8m_m_only =
240242
ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M | ARM_EXT2_V8M_MAIN);
@@ -843,6 +845,7 @@ struct asm_opcode
843845
#define BAD_THUMB32 _("instruction not supported in Thumb16 mode")
844846
#define BAD_ADDR_MODE _("instruction does not accept this addressing mode");
845847
#define BAD_BRANCH _("branch must be last instruction in IT block")
848+
#define BAD_BRANCH_OFF _("branch out of range or not a multiple of 2")
846849
#define BAD_NOT_IT _("instruction not allowed in IT block")
847850
#define BAD_FPU _("selected FPU does not support instruction")
848851
#define BAD_OUT_IT _("thumb conditional instruction should be in IT block")
@@ -13272,6 +13275,26 @@ do_t_usat16 (void)
1327213275
inst.instruction |= Rn << 16;
1327313276
}
1327413277

13278+
/* Checking the range of the branch offset (VAL) with NBITS bits
13279+
and IS_SIGNED signedness. Also checks the LSB to be 0. */
13280+
static int
13281+
v8_1_branch_value_check (int val, int nbits, int is_signed)
13282+
{
13283+
gas_assert (nbits > 0 && nbits <= 32);
13284+
if (is_signed)
13285+
{
13286+
int cmp = (1 << (nbits - 1));
13287+
if ((val < -cmp) || (val >= cmp) || (val & 0x01))
13288+
return FAIL;
13289+
}
13290+
else
13291+
{
13292+
if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
13293+
return FAIL;
13294+
}
13295+
return SUCCESS;
13296+
}
13297+
1327513298
/* Neon instruction encoder helpers. */
1327613299

1327713300
/* Encodings for the different types for various Neon opcodes. */
@@ -22791,6 +22814,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
2279122814
return (base + 4) & ~3;
2279222815

2279322816
/* Thumb branches are simply offset by +4. */
22817+
case BFD_RELOC_THUMB_PCREL_BRANCH5:
2279422818
case BFD_RELOC_THUMB_PCREL_BRANCH7:
2279522819
case BFD_RELOC_THUMB_PCREL_BRANCH9:
2279622820
case BFD_RELOC_THUMB_PCREL_BRANCH12:
@@ -24669,6 +24693,30 @@ md_apply_fix (fixS * fixP,
2466924693
}
2467024694
break;
2467124695

24696+
case BFD_RELOC_THUMB_PCREL_BRANCH5:
24697+
if (fixP->fx_addsy
24698+
&& (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24699+
&& !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
24700+
&& ARM_IS_FUNC (fixP->fx_addsy)
24701+
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
24702+
{
24703+
/* Force a relocation for a branch 5 bits wide. */
24704+
fixP->fx_done = 0;
24705+
}
24706+
if (v8_1_branch_value_check (value, 5, FALSE) == FAIL)
24707+
as_bad_where (fixP->fx_file, fixP->fx_line,
24708+
BAD_BRANCH_OFF);
24709+
24710+
if (fixP->fx_done || !seg->use_rela_p)
24711+
{
24712+
addressT boff = value >> 1;
24713+
24714+
newval = md_chars_to_number (buf, THUMB_SIZE);
24715+
newval |= (boff << 7);
24716+
md_number_to_chars (buf, newval, THUMB_SIZE);
24717+
}
24718+
break;
24719+
2467224720
case BFD_RELOC_ARM_V4BX:
2467324721
/* This will need to go in the object file. */
2467424722
fixP->fx_done = 0;
@@ -24880,6 +24928,12 @@ tc_gen_reloc (asection *section, fixS *fixp)
2488024928
_("ADRL used for a symbol not defined in the same file"));
2488124929
return NULL;
2488224930

24931+
case BFD_RELOC_THUMB_PCREL_BRANCH5:
24932+
as_bad_where (fixp->fx_file, fixp->fx_line,
24933+
_("%s used for a symbol not defined in the same file"),
24934+
bfd_get_reloc_code_name (fixp->fx_r_type));
24935+
return NULL;
24936+
2488324937
case BFD_RELOC_ARM_OFFSET_IMM:
2488424938
if (section->use_rela_p)
2488524939
{

opcodes/ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2019-04-15 Sudakshina Das <[email protected]>
2+
3+
* arm-dis.c (print_insn_thumb32): Updated to accept new %G pattern.
4+
15
2019-04-15 Thomas Preud'homme <[email protected]>
26

37
* arm-dis.c (select_arm_features): Add logic for Armv8.1-M Mainline.

opcodes/arm-dis.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,6 +2713,7 @@ static const struct opcode16 thumb_opcodes[] =
27132713
27142714
%E print the lsb and width fields of a bfc/bfi instruction
27152715
%F print the lsb and width fields of a sbfx/ubfx instruction
2716+
%G print a fallback offset for Branch Future instructions
27162717
%b print a conditional branch offset
27172718
%B print an unconditional branch offset
27182719
%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)
58625863
}
58635864
break;
58645865

5866+
case 'G':
5867+
{
5868+
unsigned int boff = (((given & 0x07800000) >> 23) << 1);
5869+
func (stream, "%x", boff);
5870+
}
5871+
break;
5872+
58655873
case 'b':
58665874
{
58675875
unsigned int S = (given & 0x04000000u) >> 26;

0 commit comments

Comments
 (0)