Re: [gcc-5-branch][PATCH][AARCH64]Fix for branch offsets over 1 MiB

2015-09-25 Thread Andre Vieira

Ping.

On 11/09/15 18:15, Andre Vieira wrote:

Conditional branches have a maximum range of [-1048576, 1048572]. Any
destination further away can not be reached by these.
To be able to have conditional branches in very large functions, we
invert the condition and change the destination to jump over an
unconditional branch to the original, far away, destination.

This patch backports the fix from trunk to the gcc-5-branch.
The original patch is at:
https://gcc.gnu.org/ml/gcc-patches/2015-08/msg01493.html

gcc/ChangeLog:
2015-09-09  Andre Vieira  

Backport from mainline:
2015-08-27  Ramana Radhakrishnan  
Andre Vieira  

* config/aarch64/aarch64.md (*condjump): Handle functions > 1 MiB.
(*cb1): Likewise.
(*tb1): Likewise.
(*cb1): Likewise.
* config/aarch64/iterators.md (inv_cb): New code attribute.
(inv_tb): Likewise.
* config/aarch64/aarch64.c (aarch64_gen_far_branch): New.
* config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New.


gcc/testsuite/ChangeLog:
2015-09-09  Andre Vieira  

Backport from mainline:
2015-08-27  Andre Vieira  

* gcc.target/aarch64/long_branch_1.c: New test.





Re: [gcc-5-branch][PATCH][AARCH64]Fix for branch offsets over 1 MiB

2015-09-25 Thread James Greenhalgh
On Fri, Sep 11, 2015 at 06:15:23PM +0100, Andre Vieira wrote:
> Conditional branches have a maximum range of [-1048576, 1048572]. Any 
> destination further away can not be reached by these.
> To be able to have conditional branches in very large functions, we 
> invert the condition and change the destination to jump over an 
> unconditional branch to the original, far away, destination.
> 
> This patch backports the fix from trunk to the gcc-5-branch.
> The original patch is at:
> https://gcc.gnu.org/ml/gcc-patches/2015-08/msg01493.html

OK.

Thanks,
James

> gcc/ChangeLog:
> 2015-09-09  Andre Vieira  
> 
>Backport from mainline:
>2015-08-27  Ramana Radhakrishnan  
>Andre Vieira  
> 
>* config/aarch64/aarch64.md (*condjump): Handle functions > 1 MiB.
>(*cb1): Likewise.
>(*tb1): Likewise.
>(*cb1): Likewise.
>* config/aarch64/iterators.md (inv_cb): New code attribute.
>(inv_tb): Likewise.
>* config/aarch64/aarch64.c (aarch64_gen_far_branch): New.
>* config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New.
> 
> 
> gcc/testsuite/ChangeLog:
> 2015-09-09  Andre Vieira  
> 
>Backport from mainline:
>2015-08-27  Andre Vieira  
> 
>* gcc.target/aarch64/long_branch_1.c: New test.




[gcc-5-branch][PATCH][AARCH64]Fix for branch offsets over 1 MiB

2015-09-11 Thread Andre Vieira
Conditional branches have a maximum range of [-1048576, 1048572]. Any 
destination further away can not be reached by these.
To be able to have conditional branches in very large functions, we 
invert the condition and change the destination to jump over an 
unconditional branch to the original, far away, destination.


This patch backports the fix from trunk to the gcc-5-branch.
The original patch is at:
https://gcc.gnu.org/ml/gcc-patches/2015-08/msg01493.html

gcc/ChangeLog:
2015-09-09  Andre Vieira  

  Backport from mainline:
  2015-08-27  Ramana Radhakrishnan  
  Andre Vieira  

  * config/aarch64/aarch64.md (*condjump): Handle functions > 1 MiB.
  (*cb1): Likewise.
  (*tb1): Likewise.
  (*cb1): Likewise.
  * config/aarch64/iterators.md (inv_cb): New code attribute.
  (inv_tb): Likewise.
  * config/aarch64/aarch64.c (aarch64_gen_far_branch): New.
  * config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New.


gcc/testsuite/ChangeLog:
2015-09-09  Andre Vieira  

  Backport from mainline:
  2015-08-27  Andre Vieira  

  * gcc.target/aarch64/long_branch_1.c: New test.
