This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[ARM] use architectural nops
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils <binutils at sources dot redhat dot com>
- Date: Tue, 31 Mar 2009 14:45:07 +0100
- Subject: [ARM] use architectural nops
This patch changes arm's code alignment to use architectural nop instructions,
when available. For thumb2 we generate 4 byte nops when possible, rather than
pairs of 2-byte nops.
tested for arm-eabi.
ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
2009-03-30 Nathan Sidwell <nathan@codesourcery.com>
* config/tc-arm.c (do_nop): Generate v6k nops whenever possible.
(arm_handle_align): Generate v6k ARM, thumb2 wide & narrow nops
whenever possible.
testsuite/
* gas/arm/align.s, gas/arm/align.d: New.
* gas/arm/thumb32.d, gas/arm/arch6zk.d, gas/arm/arch6zk.s,
arm/thumb2_relax.d: Adjust for align changes.
Index: config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.378
diff -c -3 -p -r1.378 tc-arm.c
*** config/tc-arm.c 18 Mar 2009 15:28:24 -0000 1.378
--- config/tc-arm.c 30 Mar 2009 15:59:33 -0000
*************** do_mull (void)
*** 7316,7326 ****
static void
do_nop (void)
{
! if (inst.operands[0].present)
{
/* Architectural NOP hints are CPSR sets with no bits selected. */
inst.instruction &= 0xf0000000;
! inst.instruction |= 0x0320f000 + inst.operands[0].imm;
}
}
--- 7316,7329 ----
static void
do_nop (void)
{
! if (inst.operands[0].present
! || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
{
/* Architectural NOP hints are CPSR sets with no bits selected. */
inst.instruction &= 0xf0000000;
! inst.instruction |= 0x0320f000;
! if (inst.operands[0].present)
! inst.instruction |= inst.operands[0].imm;
}
}
*************** md_section_align (segT segment ATTRIBUT
*** 17580,17593 ****
void
arm_handle_align (fragS * fragP)
{
! static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
! static char const thumb_noop[2] = { 0xc0, 0x46 };
! static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
! static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
!
! int bytes, fix, noop_size;
char * p;
const char * noop;
if (fragP->fr_type != rs_align_code)
return;
--- 17583,17620 ----
void
arm_handle_align (fragS * fragP)
{
! static char const arm_noop[2][2][4] =
! {
! { /* ARMv1 */
! {0x00, 0x00, 0xa0, 0xe1}, /* LE */
! {0xe1, 0xa0, 0x00, 0x00}, /* BE */
! },
! { /* ARMv6k */
! {0x00, 0xf0, 0x20, 0xe3}, /* LE */
! {0xe3, 0x20, 0xf0, 0x00}, /* BE */
! },
! };
! static char const thumb_noop[2][2][2] =
! {
! { /* Thumb-1 */
! {0xc0, 0x46}, /* LE */
! {0x46, 0xc0}, /* BE */
! },
! { /* Thumb-2 */
! {0x00, 0xbf}, /* LE */
! {0xbf, 0x00} /* BE */
! }
! };
! static char const wide_thumb_noop[2][4] =
! { /* Wide Thumb-2 */
! {0xaf, 0xf3, 0x00, 0x80}, /* LE */
! {0xf3, 0xaf, 0x80, 0x00}, /* BE */
! };
!
! unsigned bytes, fix, noop_size;
char * p;
const char * noop;
+ const char *narrow_noop = NULL;
if (fragP->fr_type != rs_align_code)
return;
*************** arm_handle_align (fragS * fragP)
*** 17603,17623 ****
if (fragP->tc_frag_data & (~ MODE_RECORDED))
{
! if (target_big_endian)
! noop = thumb_bigend_noop;
else
! noop = thumb_noop;
! noop_size = sizeof (thumb_noop);
}
else
{
! if (target_big_endian)
! noop = arm_bigend_noop;
! else
! noop = arm_noop;
! noop_size = sizeof (arm_noop);
}
!
if (bytes & (noop_size - 1))
{
fix = bytes & (noop_size - 1);
--- 17630,17653 ----
if (fragP->tc_frag_data & (~ MODE_RECORDED))
{
! if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
! {
! narrow_noop = thumb_noop[1][target_big_endian];
! noop = wide_thumb_noop[target_big_endian];
! }
else
! noop = thumb_noop[0][target_big_endian];
! noop_size = 2;
}
else
{
! noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k) != 0]
! [target_big_endian];
! noop_size = 4;
}
!
! fragP->fr_var = noop_size;
!
if (bytes & (noop_size - 1))
{
fix = bytes & (noop_size - 1);
*************** arm_handle_align (fragS * fragP)
*** 17626,17631 ****
--- 17656,17676 ----
bytes -= fix;
}
+ if (narrow_noop)
+ {
+ if (bytes & noop_size)
+ {
+ /* Insert a narrow noop. */
+ memcpy (p, narrow_noop, noop_size);
+ p += noop_size;
+ bytes -= noop_size;
+ fix += noop_size;
+ }
+
+ /* Use wide noops for the remainder */
+ noop_size = 4;
+ }
+
while (bytes >= noop_size)
{
memcpy (p, noop, noop_size);
*************** arm_handle_align (fragS * fragP)
*** 17635,17641 ****
}
fragP->fr_fix += fix;
- fragP->fr_var = noop_size;
}
/* Called from md_do_align. Used to create an alignment
--- 17680,17685 ----
Index: testsuite/gas/arm/align.d
===================================================================
RCS file: testsuite/gas/arm/align.d
diff -N testsuite/gas/arm/align.d
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gas/arm/align.d 30 Mar 2009 15:59:34 -0000
***************
*** 0 ****
--- 1,25 ----
+ # name: ARM V6t2 Alignment
+ # as: -march=armv6kt2
+ # objdump: -dr --prefix-addresses --show-raw-insn
+
+ .*: +file format .*arm.*
+
+ Disassembly of section .text:
+ 0+000 <[^>]*> bf00 nop
+ 0+002 <[^>]*> 4611 mov r1, r2
+ 0+004 <[^>]*> f3af 8000 nop.w
+ 0+008 <[^>]*> f3af 8000 nop.w
+ 0+00c <[^>]*> f3af 8000 nop.w
+ 0+010 <[^>]*> 4611 mov r1, r2
+ 0+012 <[^>]*> bf00 nop
+ 0+014 <[^>]*> f3af 8000 nop.w
+ 0+018 <[^>]*> e320f000 nop \{0\}
+ 0+01c <[^>]*> e1a01002 mov r1, r2
+ 0+020 <[^>]*> e1a01002 mov r1, r2
+ 0+024 <[^>]*> e320f000 nop \{0\}
+ 0+028 <[^>]*> e320f000 nop \{0\}
+ 0+02c <[^>]*> e320f000 nop \{0\}
+ 0+030 <[^>]*> e320f000 nop \{0\}
+ 0+034 <[^>]*> e320f000 nop \{0\}
+ 0+038 <[^>]*> e320f000 nop \{0\}
+ 0+03c <[^>]*> e320f000 nop \{0\}
Index: testsuite/gas/arm/align.s
===================================================================
RCS file: testsuite/gas/arm/align.s
diff -N testsuite/gas/arm/align.s
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gas/arm/align.s 30 Mar 2009 15:59:34 -0000
***************
*** 0 ****
--- 1,14 ----
+ .syntax unified
+ .thumb
+ nop
+ mov r1,r2
+ .p2align 4
+ mov r1,r2
+ .p2align 3
+
+ .arm
+ nop
+ mov r1,r2
+ .p2align 4
+ mov r1,r2
+ .p2align 5
Index: testsuite/gas/arm/arch6zk.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/arch6zk.d,v
retrieving revision 1.4
diff -c -3 -p -r1.4 arch6zk.d
*** testsuite/gas/arm/arch6zk.d 8 Sep 2005 12:49:25 -0000 1.4
--- testsuite/gas/arm/arch6zk.d 30 Mar 2009 15:59:34 -0000
*************** Disassembly of section .text:
*** 26,32 ****
0+048 <[^>]*> e320f001 ? yield
0+04c <[^>]*> e16ec371 ? smc 60465
0+050 <[^>]*> 11613c7e ? smcne 5070
! 0+054 <[^>]*> e1a00000 ? nop[ ]+\(mov r0,r0\)
! 0+058 <[^>]*> e1a00000 ? nop[ ]+\(mov r0,r0\)
! 0+05c <[^>]*> e1a00000 ? nop[ ]+\(mov r0,r0\)
!
--- 26,29 ----
0+048 <[^>]*> e320f001 ? yield
0+04c <[^>]*> e16ec371 ? smc 60465
0+050 <[^>]*> 11613c7e ? smcne 5070
! #...
Index: testsuite/gas/arm/arch6zk.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/arch6zk.s,v
retrieving revision 1.4
diff -c -3 -p -r1.4 arch6zk.s
*** testsuite/gas/arm/arch6zk.s 8 Sep 2005 12:49:25 -0000 1.4
--- testsuite/gas/arm/arch6zk.s 30 Mar 2009 15:59:34 -0000
*************** label:
*** 26,33 ****
smc 0xec31
smcne 0x13ce
! # Add three nop instructions to ensure that the
! # output is 32-byte aligned as required for arm-aout.
! nop
! nop
! nop
--- 26,30 ----
smc 0xec31
smcne 0x13ce
! # Ensure output is 32-byte aligned as required for arm-aout.
! .p2align 5
Index: testsuite/gas/arm/thumb2_relax.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb2_relax.d,v
retrieving revision 1.3
diff -c -3 -p -r1.3 thumb2_relax.d
*** testsuite/gas/arm/thumb2_relax.d 6 Jun 2007 17:36:54 -0000 1.3
--- testsuite/gas/arm/thumb2_relax.d 30 Mar 2009 15:59:35 -0000
*************** Disassembly of section .text:
*** 20,26 ****
0+02e <[^>]+> f89f 800c ldrb.w r8, \[pc, #12\] ; 0+03c <[^>]+>
0+032 <[^>]+> f89f 100a ldrb.w r1, \[pc, #10\] ; 0+03e <[^>]+>
0+036 <[^>]+> f81f 1038 ldrb.w r1, \[pc, #-56\] ; 0+000 <[^>]+>
! 0+03a <[^>]+> 46c0 nop \(mov r8, r8\)
0+03c <[^>]+> bf00 nop
0+03e <[^>]+> f995 1000 ldrsb.w r1, \[r5\]
0+042 <[^>]+> f995 1023 ldrsb.w r1, \[r5, #35\]
--- 20,26 ----
0+02e <[^>]+> f89f 800c ldrb.w r8, \[pc, #12\] ; 0+03c <[^>]+>
0+032 <[^>]+> f89f 100a ldrb.w r1, \[pc, #10\] ; 0+03e <[^>]+>
0+036 <[^>]+> f81f 1038 ldrb.w r1, \[pc, #-56\] ; 0+000 <[^>]+>
! 0+03a <[^>]+> bf00 nop
0+03c <[^>]+> bf00 nop
0+03e <[^>]+> f995 1000 ldrsb.w r1, \[r5\]
0+042 <[^>]+> f995 1023 ldrsb.w r1, \[r5, #35\]
*************** Disassembly of section .text:
*** 89,95 ****
0+126 <[^>]+> f8df 800c ldr.w r8, \[pc, #12\] ; 0+134 <[^>]+>
0+12a <[^>]+> f8df 100a ldr.w r1, \[pc, #10\] ; 0+136 <[^>]+>
0+12e <[^>]+> f85f 1036 ldr.w r1, \[pc, #-54\] ; 0+0fa <[^>]+>
! 0+132 <[^>]+> 46c0 nop \(mov r8, r8\)
0+134 <[^>]+> bf00 nop
0+136 <[^>]+> 7029 strb r1, \[r5, #0\]
0+138 <[^>]+> f885 1023 strb.w r1, \[r5, #35\]
--- 89,95 ----
0+126 <[^>]+> f8df 800c ldr.w r8, \[pc, #12\] ; 0+134 <[^>]+>
0+12a <[^>]+> f8df 100a ldr.w r1, \[pc, #10\] ; 0+136 <[^>]+>
0+12e <[^>]+> f85f 1036 ldr.w r1, \[pc, #-54\] ; 0+0fa <[^>]+>
! 0+132 <[^>]+> bf00 nop
0+134 <[^>]+> bf00 nop
0+136 <[^>]+> 7029 strb r1, \[r5, #0\]
0+138 <[^>]+> f885 1023 strb.w r1, \[r5, #35\]
Index: testsuite/gas/arm/thumb32.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb32.d,v
retrieving revision 1.28
diff -c -3 -p -r1.28 thumb32.d
*** testsuite/gas/arm/thumb32.d 29 Jan 2009 11:52:26 -0000 1.28
--- testsuite/gas/arm/thumb32.d 30 Mar 2009 15:59:37 -0000
*************** Disassembly of section .text:
*** 277,283 ****
0[0-9a-f]+ <[^>]+> e002 b\.n 0+358 <[^>]+>
0[0-9a-f]+ <[^>]+> e7d4 b\.n 0+2fe <[^>]+>
0[0-9a-f]+ <[^>]+> e000 b\.n 0+358 <[^>]+>
! 0[0-9a-f]+ <[^>]+> 46c0 nop \(mov r8, r8\)
0[0-9a-f]+ <[^>]+> f43f affe beq\.w 0+358 <[^>]+>
0[0-9a-f]+ <[^>]+> f000 8058 beq\.w 0+410 <[^>]+>
0[0-9a-f]+ <[^>]+> f47f affa bne\.w 0+358 <[^>]+>
--- 277,283 ----
0[0-9a-f]+ <[^>]+> e002 b\.n 0+358 <[^>]+>
0[0-9a-f]+ <[^>]+> e7d4 b\.n 0+2fe <[^>]+>
0[0-9a-f]+ <[^>]+> e000 b\.n 0+358 <[^>]+>
! 0[0-9a-f]+ <[^>]+> bf00 nop
0[0-9a-f]+ <[^>]+> f43f affe beq\.w 0+358 <[^>]+>
0[0-9a-f]+ <[^>]+> f000 8058 beq\.w 0+410 <[^>]+>
0[0-9a-f]+ <[^>]+> f47f affa bne\.w 0+358 <[^>]+>