This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

power6 nops


As the comment says below, this patch modifies the nop sequence for
power6, so that the last nop emitted is a group terminating nop.  This
ensures that code after .p2align starts with a new group, making gcc's
-falign-loops a little more effective on power6.  I've also tweaked
md_section_align and defined SUB_SEGMENT_ALIGN so that the generally
useless padding at the end of a section is not emitted.

	* 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.

Index: gas/config/tc-ppc.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.c,v
retrieving revision 1.112
diff -u -p -r1.112 tc-ppc.c
--- gas/config/tc-ppc.c	7 Jun 2006 11:27:58 -0000	1.112
+++ gas/config/tc-ppc.c	22 Sep 2006 09:54:08 -0000
@@ -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: gas/config/tc-ppc.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.h,v
retrieving revision 1.32
diff -u -p -r1.32 tc-ppc.h
--- gas/config/tc-ppc.h	19 May 2006 11:26:11 -0000	1.32
+++ gas/config/tc-ppc.h	22 Sep 2006 09:54:08 -0000
@@ -78,31 +78,12 @@ extern char *ppc_target_format PARAMS ((
 
 #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							\

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]