S/390: Fix optional operand handling after memory addresses

Instructions having an optional argument following a memory address
operand were not handled correctly if the optional argument was not
specified.

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.
This commit is contained in:
Andreas Krebbel 2018-11-09 11:00:47 +01:00
parent 0e2779e98d
commit 13daa8e488
4 changed files with 42 additions and 24 deletions

View file

@ -1228,6 +1228,24 @@ s390_elf_cons (int nbytes /* 1=.byte, 2=.word, 4=.long */)
demand_empty_rest_of_line (); 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 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 we go, because that would require us to first create the frag, and
that would screw up references to ``.''. */ that would screw up references to ``.''. */
@ -1467,6 +1485,9 @@ md_gather_operands (char *str,
while (!(operand->flags & S390_OPERAND_BASE)) while (!(operand->flags & S390_OPERAND_BASE))
operand = s390_operands + *(++opindex_ptr); 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 there is a next operand it must be separated by a comma. */
if (opindex_ptr[1] != '\0') if (opindex_ptr[1] != '\0')
{ {
@ -1510,18 +1531,7 @@ md_gather_operands (char *str,
as_bad (_("syntax error; missing ')' after base register")); as_bad (_("syntax error; missing ')' after base register"));
skip_optional = 0; skip_optional = 0;
if ((opcode->flags & (S390_INSTR_FLAG_OPTPARM if (*str == '\0' && skip_optargs_p (opcode->flags, &opindex_ptr[1]))
| 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')
continue; continue;
/* If there is a next operand it must be separated by a comma. */ /* If there is a next operand it must be separated by a comma. */
@ -1553,18 +1563,7 @@ md_gather_operands (char *str,
str++; str++;
} }
if ((opcode->flags & (S390_INSTR_FLAG_OPTPARM if (*str == '\0' && skip_optargs_p (opcode->flags, &opindex_ptr[1]))
| 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')
continue; continue;
/* If there is a next operand it must be separated by a comma. */ /* If there is a next operand it must be separated by a comma. */

View file

@ -33,6 +33,7 @@ if [expr [istarget "s390-*-*"] || [istarget "s390x-*-*"]] then {
run_dump_test "zarch-reloc" "{as -m64}" run_dump_test "zarch-reloc" "{as -m64}"
run_dump_test "zarch-operands" "{as -m64} {as -march=z9-109}" 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-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-1" ""
run_list_test "machine-parsing-2" "" run_list_test "machine-parsing-2" ""
run_list_test "machine-parsing-3" "" run_list_test "machine-parsing-3" ""

View file

@ -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

View file

@ -0,0 +1,6 @@
.text
foo:
vst %v0,16
vst %v0,16,3
vst %v0,16(%r2)
vst %v0,16(%r2),3