From 5b9f35c3a6dff67328e66e82f33ef3dc732ff5f7 Mon Sep 17 00:00:00 2001
From: Andre Simoes Dias Vieira 
Date: Tue, 8 Sep 2015 16:51:14 +0100
Subject: [PATCH] Backport fix for far branches

---
 gcc/config/aarch64/aarch64-protos.h  |  1 +
 gcc/config/aarch64/aarch64.c | 23 ++
 gcc/config/aarch64/aarch64.md| 89 +++
 gcc/config/aarch64/iterators.md  |  6 ++
 gcc/testsuite/gcc.target/aarch64/long_branch_1.c | 91 
 5 files changed, 195 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/long_branch_1.c

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 59c5824f894cf5dafe93a996180056696518feb4..8669694bfc33cc040baeab5aaddc7a0575071add 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -258,6 +258,7 @@ void aarch64_init_expanders (void);
 void aarch64_print_operand (FILE *, rtx, char);
 void aarch64_print_operand_address (FILE *, rtx);
 void aarch64_emit_call_insn (rtx);
+const char * aarch64_gen_far_branch (rtx *, int, const char *, const char *);
 
 /* Initialize builtins for SIMD intrinsics.  */
 void init_aarch64_simd_builtins (void);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index cd20b48d7fd300ab496e67cae0d6e503ac305409..c2e4252cf689a4d7b28890743095536f3a390338 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1029,6 +1029,29 @@ aarch64_split_128bit_move_p (rtx dst, rtx src)
 
 /* Split a complex SIMD combine.  */
 
+/* Generate code to enable conditional branches in functions over 1 MiB.  */
+const char *
+aarch64_gen_far_branch (rtx * operands, int pos_label, const char * dest,
+			const char * branch_format)
+{
+rtx_code_label * tmp_label = gen_label_rtx ();
+char label_buf[256];
+char buffer[128];
+ASM_GENERATE_INTERNAL_LABEL (label_buf, dest,
+ CODE_LABEL_NUMBER (tmp_label));
+const char *label_ptr = targetm.strip_name_encoding (label_buf);
+rtx dest_label = operands[pos_label];
+operands[pos_label] = tmp_label;
+
+snprintf (buffer, sizeof (buffer), "%s%s", branch_format, label_ptr);
+output_asm_insn (buffer, operands);
+
+snprintf (buffer, sizeof (buffer), "b\t%%l%d\n%s:", pos_label, label_ptr);
+operands[pos_label] = dest_label;
+output_asm_insn (buffer, operands);
+return "";
+}
+
 void
 aarch64_split_simd_combine (rtx dst, rtx src1, rtx src2)
 {
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 4e7a6d19ac2ff8067912052697ca7a1fc403f910..c3c3beb75b4d4486d5b235e31b4db7bd213c7c7b 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -179,6 +179,13 @@
 	 (const_string "no")
 	] (const_string "yes")))
 
+;; Attribute that specifies whether we are dealing with a branch to a
+;; label that is far away, i.e. further away than the maximum/minimum
+;; representable in a signed 21-bits number.
+;; 0 :=: no
+;; 1 :=: yes
+(define_attr "far_branch" "" (const_int 0))
+
 ;; ---
 ;; Pipeline descriptions and scheduling
 ;; ---
@@ -306,8 +313,23 @@
 			   (label_ref (match_operand 2 "" ""))
 			   (pc)))]
   ""
