[ARM,9/16] New BFL instruction for Armv8.1-M Mainline

Message ID 6d972169-3e59-80d1-735b-dc9c86cf8dc2@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:39 p.m.
Hi

This patch is part of a series of patches to add support for Armv8.1-M 
Mainline instructions to binutils.

This patch adds the BFL instruction.

Testing: Added new test for the valid and invalid instruction operands. 
Testsuite shows no regression when run for arm-none-eabi targets.

Thanks
Sudi


ChangeLog entries are as follows :

*** gas/ChangeLog ***

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

	* config/tc-arm.c (T16_32_TAB): New entrie for bfl.
	(do_t_v8_1_branch): New switch case for bfl.
	(insns): New instruction for bfl.
	* testsuite/gas/arm/armv8_1-m-bfl.d: New.
	* testsuite/gas/arm/armv8_1-m-bfl.s: New.
	* testsuite/gas/arm/armv8_1-m-bfl-bad.s: New.
	* testsuite/gas/arm/armv8_1-m-bfl-bad.d: New.
	* testsuite/gas/arm/armv8_1-m-bfl-bad.l: New.

*** ld/ChangeLog ***

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

	* testsuite/ld-arm/bfl.s: New.
	* testsuite/ld-arm/bfl.d: New.
	* testsuite/ld-arm/arm-elf.exp: Add above test.

*** opcodes/ChangeLog ***

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

	* arm-dis.c (thumb32_opcodes): New instruction bfl.

Comments

Andre Vieira (lists) April 12, 2019, 10:40 a.m. | #1
Hi,

Fixed some testisms highlighted by Nick.

This OK?

*** gas/ChangeLog ***

2019-04-12  Sudakshina Das  <sudi.das@arm.com>
             Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (T16_32_TAB): New entrie for bfl.
	(do_t_v8_1_branch): New switch case for bfl.
	(insns): New instruction for bfl.
	* testsuite/gas/arm/armv8_1-m-bfl.d: New.
	* testsuite/gas/arm/armv8_1-m-bfl.s: New.
	* testsuite/gas/arm/armv8_1-m-bfl-bad.s: New.
	* testsuite/gas/arm/armv8_1-m-bfl-bad.d: New.
	* testsuite/gas/arm/armv8_1-m-bfl-bad.l: New.
	* testsuite/gas/arm/armv8_1-m-bfl-rel.d: New.
	* testsuite/gas/arm/armv8_1-m-bfl-rel.s: New.

*** ld/ChangeLog ***

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

	* testsuite/ld-arm/bfl.s: New.
	* testsuite/ld-arm/bfl.d: New.
	* testsuite/ld-arm/arm-elf.exp: Add above test.

*** opcodes/ChangeLog ***

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

	* arm-dis.c (thumb32_opcodes): New instruction bfl.

On 04/04/2019 14:39, Andre Vieira (lists) wrote:
> Hi

> 

> This patch is part of a series of patches to add support for Armv8.1-M 

> Mainline instructions to binutils.

> 

> This patch adds the BFL instruction.

> 

> Testing: Added new test for the valid and invalid instruction operands. 

> Testsuite shows no regression when run for arm-none-eabi targets.

> 

> Thanks

> Sudi

> 

> 

> ChangeLog entries are as follows :

> 

> *** gas/ChangeLog ***

> 

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

> 

>      * config/tc-arm.c (T16_32_TAB): New entrie for bfl.

>      (do_t_v8_1_branch): New switch case for bfl.

>      (insns): New instruction for bfl.

>      * testsuite/gas/arm/armv8_1-m-bfl.d: New.

>      * testsuite/gas/arm/armv8_1-m-bfl.s: New.

>      * testsuite/gas/arm/armv8_1-m-bfl-bad.s: New.

>      * testsuite/gas/arm/armv8_1-m-bfl-bad.d: New.

>      * testsuite/gas/arm/armv8_1-m-bfl-bad.l: New.

> 

> *** ld/ChangeLog ***

> 

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

> 

>      * testsuite/ld-arm/bfl.s: New.

>      * testsuite/ld-arm/bfl.d: New.

>      * testsuite/ld-arm/arm-elf.exp: Add above test.

> 

> *** opcodes/ChangeLog ***

> 

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

> 

