]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
tidy target HANDLE_ALIGN
authorAlan Modra <amodra@gmail.com>
Sat, 17 May 2025 05:41:14 +0000 (15:11 +0930)
committerAlan Modra <amodra@gmail.com>
Thu, 22 May 2025 22:56:08 +0000 (08:26 +0930)
avr, kvx, metag, mn10300, nds32, v850, visium, and wasm32 targets
defined HANDLE_ALIGN without defining MAX_MEM_FOR_RS_ALIGN_CODE.  This
can result in a rather large chunk of memory being allocated.  Fix
that by a combination of changing the default allocation to one byte
and/or defining a target MAX_MEM_FOR_RS_ALIGN_CODE.

arm wanted to write out the entire set of nops, and limited allowed
code alignment to 64 bytes to prevent large memory allocations.
Fix that by making use of the fact that rs_align_code frags repeat
fr_var bytes at fr_literal + fr_fix to fill out the required area.
Fix metag, nds32 and kvx too, which it seems copied either arm or x86
in similarly not making use of repeating patterns.

It's worth mentioning that my tidy to kvx changed the order of nop
bundles, placing a short bundle first rather than last.

epiphany was totally broken in that uninitialised data was written out
for any alignment requiring more than three bytes of fill.

ppc created a new frag to handle a branch over a large number of nops.
This saves 4 bytes per rs_align_code frag, and most times the branch
isn't used so it is generally a win for memory usage, but I figured
the extra code complexity wasn't worth it.  So that code of mine goes.
visium copied the same scheme, so that goes too.

This leaves x86 as the only target making large allocations for
alignment frags.

* frags.c (MAX_MEM_FOR_RS_ALIGN_CODE): Default to 1.
* config/tc-aarch64.c (aarch64_handle_align): Remove always true
condition.
* config/tc-aarch64.h (MAX_MEM_FOR_RS_ALIGN_CODE): Move to be
adjacent to HANDLE_ALIGN define.
* config/tc-arm.c (arm_handle_align): Allow alignment of more
than MAX_MEM_FOR_RS_ALIGN_CODE bytes.  Just write one repeat
of nop pattern to frag.
(arm_frag_align_code): Delete function.
* config/tc-arm.h (MAX_MEM_ALIGNMENT_BYTES): Don't define.
(MAX_MEM_FOR_RS_ALIGN_CODE): Set to 7.
(md_do_align): Don't define.
(arm_frag_align_code): Don't declare.
* config/tc-epiphany.c (epiphany_handle_align): Correct frag
so that nop_pattern repeats rather than random data.
* config/tc-epiphany.h (MAX_MEM_FOR_RS_ALIGN_CODE): Define.
* config/tc-kvx.c (kvx_make_nops): Merge into..
(kvx_handle_align): ..here.  Put short nop bundle first,
followed by repeated full nop bundle.
* config/tc-kvx.h (MAX_MEM_FOR_RS_ALIGN_CODE): Define.
* config/tc-m32c.h (HANDLE_ALIGN, MAX_MEM_FOR_RS_ALIGN_CODE):
Don't define.
* config/tc-metag.c (metag_handle_align): Just write one
repeat of nop pattern to frag.
* config/tc-metag.h (MAX_MEM_FOR_RS_ALIGN_CODE): Define.
* config/tc-nds32.c (nds32_handle_align): Just write one
repeat of nop pattern to frag.
* config/tc-nds32.h (MAX_MEM_FOR_RS_ALIGN_CODE): Define.
* config/tc-ppc.c (ppc_handle_align): Don't make a new frag
for branch.
* config/tc-ppc.h (MAX_MEM_FOR_RS_ALIGN_CODE): Increase to 8.
* config/tc-visium.c (visium_handle_align): Don't make a new
frag for branch.
* config/tc-visium.h (MAX_MEM_FOR_RS_ALIGN_CODE): Define.
* config/tc-wasm32.h (HANDLE_ALIGN): Don't define.
* testsuite/gas/epiphany/nop.d,
* testsuite/gas/epiphany/nop.s: New test.
* testsuite/gas/epiphany/allinsn.exp: Run it.
* testsuite/gas/kvx/nop-align.d: Adjust.