-  "b%m0\\t%l2"
-  [(set_attr "type" "branch")]
+  {
+if (get_attr_length (insn) == 8)
+  return aarch64_gen_far_branch (operands, 2, "Lbcond", "b%M0\\t");
+else
+  return  "b%m0\\t%l2";
+  }
+  [(set_attr "type" "branch")
+   (set (attr "length")
+	(if_then_else (and 

Re: [PATCH][AARCH64]Fix for branch offsets over 1 MiB

2015-08-26 Thread Marcus Shawcroft
On 25 August 2015 at 14:12, Andre Vieira andre.simoesdiasvie...@arm.com wrote:

 gcc/ChangeLog:
 2015-08-07  Ramana Radhakrishnan  ramana.radhakrish...@arm.com
 Andre Vieira  andre.simoesdiasvie...@arm.com

 * config/aarch64/aarch64.md (*condjump): Handle functions  1 Mib.
 (*cboptabmode1): Likewise.
 (*tboptabmode1): Likewise.
 (*cboptabmode1): Likewise.
 * config/aarch64/iterators.md (inv_cb): New code attribute.
 (inv_tb): Likewise.
 * config/aarch64/aarch64.c (aarch64_gen_far_branch): New.
 * config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New.

 gcc/testsuite/ChangeLog:
 2015-08-07  Andre Vieira  andre.simoesdiasvie...@arm.com

 * gcc.target/aarch64/long_branch_1.c: New test.

OK /Marcus


Re: [PATCH][AARCH64]Fix for branch offsets over 1 MiB

2015-08-25 Thread Andrew Pinski
On Tue, Aug 25, 2015 at 5:50 PM, Andrew Pinski pins...@gmail.com wrote:
 On Tue, Aug 25, 2015 at 5:37 PM, Andre Vieira
 andre.simoesdiasvie...@arm.com wrote:
 Conditional branches have a maximum range of [-1048576, 1048572]. Any
 destination further away can not be reached by these.
 To be able to have conditional branches in very large functions, we invert
 the condition and change the destination to jump over an unconditional
 branch to the original, far away, destination.

 gcc/ChangeLog:
 2015-08-07  Ramana Radhakrishnan  ramana.radhakrish...@arm.com
 Andre Vieira  andre.simoesdiasvie...@arm.com

 * config/aarch64/aarch64.md (*condjump): Handle functions  1
 Mib.
 (*cboptabmode1): Idem.
 (*tboptabmode1): Idem.
 (*cboptabmode1): Idem.
 * config/aarch64/iterators.md (inv_cb): New code attribute.
 (inv_tb): Idem.
 * config/aarch64/aarch64.c (aarch64_gen_far_branch): New.
 * config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New.

 gcc/testsuite/ChangeLog:
 2015-08-07  Andre Vieira  andre.simoesdiasvie...@arm.com

 * gcc.target/aarch64/long-branch.c: New test.

 Just a few comments about the testcase.  You could improve the size
 (on disk) of the testcase by using the preprocessor some more:
 Something like:
 #define CASE_ENTRY2 (x) CASE_ENTRY ((x)) CASE_ENTRY ((x)+1)
 #define CASE_ENTRY4 (x) CASE_ENTRY2 ((x)) CASE_ENTRY2 ((x)+2+1)
 #define CASE_ENTRY8 (x) CASE_ENTRY4 ((x)) CASE_ENTRY4 ((x)+4+1)
 #define CASE_ENTRY16 (x) CASE_ENTRY8 ((x)) CASE_ENTRY8 ((x)+8+1)
 #define CASE_ENTRY32 (x) CASE_ENTRY16 ((x)) CASE_ENTRY16 ((x)+16)
 #define CASE_ENTRY64 (x) CASE_ENTRY32 ((x)) CASE_ENTRY32 ((x)+32+1)
 #define CASE_ENTRY128 (x) CASE_ENTRY64 ((x)) CASE_ENTRY16 ((x)+64+1)
 #define CASE_ENTRY256 (x) CASE_ENTRY128 ((x)) CASE_ENTRY128 ((x)+128+1)


I do have an off by one error but you should get the idea.  Basically
instead of 200 lines, we only have 9 lines (log2(256) == 8).

Thanks,
Andrew


 And then use
 CASE_ENTRY256 (1)

 You can do the same trick to reduce the size of CASE_ENTRY too.

 Thanks,
 Andrew Pinski


Re: [PATCH][AARCH64]Fix for branch offsets over 1 MiB

2015-08-25 Thread Andrew Pinski
On Tue, Aug 25, 2015 at 5:37 PM, Andre Vieira
andre.simoesdiasvie...@arm.com wrote:
 Conditional branches have a maximum range of [-1048576, 1048572]. Any
 destination further away can not be reached by these.
 To be able to have conditional branches in very large functions, we invert
 the condition and change the destination to jump over an unconditional
 branch to the original, far away, destination.

 gcc/ChangeLog:
 2015-08-07  Ramana Radhakrishnan  ramana.radhakrish...@arm.com
 Andre Vieira  andre.simoesdiasvie...@arm.com

 * config/aarch64/aarch64.md (*condjump): Handle functions  1
 Mib.
 (*cboptabmode1): Idem.
 (*tboptabmode1): Idem.
 (*cboptabmode1): Idem.
 * config/aarch64/iterators.md (inv_cb): New code attribute.
 (inv_tb): Idem.
 * config/aarch64/aarch64.c (aarch64_gen_far_branch): New.
 * config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New.

 gcc/testsuite/ChangeLog:
 2015-08-07  Andre Vieira  andre.simoesdiasvie...@arm.com

 * gcc.target/aarch64/long-branch.c: New test.

Just a few comments about the testcase.  You could improve the size
(on disk) of the testcase by using the preprocessor some more:
Something like:
#define CASE_ENTRY2 (x) CASE_ENTRY ((x)) CASE_ENTRY ((x)+1)
#define CASE_ENTRY4 (x) CASE_ENTRY2 ((x)) CASE_ENTRY2 ((x)+2+1)
#define CASE_ENTRY8 (x) CASE_ENTRY4 ((x)) CASE_ENTRY4 ((x)+4+1)
#define CASE_ENTRY16 (x) CASE_ENTRY8 ((x)) CASE_ENTRY8 ((x)+8+1)
#define CASE_ENTRY32 (x) CASE_ENTRY16 ((x)) CASE_ENTRY16 ((x)+16)
#define CASE_ENTRY64 (x) CASE_ENTRY32 ((x)) CASE_ENTRY32 ((x)+32+1)
#define CASE_ENTRY128 (x) CASE_ENTRY64 ((x)) CASE_ENTRY16 ((x)+64+1)
#define CASE_ENTRY256 (x) CASE_ENTRY128 ((x)) CASE_ENTRY128 ((x)+128+1)

And then use
CASE_ENTRY256 (1)

You can do the same trick to reduce the size of CASE_ENTRY too.

Thanks,
Andrew Pinski


[PATCH][AARCH64]Fix for branch offsets over 1 MiB

2015-08-25 Thread Andre Vieira
Conditional branches have a maximum range of [-1048576, 1048572]. Any 
destination further away can not be reached by these.
To be able to have conditional branches in very large functions, we 
invert the condition and change the destination to jump over an 
unconditional branch to the original, far away, destination.


gcc/ChangeLog:
2015-08-07  Ramana Radhakrishnan  ramana.radhakrish...@arm.com
Andre Vieira  andre.simoesdiasvie...@arm.com

* config/aarch64/aarch64.md (*condjump): Handle functions  1
Mib.
(*cboptabmode1): Idem.
(*tboptabmode1): Idem.
(*cboptabmode1): Idem.
* config/aarch64/iterators.md (inv_cb): New code attribute.
(inv_tb): Idem.
* config/aarch64/aarch64.c (aarch64_gen_far_branch): New.
* config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New.

gcc/testsuite/ChangeLog:
2015-08-07  Andre Vieira  andre.simoesdiasvie...@arm.com

* gcc.target/aarch64/long-branch.c: New test.
From 9759c5a50c44b0421c7911014e63a6222dd9017d Mon Sep 17 00:00:00 2001
From: Andre Simoes Dias Vieira andsi...@arm.com
Date: Fri, 14 Aug 2015 10:21:57 +0100
Subject: [PATCH] fix for far branches

---
 gcc/config/aarch64/aarch64-protos.h|   1 +
 gcc/config/aarch64/aarch64.c   |  23 +
 gcc/config/aarch64/aarch64.md  |  89 +++-
 gcc/config/aarch64/iterators.md|   6 +
 gcc/testsuite/gcc.target/aarch64/long_branch.c | 565 +
 5 files changed, 669 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/long_branch.c

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 32b5d0958a6e0b2356874736f858f007fe68cdda..87a26deb6a0dbf13e25275baeebec21a37a42f41 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -316,6 +316,7 @@ unsigned aarch64_trampoline_size (void);
 void aarch64_asm_output_labelref (FILE *, const char *);
 void aarch64_cpu_cpp_builtins (cpp_reader *);
 void aarch64_elf_asm_named_section (const char *, unsigned, tree);
+const char * aarch64_gen_far_branch (rtx *, int, const char *, const char *);
 void aarch64_err_no_fpadvsimd (machine_mode, const char *);
 void aarch64_expand_epilogue (bool);
 void aarch64_expand_mov_immediate (rtx, rtx);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 7159f5aca5df97f154b3e654f60af9136354f335..3b491a232d81892b6511bad84e4174d939fa1be7 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -587,6 +587,29 @@ static const char * const aarch64_condition_codes[] =
   hi, ls, ge, lt, gt, le, al, nv
 };
 
+/* Generate code to enable conditional branches in functions over 1 MiB.  */
+const char *
+aarch64_gen_far_branch (rtx * operands, int pos_label, const char * dest,
+			const char * branch_format)
+{
+rtx_code_label * tmp_label = gen_label_rtx ();
+char label_buf[256];
+char buffer[128];
+ASM_GENERATE_INTERNAL_LABEL (label_buf, dest,
+ CODE_LABEL_NUMBER (tmp_label));
+const char *label_ptr = targetm.strip_name_encoding (label_buf);
+rtx dest_label = operands[pos_label];
+operands[pos_label] = tmp_label;
+
+snprintf (buffer, sizeof (buffer), %s%s, branch_format, label_ptr);
+output_asm_insn (buffer, operands);
+
+snprintf (buffer, sizeof (buffer), b\t%%l%d\n%s:, pos_label, label_ptr);
+operands[pos_label] = dest_label;
+output_asm_insn (buffer, operands);
+return ;
+}
+
 void
 aarch64_err_no_fpadvsimd (machine_mode mode, const char *msg)
 {
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 35255e91a95cdf20d52270470202f7499ba46bb2..74f6e3ec4bdcd076c2ad6d1431102aa50dfb5068 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -181,6 +181,13 @@
 	 (const_string no)
 	] (const_string yes)))
 
+;; Attribute that specifies whether we are dealing with a branch to a
+;; label that is far away, i.e. further away than the maximum/minimum
+;; representable in a signed 21-bits number.
+;; 0 :=: no
+;; 1 :=: yes
+(define_attr far_branch  (const_int 0))
+
 ;; ---
 ;; Pipeline descriptions and scheduling
 ;; ---
@@ -308,8 +315,23 @@
 			   (label_ref (match_operand 2  ))
 			   (pc)))]
   
