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

Message ID 582D84DA.4060108@foss.arm.com
State New
Headers show

Commit Message

Renlin Li Nov. 17, 2016, 10:22 a.m.
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.

Comments

Nick Clifton Nov. 18, 2016, 4:58 p.m. | #1
Hi 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.


Approved - please apply.

Cheers
  Nick

Patch hide | download patch | download mbox

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