* config/tc-ppc.c (md_section_align): Don't round up address for ELF.
authorAlan Modra <amodra@gmail.com>
Fri, 22 Sep 2006 11:05:27 +0000 (11:05 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 22 Sep 2006 11:05:27 +0000 (11:05 +0000)
(ppc_handle_align): New function.
* config/tc-ppc.h (HANDLE_ALIGN): Use ppc_handle_align.
(SUB_SEGMENT_ALIGN): Define as zero.

gas/ChangeLog
gas/config/tc-ppc.c
gas/config/tc-ppc.h

index 5c0b736..2d1137d 100644 (file)
@@ -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.
index 7af4fa6..35e30b0 100644 (file)
@@ -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
index 5a43420..e9cce7f 100644 (file)
@@ -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                                                        \