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:
parent
0e2779e98d
commit
13daa8e488
4 changed files with 42 additions and 24 deletions
|
@ -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. */
|
||||||
|
|
|
@ -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" ""
|
||||||
|
|
12
gas/testsuite/gas/s390/zarch-optargs.d
Normal file
12
gas/testsuite/gas/s390/zarch-optargs.d
Normal 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
|
6
gas/testsuite/gas/s390/zarch-optargs.s
Normal file
6
gas/testsuite/gas/s390/zarch-optargs.s
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.text
|
||||||
|
foo:
|
||||||
|
vst %v0,16
|
||||||
|
vst %v0,16,3
|
||||||
|
vst %v0,16(%r2)
|
||||||
|
vst %v0,16(%r2),3
|
Loading…
Add table
Add a link
Reference in a new issue