[PATCH, MIPS] Relax alignment check for LDPC

Matthew Fortune Matthew.Fortune@imgtec.com
Tue Dec 16 14:06:00 GMT 2014


The R6 LDPC instruction requires an 8-byte aligned load address but
does not require LDPC itself to be 8-byte aligned. Unfortunately the
tests for LPDC were aligning the LDPC instruction so did not catch
this issue.

The alignment check for BFD_RELOC_MIPS_18_PCREL_S3 was incorrectly
using the valP value as the target address of the reloc when it is
actually the calculated value to be patched into an instruction.
Since BFD_RELOC_MIPS_18_PCREL_S3 is recorded as relative to the
current PC rather than PC & ~7 then valP can end up as a multiple
of 4 rather than 8 even if the target address is correctly 8-byte
aligned.  Instead of recalculating the true target address from
the fixup I just check that valP is a 4-byte multiple leaving the
linker to do the accurate check as it could end up misaligning the
target anyway.

OK to apply (and backport to 2.25)?

Thanks,
Matthew

gas/

	* config/tc-mips.c (md_apply_fix): Relax alignment check
	for BFD_RELOC_MIPS_18_PCREL_S3.

gas/testsuite/

	* gas/mips/r6-64.s: Remove .align directives from LDPC
	instructions.
	* gas/mips/r6-64-n32.d: remove the NOPs from LDPC expected
	output and update addresses.
	* gas/mips/r6-64-n64.d: Likewise.
---
 gas/config/tc-mips.c               |  6 +++++-
 gas/testsuite/gas/mips/r6-64-n32.d | 20 +++++++-------------
 gas/testsuite/gas/mips/r6-64-n64.d | 32 +++++++++++++-------------------
 gas/testsuite/gas/mips/r6-64.s     |  5 -----
 4 files changed, 25 insertions(+), 38 deletions(-)

diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index c9266db..3adebf4 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -15009,7 +15009,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       break;
 
     case BFD_RELOC_MIPS_18_PCREL_S3:
-      if ((*valP & 0x7) != 0)
+      /* There is little point checking for a correctly aligned destination
+	 for R_MIPS_PC18_S3 as only the linker will know for sure if the
+	 destination address ends up 8-byte aligned or not.  Check for a
+	 minimum of 4-byte alignment instead.  */
+      if ((*valP & 0x3) != 0)
 	as_bad_where (fixP->fx_file, fixP->fx_line,
 		      _("PC-relative access to misaligned address (%lx)"),
 		      (long) *valP);
diff --git a/gas/testsuite/gas/mips/r6-64-n32.d b/gas/testsuite/gas/mips/r6-64-n32.d
index 6d471c6..d08039a 100644
--- a/gas/testsuite/gas/mips/r6-64-n32.d
+++ b/gas/testsuite/gas/mips/r6-64-n32.d
@@ -44,18 +44,12 @@ Disassembly of section .text:
 [	]*78: R_MIPS_PC19_S2	L0.+0xffffc
 0+007c <[^>]*> ec940000 	lwupc	a0,fff0007c <[^>]*>
 0+0080 <[^>]*> ec93ffff 	lwupc	a0,0010007c <[^>]*>
-0+0084 <[^>]*> 00000000 	nop
+0+0084 <[^>]*> ec980000 	ldpc	a0,00000080 <[^>]*>
+[	]*84: R_MIPS_PC18_S3	\.L1.1
 0+0088 <[^>]*> ec980000 	ldpc	a0,00000088 <[^>]*>
-[	]*88: R_MIPS_PC18_S3	\.L1.1
-0+008c <[^>]*> 00000000 	nop
-0+0090 <[^>]*> ec980000 	ldpc	a0,00000090 <[^>]*>
-[	]*90: R_MIPS_PC18_S3	L0.-0x100000
-0+0094 <[^>]*> 00000000 	nop
-0+0098 <[^>]*> ec980000 	ldpc	a0,00000098 <[^>]*>
-[	]*98: R_MIPS_PC18_S3	L0.+0xffff8
-0+009c <[^>]*> 00000000 	nop
-0+00a0 <[^>]*> ec9a0000 	ldpc	a0,fff000a0 <[^>]*>
-0+00a4 <[^>]*> 00000000 	nop
-0+00a8 <[^>]*> ec99ffff 	ldpc	a0,001000a0 <[^>]*>
-0+00ac <[^>]*> 00000000 	nop
+[	]*88: R_MIPS_PC18_S3	L0.-0x100000
+0+008c <[^>]*> ec980000 	ldpc	a0,00000088 <[^>]*>
+[	]*8c: R_MIPS_PC18_S3	L0.+0xffff8
+0+0090 <[^>]*> ec9a0000 	ldpc	a0,fff00090 <[^>]*>
+0+0094 <[^>]*> ec99ffff 	ldpc	a0,00100088 <[^>]*>
 	\.\.\.
