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]

[GAS][ARM][PR20827]Fix gas error for two register form instruction (pre-UAL syntax).


Hi all,

Previously, I had a patch to emit warning for PC used in data processing instructions
with register-shifted register operand.
https://sourceware.org/ml/binutils/2016-10/msg00073.html

It will assert if any operand is not presented before the shifted register operand.
However, there is a relaxation of requirements I had missed in pre-UAL syntax.
If the destination register is the same as the first operand, a two register
form of the instruction can be used.

so the following two instruction are the same.
1) add r5, r4, lsl r0
2) add r5, r5, r4, lsl r0

Although, the preferred form for ALU instructions specifies three registers,
even if the destination register is the same as the first operand.
If unified syntax is selected, gas will give error for instruction 1) during operand parsing.

This patch fixes the bug. binutils arm-none-eabi regression test checked Okay.
Okay to check in the change?

The previous change is not in the 2.27 release branch.
So the 2.27 shouldn't have the problem.

Regards,
Renlin


gas/ChangeLog:

2016-11-17  Renlin Li  <renlin.li@arm.com>

	* config/tc-arm.c (encode_arm_shift): Don't assert for operands not
	presented.
	* testsuite/gas/arm/add-shift-two.d: New.
	* testsuite/gas/arm/add-shift-two.s: New.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 9a12bcc..e37d354 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -7435,8 +7435,11 @@ encode_arm_shift (int i)
       int index;
       for (index = 0; index <= i; ++index)
 	{
-	  gas_assert (inst.operands[index].present);
-	  if (inst.operands[index].isreg && inst.operands[index].reg == REG_PC)
+	  /* Check the operand only when it's presented.  In pre-UAL syntax,
+	     if the destination register is the same as the first operand, two
+	     register form of the instruction can be used.  */
+	  if (inst.operands[index].present && inst.operands[index].isreg
+	      && inst.operands[index].reg == REG_PC)
 	    as_warn (UNPRED_REG ("r15"));
 	}
 
diff --git a/gas/testsuite/gas/arm/add-shift-two.d b/gas/testsuite/gas/arm/add-shift-two.d
new file mode 100644
index 0000000..46a58c5
--- /dev/null
+++ b/gas/testsuite/gas/arm/add-shift-two.d
@@ -0,0 +1,11 @@
+# name: Two register form of data processing instruction with register shifted register operand
+# as:
+# objdump: -dr
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+   0:	e0855014 	add	r5, r5, r4, lsl r0
+   4:	e0855014 	add	r5, r5, r4, lsl r0
diff --git a/gas/testsuite/gas/arm/add-shift-two.s b/gas/testsuite/gas/arm/add-shift-two.s
new file mode 100644
index 0000000..72560cd
--- /dev/null
+++ b/gas/testsuite/gas/arm/add-shift-two.s
@@ -0,0 +1,5 @@
+	.arch armv7-a
+	.text
+	# PR 20827
+	add r5, r4, lsl r0
+	add r5, r5, r4, lsl r0

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