23 files changed:
gas/config/tc-aarch64.c
gas/config/tc-aarch64.h
gas/config/tc-arm.c
gas/config/tc-arm.h
gas/config/tc-epiphany.c
gas/config/tc-epiphany.h
gas/config/tc-kvx.c
gas/config/tc-kvx.h
gas/config/tc-m32c.h
gas/config/tc-metag.c
gas/config/tc-metag.h
gas/config/tc-nds32.c
gas/config/tc-nds32.h
gas/config/tc-ppc.c
gas/config/tc-ppc.h
gas/config/tc-visium.c
gas/config/tc-visium.h
gas/config/tc-wasm32.h
gas/frags.c
gas/testsuite/gas/epiphany/allinsn.exp
gas/testsuite/gas/epiphany/nop.d [new file with mode: 0644]
gas/testsuite/gas/epiphany/nop.s [new file with mode: 0644]
gas/testsuite/gas/kvx/nop-align.d

index 32940addb02c4fb7c4fd3e07083c7fd1ed00aa44..9005fc77eb1bb21804609c740e9e09a0a618498b 100644 (file)
@@ -9061,8 +9061,7 @@ aarch64_handle_align (fragS * fragP)
       fragP->fr_fix += fix;
     }
 
-  if (noop_size)
-    memcpy (p, aarch64_noop, noop_size);
+  memcpy (p, aarch64_noop, noop_size);
   fragP->fr_var = noop_size;
 }
 
index c2d05113647f8f7671f6e0e701c75241af3a67c9..5642710282fbcaebf4e45106c06055ec616335a4 100644 (file)
@@ -162,10 +162,6 @@ void aarch64_elf_copy_symbol_attributes (symbolS *, symbolS *);
 
 #define TC_CONS_FIX_NEW(f,w,s,e,r) cons_fix_new_aarch64 ((f), (w), (s), (e))
 
-/* Max space for a rs_align_code fragment is 3 unaligned bytes
-   (fr_fix) plus 4 bytes to contain the repeating NOP (fr_var).  */
-#define MAX_MEM_FOR_RS_ALIGN_CODE 7
-
 /* For frags in code sections we need to record whether they contain
    code or data.  */
 struct aarch64_frag_type
@@ -183,6 +179,9 @@ struct aarch64_frag_type
 #define TC_FRAG_TYPE           struct aarch64_frag_type
 #define TC_FRAG_INIT(fragp, max_bytes) aarch64_init_frag (fragp, max_bytes)
 #define HANDLE_ALIGN(sec, fragp) aarch64_handle_align (fragp)
+/* Max space for a rs_align_code fragment is 3 unaligned bytes
+   (fr_fix) plus 4 bytes to contain the repeating NOP (fr_var).  */
+#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
 
 #define md_do_align(N, FILL, LEN, MAX, LABEL)                                  \
   if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg))    \
index 1d401d17b6b8f40e9b806d313753a94c292d27d5..ad4eef4bc04e2ed5ef385a40c3bc157428b57f00 100644 (file)
@@ -26604,9 +26604,6 @@ arm_handle_align (fragS * fragP)
   p = fragP->fr_literal + fragP->fr_fix;
   fix = 0;
 
-  if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
-    bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
-
   gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
 
   if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
@@ -26636,8 +26633,6 @@ arm_handle_align (fragS * fragP)
 #endif
     }
 
-  fragP->fr_var = noop_size;
-
   if (bytes & (noop_size - 1))
     {
       fix = bytes & (noop_size - 1);
@@ -26664,45 +26659,9 @@ arm_handle_align (fragS * fragP)
       noop_size = 4;
     }
 
-  while (bytes >= noop_size)
-    {
-      memcpy (p, noop, noop_size);
-      p += noop_size;
-      bytes -= noop_size;
-      fix += noop_size;
-    }
-
   fragP->fr_fix += fix;