diff --git a/gas/testsuite/gas/mips/r6-64-n64.d b/gas/testsuite/gas/mips/r6-64-n64.d
index 2202820..6a4c593 100644
--- a/gas/testsuite/gas/mips/r6-64-n64.d
+++ b/gas/testsuite/gas/mips/r6-64-n64.d
@@ -50,24 +50,18 @@ Disassembly of section .text:
 [	]*78: R_MIPS_NONE	\*ABS\*\+0xffffc
 0+007c <[^>]*> ec940000 	lwupc	a0,f+ff0007c <[^>]*>
 0+0080 <[^>]*> ec93ffff 	lwupc	a0,0+010007c <[^>]*>
-0+0084 <[^>]*> 00000000 	nop
+0+0084 <[^>]*> ec980000 	ldpc	a0,0+0000080 <[^>]*>
+[	]*84: R_MIPS_PC18_S3	\.L1.1
+[	]*84: R_MIPS_NONE	\*ABS\*
+[	]*84: R_MIPS_NONE	\*ABS\*
 0+0088 <[^>]*> ec980000 	ldpc	a0,0+0000088 <[^>]*>
-[	]*88: R_MIPS_PC18_S3	\.L1.1
-[	]*88: R_MIPS_NONE	\*ABS\*
-[	]*88: R_MIPS_NONE	\*ABS\*
-0+008c <[^>]*> 00000000 	nop
-0+0090 <[^>]*> ec980000 	ldpc	a0,0+0000090 <[^>]*>
-[	]*90: R_MIPS_PC18_S3	L0.-0x100000
-[	]*90: R_MIPS_NONE	\*ABS\*-0x100000
-[	]*90: R_MIPS_NONE	\*ABS\*-0x100000
-0+0094 <[^>]*> 00000000 	nop
-0+0098 <[^>]*> ec980000 	ldpc	a0,0+0000098 <[^>]*>
-[	]*98: R_MIPS_PC18_S3	L0.\+0xffff8
-[	]*98: R_MIPS_NONE	\*ABS\*\+0xffff8
-[	]*98: R_MIPS_NONE	\*ABS\*\+0xffff8
-0+009c <[^>]*> 00000000 	nop
-0+00a0 <[^>]*> ec9a0000 	ldpc	a0,f+ff000a0 <[^>]*>
-0+00a4 <[^>]*> 00000000 	nop
-0+00a8 <[^>]*> ec99ffff 	ldpc	a0,0+01000a0 <[^>]*>
-0+00ac <[^>]*> 00000000 	nop
+[	]*88: R_MIPS_PC18_S3	L0.-0x100000
+[	]*88: R_MIPS_NONE	\*ABS\*-0x100000
+[	]*88: R_MIPS_NONE	\*ABS\*-0x100000
+0+008c <[^>]*> ec980000 	ldpc	a0,0+0000088 <[^>]*>
+[	]*8c: R_MIPS_PC18_S3	L0.\+0xffff8
+[	]*8c: R_MIPS_NONE	\*ABS\*\+0xffff8
+[	]*8c: R_MIPS_NONE	\*ABS\*\+0xffff8
+0+0090 <[^>]*> ec9a0000 	ldpc	a0,f+ff00090 <[^>]*>
+0+0094 <[^>]*> ec99ffff 	ldpc	a0,0+0100088 <[^>]*>
 	\.\.\.
diff --git a/gas/testsuite/gas/mips/r6-64.s b/gas/testsuite/gas/mips/r6-64.s
index 7a97ad2..6486417 100644
--- a/gas/testsuite/gas/mips/r6-64.s
+++ b/gas/testsuite/gas/mips/r6-64.s
@@ -40,15 +40,10 @@
         lwu      $4, (-262144 << 2)($pc)
         lwu      $4, (262143 << 2)($pc)
 
-        .align 3
         ldpc     $4, 1f
-        .align 3
         ldpc     $4, .+(-131072 << 3)
-        .align 3
         ldpc     $4, .+(131071 << 3)
-        .align 3
         ld     $4, (-131072 << 3)($pc)
-        .align 3
         ld     $4, (131071 << 3)($pc)
         .align 3
 1:
-- 
1.9.4



More information about the Binutils mailing list