+2018-05-09  Max Filippov  <jcmvbkbc@gmail.com>
+
+       * config/tc-xtensa.c (xtensa_is_init_fini): New function.
+       (xtensa_move_literals): Only attempt to assign literal pool to
+       literals with tc_frag_data.is_literal mark and not in .init or
+       .fini sections.
+       Join nested 'if' conditions to simplify function structure.
+       (xtensa_switch_to_non_abs_literal_fragment): Use
+       xtensa_is_init_fini to test for .init/.fini sections.
+       * testsuite/gas/xtensa/all.exp (auto-litpools-3)
+       (auto-litpools-4, text-section-literals-1): New tests.
+       * testsuite/gas/xtensa/auto-litpools-3.d: New test results.
+       * testsuite/gas/xtensa/auto-litpools-3.s: New test source.
+       * testsuite/gas/xtensa/auto-litpools-4.d: New test results.
+       * testsuite/gas/xtensa/auto-litpools-4.s: New test source.
+       * testsuite/gas/xtensa/text-section-literals-1.d: New test results.
+       * testsuite/gas/xtensa/text-section-literals-1.s: New test source.
+
 2018-05-09  Dimitar Dimitrov  <dimitar@dinux.eu>
 
        * config/tc-pru.c (md_apply_fix): Make LDI32 relocation conformant
 
   return lp;
 }
 
+static bfd_boolean xtensa_is_init_fini (segT seg)
+{
+  if (!seg)
+    return 0;
+  return strcmp (segment_name (seg), INIT_SECTION_NAME) == 0
+    || strcmp (segment_name (seg), FINI_SECTION_NAME) == 0;
+}
+
 static void
 xtensa_move_literals (void)
 {
       struct litpool_frag *lpf = lps->frag_list.next;
       addressT addr = 0;
 
+      if (xtensa_is_init_fini (lps->seg))
+       continue;
+
       for ( ; frchP; frchP = frchP->frch_next)
        {
          fragS *fragP;
                  int slot;
                  for (slot = 0; slot < MAX_SLOTS; slot++)
                    {
-                     if (fragP->tc_frag_data.literal_frags[slot])
+                     fragS *litfrag = fragP->tc_frag_data.literal_frags[slot];
+
+                     if (litfrag
+                         && litfrag->tc_frag_data.is_literal
+                         && !litfrag->tc_frag_data.literal_frag)
                        {
-                         /* L32R; point its literal to the nearest litpool
-                            preferring non-"candidate" positions to avoid
-                            the jump-around.  */
-                         fragS *litfrag = fragP->tc_frag_data.literal_frags[slot];
-
-                         if (!litfrag->tc_frag_data.literal_frag)
-                           {
-                             struct litpool_frag *lp;
-
-                             lp = xg_find_litpool (lps, lpf, addr);
-                             /* Take earliest use of this literal to avoid
-                                forward refs.  */
-                             litfrag->tc_frag_data.literal_frag = lp->fragP;
-                           }
+                         /* L32R referring .literal or generated as a result
+                            of relaxation.  Point its literal to the nearest
+                            litpool preferring non-"candidate" positions to
+                            avoid the jump-around.  */
+
+                         struct litpool_frag *lp;
+
+                         lp = xg_find_litpool (lps, lpf, addr);
+                         /* Take earliest use of this literal to avoid
+                            forward refs.  */
+                         litfrag->tc_frag_data.literal_frag = lp->fragP;
                        }
                    }
                }
 {
   fragS *pool_location = get_literal_pool_location (now_seg);
   segT lit_seg;
-  bfd_boolean is_init =
-    (now_seg && !strcmp (segment_name (now_seg), INIT_SECTION_NAME));
-  bfd_boolean is_fini =
-    (now_seg && !strcmp (segment_name (now_seg), FINI_SECTION_NAME));
+  bfd_boolean is_init_fini = xtensa_is_init_fini (now_seg);
 
   if (pool_location == NULL
       && !use_literal_section
-      && !is_init && ! is_fini)
+      && !is_init_fini)
     {
       if (!auto_litpools)
        {
   xtensa_switch_section_emit_state (result, lit_seg, 0);
 
   if (!use_literal_section
-      && !is_init && !is_fini
+      && !is_init_fini
       && get_literal_pool_location (now_seg) != pool_location)
     {
       /* Close whatever frag is there.  */
 
     run_dump_test "first_frag_align"
     run_dump_test "auto-litpools"
     run_dump_test "auto-litpools-2"
+    run_dump_test "auto-litpools-3"
+    run_dump_test "auto-litpools-4"
     run_dump_test "auto-litpools-first1"
     run_dump_test "auto-litpools-first2"
     run_dump_test "loc"
     run_dump_test "init-fini-literals"
+    run_dump_test "text-section-literals-1"
 }
 
 if [info exists errorInfo] then {