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 ();
}
/* 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. */

View File

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

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