aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2025-05-17 15:11:14 +0930
committerAlan Modra <amodra@gmail.com>2025-05-23 08:26:08 +0930
commit7ca6020a4e527e37454fa4ee1d4412ee68c38207 (patch)
treece4261aac9f6e845b7047e760b76b887aa0f5408
parentebed2c2c43aeaa6e4e603d07e930eceda510c02d (diff)
downloadbinutils-7ca6020a4e527e37454fa4ee1d4412ee68c38207.zip
binutils-7ca6020a4e527e37454fa4ee1d4412ee68c38207.tar.gz
binutils-7ca6020a4e527e37454fa4ee1d4412ee68c38207.tar.bz2
tidy target HANDLE_ALIGN
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.
-rw-r--r--gas/config/tc-aarch64.c3
-rw-r--r--gas/config/tc-aarch64.h7
-rw-r--r--gas/config/tc-arm.c45
-rw-r--r--gas/config/tc-arm.h12
-rw-r--r--gas/config/tc-epiphany.c16
-rw-r--r--gas/config/tc-epiphany.h1
-rw-r--r--gas/config/tc-kvx.c86
-rw-r--r--gas/config/tc-kvx.h1
-rw-r--r--gas/config/tc-m32c.h2
-rw-r--r--gas/config/tc-metag.c24
-rw-r--r--gas/config/tc-metag.h1
-rw-r--r--gas/config/tc-nds32.c23
-rw-r--r--gas/config/tc-nds32.h1
-rw-r--r--gas/config/tc-ppc.c21
-rw-r--r--gas/config/tc-ppc.h2
-rw-r--r--gas/config/tc-visium.c22
-rw-r--r--gas/config/tc-visium.h1
-rw-r--r--gas/config/tc-wasm32.h1
-rw-r--r--gas/frags.c13
-rw-r--r--gas/testsuite/gas/epiphany/allinsn.exp1
-rw-r--r--gas/testsuite/gas/epiphany/nop.d16
-rw-r--r--gas/testsuite/gas/epiphany/nop.s5
-rw-r--r--gas/testsuite/gas/kvx/nop-align.d4
23 files changed, 106 insertions, 202 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 32940ad..9005fc7 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -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;
}
diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h
index c2d0511..5642710 100644
--- a/gas/config/tc-aarch64.h
+++ b/gas/config/tc-aarch64.h
@@ -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)) \
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 1d401d1..ad4eef4 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -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.
diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
index 24e2197..1472c1d 100644
--- a/gas/config/tc-arm.h
+++ b/gas/config/tc-arm.h
@@ -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);
diff --git a/gas/config/tc-epiphany.c b/gas/config/tc-epiphany.c
index c8947c8..be3235a 100644
--- a/gas/config/tc-epiphany.c
+++ b/gas/config/tc-epiphany.c
@@ -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;
}
/* Read a comma separated incrementing list of register names
diff --git a/gas/config/tc-epiphany.h b/gas/config/tc-epiphany.h
index dde6733..418d491 100644
--- a/gas/config/tc-epiphany.h
+++ b/gas/config/tc-epiphany.h
@@ -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"
diff --git a/gas/config/tc-kvx.c b/gas/config/tc-kvx.c
index 942b1ab..b4aba5b 100644
--- a/gas/config/tc-kvx.c
+++ b/gas/config/tc-kvx.c
@@ -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;
}
}
/*
diff --git a/gas/config/tc-kvx.h b/gas/config/tc-kvx.h
index a4d0e2d..1445868 100644
--- a/gas/config/tc-kvx.h
+++ b/gas/config/tc-kvx.h
@@ -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
diff --git a/gas/config/tc-m32c.h b/gas/config/tc-m32c.h
index bcdca98..c8e03ed 100644
--- a/gas/config/tc-m32c.h
+++ b/gas/config/tc-m32c.h
@@ -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
diff --git a/gas/config/tc-metag.c b/gas/config/tc-metag.c
index 3a36d6a..195e6a4 100644
--- a/gas/config/tc-metag.c
+++ b/gas/config/tc-metag.c
@@ -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;
}
diff --git a/gas/config/tc-metag.h b/gas/config/tc-metag.h
index 9d112c4..646a864 100644
--- a/gas/config/tc-metag.h
+++ b/gas/config/tc-metag.h
@@ -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 *);
diff --git a/gas/config/tc-nds32.c b/gas/config/tc-nds32.c
index 2e0b8e5..26172e5 100644
--- a/gas/config/tc-nds32.c
+++ b/gas/config/tc-nds32.c
@@ -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 */
diff --git a/gas/config/tc-nds32.h b/gas/config/tc-nds32.h
index 14109f0..88b6fbe 100644
--- a/gas/config/tc-nds32.h
+++ b/gas/config/tc-nds32.h
@@ -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)
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 0de2714..eef82d7 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -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);
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
index f6b37f8..45547cf 100644
--- a/gas/config/tc-ppc.h
+++ b/gas/config/tc-ppc.h
@@ -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);
diff --git a/gas/config/tc-visium.c b/gas/config/tc-visium.c
index c00db12..93c108f 100644
--- a/gas/config/tc-visium.c
+++ b/gas/config/tc-visium.c
@@ -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
diff --git a/gas/config/tc-visium.h b/gas/config/tc-visium.h
index 01f8628..851719b 100644
--- a/gas/config/tc-visium.h
+++ b/gas/config/tc-visium.h
@@ -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);
diff --git a/gas/config/tc-wasm32.h b/gas/config/tc-wasm32.h
index b2ccf1c..2a84a97 100644
--- a/gas/config/tc-wasm32.h
+++ b/gas/config/tc-wasm32.h
@@ -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 *);
diff --git a/gas/frags.c b/gas/frags.c
index 6684e27..094bb9a 100644
--- a/gas/frags.c
+++ b/gas/frags.c
@@ -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
diff --git a/gas/testsuite/gas/epiphany/allinsn.exp b/gas/testsuite/gas/epiphany/allinsn.exp
index 5ac2ef0..b4f10a6 100644
--- a/gas/testsuite/gas/epiphany/allinsn.exp
+++ b/gas/testsuite/gas/epiphany/allinsn.exp
@@ -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
index 0000000..23f457b
--- /dev/null
+++ b/gas/testsuite/gas/epiphany/nop.d
@@ -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
index 0000000..ce5cb67
--- /dev/null
+++ b/gas/testsuite/gas/epiphany/nop.s
@@ -0,0 +1,5 @@
+ .text
+ idle
+ .p2align 3
+ idle
+ idle
diff --git a/gas/testsuite/gas/kvx/nop-align.d b/gas/testsuite/gas/kvx/nop-align.d
index 5fbb571..755cf8d 100644
--- a/gas/testsuite/gas/kvx/nop-align.d
+++ b/gas/testsuite/gas/kvx/nop-align.d
@@ -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;;