-}
-
-/* Called from md_do_align.  Used to create an alignment
-   frag in a code section.  */
-
-void
-arm_frag_align_code (int n, int max)
-{
-  char * p;
-
-  /* We assume that there will never be a requirement
-     to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes.  */
-  if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
-    {
-      char err_msg[128];
-
-      sprintf (err_msg,
-       _("alignments greater than %d bytes not supported in .text sections."),
-       MAX_MEM_FOR_RS_ALIGN_CODE + 1);
-      as_fatal ("%s", err_msg);
-    }
-
-  p = frag_var (rs_align_code,
-               MAX_MEM_FOR_RS_ALIGN_CODE,
-               1,
-               (relax_substateT) max,
-               (symbolS *) NULL,
-               (offsetT) n,
-               (char *) NULL);
-  *p = 0;
+  fragP->fr_var = noop_size;
+  memcpy (p, noop, noop_size);
 }
 
 /* Perform target specific initialisation of a frag.
index 24e2197d7e05c29776c24a1b43a8cb7f84f2ecd4..1472c1d3db1a465471a7ce35e3c21fa36ce8ac82 100644 (file)
@@ -203,9 +203,6 @@ void arm_copy_symbol_attributes (symbolS *, symbolS *);
 
 #define TC_CONS_FIX_NEW cons_fix_new_arm
 
-#define MAX_MEM_ALIGNMENT_BYTES    6
-#define MAX_MEM_FOR_RS_ALIGN_CODE ((1 << MAX_MEM_ALIGNMENT_BYTES) - 1)
-
 /* For frags in code sections we need to record whether they contain
    ARM code or THUMB code.  This is that if they have to be aligned,
    they can contain the correct type of no-op instruction.  */
@@ -231,6 +228,7 @@ arm_min (int am_p1, int am_p2)
 #define TC_FRAG_INIT(fragp, max_bytes) arm_init_frag (fragp, max_bytes)
 #define TC_ALIGN_ZERO_IS_DEFAULT 1
 #define HANDLE_ALIGN(sec, fragp) arm_handle_align (fragp)
+#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
 /* PR gas/19276: COFF/PE segment alignment is already handled in coff_frob_section().  */
 #ifndef TE_PE
 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN)                                \
@@ -238,13 +236,6 @@ arm_min (int am_p1, int am_p2)
    ? arm_min (2, get_recorded_alignment (SEG)) : 0)
 #endif
 
-#define md_do_align(N, FILL, LEN, MAX, LABEL)                                  \
-  if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg))    \
-    {                                                                          \
-      arm_frag_align_code (N, MAX);                                            \
-      goto LABEL;                                                              \
-    }
-
 #define DWARF2_LINE_MIN_INSN_LENGTH    2
 
 /* The lr register is r14.  */
@@ -339,7 +330,6 @@ struct arm_segment_info_type
 
 #define MD_PCREL_FROM_SECTION(F,S) md_pcrel_from_section(F,S)
 
-extern void arm_frag_align_code (int, int);
 extern void arm_validate_fix (struct fix *);
 extern const char * elf32_arm_target_format (void);
 extern void arm_elf_change_section (void);
index c8947c8a5f1b9147db46c36e29e792dfa52ceca5..be3235ae70a702da9afe4749751d073affaec039 100644 (file)
@@ -314,7 +314,7 @@ static const unsigned char nop_pattern[] = { 0xa2, 0x01 };
 void
 epiphany_handle_align (fragS *fragp)
 {
-  int bytes, fix;
+  int bytes;
   char *p;
 
   if (fragp->fr_type != rs_align_code)
@@ -322,23 +322,15 @@ epiphany_handle_align (fragS *fragp)
 
   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   p = fragp->fr_literal + fragp->fr_fix;
-  fix = 0;
 
   if (bytes & 1)
     {
-      fix = 1;
       *p++ = 0;
-      bytes--;
+      fragp->fr_fix++;
     }
 
-  if (bytes & 2)
-    {
-      memcpy (p, nop_pattern, 2);
-      p += 2;
-      bytes -= 2;
-      fix += 2;
-    }
-  fragp->fr_fix += fix;
+  memcpy (p, nop_pattern, 2);
+  fragp->fr_var = 2;
 }
 \f
 /* Read a comma separated incrementing list of register names
index dde673305f4b4a282c192f02b4235811189abeed..418d4914c46dd2fc692b396b7f96b585fe46abfa 100644 (file)
@@ -74,6 +74,7 @@ extern int epiphany_cgen_parse_fix_exp (int, expressionS *);
 
 #define HANDLE_ALIGN(s, f) epiphany_handle_align (f)
 extern void epiphany_handle_align (fragS *);
+#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
 
 #define TARGET_FORMAT "elf32-epiphany"
 
index 942b1aba744a8ab34643ea13fc82008d16d85099..b4aba5bc2a6d0ce27ded7b688bee30cc8f3b8e75 100644 (file)
@@ -2518,16 +2518,15 @@ kvx_force_reloc_sub_same (fixS * fixP, segT sec)
   return 1;
 }
 
-/* Implement HANDLE_ALIGN.  */
+/* Pads code section with bundle of nops when possible, 0 if not. */
 
