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]

[patch, nios2] fix constant fixup overflow assembler bug


Altera reported a Nios II assembler bug to us in which a movia pseudo-instruction with a negative constant operand generated bad code. E.g.

	movia r2, 0xfffffff0

turned into

	movhi	r3,0             <- wrong register r3 instead of r2
	addi	r2,r2,-16

Turns out this really didn't have anything to do with movia per se; the problem was the failure to mask constant BFD_RELOC_NIOS2_HIADJ16 fixups to 16 bits before or'ing them with the instruction word. Such masking is indicated by the documentation for the %hiadj macro in the processor documentation.

I've checked in the attached patch with the obvious fix and an additional test case. Since this was a fairly generic change that could affect things other than movia, I also regression-tested on gcc/g++/libstdc++ testsuites to give broader test coverage.

-Sandra

2013-06-12  Sandra Loosemore  <sandra@codesourcery.com>

	gas/
	* config/tc-nios2.c (md_apply_fix):  Mask constant
	BFD_RELOC_NIOS2_HIADJ16 value to 16 bits.

	gas/testsuite/
	* gas/nios2/movia.s: Add additional test case with negative
	constant value.
	* gas/nios2/movia.d: Likewise.
Index: gas/config/tc-nios2.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-nios2.c,v
retrieving revision 1.5
diff -u -p -r1.5 tc-nios2.c
--- gas/config/tc-nios2.c	10 Jun 2013 01:04:42 -0000	1.5
+++ gas/config/tc-nios2.c	12 Jun 2013 04:27:27 -0000
@@ -1258,7 +1258,8 @@ md_apply_fix (fixS *fixP, valueT *valP, 
 	      fixup = fixup & 0xFFFF;
 	      break;
 	    case BFD_RELOC_NIOS2_HIADJ16:
-	      fixup = ((fixup >> 16) & 0xFFFF) + ((fixup >> 15) & 0x01);
+	      fixup = ((((fixup >> 16) & 0xFFFF) + ((fixup >> 15) & 0x01))
+		       & 0xFFFF);
 	      break;
 	    default:
 	      {
Index: gas/testsuite/gas/nios2/movia.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/nios2/movia.d,v
retrieving revision 1.2
diff -u -p -r1.2 movia.d
--- gas/testsuite/gas/nios2/movia.d	12 Mar 2013 21:34:58 -0000	1.2
+++ gas/testsuite/gas/nios2/movia.d	12 Jun 2013 04:27:27 -0000
@@ -16,3 +16,5 @@ Disassembly of section .text:
 			10: R_NIOS2_HIADJ16	sym-0x7fffffff
 0+0014 <[^>]*> 21000004 	addi	r4,r4,0
 			14: R_NIOS2_LO16	sym-0x7fffffff
+0+0018 <[^>]*> 00800034 	movhi	r2,0
+0+001c <[^>]*> 10bffc04 	addi	r2,r2,-16
Index: gas/testsuite/gas/nios2/movia.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/nios2/movia.s,v
retrieving revision 1.1
diff -u -p -r1.1 movia.s
--- gas/testsuite/gas/nios2/movia.s	6 Feb 2013 23:22:16 -0000	1.1
+++ gas/testsuite/gas/nios2/movia.s	12 Jun 2013 04:27:27 -0000
@@ -4,3 +4,4 @@ foo:
 	movia r2, 0x80808080
 	movia r3, sym + 0x80000000
 	movia r4, sym - 0x7fffffff
+	movia r2, 0xfffffff0

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