>      * arm-dis.c (thumb32_opcodes): New instruction bfl.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 177d90f1c6fdc9ad99a395b479b16e5b9f8ae0b6..5643e3f6bcafe95816c666ad3ed9844ad458c54e 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -10507,6 +10507,7 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
   X(_bcond, d000, f0008000),			\
   X(_bf,    0000, f040e001),			\
   X(_bfx,   0000, f060e001),			\
+  X(_bfl,   0000, f000c001),			\
   X(_bflx,  0000, f070e001),			\
   X(_bic,   4380, ea200000),			\
   X(_bics,  4380, ea300000),			\
@@ -13364,6 +13365,25 @@ do_t_branch_future (void)
 	  }
 	break;
 
+      case T_MNEM_bfl:
+	if (inst.operands[1].hasreloc == 0)
+	  {
+	    int val = inst.operands[1].imm;
+	    if (v8_1_branch_value_check (inst.operands[1].imm, 19, TRUE) == FAIL)
+	      as_bad (BAD_BRANCH_OFF);
+
+	    int immA = (val & 0x0007f000) >> 12;
+	    int immB = (val & 0x00000ffc) >> 2;
+	    int immC = (val & 0x00000002) >> 1;
+	    inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
+	  }
+	  else
+	  {
+	    inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
+	    inst.relocs[1].pc_rel = 1;
+	  }
+	break;
+
       case T_MNEM_bfx:
       case T_MNEM_bflx:
 	inst.instruction |= inst.operands[1].reg << 16;
@@ -21687,6 +21707,7 @@ static const struct asm_opcode insns[] =
 #define THUMB_VARIANT & arm_ext_v8_1m_main
  toC("bf",     _bf,	2, (EXPs, EXPs),	     t_branch_future),
  toC("bfx",    _bfx,	2, (EXPs, RRnpcsp),	     t_branch_future),