-static void
-kvx_make_nops (char *buf, bfd_vma bytes)
+void
+kvx_handle_align (fragS *fragP)
 {
-  bfd_vma i = 0;
-  unsigned int j;
+  if (fragP->fr_type != rs_align_code)
+    return;
 
   static unsigned int nop_single = 0;
-
   if (!nop_single)
     {
       const struct kvxopc *opcode =
@@ -2540,52 +2539,49 @@ kvx_make_nops (char *buf, bfd_vma bytes)
       nop_single = opcode->codewords[0].opcode;
     }
 
-  /* KVX instructions are always 4-bytes aligned. If we are at a position */
-  /* that is not 4 bytes aligned, it means this is not part of an instruction, */
-  /* so it is safe to use a zero byte for padding. */
+  bfd_signed_vma bytes = (fragP->fr_next->fr_address
+                         - fragP->fr_address - fragP->fr_fix);
+  if (bytes <= 0)
+    return;
 
-  for (j = bytes % 4; j > 0; j--)
-    buf[i++] = 0;
+  char *p = fragP->fr_literal + fragP->fr_fix;
 
-  for (j = 0; j < (bytes - i); j += 4)
+  /* KVX instructions are always 4-bytes aligned.  If we are at a
+     position that is not 4 bytes aligned, it means this is not part
+     of an instruction, so it is safe to use a zero byte for padding.  */
+  int fix = bytes & 3;
+  if (fix != 0)
     {
-      unsigned nop = nop_single;
-
-      // nop has bundle end only if #4 nop or last padding nop.
-      // Sets the parallel bit when neither conditions are matched.
-      // 4*4 = biggest nop bundle we can get
-      // 12 = offset when writting the last nop possible in a 4 nops bundle
-      // bytes-i-4 = offset for the last 4-words in the padding
-      if (j % (4 * 4) != 12 && j != (bytes - i - 4))
-       nop |= PARALLEL_BIT;
-
-      memcpy (buf + i + j, &nop, sizeof (nop));
+      memset (p, 0, fix);
+      p += fix;
+      bytes -= fix;
     }
-}
 
-/* Pads code section with bundle of nops when possible, 0 if not. */
-void
-kvx_handle_align (fragS *fragP)
-{
-  switch (fragP->fr_type)
+  /* Output any nops that don't make a full bundle.  */
+  while (bytes & 15)
     {
-    case rs_align_code:
-      {
-       bfd_signed_vma bytes = (fragP->fr_next->fr_address
-                               - fragP->fr_address - fragP->fr_fix);
-       char *p = fragP->fr_literal + fragP->fr_fix;
-
-       if (bytes <= 0)
-         break;
-
-       /* Insert zeros or nops to get 4 byte alignment.  */
-       kvx_make_nops (p, bytes);
-       fragP->fr_fix += bytes;
-      }
-      break;
+      unsigned int nop = nop_single;
+      bytes -= 4;
+      if (bytes & 15)
+       nop |= PARALLEL_BIT;
+      memcpy (p, &nop, 4);
+      p += 4;
+      fix += 4;
+    }
+  fragP->fr_fix += fix;
 
-    default:
-      break;
+  /* Any more are repeated copies of this full bundle of nops.  */
+  if (bytes)
+    {
+      unsigned int nop = nop_single | PARALLEL_BIT;
+      memcpy (p, &nop, 4);
+      p += 4;
+      memcpy (p, &nop, 4);
+      p += 4;
+      memcpy (p, &nop, 4);
+      p += 4;
+      memcpy (p, &nop_single, 4);
+      fragP->fr_var = 16;
     }
 }
 /*
index a4d0e2d9b13cc5025a90e7f463537f6fe9a94e1f..1445868ea2828b430ac2bb8bfabe24106996e527 100644 (file)
@@ -297,6 +297,7 @@ extern void kvx_cons_fix_new (fragS *f, int where, int nbytes,
 /* Enable special handling for the alignment directive.  */
 extern void kvx_handle_align (fragS *);
 #define HANDLE_ALIGN(s, f) kvx_handle_align (f)
