diff options
author | Alan Modra <amodra@gmail.com> | 2006-09-22 11:05:27 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2006-09-22 11:05:27 +0000 |
commit | 3aeeedbb71f648211ae2efde0d0cf4b24abcefe1 (patch) | |
tree | b426e937318e978e0f9fbc26656807bb8713168c /gas/config/tc-ppc.c | |
parent | 637ea4ae1f0deac170ed7589f0cec6e55291df3e (diff) | |
download | gdb-3aeeedbb71f648211ae2efde0d0cf4b24abcefe1.zip gdb-3aeeedbb71f648211ae2efde0d0cf4b24abcefe1.tar.gz gdb-3aeeedbb71f648211ae2efde0d0cf4b24abcefe1.tar.bz2 |
* config/tc-ppc.c (md_section_align): Don't round up address for ELF.
(ppc_handle_align): New function.
* config/tc-ppc.h (HANDLE_ALIGN): Use ppc_handle_align.
(SUB_SEGMENT_ALIGN): Define as zero.
Diffstat (limited to 'gas/config/tc-ppc.c')
-rw-r--r-- | gas/config/tc-ppc.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 7af4fa6..35e30b0 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -5265,13 +5265,15 @@ md_number_to_chars (buf, val, n) /* Align a section (I don't know why this is machine dependent). */ valueT -md_section_align (seg, addr) - asection *seg; - valueT addr; +md_section_align (asection *seg ATTRIBUTE_UNUSED, valueT addr) { +#ifdef OBJ_ELF + return addr; +#else int align = bfd_get_section_alignment (stdoutput, seg); return ((addr + (1 << align) - 1) & (-1 << align)); +#endif } /* We don't have any form of relaxing. */ @@ -5519,6 +5521,47 @@ ppc_fix_adjustable (fix) } #endif +/* Implement HANDLE_ALIGN. This writes the NOP pattern into an + rs_align_code frag. */ + +void +ppc_handle_align (struct frag *fragP) +{ + valueT count = (fragP->fr_next->fr_address + - (fragP->fr_address + fragP->fr_fix)); + + if (count != 0 && (count & 3) == 0) + { + char *dest = fragP->fr_literal + fragP->fr_fix; + + fragP->fr_var = 4; + md_number_to_chars (dest, 0x60000000, 4); + + if ((ppc_cpu & PPC_OPCODE_POWER6) != 0) + { + /* For power6, we want the last nop to be a group terminating + one, "ori 1,1,0". Do this by inserting an rs_fill frag + immediately after this one, with its address set to the last + nop location. This will automatically reduce the number of + nops in the current frag by one. */ + if (count > 4) + { + struct frag *group_nop = xmalloc (SIZEOF_STRUCT_FRAG + 4); + + memcpy (group_nop, fragP, SIZEOF_STRUCT_FRAG); + group_nop->fr_address = group_nop->fr_next->fr_address - 4; + group_nop->fr_fix = 0; + group_nop->fr_offset = 1; + group_nop->fr_type = rs_fill; + fragP->fr_next = group_nop; + dest = group_nop->fr_literal; + } + + md_number_to_chars (dest, 0x60210000, 4); + } + } +} + /* Apply a fixup to the object code. This is called for all the fixups we generated by the call to fix_new_exp, above. In the call above we used a reloc code which was the largest legal reloc code |