fragP->fr_fix += fix;
}
- if (noop_size)
- memcpy (p, aarch64_noop, noop_size);
+ memcpy (p, aarch64_noop, noop_size);
fragP->fr_var = noop_size;
}
#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
#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)) \
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))
#endif
}
- fragP->fr_var = noop_size;
-
if (bytes & (noop_size - 1))
{
fix = bytes & (noop_size - 1);
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.
#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. */
#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) \
? 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. */
#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);
void
epiphany_handle_align (fragS *fragp)
{
- int bytes, fix;
+ int bytes;
char *p;
if (fragp->fr_type != rs_align_code)
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
#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"
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 =
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;
}
}
/*
/* 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
#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
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;
}
/* 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 *);
{
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--;
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 */
#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)
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);
/* 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);
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
#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);
#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 *);
#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
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
}
--- /dev/null
+#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
--- /dev/null
+ .text
+ idle
+ .p2align 3
+ idle
+ idle
[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;;