+#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 12 + 16)
 
 #ifdef OBJ_ELF
 
index bcdca98a1915ad449068499f48f1a1fd3c495b92..c8e03edd0c72cc789ba3fd883ef6196edfcab9b2 100644 (file)
@@ -79,5 +79,3 @@ extern int m32c_is_colon_insn (char *, char *);
 #define H_TICK_HEX 1
 
 #define NOP_OPCODE (bfd_get_mach (stdoutput) == bfd_mach_m32c ? 0xde : 0x04)
-#define HANDLE_ALIGN(sec, fragP)
-#define MAX_MEM_FOR_RS_ALIGN_CODE 1
index 3a36d6abce56c3e67d0def8592786daec8ff86fb..195e6a4040fc8b3695ec7eb27a208f96a98b7f54 100644 (file)
@@ -6842,33 +6842,21 @@ void
 metag_handle_align (fragS * fragP)
 {
   static unsigned char const noop[4] = { 0xfe, 0xff, 0xff, 0xa0 };
-  int bytes, fix;
-  char *p;
 
   if (fragP->fr_type != rs_align_code)
     return;
 
-  bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
-  p = fragP->fr_literal + fragP->fr_fix;
-  fix = 0;
-
-  if (bytes & 3)
+  int bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
+  char *p = fragP->fr_literal + fragP->fr_fix;
+  int fix = bytes & 3;
+  if (fix != 0)
     {
-      fix = bytes & 3;
       memset (p, 0, fix);
       p += fix;
-      bytes -= fix;
-    }
-
-  while (bytes >= 4)
-    {
-      memcpy (p, noop, 4);
-      p += 4;
-      bytes -= 4;
-      fix += 4;
+      fragP->fr_fix += fix;
     }
 
-  fragP->fr_fix += fix;
+  memcpy (p, noop, 4);
   fragP->fr_var = 4;
 }
 
index 9d112c4ae706758a1d88614c0f7b5962ea5c4d37..646a8645e8ce758d03be54530678c0e85704d8e9 100644 (file)
@@ -52,6 +52,7 @@ extern int metag_force_relocation (struct fix *);
 /* Call md_pcrel_from_section(), not md_pcrel_from().  */
 #define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC)
 
+#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
 #define HANDLE_ALIGN(sec, fragp) metag_handle_align (fragp)
 extern void metag_handle_align (struct frag *);
 
index 2e0b8e590998bea811bae9f70abc70d72f59e67a..26172e54b3a5e0147f4e8209d395d8550baa617d 100644 (file)
@@ -4633,16 +4633,15 @@ nds32_handle_align (fragS *fragp)
 {
   static const unsigned char nop16[] = { 0x92, 0x00 };
   static const unsigned char nop32[] = { 0x40, 0x00, 0x00, 0x09 };
-  int bytes;
-  char *p;
 
   if (fragp->fr_type != rs_align_code)
     return;
 
-  bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
-  p = fragp->fr_literal + fragp->fr_fix;
+  int bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+  char *p = fragp->fr_literal + fragp->fr_fix;
+  int fix = bytes & 1;
 
-  if (bytes & 1)
+  if (fix != 0)
     {
       *p++ = 0;
       bytes--;
@@ -4658,18 +4657,12 @@ nds32_handle_align (fragS *fragp)
                   BFD_RELOC_NDS32_INSN16);
       memcpy (p, nop16, 2);
       p += 2;
-      bytes -= 2;
+      fix += 2;
     }
+  fragp->fr_fix += fix;
 
-  while (bytes >= 4)
-    {
-      memcpy (p, nop32, 4);
-      p += 4;
-      bytes -= 4;
-    }
-
-  bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
-  fragp->fr_fix += bytes;
+  fragp->fr_var = 4;
+  memcpy (p, nop32, 4);
 }
 
 /* md_flush_pending_output  */
index 14109f09dd06298d819d773744585f09fff2eb79..88b6fbee213aaad314e43454ed23386d631d76c5 100644 (file)
@@ -112,6 +112,7 @@ extern void tc_nds32_frame_initial_instructions (void);
 #define GAS_SORT_RELOCS                                1
 /* Values passed to md_apply_fix don't include the symbol value.  */
 #define MD_APPLY_SYM_VALUE(FIX)                        0