+ toC("bfl",    _bfl,	2, (EXPs, EXPs),	     t_branch_future),
  toC("bflx",   _bflx,	2, (EXPs, RRnpcsp),	     t_branch_future),
 };
 #undef ARM_VARIANT
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.d b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..6a8f6f3cfd74d2f068048c39eab29eb70d165350
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.d
@@ -0,0 +1,4 @@
+#name: Invalid Armv8.1-M Mainline BFL instructions
+#source: armv8_1-m-bfl-bad.s
+#as: -march=armv8.1-m.main
+#error_output: armv8_1-m-bfl-bad.l
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.l b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..3f7ed80a6d07a4a2c05e8968e95c26d66eae2fab
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.l
@@ -0,0 +1,9 @@
+.*: Assembler messages:
+.*:6: Error: branch out of range or not a multiple of 2
+.*:7: Error: branch out of range or not a multiple of 2
+.*:8: Error: branch out of range or not a multiple of 2
+.*:9: Error: branch out of range or not a multiple of 2
+.*:11: Error: branch out of range or not a multiple of 2
+.*:12: Error: branch out of range or not a multiple of 2
+.*:13: Error: branch out of range or not a multiple of 2
+.*:14: Error: branch out of range or not a multiple of 2
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.s b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..2af310820c39231978b50a8b5728b0f1f40e9efe
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.s
@@ -0,0 +1,14 @@
+	.syntax unified
+	.text
+	.thumb
+foo:
+	# OP0 : Unsigned, 5-bit, even
+	bfl  0, 36
+	bfl -2, 36
+	bfl  3, 36
+	bfl 32, 36
+	# OP1 : signed, 19-bit, even
+	bf  2, -5
+	bf  2,  5
+	bf  2,  262144
+	bf  2, -262146
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl-rel.d b/gas/testsuite/gas/arm/armv8_1-m-bfl-rel.d
new file mode 100644
index 0000000000000000000000000000000000000000..13c6bf1caa5cb68844bd4b4d33acef9223edfa03
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl-rel.d
@@ -0,0 +1,10 @@
+#name: Valid Armv8.1-M Mainline BFL instruction with relocation
+#as: -march=armv8.1-m.main
+#objdump: -dr --prefix-addresses --show-raw-insn
+#skip: *-*-pe *-wince-*
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> f0ff c7ff 	bfl	2, 00000000 <.target>
+			0: R_ARM_THM_BF18	.target
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl-rel.s b/gas/testsuite/gas/arm/armv8_1-m-bfl-rel.s
new file mode 100644
index 0000000000000000000000000000000000000000..01c68828a792f4a06c8aad947e6da26dd5455cf6
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl-rel.s
@@ -0,0 +1,5 @@
+	.syntax unified
+	.text
+	.thumb
+foo:
+	bfl 2, .target
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl.d b/gas/testsuite/gas/arm/armv8_1-m-bfl.d
new file mode 100644
index 0000000000000000000000000000000000000000..e15636b359f8db2829e46706f9cd0ea3e1d45500
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl.d
@@ -0,0 +1,13 @@
+#name: Valid Armv8.1-M Mainline BFL instruction
+#as: -march=armv8.1-m.main
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> f080 c803 	bfl	2, 0000000a <foo\+0xa>
+0[0-9a-f]+ <[^>]+> 4608      	mov	r0, r1
+0[0-9a-f]+ <[^>]+> f100 c801 	bfl	4, 0000000c <foo\+0xc>
+0[0-9a-f]+ <[^>]+> 460a      	mov	r2, r1
+0[0-9a-f]+ <[^>]+> 4613      	mov	r3, r2
+0[0-9a-f]+ <[^>]+> 4614      	mov	r4, r2
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl.s b/gas/testsuite/gas/arm/armv8_1-m-bfl.s
new file mode 100644
index 0000000000000000000000000000000000000000..4605bee468618b76c52f3d90737a060b1b5614a2
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl.s
@@ -0,0 +1,12 @@
+	.syntax unified
+	.text
+	.thumb
+foo:
+	bfl 2, 6
+	mov r0, r1
+	bfl .LBranch, .LB2
+	mov r2, r1
+.LB2:
+	mov r3, r2
+.LBranch:
+	mov r4, r2
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index ef3a49c23742f4c43c78e73aa692928ba3d56123..528565e97bee829c193ad54ab21e2f9a7071a718 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -670,6 +670,9 @@ set armeabitests_nonacl {
      {"Armv8.1-M Mainline BF" "-r -Ttext 0x1000 --section-start .foo=0x1001000" "" "-march=armv8.1-m.main" {bf.s}
       {{objdump -dr bf.d}}
      "bf"}
+     {"Armv8.1-M Mainline BFL" "-r -Ttext 0x1000 --section-start .foo=0x1001000" "" "-march=armv8.1-m.main" {bfl.s}
+      {{objdump -dr bfl.d}}
+     "bfl"}
 
     {"R_ARM_THM_JUMP24 Relocation veneers: Short 1"
      "--no-fix-arm1176 --section-start destsect=0x00009000 --section-start .text=0x8000" ""
diff --git a/ld/testsuite/ld-arm/bfl.d b/ld/testsuite/ld-arm/bfl.d
new file mode 100644
index 0000000000000000000000000000000000000000..dcf3202eaad16c5659bc65f4890fbd3b6796f206
--- /dev/null
+++ b/ld/testsuite/ld-arm/bfl.d
@@ -0,0 +1,14 @@
+
+.*:     file format elf32-.*arm
+
+
+Disassembly of section .text:
+
+00001000 <_start>:
+    1000:	f0ff c7ff 	bfl	2, 1001000 <bar>
+			1000: R_ARM_THM_BF18	bar
+
+Disassembly of section .foo:
+
+01001000 <bar>:
+ 1001000:	4770      	bx	lr
diff --git a/ld/testsuite/ld-arm/bfl.s b/ld/testsuite/ld-arm/bfl.s
new file mode 100644
index 0000000000000000000000000000000000000000..e9fb0a70f6c6c6ee802b0bd91dfcd608c94a0d30
--- /dev/null
+++ b/ld/testsuite/ld-arm/bfl.s
@@ -0,0 +1,19 @@
+	.global _start
+	.syntax unified
+
+@ We will place the section .text at 0x1000.
+
+	.text
+	.thumb_func
+
+_start:
+	bfl 2, bar
+
+@ We will place the section .foo at 0x1001000.
+
+	.section .foo, "xa"
+	.thumb_func
+
+bar:
+	bx lr
+
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index a70ed814fb1177132df1d5121cc68b2fef876b0c..12e28c3df6d79df7e1ae3a69e61b8c07b0e7c4e3 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -2754,6 +2754,8 @@ static const struct opcode32 thumb32_opcodes[] =
     0xf040e001, 0xf860f001, "bf%c\t%G, %W"},
   {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
     0xf060e001, 0xf8f0f001, "bfx%c\t%G, %16-19S"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf000c001, 0xf800f001, "bfl%c\t%G, %Y"},
   {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
     0xf070e001, 0xf8f0f001, "bflx%c\t%G, %16-19S"},

Patch

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 177d90f1c6fdc9ad99a395b479b16e5b9f8ae0b6..5643e3f6bcafe95816c666ad3ed9844ad458c54e 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -10507,6 +10507,7 @@  encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
   X(_bcond, d000, f0008000),			\
   X(_bf,    0000, f040e001),			\
   X(_bfx,   0000, f060e001),			\
+  X(_bfl,   0000, f000c001),			\
   X(_bflx,  0000, f070e001),			\
   X(_bic,   4380, ea200000),			\
   X(_bics,  4380, ea300000),			\
@@ -13364,6 +13365,25 @@  do_t_branch_future (void)
 	  }
 	break;
 
