--- /dev/null
+From 6d852ffb43b111a39162135c95249e749c4e285b Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Thu, 6 Aug 2015 01:16:02 +0300
+Subject: [PATCH] xtensa: add -mauto-litpools option
+
+With support from assembler this option allows compiling huge functions,
+where single literal pool at the beginning of a function may not be
+reachable by L32R instructions at its end.
+
+Currently assembler --auto-litpools option cannot deal with literals
+used from multiple locations separated by more than 256 KBytes of code.
+Don't turn constants into literals, instead use MOVI instruction to load
+them into registers and let the assembler turn them into literals as
+necessary.
+
+2015-08-12 Max Filippov <jcmvbkbc@gmail.com>
+gcc/
+ * config/xtensa/constraints.md (define_constraint "Y"): New
+ constraint.
+ * config/xtensa/elf.h (ASM_SPEC): Add m(no-)auto-litpools.
+ * config/xtensa/linux.h (ASM_SPEC): Likewise.
+ * config/xtensa/predicates.md (move_operand): Match constants
+ and symbols in the presence of TARGET_AUTO_LITPOOLS.
+ * config/xtensa/xtensa.c (xtensa_valid_move): Don't allow
+ immediate references to TLS data.
+ (xtensa_emit_move_sequence): Don't force constants to memory in
+ the presence of TARGET_AUTO_LITPOOLS.
+ (print_operand): Add 'y' format, same as default, but capable of
+ printing SF mode constants as well.
+ * config/xtensa/xtensa.md (movsi_internal, movhi_internal)
+ (movsf_internal): Add movi pattern that loads literal.
+ (movsf, movdf): Don't force constants to memory in the presence
+ of TARGET_AUTO_LITPOOLS.
+ (movdf_internal): Add 'Y' constraint.
+ * config/xtensa/xtensa.opt (mauto-litpools): New option.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+Backported from: r226828
+Changes to ChangeLogs and documentation are dropped.
+
+ gcc/config/xtensa/constraints.md | 5 +++++
+ gcc/config/xtensa/elf.h | 4 +++-
+ gcc/config/xtensa/linux.h | 4 +++-
+ gcc/config/xtensa/predicates.md | 3 ++-
+ gcc/config/xtensa/xtensa.c | 19 ++++++++++++++++++-
+ gcc/config/xtensa/xtensa.md | 35 +++++++++++++++++++----------------
+ gcc/config/xtensa/xtensa.opt | 4 ++++
+ 7 files changed, 54 insertions(+), 20 deletions(-)
+
+diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
+index 30f4c1f..773d4f9 100644
+--- a/gcc/config/xtensa/constraints.md
++++ b/gcc/config/xtensa/constraints.md
+@@ -111,6 +111,11 @@
+ (and (match_code "const_int")
+ (match_test "xtensa_mask_immediate (ival)")))
+
++(define_constraint "Y"
++ "A constant that can be used in relaxed MOVI instructions."
++ (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
++ (match_test "TARGET_AUTO_LITPOOLS")))
++
+ ;; Memory constraints. Do not use define_memory_constraint here. Doing so
+ ;; causes reload to force some constants into the constant pool, but since
+ ;; the Xtensa constant pool can only be accessed with L32R instructions, it
+diff --git a/gcc/config/xtensa/elf.h b/gcc/config/xtensa/elf.h
+index e59bede..12056f7 100644
+--- a/gcc/config/xtensa/elf.h
++++ b/gcc/config/xtensa/elf.h
+@@ -48,7 +48,9 @@ along with GCC; see the file COPYING3. If not see
+ %{mtarget-align:--target-align} \
+ %{mno-target-align:--no-target-align} \
+ %{mlongcalls:--longcalls} \
+- %{mno-longcalls:--no-longcalls}"
++ %{mno-longcalls:--no-longcalls} \
++ %{mauto-litpools:--auto-litpools} \
++ %{mno-auto-litpools:--no-auto-litpools}"
+
+ #undef LIB_SPEC
+ #define LIB_SPEC "-lc -lsim -lc -lhandlers-sim -lhal"
+diff --git a/gcc/config/xtensa/linux.h b/gcc/config/xtensa/linux.h
+index 675aacf..5b0243a 100644
+--- a/gcc/config/xtensa/linux.h
++++ b/gcc/config/xtensa/linux.h
+@@ -42,7 +42,9 @@ along with GCC; see the file COPYING3. If not see
+ %{mtarget-align:--target-align} \
+ %{mno-target-align:--no-target-align} \
+ %{mlongcalls:--longcalls} \
+- %{mno-longcalls:--no-longcalls}"
++ %{mno-longcalls:--no-longcalls} \
++ %{mauto-litpools:--auto-litpools} \
++ %{mno-auto-litpools:--no-auto-litpools}"
+
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+
+diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
+index e02209e..d7dfa11 100644
+--- a/gcc/config/xtensa/predicates.md
++++ b/gcc/config/xtensa/predicates.md
+@@ -142,7 +142,8 @@
+ (match_test "GET_MODE_CLASS (mode) == MODE_INT
+ && xtensa_simm12b (INTVAL (op))"))
+ (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
+- (match_test "TARGET_CONST16 && CONSTANT_P (op)
++ (match_test "(TARGET_CONST16 || TARGET_AUTO_LITPOOLS)
++ && CONSTANT_P (op)
+ && GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0")))))
+
+ ;; Accept the floating point constant 1 in the appropriate mode.
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
+index eb039ba..206ff80 100644
+--- a/gcc/config/xtensa/xtensa.c
++++ b/gcc/config/xtensa/xtensa.c
+@@ -501,6 +501,9 @@ xtensa_valid_move (machine_mode mode, rtx *operands)
+ {
+ int dst_regnum = xt_true_regnum (operands[0]);
+
++ if (xtensa_tls_referenced_p (operands[1]))
++ return FALSE;
++
+ /* The stack pointer can only be assigned with a MOVSP opcode. */
+ if (dst_regnum == STACK_POINTER_REGNUM)
+ return !TARGET_WINDOWED_ABI
+@@ -1069,7 +1072,7 @@ xtensa_emit_move_sequence (rtx *operands, machine_mode mode)
+ return 1;
+ }
+
+- if (! TARGET_CONST16)
++ if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16)
+ {
+ src = force_const_mem (SImode, src);
+ operands[1] = src;
+@@ -2449,6 +2452,20 @@ print_operand (FILE *file, rtx x, int letter)
+ }
+ break;
+
++ case 'y':
++ if (GET_CODE (x) == CONST_DOUBLE &&
++ GET_MODE (x) == SFmode)
++ {
++ REAL_VALUE_TYPE r;
++ long l;
++ REAL_VALUE_FROM_CONST_DOUBLE (r, x);
++ REAL_VALUE_TO_TARGET_SINGLE (r, l);
++ fprintf (file, "0x%08lx", l);
++ break;
++ }
++
++ /* fall through */
++
+ default:
+ if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
+ fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
+diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
+index 6d84384..0e673a3 100644
+--- a/gcc/config/xtensa/xtensa.md
++++ b/gcc/config/xtensa/xtensa.md
+@@ -761,8 +761,8 @@
+ })
+
+ (define_insn "movsi_internal"
+- [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
+- (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
++ [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
++ (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
+ "xtensa_valid_move (SImode, operands)"
+ "@
+ movi.n\t%0, %x1
+@@ -774,15 +774,16 @@
+ mov\t%0, %1
+ movsp\t%0, %1
+ movi\t%0, %x1
++ movi\t%0, %1
+ const16\t%0, %t1\;const16\t%0, %b1
+ %v1l32r\t%0, %1
+ %v1l32i\t%0, %1
+ %v0s32i\t%1, %0
+ rsr\t%0, ACCLO
+ wsr\t%1, ACCLO"
+- [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
++ [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
+ (set_attr "mode" "SI")
+- (set_attr "length" "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
++ (set_attr "length" "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
+
+ ;; 16-bit Integer moves
+
+@@ -796,21 +797,22 @@
+ })
+
+ (define_insn "movhi_internal"
+- [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
+- (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
++ [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
++ (match_operand:HI 1 "move_operand" "M,d,r,I,Y,U,r,*A,*r"))]
+ "xtensa_valid_move (HImode, operands)"
+ "@
+ movi.n\t%0, %x1
+ mov.n\t%0, %1
+ mov\t%0, %1
+ movi\t%0, %x1
++ movi\t%0, %1
+ %v1l16ui\t%0, %1
+ %v0s16i\t%1, %0
+ rsr\t%0, ACCLO
+ wsr\t%1, ACCLO"
+- [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
++ [(set_attr "type" "move,move,move,move,move,load,store,rsr,wsr")
+ (set_attr "mode" "HI")
+- (set_attr "length" "2,2,3,3,3,3,3,3")])
++ (set_attr "length" "2,2,3,3,3,3,3,3,3")])
+
+ ;; 8-bit Integer moves
+
+@@ -881,7 +883,7 @@
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ {
+- if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
++ if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (SFmode, operands[1]);
+
+ if ((!register_operand (operands[0], SFmode)
+@@ -896,8 +898,8 @@
+ })
+
+ (define_insn "movsf_internal"
+- [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
+- (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
++ [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
++ (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
+ "((register_operand (operands[0], SFmode)
+ || register_operand (operands[1], SFmode))
+ && !(FP_REG_P (xt_true_regnum (operands[0]))
+@@ -912,13 +914,14 @@
+ mov\t%0, %1
+ wfr\t%0, %1
+ rfr\t%0, %1
++ movi\t%0, %y1
+ const16\t%0, %t1\;const16\t%0, %b1
+ %v1l32r\t%0, %1
+ %v1l32i\t%0, %1
+ %v0s32i\t%1, %0"
+- [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
++ [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
+ (set_attr "mode" "SF")
+- (set_attr "length" "3,3,3,2,2,2,3,3,3,6,3,3,3")])
++ (set_attr "length" "3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
+
+ (define_insn "*lsiu"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+@@ -991,7 +994,7 @@
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ {
+- if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
++ if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
+ operands[1] = force_const_mem (DFmode, operands[1]);
+
+ if (!register_operand (operands[0], DFmode)
+@@ -1002,8 +1005,8 @@
+ })
+
+ (define_insn_and_split "movdf_internal"
+- [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
+- (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
++ [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U")
++ (match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))]
+ "register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode)"
+ "#"
+diff --git a/gcc/config/xtensa/xtensa.opt b/gcc/config/xtensa/xtensa.opt
+index 2fd6cee..21c6e96 100644
+--- a/gcc/config/xtensa/xtensa.opt
++++ b/gcc/config/xtensa/xtensa.opt
+@@ -38,6 +38,10 @@ mtext-section-literals
+ Target
+ Intersperse literal pools with code in the text section
+
++mauto-litpools
++Target Report Mask(AUTO_LITPOOLS)
++Relax literals in assembler and place them automatically in the text section
++
+ mserialize-volatile
+ Target Report Mask(SERIALIZE_VOLATILE)
+ -mno-serialize-volatile Do not serialize volatile memory references with MEMW instructions
+--
+1.8.1.4
+
--- /dev/null
+From 6d852ffb43b111a39162135c95249e749c4e285b Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Thu, 6 Aug 2015 01:16:02 +0300
+Subject: [PATCH] xtensa: add -mauto-litpools option
+
+With support from assembler this option allows compiling huge functions,
+where single literal pool at the beginning of a function may not be
+reachable by L32R instructions at its end.
+
+Currently assembler --auto-litpools option cannot deal with literals
+used from multiple locations separated by more than 256 KBytes of code.
+Don't turn constants into literals, instead use MOVI instruction to load
+them into registers and let the assembler turn them into literals as
+necessary.
+
+2015-08-12 Max Filippov <jcmvbkbc@gmail.com>
+gcc/
+ * config/xtensa/constraints.md (define_constraint "Y"): New
+ constraint.
+ * config/xtensa/elf.h (ASM_SPEC): Add m(no-)auto-litpools.
+ * config/xtensa/linux.h (ASM_SPEC): Likewise.
+ * config/xtensa/predicates.md (move_operand): Match constants
+ and symbols in the presence of TARGET_AUTO_LITPOOLS.
+ * config/xtensa/xtensa.c (xtensa_valid_move): Don't allow
+ immediate references to TLS data.
+ (xtensa_emit_move_sequence): Don't force constants to memory in
+ the presence of TARGET_AUTO_LITPOOLS.
+ (print_operand): Add 'y' format, same as default, but capable of
+ printing SF mode constants as well.
+ * config/xtensa/xtensa.md (movsi_internal, movhi_internal)
+ (movsf_internal): Add movi pattern that loads literal.
+ (movsf, movdf): Don't force constants to memory in the presence
+ of TARGET_AUTO_LITPOOLS.
+ (movdf_internal): Add 'Y' constraint.
+ * config/xtensa/xtensa.opt (mauto-litpools): New option.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+Backported from: r226828
+Changes to ChangeLogs and documentation are dropped.
+
+ gcc/config/xtensa/constraints.md | 5 +++++
+ gcc/config/xtensa/elf.h | 4 +++-
+ gcc/config/xtensa/linux.h | 4 +++-
+ gcc/config/xtensa/predicates.md | 3 ++-
+ gcc/config/xtensa/xtensa.c | 19 ++++++++++++++++++-
+ gcc/config/xtensa/xtensa.md | 35 +++++++++++++++++++----------------
+ gcc/config/xtensa/xtensa.opt | 4 ++++
+ 7 files changed, 54 insertions(+), 20 deletions(-)
+
+diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
+index 30f4c1f..773d4f9 100644
+--- a/gcc/config/xtensa/constraints.md
++++ b/gcc/config/xtensa/constraints.md
+@@ -111,6 +111,11 @@
+ (and (match_code "const_int")
+ (match_test "xtensa_mask_immediate (ival)")))
+
++(define_constraint "Y"
++ "A constant that can be used in relaxed MOVI instructions."
++ (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
++ (match_test "TARGET_AUTO_LITPOOLS")))
++
+ ;; Memory constraints. Do not use define_memory_constraint here. Doing so
+ ;; causes reload to force some constants into the constant pool, but since
+ ;; the Xtensa constant pool can only be accessed with L32R instructions, it
+diff --git a/gcc/config/xtensa/elf.h b/gcc/config/xtensa/elf.h
+index e59bede..12056f7 100644
+--- a/gcc/config/xtensa/elf.h
++++ b/gcc/config/xtensa/elf.h
+@@ -48,7 +48,9 @@ along with GCC; see the file COPYING3. If not see
+ %{mtarget-align:--target-align} \
+ %{mno-target-align:--no-target-align} \
+ %{mlongcalls:--longcalls} \
+- %{mno-longcalls:--no-longcalls}"
++ %{mno-longcalls:--no-longcalls} \
++ %{mauto-litpools:--auto-litpools} \
++ %{mno-auto-litpools:--no-auto-litpools}"
+
+ #undef LIB_SPEC
+ #define LIB_SPEC "-lc -lsim -lc -lhandlers-sim -lhal"
+diff --git a/gcc/config/xtensa/linux.h b/gcc/config/xtensa/linux.h
+index 675aacf..5b0243a 100644
+--- a/gcc/config/xtensa/linux.h
++++ b/gcc/config/xtensa/linux.h
+@@ -42,7 +42,9 @@ along with GCC; see the file COPYING3. If not see
+ %{mtarget-align:--target-align} \
+ %{mno-target-align:--no-target-align} \
+ %{mlongcalls:--longcalls} \
+- %{mno-longcalls:--no-longcalls}"
++ %{mno-longcalls:--no-longcalls} \
++ %{mauto-litpools:--auto-litpools} \
++ %{mno-auto-litpools:--no-auto-litpools}"
+
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+
+diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
+index e02209e..d7dfa11 100644
+--- a/gcc/config/xtensa/predicates.md
++++ b/gcc/config/xtensa/predicates.md
+@@ -142,7 +142,8 @@
+ (match_test "GET_MODE_CLASS (mode) == MODE_INT
+ && xtensa_simm12b (INTVAL (op))"))
+ (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
+- (match_test "TARGET_CONST16 && CONSTANT_P (op)
++ (match_test "(TARGET_CONST16 || TARGET_AUTO_LITPOOLS)
++ && CONSTANT_P (op)
+ && GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0")))))
+
+ ;; Accept the floating point constant 1 in the appropriate mode.
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
+index eb039ba..206ff80 100644
+--- a/gcc/config/xtensa/xtensa.c
++++ b/gcc/config/xtensa/xtensa.c
+@@ -501,6 +501,9 @@ xtensa_valid_move (machine_mode mode, rtx *operands)
+ {
+ int dst_regnum = xt_true_regnum (operands[0]);
+
++ if (xtensa_tls_referenced_p (operands[1]))
++ return FALSE;
++
+ /* The stack pointer can only be assigned with a MOVSP opcode. */
+ if (dst_regnum == STACK_POINTER_REGNUM)
+ return !TARGET_WINDOWED_ABI
+@@ -1069,7 +1072,7 @@ xtensa_emit_move_sequence (rtx *operands, machine_mode mode)
+ return 1;
+ }
+
+- if (! TARGET_CONST16)
++ if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16)
+ {
+ src = force_const_mem (SImode, src);
+ operands[1] = src;
+@@ -2449,6 +2452,20 @@ print_operand (FILE *file, rtx x, int letter)
+ }
+ break;
+
++ case 'y':
++ if (GET_CODE (x) == CONST_DOUBLE &&
++ GET_MODE (x) == SFmode)
++ {
++ REAL_VALUE_TYPE r;
++ long l;
++ REAL_VALUE_FROM_CONST_DOUBLE (r, x);
++ REAL_VALUE_TO_TARGET_SINGLE (r, l);
++ fprintf (file, "0x%08lx", l);
++ break;
++ }
++
++ /* fall through */
++
+ default:
+ if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
+ fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
+diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
+index 6d84384..0e673a3 100644
+--- a/gcc/config/xtensa/xtensa.md
++++ b/gcc/config/xtensa/xtensa.md
+@@ -761,8 +761,8 @@
+ })
+
+ (define_insn "movsi_internal"
+- [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
+- (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
++ [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
++ (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
+ "xtensa_valid_move (SImode, operands)"
+ "@
+ movi.n\t%0, %x1
+@@ -774,15 +774,16 @@
+ mov\t%0, %1
+ movsp\t%0, %1
+ movi\t%0, %x1
++ movi\t%0, %1
+ const16\t%0, %t1\;const16\t%0, %b1
+ %v1l32r\t%0, %1
+ %v1l32i\t%0, %1
+ %v0s32i\t%1, %0
+ rsr\t%0, ACCLO
+ wsr\t%1, ACCLO"
+- [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
++ [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
+ (set_attr "mode" "SI")
+- (set_attr "length" "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
++ (set_attr "length" "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
+
+ ;; 16-bit Integer moves
+
+@@ -796,21 +797,22 @@
+ })
+
+ (define_insn "movhi_internal"
+- [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
+- (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
++ [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
++ (match_operand:HI 1 "move_operand" "M,d,r,I,Y,U,r,*A,*r"))]
+ "xtensa_valid_move (HImode, operands)"
+ "@
+ movi.n\t%0, %x1
+ mov.n\t%0, %1
+ mov\t%0, %1
+ movi\t%0, %x1
++ movi\t%0, %1
+ %v1l16ui\t%0, %1
+ %v0s16i\t%1, %0
+ rsr\t%0, ACCLO
+ wsr\t%1, ACCLO"
+- [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
++ [(set_attr "type" "move,move,move,move,move,load,store,rsr,wsr")
+ (set_attr "mode" "HI")
+- (set_attr "length" "2,2,3,3,3,3,3,3")])
++ (set_attr "length" "2,2,3,3,3,3,3,3,3")])
+
+ ;; 8-bit Integer moves
+
+@@ -881,7 +883,7 @@
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ {
+- if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
++ if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (SFmode, operands[1]);
+
+ if ((!register_operand (operands[0], SFmode)
+@@ -896,8 +898,8 @@
+ })
+
+ (define_insn "movsf_internal"
+- [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
+- (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
++ [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
++ (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
+ "((register_operand (operands[0], SFmode)
+ || register_operand (operands[1], SFmode))
+ && !(FP_REG_P (xt_true_regnum (operands[0]))
+@@ -912,13 +914,14 @@
+ mov\t%0, %1
+ wfr\t%0, %1
+ rfr\t%0, %1
++ movi\t%0, %y1
+ const16\t%0, %t1\;const16\t%0, %b1
+ %v1l32r\t%0, %1
+ %v1l32i\t%0, %1
+ %v0s32i\t%1, %0"
+- [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
++ [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
+ (set_attr "mode" "SF")
+- (set_attr "length" "3,3,3,2,2,2,3,3,3,6,3,3,3")])
++ (set_attr "length" "3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
+
+ (define_insn "*lsiu"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+@@ -991,7 +994,7 @@
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ {
+- if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
++ if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
+ operands[1] = force_const_mem (DFmode, operands[1]);
+
+ if (!register_operand (operands[0], DFmode)
+@@ -1002,8 +1005,8 @@
+ })
+
+ (define_insn_and_split "movdf_internal"
+- [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
+- (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
++ [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U")
++ (match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))]
+ "register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode)"
+ "#"
+diff --git a/gcc/config/xtensa/xtensa.opt b/gcc/config/xtensa/xtensa.opt
+index 2fd6cee..21c6e96 100644
+--- a/gcc/config/xtensa/xtensa.opt
++++ b/gcc/config/xtensa/xtensa.opt
+@@ -38,6 +38,10 @@ mtext-section-literals
+ Target
+ Intersperse literal pools with code in the text section
+
++mauto-litpools
++Target Report Mask(AUTO_LITPOOLS)
++Relax literals in assembler and place them automatically in the text section
++
+ mserialize-volatile
+ Target Report Mask(SERIALIZE_VOLATILE)
+ -mno-serialize-volatile Do not serialize volatile memory references with MEMW instructions
+--
+1.8.1.4
+
--- /dev/null
+From 6d852ffb43b111a39162135c95249e749c4e285b Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Thu, 6 Aug 2015 01:16:02 +0300
+Subject: [PATCH] xtensa: add -mauto-litpools option
+
+With support from assembler this option allows compiling huge functions,
+where single literal pool at the beginning of a function may not be
+reachable by L32R instructions at its end.
+
+Currently assembler --auto-litpools option cannot deal with literals
+used from multiple locations separated by more than 256 KBytes of code.
+Don't turn constants into literals, instead use MOVI instruction to load
+them into registers and let the assembler turn them into literals as
+necessary.
+
+2015-08-12 Max Filippov <jcmvbkbc@gmail.com>
+gcc/
+ * config/xtensa/constraints.md (define_constraint "Y"): New
+ constraint.
+ * config/xtensa/elf.h (ASM_SPEC): Add m(no-)auto-litpools.
+ * config/xtensa/linux.h (ASM_SPEC): Likewise.
+ * config/xtensa/predicates.md (move_operand): Match constants
+ and symbols in the presence of TARGET_AUTO_LITPOOLS.
+ * config/xtensa/xtensa.c (xtensa_valid_move): Don't allow
+ immediate references to TLS data.
+ (xtensa_emit_move_sequence): Don't force constants to memory in
+ the presence of TARGET_AUTO_LITPOOLS.
+ (print_operand): Add 'y' format, same as default, but capable of
+ printing SF mode constants as well.
+ * config/xtensa/xtensa.md (movsi_internal, movhi_internal)
+ (movsf_internal): Add movi pattern that loads literal.
+ (movsf, movdf): Don't force constants to memory in the presence
+ of TARGET_AUTO_LITPOOLS.
+ (movdf_internal): Add 'Y' constraint.
+ * config/xtensa/xtensa.opt (mauto-litpools): New option.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+Backported from: r226828
+Changes to ChangeLogs and documentation are dropped.
+
+ gcc/config/xtensa/constraints.md | 5 +++++
+ gcc/config/xtensa/elf.h | 4 +++-
+ gcc/config/xtensa/linux.h | 4 +++-
+ gcc/config/xtensa/predicates.md | 3 ++-
+ gcc/config/xtensa/xtensa.c | 19 ++++++++++++++++++-
+ gcc/config/xtensa/xtensa.md | 35 +++++++++++++++++++----------------
+ gcc/config/xtensa/xtensa.opt | 4 ++++
+ 7 files changed, 54 insertions(+), 20 deletions(-)
+
+diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
+index 30f4c1f..773d4f9 100644
+--- a/gcc/config/xtensa/constraints.md
++++ b/gcc/config/xtensa/constraints.md
+@@ -111,6 +111,11 @@
+ (and (match_code "const_int")
+ (match_test "xtensa_mask_immediate (ival)")))
+
++(define_constraint "Y"
++ "A constant that can be used in relaxed MOVI instructions."
++ (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
++ (match_test "TARGET_AUTO_LITPOOLS")))
++
+ ;; Memory constraints. Do not use define_memory_constraint here. Doing so
+ ;; causes reload to force some constants into the constant pool, but since
+ ;; the Xtensa constant pool can only be accessed with L32R instructions, it
+diff --git a/gcc/config/xtensa/elf.h b/gcc/config/xtensa/elf.h
+index e59bede..12056f7 100644
+--- a/gcc/config/xtensa/elf.h
++++ b/gcc/config/xtensa/elf.h
+@@ -48,7 +48,9 @@ along with GCC; see the file COPYING3. If not see
+ %{mtarget-align:--target-align} \
+ %{mno-target-align:--no-target-align} \
+ %{mlongcalls:--longcalls} \
+- %{mno-longcalls:--no-longcalls}"
++ %{mno-longcalls:--no-longcalls} \
++ %{mauto-litpools:--auto-litpools} \
++ %{mno-auto-litpools:--no-auto-litpools}"
+
+ #undef LIB_SPEC
+ #define LIB_SPEC "-lc -lsim -lc -lhandlers-sim -lhal"
+diff --git a/gcc/config/xtensa/linux.h b/gcc/config/xtensa/linux.h
+index 675aacf..5b0243a 100644
+--- a/gcc/config/xtensa/linux.h
++++ b/gcc/config/xtensa/linux.h
+@@ -42,7 +42,9 @@ along with GCC; see the file COPYING3. If not see
+ %{mtarget-align:--target-align} \
+ %{mno-target-align:--no-target-align} \
+ %{mlongcalls:--longcalls} \
+- %{mno-longcalls:--no-longcalls}"
++ %{mno-longcalls:--no-longcalls} \
++ %{mauto-litpools:--auto-litpools} \
++ %{mno-auto-litpools:--no-auto-litpools}"
+
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+
+diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
+index e02209e..d7dfa11 100644
+--- a/gcc/config/xtensa/predicates.md
++++ b/gcc/config/xtensa/predicates.md
+@@ -142,7 +142,8 @@
+ (match_test "GET_MODE_CLASS (mode) == MODE_INT
+ && xtensa_simm12b (INTVAL (op))"))
+ (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
+- (match_test "TARGET_CONST16 && CONSTANT_P (op)
++ (match_test "(TARGET_CONST16 || TARGET_AUTO_LITPOOLS)
++ && CONSTANT_P (op)
+ && GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0")))))
+
+ ;; Accept the floating point constant 1 in the appropriate mode.
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
+index eb039ba..206ff80 100644
+--- a/gcc/config/xtensa/xtensa.c
++++ b/gcc/config/xtensa/xtensa.c
+@@ -501,6 +501,9 @@ xtensa_valid_move (machine_mode mode, rtx *operands)
+ {
+ int dst_regnum = xt_true_regnum (operands[0]);
+
++ if (xtensa_tls_referenced_p (operands[1]))
++ return FALSE;
++
+ /* The stack pointer can only be assigned with a MOVSP opcode. */
+ if (dst_regnum == STACK_POINTER_REGNUM)
+ return !TARGET_WINDOWED_ABI
+@@ -1069,7 +1072,7 @@ xtensa_emit_move_sequence (rtx *operands, machine_mode mode)
+ return 1;
+ }
+
+- if (! TARGET_CONST16)
++ if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16)
+ {
+ src = force_const_mem (SImode, src);
+ operands[1] = src;
+@@ -2449,6 +2452,20 @@ print_operand (FILE *file, rtx x, int letter)
+ }
+ break;
+
++ case 'y':
++ if (GET_CODE (x) == CONST_DOUBLE &&
++ GET_MODE (x) == SFmode)
++ {
++ REAL_VALUE_TYPE r;
++ long l;
++ REAL_VALUE_FROM_CONST_DOUBLE (r, x);
++ REAL_VALUE_TO_TARGET_SINGLE (r, l);
++ fprintf (file, "0x%08lx", l);
++ break;
++ }
++
++ /* fall through */
++
+ default:
+ if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
+ fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
+diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
+index 6d84384..0e673a3 100644
+--- a/gcc/config/xtensa/xtensa.md
++++ b/gcc/config/xtensa/xtensa.md
+@@ -761,8 +761,8 @@
+ })
+
+ (define_insn "movsi_internal"
+- [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
+- (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
++ [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
++ (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
+ "xtensa_valid_move (SImode, operands)"
+ "@
+ movi.n\t%0, %x1
+@@ -774,15 +774,16 @@
+ mov\t%0, %1
+ movsp\t%0, %1
+ movi\t%0, %x1
++ movi\t%0, %1
+ const16\t%0, %t1\;const16\t%0, %b1
+ %v1l32r\t%0, %1
+ %v1l32i\t%0, %1
+ %v0s32i\t%1, %0
+ rsr\t%0, ACCLO
+ wsr\t%1, ACCLO"
+- [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
++ [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
+ (set_attr "mode" "SI")
+- (set_attr "length" "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
++ (set_attr "length" "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
+
+ ;; 16-bit Integer moves
+
+@@ -796,21 +797,22 @@
+ })
+
+ (define_insn "movhi_internal"
+- [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
+- (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
++ [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
++ (match_operand:HI 1 "move_operand" "M,d,r,I,Y,U,r,*A,*r"))]
+ "xtensa_valid_move (HImode, operands)"
+ "@
+ movi.n\t%0, %x1
+ mov.n\t%0, %1
+ mov\t%0, %1
+ movi\t%0, %x1
++ movi\t%0, %1
+ %v1l16ui\t%0, %1
+ %v0s16i\t%1, %0
+ rsr\t%0, ACCLO
+ wsr\t%1, ACCLO"
+- [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
++ [(set_attr "type" "move,move,move,move,move,load,store,rsr,wsr")
+ (set_attr "mode" "HI")
+- (set_attr "length" "2,2,3,3,3,3,3,3")])
++ (set_attr "length" "2,2,3,3,3,3,3,3,3")])
+
+ ;; 8-bit Integer moves
+
+@@ -881,7 +883,7 @@
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ {
+- if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
++ if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (SFmode, operands[1]);
+
+ if ((!register_operand (operands[0], SFmode)
+@@ -896,8 +898,8 @@
+ })
+
+ (define_insn "movsf_internal"
+- [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
+- (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
++ [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
++ (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
+ "((register_operand (operands[0], SFmode)
+ || register_operand (operands[1], SFmode))
+ && !(FP_REG_P (xt_true_regnum (operands[0]))
+@@ -912,13 +914,14 @@
+ mov\t%0, %1
+ wfr\t%0, %1
+ rfr\t%0, %1
++ movi\t%0, %y1
+ const16\t%0, %t1\;const16\t%0, %b1
+ %v1l32r\t%0, %1
+ %v1l32i\t%0, %1
+ %v0s32i\t%1, %0"
+- [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
++ [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
+ (set_attr "mode" "SF")
+- (set_attr "length" "3,3,3,2,2,2,3,3,3,6,3,3,3")])
++ (set_attr "length" "3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
+
+ (define_insn "*lsiu"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+@@ -991,7 +994,7 @@
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ {
+- if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
++ if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
+ operands[1] = force_const_mem (DFmode, operands[1]);
+
+ if (!register_operand (operands[0], DFmode)
+@@ -1002,8 +1005,8 @@
+ })
+
+ (define_insn_and_split "movdf_internal"
+- [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
+- (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
++ [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U")
++ (match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))]
+ "register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode)"
+ "#"
+diff --git a/gcc/config/xtensa/xtensa.opt b/gcc/config/xtensa/xtensa.opt
+index 2fd6cee..21c6e96 100644
+--- a/gcc/config/xtensa/xtensa.opt
++++ b/gcc/config/xtensa/xtensa.opt
+@@ -38,6 +38,10 @@ mtext-section-literals
+ Target
+ Intersperse literal pools with code in the text section
+
++mauto-litpools
++Target Report Mask(AUTO_LITPOOLS)
++Relax literals in assembler and place them automatically in the text section
++
+ mserialize-volatile
+ Target Report Mask(SERIALIZE_VOLATILE)
+ -mno-serialize-volatile Do not serialize volatile memory references with MEMW instructions
+--
+1.8.1.4
+