+#define MAX_MEM_FOR_RS_ALIGN_CODE              (1 + 2 + 4)
 #define HANDLE_ALIGN(s, f)                     nds32_handle_align (f)
 #undef DIFF_EXPR_OK                            /* They should be fixed in linker.  */
 #define md_relax_frag(segment, fragP, stretch) nds32_relax_frag (segment, fragP, stretch)
index 0de27140d6af991eec5f1b7c7e2e7bf18fc89da9..eef82d70169fc8c1bfacc5dc7a096e05c896d25b 100644 (file)
@@ -6913,28 +6913,13 @@ ppc_handle_align (segT sec, struct frag *fragP)
 
       if (count > 4 * nop_limit && count < 0x2000000)
        {
-         struct frag *rest;
-
-         /* Make a branch, then follow with nops.  Insert another
-            frag to handle the nops.  */
+         /* Make a branch, then follow with nops.  */
          md_number_to_chars (dest, 0x48000000 + count, 4);
+         dest += 4;
+         fragP->fr_fix += 4;
          count -= 4;
          if (count == 0)
            return;
-
-         segment_info_type *seginfo = seg_info (sec);
-         struct obstack *ob = &seginfo->frchainP->frch_obstack;
-         rest = frag_alloc (ob, 4);
-         memcpy (rest, fragP, SIZEOF_STRUCT_FRAG);
-         fragP->fr_next = rest;
-         fragP = rest;
-         rest->fr_address += rest->fr_fix + 4;
-         rest->fr_fix = 0;
-         /* If we leave the next frag as rs_align_code we'll come here
-            again, resulting in a bunch of branches rather than a
-            branch followed by nops.  */
-         rest->fr_type = rs_align;
-         dest = rest->fr_literal;
        }
 
       md_number_to_chars (dest, 0x60000000, 4);
index f6b37f80ef4645b68d5ddd3d47bb13f71d6ab063..45547cfdc5701616e0c82447220d2268be1f6fe0 100644 (file)
@@ -72,7 +72,7 @@ extern const char *ppc_target_format (void);
 /* We don't need to handle .word strangely.  */
 #define WORKING_DOT_WORD
 
-#define MAX_MEM_FOR_RS_ALIGN_CODE 4
+#define MAX_MEM_FOR_RS_ALIGN_CODE 8
 #define HANDLE_ALIGN(SEC, FRAGP)                                               \
   if ((FRAGP)->fr_type == rs_align_code)                               \
     ppc_handle_align (SEC, FRAGP);
index c00db12e38635e33ac08c810c65022cd496ee6c6..93c108f03685746673542d7bdd18da15a6bb0ca4 100644 (file)
@@ -555,30 +555,16 @@ visium_handle_align (fragS *fragP)
   if (count == 0)
     return;
 
-  fragP->fr_var = 4;
-
   if (count > 4 * nop_limit && count <= 131068)
     {
-      struct frag *rest;
-
-      /* Make a branch, then follow with nops.  Insert another
-         frag to handle the nops.  */
+      /* Make a branch, then follow with nops.  */
       md_number_to_chars (p, 0x78000000 + (count >> 2), 4);
       visium_update_parity_bit (p);
-
-      rest = xmalloc (SIZEOF_STRUCT_FRAG + 4);
-      memcpy (rest, fragP, SIZEOF_STRUCT_FRAG);
-      fragP->fr_next = rest;
-      rest->fr_address += rest->fr_fix + 4;
-      rest->fr_fix = 0;
-      /* If we leave the next frag as rs_align_code we'll come here
-        again, resulting in a bunch of branches rather than a
-        branch followed by nops.  */
-      rest->fr_type = rs_align;
-      p = rest->fr_literal;
+      p += 4;
+      fragP->fr_fix += 4;
     }
 
