aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-ppc.c49
-rw-r--r--gas/config/tc-ppc.h33
3 files changed, 60 insertions, 29 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 5c0b736..2d1137d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2006-09-22 Alan Modra <amodra@bigpond.net.au>
+
+ * 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.
+
2006-09-20 Bob Wilson <bob.wilson@acm.org>
* doc/as.texinfo: Fix cross reference usage, typos and grammar.
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
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
index 5a43420..e9cce7f 100644
--- a/gas/config/tc-ppc.h
+++ b/gas/config/tc-ppc.h
@@ -1,6 +1,6 @@
/* tc-ppc.h -- Header file for tc-ppc.c.
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005 Free Software Foundation, Inc.
+ 2004, 2005, 2006 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
@@ -78,31 +78,12 @@ extern char *ppc_target_format PARAMS ((void));
#define MAX_MEM_FOR_RS_ALIGN_CODE 4
#define HANDLE_ALIGN(FRAGP) \
- if ((FRAGP)->fr_type == rs_align_code) \
- { \
- 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; \
- if (target_big_endian) \
- { \
- *dest++ = 0x60; \
- *dest++ = 0; \
- *dest++ = 0; \
- *dest++ = 0; \
- } \
- else \
- { \
- *dest++ = 0; \
- *dest++ = 0; \
- *dest++ = 0; \
- *dest++ = 0x60; \
- } \
- } \
- }
+ if ((FRAGP)->fr_type == rs_align_code) \
+ ppc_handle_align (FRAGP);
+
+extern void ppc_handle_align (struct frag *);
+
+#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
#define md_frag_check(FRAGP) \
if ((FRAGP)->has_code \