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, ARM] Fix ADR encoding


According to ARMARM, we should use encoding A2 when "<label> before current instruction" for ADR instruction. But now we use encoding A1. This patch should fix it. Tested on arm-none-eabi. Is it OK?


-- Jie Zhang CodeSourcery
	* config/tc-arm.c (md_apply_fix): Use encoding A2 of ADR
	if offset is negative.

	testsuite/
	* gas/arm/adr.d: New test.
	* gas/arm/adr.s: New test.

Index: config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.439
diff -u -p -r1.439 tc-arm.c
--- config/tc-arm.c	19 Mar 2010 14:43:09 -0000	1.439
+++ config/tc-arm.c	31 Mar 2010 02:18:02 -0000
@@ -19797,13 +19797,22 @@ md_apply_fix (fixS *	fixP,
 	  break;
 	}
 
-      newimm = encode_arm_immediate (value);
       temp = md_chars_to_number (buf, INSN_SIZE);
 
-      /* If the instruction will fail, see if we can fix things up by
-	 changing the opcode.  */
-      if (newimm == (unsigned int) FAIL
-	  && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
+      /* If the offset is negative, we should use encoding A2 for ADR.  */
+      if ((temp & 0xfff0000) == 0x28f0000 && value < 0)
+	newimm = negate_data_op (&temp, value);
+      else
+	{
+	  newimm = encode_arm_immediate (value);
+
+	  /* If the instruction will fail, see if we can fix things up by
+	     changing the opcode.  */
+	  if (newimm == (unsigned int) FAIL)
+	    newimm = negate_data_op (&temp, value);
+	}
+
+      if (newimm == (unsigned int) FAIL)
 	{
 	  as_bad_where (fixP->fx_file, fixP->fx_line,
 			_("invalid constant (%lx) after fixup"),
Index: testsuite/gas/arm/adr.d
===================================================================
RCS file: testsuite/gas/arm/adr.d
diff -N testsuite/gas/arm/adr.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/adr.d	31 Mar 2010 02:18:02 -0000
@@ -0,0 +1,9 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: ADR
+
+# Test the `ADR' pseudo-op
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+ <.*> 824ff203 	subhi	pc, pc, #805306368	; 0x30000000
Index: testsuite/gas/arm/adr.s
===================================================================
RCS file: testsuite/gas/arm/adr.s
diff -N testsuite/gas/arm/adr.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/adr.s	31 Mar 2010 02:18:02 -0000
@@ -0,0 +1,5 @@
+	@ test ADR pseudo-op
+	.text
+	.global foo
+foo:
+	adrhi	pc, . - 0x2ffffff8

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