+      case T_MNEM_bfl:
+	if (inst.operands[1].hasreloc == 0)
+	  {
+	    int val = inst.operands[1].imm;
+	    if (v8_1_branch_value_check (inst.operands[1].imm, 19, TRUE) == FAIL)
+	      as_bad (BAD_BRANCH_OFF);
+
+	    int immA = (val & 0x0007f000) >> 12;
+	    int immB = (val & 0x00000ffc) >> 2;
+	    int immC = (val & 0x00000002) >> 1;
+	    inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
+	  }
+	  else
+	  {
+	    inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
+	    inst.relocs[1].pc_rel = 1;
+	  }
+	break;
+
       case T_MNEM_bfx:
       case T_MNEM_bflx:
 	inst.instruction |= inst.operands[1].reg << 16;
@@ -21687,6 +21707,7 @@  static const struct asm_opcode insns[] =
 #define THUMB_VARIANT & arm_ext_v8_1m_main
  toC("bf",     _bf,	2, (EXPs, EXPs),	     t_branch_future),
  toC("bfx",    _bfx,	2, (EXPs, RRnpcsp),	     t_branch_future),
+ toC("bfl",    _bfl,	2, (EXPs, EXPs),	     t_branch_future),
  toC("bflx",   _bflx,	2, (EXPs, RRnpcsp),	     t_branch_future),
 };
 #undef ARM_VARIANT
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.d b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..6a8f6f3cfd74d2f068048c39eab29eb70d165350
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.d
@@ -0,0 +1,4 @@ 
+#name: Invalid Armv8.1-M Mainline BFL instructions
+#source: armv8_1-m-bfl-bad.s
+#as: -march=armv8.1-m.main
+#error_output: armv8_1-m-bfl-bad.l
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.l b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..3f7ed80a6d07a4a2c05e8968e95c26d66eae2fab
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.l
@@ -0,0 +1,9 @@ 
+.*: Assembler messages:
+.*:6: Error: branch out of range or not a multiple of 2
+.*:7: Error: branch out of range or not a multiple of 2
+.*:8: Error: branch out of range or not a multiple of 2
+.*:9: Error: branch out of range or not a multiple of 2
+.*:11: Error: branch out of range or not a multiple of 2
+.*:12: Error: branch out of range or not a multiple of 2
+.*:13: Error: branch out of range or not a multiple of 2
+.*:14: Error: branch out of range or not a multiple of 2
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.s b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..2af310820c39231978b50a8b5728b0f1f40e9efe
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl-bad.s
@@ -0,0 +1,14 @@ 
+	.syntax unified
+	.text
+	.thumb
+foo:
+	# OP0 : Unsigned, 5-bit, even
+	bfl  0, 36
+	bfl -2, 36
+	bfl  3, 36
+	bfl 32, 36
+	# OP1 : signed, 19-bit, even
+	bf  2, -5
+	bf  2,  5
+	bf  2,  262144
+	bf  2, -262146
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl.d b/gas/testsuite/gas/arm/armv8_1-m-bfl.d
new file mode 100644
index 0000000000000000000000000000000000000000..f5fff51ab2e906ea4b9e2703340da573fd694609
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl.d
@@ -0,0 +1,17 @@ 
+#name: Valid Armv8.1-M Mainline BFL instruction
+#source: armv8_1-m-bfl.s
+#as: -march=armv8.1-m.main
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> f080 c803 	bfl	2, 0000000a <foo\+0xa>
+0[0-9a-f]+ <[^>]+> 4608      	mov	r0, r1
+0[0-9a-f]+ <[^>]+> f0ff c7ff 	bfl	2, 00000000 <.target>
+			6: R_ARM_THM_BF18	.target
+0[0-9a-f]+ <[^>]+> 4609      	mov	r1, r1
+0[0-9a-f]+ <[^>]+> f100 c801 	bfl	4, 00000012 <foo\+0x12>
+0[0-9a-f]+ <[^>]+> 460a      	mov	r2, r1
+0[0-9a-f]+ <[^>]+> 4613      	mov	r3, r2
+0[0-9a-f]+ <[^>]+> 4614      	mov	r4, r2
diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfl.s b/gas/testsuite/gas/arm/armv8_1-m-bfl.s
new file mode 100644
index 0000000000000000000000000000000000000000..06afa7cdbffd27a57453b1d9ac2719798cc2163b
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8_1-m-bfl.s
@@ -0,0 +1,14 @@ 
+	.syntax unified
+	.text
+	.thumb
+foo:
+	bfl 2, 6
+	mov r0, r1
+	bfl 2, .target
+	mov r1, r1
+	bfl .LBranch, .LB2
+	mov r2, r1
+.LB2:
+	mov r3, r2
+.LBranch:
+	mov r4, r2
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index ef3a49c23742f4c43c78e73aa692928ba3d56123..528565e97bee829c193ad54ab21e2f9a7071a718 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -670,6 +670,9 @@  set armeabitests_nonacl {
      {"Armv8.1-M Mainline BF" "-r -Ttext 0x1000 --section-start .foo=0x1001000" "" "-march=armv8.1-m.main" {bf.s}
       {{objdump -dr bf.d}}
      "bf"}
+     {"Armv8.1-M Mainline BFL" "-r -Ttext 0x1000 --section-start .foo=0x1001000" "" "-march=armv8.1-m.main" {bfl.s}
+      {{objdump -dr bfl.d}}
+     "bfl"}
 
     {"R_ARM_THM_JUMP24 Relocation veneers: Short 1"
      "--no-fix-arm1176 --section-start destsect=0x00009000 --section-start .text=0x8000" ""
diff --git a/ld/testsuite/ld-arm/bfl.d b/ld/testsuite/ld-arm/bfl.d
new file mode 100644
index 0000000000000000000000000000000000000000..32903504bd02bee217a0dc27af127a28d36a83ee
--- /dev/null
+++ b/ld/testsuite/ld-arm/bfl.d
@@ -0,0 +1,14 @@ 
+
+.*:     file format elf32-littlearm
+
+
+Disassembly of section .text:
+
+00001000 <_start>:
+    1000:	f0ff c7ff 	bfl	2, 1001000 <bar>
+			1000: R_ARM_THM_BF18	bar
+
+Disassembly of section .foo:
+
+01001000 <bar>:
+ 1001000:	4770      	bx	lr
diff --git a/ld/testsuite/ld-arm/bfl.s b/ld/testsuite/ld-arm/bfl.s
new file mode 100644
index 0000000000000000000000000000000000000000..e9fb0a70f6c6c6ee802b0bd91dfcd608c94a0d30
--- /dev/null
+++ b/ld/testsuite/ld-arm/bfl.s
@@ -0,0 +1,19 @@ 
+	.global _start
+	.syntax unified
+
+@ We will place the section .text at 0x1000.
+
+	.text
+	.thumb_func
+
+_start:
+	bfl 2, bar
+
+@ We will place the section .foo at 0x1001000.
+
+	.section .foo, "xa"
+	.thumb_func
+
+bar:
+	bx lr
+
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index a70ed814fb1177132df1d5121cc68b2fef876b0c..12e28c3df6d79df7e1ae3a69e61b8c07b0e7c4e3 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -2754,6 +2754,8 @@  static const struct opcode32 thumb32_opcodes[] =
     0xf040e001, 0xf860f001, "bf%c\t%G, %W"},
   {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
     0xf060e001, 0xf8f0f001, "bfx%c\t%G, %16-19S"},
+  {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+    0xf000c001, 0xf800f001, "bfl%c\t%G, %Y"},
   {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
     0xf070e001, 0xf8f0f001, "bflx%c\t%G, %16-19S"},