This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
power6 nops
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Fri, 22 Sep 2006 20:30:06 +0930
- Subject: 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