[Committed] S/390: Fix optional operand handling after memory addresses

Message ID 1541758024-23725-1-git-send-email-krebbel@linux.ibm.com
State New
Headers show
Series
  • [Committed] S/390: Fix optional operand handling after memory addresses
Related show

Commit Message

Andreas Krebbel Nov. 9, 2018, 10:07 a.m.
Instructions having an optional argument following a memory address
operand were not handled correctly if the optional argument was not
specified.

Committed to mainline. No regressions

gas/ChangeLog:

2018-11-09  Andreas Krebbel  <krebbel@linux.ibm.com>

	* config/tc-s390.c (skip_optargs_p): New function.
	(md_gather_operands): Use skip_optargs_p.
	* testsuite/gas/s390/s390.exp: Run the new test.
	* testsuite/gas/s390/zarch-optargs.d: New test.
	* testsuite/gas/s390/zarch-optargs.s: New test.
---
 gas/config/tc-s390.c                   | 47 +++++++++++++++++-----------------
 gas/testsuite/gas/s390/s390.exp        |  1 +
 gas/testsuite/gas/s390/zarch-optargs.d | 12 +++++++++
 gas/testsuite/gas/s390/zarch-optargs.s |  6 +++++
 4 files changed, 42 insertions(+), 24 deletions(-)
 create mode 100644 gas/testsuite/gas/s390/zarch-optargs.d
 create mode 100644 gas/testsuite/gas/s390/zarch-optargs.s

-- 
2.7.4

Patch

diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c
index 6b58c4c..c343c5f 100644
--- a/gas/config/tc-s390.c
+++ b/gas/config/tc-s390.c
@@ -1228,6 +1228,24 @@  s390_elf_cons (int nbytes /* 1=.byte, 2=.word, 4=.long */)
   demand_empty_rest_of_line ();
 }
 
+/* Return true if all remaining operands in the opcode with
+   OPCODE_FLAGS can be skipped.  */
+static bfd_boolean
+skip_optargs_p (unsigned int opcode_flags, const unsigned char *opindex_ptr)
+{
+  if ((opcode_flags & (S390_INSTR_FLAG_OPTPARM | S390_INSTR_FLAG_OPTPARM2))
+      && opindex_ptr[0] != '\0'
+      && opindex_ptr[1] == '\0')
+    return TRUE;
+
+  if ((opcode_flags & S390_INSTR_FLAG_OPTPARM2)
+      && opindex_ptr[0] != '\0'
+      && opindex_ptr[1] != '\0'
+      && opindex_ptr[2] == '\0')
+    return TRUE;
+  return FALSE;
+}
+
 /* We need to keep a list of fixups.  We can't simply generate them as
    we go, because that would require us to first create the frag, and
    that would screw up references to ``.''.  */
@@ -1467,6 +1485,9 @@  md_gather_operands (char *str,
 	      while (!(operand->flags & S390_OPERAND_BASE))
 		operand = s390_operands + *(++opindex_ptr);
 
+	      if (*str == '\0' && skip_optargs_p (opcode->flags, &opindex_ptr[1]))
+		continue;
+
 	      /* If there is a next operand it must be separated by a comma.  */
 	      if (opindex_ptr[1] != '\0')
 		{
@@ -1510,18 +1531,7 @@  md_gather_operands (char *str,
 	    as_bad (_("syntax error; missing ')' after base register"));
 	  skip_optional = 0;
 
-	  if ((opcode->flags & (S390_INSTR_FLAG_OPTPARM
-				| S390_INSTR_FLAG_OPTPARM2))
-	      && opindex_ptr[1] != '\0'
-	      && opindex_ptr[2] == '\0'
-	      && *str == '\0')
-	    continue;
-
-	  if ((opcode->flags & S390_INSTR_FLAG_OPTPARM2)
-	      && opindex_ptr[1] != '\0'
-	      && opindex_ptr[2] != '\0'
-	      && opindex_ptr[3] == '\0'
-	      && *str == '\0')
+	  if (*str == '\0' && skip_optargs_p (opcode->flags, &opindex_ptr[1]))
 	    continue;
 
 	  /* If there is a next operand it must be separated by a comma.  */
@@ -1553,18 +1563,7 @@  md_gather_operands (char *str,
 	      str++;
 	    }
 
-	  if ((opcode->flags & (S390_INSTR_FLAG_OPTPARM
-				| S390_INSTR_FLAG_OPTPARM2))
-	      && opindex_ptr[1] != '\0'
-	      && opindex_ptr[2] == '\0'
-	      && *str == '\0')
-	    continue;
-
-	  if ((opcode->flags & S390_INSTR_FLAG_OPTPARM2)
-	      && opindex_ptr[1] != '\0'
-	      && opindex_ptr[2] != '\0'
-	      && opindex_ptr[3] == '\0'
-	      && *str == '\0')
+	  if (*str == '\0' && skip_optargs_p (opcode->flags, &opindex_ptr[1]))
 	    continue;
 
 	  /* If there is a next operand it must be separated by a comma.  */
diff --git a/gas/testsuite/gas/s390/s390.exp b/gas/testsuite/gas/s390/s390.exp
index f0258ef..3853d2f 100644
--- a/gas/testsuite/gas/s390/s390.exp
+++ b/gas/testsuite/gas/s390/s390.exp
@@ -33,6 +33,7 @@  if [expr [istarget "s390-*-*"] ||  [istarget "s390x-*-*"]]  then {
     run_dump_test "zarch-reloc" "{as -m64}"
     run_dump_test "zarch-operands" "{as -m64} {as -march=z9-109}"
     run_dump_test "zarch-machine" "{as -m64} {as -march=z900}"
+    run_dump_test "zarch-optargs" "{as -m64} {as -march=arch12}"
     run_list_test "machine-parsing-1" ""
     run_list_test "machine-parsing-2" ""
     run_list_test "machine-parsing-3" ""
diff --git a/gas/testsuite/gas/s390/zarch-optargs.d b/gas/testsuite/gas/s390/zarch-optargs.d
new file mode 100644
index 0000000..ae425e4
--- /dev/null
+++ b/gas/testsuite/gas/s390/zarch-optargs.d
@@ -0,0 +1,12 @@ 
+#name: s390x optargs
+#objdump: -dr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+.* <foo>:
+.*:	e7 00 00 10 00 0e [	 ]*vst	%v0,16
+.*:	e7 00 00 10 30 0e [	 ]*vst	%v0,16,3
+.*:	e7 00 20 10 00 0e [	 ]*vst	%v0,16\(%r2\)
+.*:	e7 00 20 10 30 0e [	 ]*vst	%v0,16\(%r2\),3
diff --git a/gas/testsuite/gas/s390/zarch-optargs.s b/gas/testsuite/gas/s390/zarch-optargs.s
new file mode 100644
index 0000000..594ca9f
--- /dev/null
+++ b/gas/testsuite/gas/s390/zarch-optargs.s
@@ -0,0 +1,6 @@ 
+.text
+foo:
+	vst     %v0,16
+	vst     %v0,16,3
+	vst     %v0,16(%r2)
+	vst     %v0,16(%r2),3