-  memset (p, 0, 4);
+  *p = 0;
 }
 
 /* Apply a fixS to the frags, now that we know the value it ought to
index 01f86285d3f308b7be97980204e6d56e8f325502..851719bd4a66960e5621ae2d0d4379bfda4c9536 100644 (file)
@@ -45,6 +45,7 @@
 #define tc_fix_adjustable(FIXP) visium_fix_adjustable (FIXP)
 extern bool visium_fix_adjustable (struct fix *);
 
+#define MAX_MEM_FOR_RS_ALIGN_CODE (4 + 1)
 #define HANDLE_ALIGN(SEC, FRAGP)                \
   if ((FRAGP)->fr_type == rs_align_code) \
     visium_handle_align (FRAGP);
index b2ccf1cff595107f1cfb7deb9d114e3f1b35e17b..2a84a979d72a368b4e2b0b26d57e7e2ed7dbf2d0 100644 (file)
@@ -75,7 +75,6 @@ extern int wasm32_force_relocation (struct fix *);
 #define elf_tc_final_processing()
 #define md_post_relax_hook
 #define md_start_line_hook()
-#define HANDLE_ALIGN(sec, fragP)
 
 
 extern bool wasm32_fix_adjustable (struct fix *);
index 6684e27618997eb9130d6f7cfc07dcba4fc01c0b..094bb9accd439a8085880f297beb6dbd4ef21251 100644 (file)
@@ -355,18 +355,11 @@ frag_align_pattern (int alignment, const char *fill_pattern,
 #define NOP_OPCODE 0x00
 #endif
 
-/* Use this to restrict the amount of memory allocated for representing
-   the alignment code.  Needs to be large enough to hold any fixed sized
+/* Use this to specify the amount of memory allocated for representing
+   the alignment code.  Needs to be large enough to hold any fixed size
    prologue plus the replicating portion.  */
 #ifndef MAX_MEM_FOR_RS_ALIGN_CODE
-  /* Assume that if HANDLE_ALIGN is not defined then no special action
-     is required to code fill, which means that we get just repeat the
-     one NOP_OPCODE byte.  */
-# ifndef HANDLE_ALIGN
-#  define MAX_MEM_FOR_RS_ALIGN_CODE  1
-# else
-#  define MAX_MEM_FOR_RS_ALIGN_CODE  (((size_t) 1 << alignment) - 1)
-# endif
+# define MAX_MEM_FOR_RS_ALIGN_CODE 1
 #endif
 
 void
index 5ac2ef04dd41f5a1afdb5f1c54427f9bbd55a7ea..b4f10a67973db57ad25c812c6ad84dff1a3e236d 100644 (file)
@@ -24,4 +24,5 @@ if [istarget epiphany*-*-*] {
     run_dump_test "badrelax"
     gas_test_error "badpostmod" "" "destination register modified by displacement-post-modified address"
     run_dump_test "addr-syntax"
+    run_dump_test nop
 }
diff --git a/gas/testsuite/gas/epiphany/nop.d b/gas/testsuite/gas/epiphany/nop.d
new file mode 100644 (file)
index 0000000..23f457b
--- /dev/null
@@ -0,0 +1,16 @@
+#as:
+#objdump: -dr
+
+.*:     file format elf32-epiphany
+
+Disassembly of section \.text:
+
+0+ <\.text>:
+   0:  01b2            idle
+   2:  01a2            nop
+   4:  01a2            nop
+   6:  01a2            nop
+   8:  01b2            idle
+   a:  01b2            idle
+   c:  01a2            nop
+   e:  01a2            nop
diff --git a/gas/testsuite/gas/epiphany/nop.s b/gas/testsuite/gas/epiphany/nop.s
new file mode 100644 (file)
index 0000000..ce5cb67
--- /dev/null
@@ -0,0 +1,5 @@
+ .text
+ idle
+ .p2align 3
+ idle
+ idle
index 5fbb571f5b414a7e9e19d9c52a7e00a6e170d139..755cf8d99825ea47788df66f1e37fab9c3015d8f 100644 (file)
@@ -20,9 +20,9 @@ Disassembly of section .text:
 
 [0-9a-f]+ <g\+0xc> nop
 [0-9a-f]+ <g\+0x10> nop
-[0-9a-f]+ <g\+0x14> nop
-[0-9a-f]+ <g\+0x18> nop;;
+[0-9a-f]+ <g\+0x14> nop;;
 
+[0-9a-f]+ <g\+0x18> nop
 [0-9a-f]+ <g\+0x1c> nop
 [0-9a-f]+ <g\+0x20> nop
 [0-9a-f]+ <g\+0x24> nop;;