-  b%m0\\t%l2
-  [(set_attr type branch)]
+  {
+if (get_attr_length (insn) == 8)
+  return aarch64_gen_far_branch (operands, 2, Lbcond, b%M0\\t);
+else
+  return  b%m0\\t%l2;
+  }
+  [(set_attr type branch)
+   (set (attr length)
+	(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
+			   (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
+		  (const_int 4)
+		  (const_int 8)))
+   (set (attr far_branch)
+	(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
+			   (lt 

Re: [PATCH][AARCH64]Fix for branch offsets over 1 MiB

2015-08-25 Thread Andre Vieira

On 25/08/15 10:52, Andrew Pinski wrote:

On Tue, Aug 25, 2015 at 5:50 PM, Andrew Pinski pins...@gmail.com wrote:

On Tue, Aug 25, 2015 at 5:37 PM, Andre Vieira
andre.simoesdiasvie...@arm.com wrote:

Conditional branches have a maximum range of [-1048576, 1048572]. Any
destination further away can not be reached by these.
To be able to have conditional branches in very large functions, we invert
the condition and change the destination to jump over an unconditional
branch to the original, far away, destination.

gcc/ChangeLog:
2015-08-07  Ramana Radhakrishnan  ramana.radhakrish...@arm.com
 Andre Vieira  andre.simoesdiasvie...@arm.com

 * config/aarch64/aarch64.md (*condjump): Handle functions  1
 Mib.
 (*cboptabmode1): Idem.
 (*tboptabmode1): Idem.
 (*cboptabmode1): Idem.
 * config/aarch64/iterators.md (inv_cb): New code attribute.
 (inv_tb): Idem.
 * config/aarch64/aarch64.c (aarch64_gen_far_branch): New.
 * config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New.

gcc/testsuite/ChangeLog:
2015-08-07  Andre Vieira  andre.simoesdiasvie...@arm.com

 * gcc.target/aarch64/long-branch.c: New test.


Just a few comments about the testcase.  You could improve the size
(on disk) of the testcase by using the preprocessor some more:
Something like:
#define CASE_ENTRY2 (x) CASE_ENTRY ((x)) CASE_ENTRY ((x)+1)
#define CASE_ENTRY4 (x) CASE_ENTRY2 ((x)) CASE_ENTRY2 ((x)+2+1)
#define CASE_ENTRY8 (x) CASE_ENTRY4 ((x)) CASE_ENTRY4 ((x)+4+1)
#define CASE_ENTRY16 (x) CASE_ENTRY8 ((x)) CASE_ENTRY8 ((x)+8+1)
#define CASE_ENTRY32 (x) CASE_ENTRY16 ((x)) CASE_ENTRY16 ((x)+16)
#define CASE_ENTRY64 (x) CASE_ENTRY32 ((x)) CASE_ENTRY32 ((x)+32+1)
#define CASE_ENTRY128 (x) CASE_ENTRY64 ((x)) CASE_ENTRY16 ((x)+64+1)
#define CASE_ENTRY256 (x) CASE_ENTRY128 ((x)) CASE_ENTRY128 ((x)+128+1)



I do have an off by one error but you should get the idea.  Basically
instead of 200 lines, we only have 9 lines (log2(256) == 8).

Thanks,
Andrew



And then use
CASE_ENTRY256 (1)

You can do the same trick to reduce the size of CASE_ENTRY too.

Thanks,
Andrew Pinski




Conditional branches have a maximum range of [-1048576, 1048572]. Any 
destination further away can not be reached by these.
To be able to have conditional branches in very large functions, we 
invert the condition and change the destination to jump over an 
unconditional branch to the original, far away, destination.


gcc/ChangeLog:
2015-08-07  Ramana Radhakrishnan  ramana.radhakrish...@arm.com
Andre Vieira  andre.simoesdiasvie...@arm.com

* config/aarch64/aarch64.md (*condjump): Handle functions  1 Mib.
(*cboptabmode1): Likewise.
(*tboptabmode1): Likewise.
(*cboptabmode1): Likewise.
* config/aarch64/iterators.md (inv_cb): New code attribute.
(inv_tb): Likewise.
* config/aarch64/aarch64.c (aarch64_gen_far_branch): New.
* config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New.

gcc/testsuite/ChangeLog:
2015-08-07  Andre Vieira  andre.simoesdiasvie...@arm.com

* gcc.target/aarch64/long_branch_1.c: New test.
From e34022ecd6f914b5a713594ca5b21b33929a3a1f Mon Sep 17 00:00:00 2001
From: Andre Simoes Dias Vieira andsi...@arm.com
Date: Tue, 25 Aug 2015 13:12:11 +0100
Subject: [PATCH] fix for far branches

---
 gcc/config/aarch64/aarch64-protos.h  |  1 +
 gcc/config/aarch64/aarch64.c | 23 ++
 gcc/config/aarch64/aarch64.md| 89 +++
 gcc/config/aarch64/iterators.md  |  6 ++
 gcc/testsuite/gcc.target/aarch64/long_branch_1.c | 91 
 5 files changed, 195 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/long_branch_1.c

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 4b3cbedbd0a5fa186619e05c0c0b400c8257b1c0..9afb7ef9afadf2b3dfeb24db230829344201deba 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -322,6 +322,7 @@ unsigned aarch64_trampoline_size (void);
 void aarch64_asm_output_labelref (FILE *, const char *);
 void aarch64_cpu_cpp_builtins (cpp_reader *);
 void aarch64_elf_asm_named_section (const char *, unsigned, tree);
+const char * aarch64_gen_far_branch (rtx *, int, const char *, const char *);
 void aarch64_err_no_fpadvsimd (machine_mode, const char *);
 void aarch64_expand_epilogue (bool);
 void aarch64_expand_mov_immediate (rtx, rtx);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 87bbf6e7988e4ef796c09075ee584822483cbbce..188d0dd555d3d765aff7e78623a4e938497bec3f 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -586,6 +586,29 @@ static const char * const aarch64_condition_codes[] =
   hi, ls, ge, lt, gt, le, al, nv
 };
 
+/* Generate code to enable conditional branches in functions over 1 MiB.  */
+const