aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Remus <jremus@linux.ibm.com>2024-11-29 15:37:19 +0100
committerJens Remus <jremus@linux.ibm.com>2024-11-29 15:37:19 +0100
commit7507fe37980edcd85b5811c2ec2859bdaf93107e (patch)
tree73c47d4137809f5738133ab1748bf66d0dfc4f6b
parent0e6fdecde3a85fc81fea6722458e6319fbe81cb7 (diff)
downloadbinutils-7507fe37980edcd85b5811c2ec2859bdaf93107e.zip
binutils-7507fe37980edcd85b5811c2ec2859bdaf93107e.tar.gz
binutils-7507fe37980edcd85b5811c2ec2859bdaf93107e.tar.bz2
s390: Fix disassembly of optional addressing operands
"nop D1(B1)" erroneously disassembled into "nop D1(B1" (missing closing parenthesis). "nop D1(X1,0)" and "nop D1(X1,)" erroneously disassembled into "nop D1(X1)" (missing zero base register) instead of "nop D1(X1,0)". Do not skip disassembly of optional operands if they are index (X) or base (B) registers or length (L) in an addressing operand sequence "D(X,B)", "D(B)", or "D(L,B). Index and base register operand values of zero are being handled separately, as they may not be omitted unconditionally. For instance a base register value of zero must be printed in above mentioned case, to distinguish the index from the base register. This also ensures proper formatting of addressing operand sequences. While at it add further test cases for instructions with optional operands. opcodes/ * s390-dis.c (s390_print_insn_with_opcode): Do not unconditionally skip disassembly of optional operands with a value of zero, if within an addressing operand sequence. gas/testsuite/ * gas/s390/zarch-optargs.d: Add further test cases for instructions with optional operands. * gas/s390/zarch-optargs.s: Likewise. Reported-by: Florian Krohm <flo2030@eich-krohm.de> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
-rw-r--r--gas/testsuite/gas/s390/zarch-optargs.d46
-rw-r--r--gas/testsuite/gas/s390/zarch-optargs.s46
-rw-r--r--opcodes/s390-dis.c34
3 files changed, 106 insertions, 20 deletions
diff --git a/gas/testsuite/gas/s390/zarch-optargs.d b/gas/testsuite/gas/s390/zarch-optargs.d
index ae425e4..919acbb 100644
--- a/gas/testsuite/gas/s390/zarch-optargs.d
+++ b/gas/testsuite/gas/s390/zarch-optargs.d
@@ -6,7 +6,45 @@
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
+# nopr [R1]
+.*: 07 00 [ ]*nopr
+.*: 07 01 [ ]*nopr %r1
+# nop [D1(X1,B1)]
+.*: 47 00 00 00 [ ]*nop 0
+.*: 47 00 0f ff [ ]*nop 4095
+.*: 47 00 2f ff [ ]*nop 4095\(%r2\)
+.*: 47 01 0f ff [ ]*nop 4095\(%r1,0\)
+.*: 47 01 2f ff [ ]*nop 4095\(%r1,%r2\)
+# cu12 R1,R2[,M3]
+.*: b2 a7 00 24 [ ]*cutfu %r2,%r4
+.*: b2 a7 30 24 [ ]*cu12 %r2,%r4,3
+# vst V1,D2(X2,B2)[,M3]
+.*: e7 10 00 10 00 0e [ ]*vst %v1,16
+.*: e7 10 00 10 30 0e [ ]*vst %v1,16,3
+.*: e7 10 30 10 00 0e [ ]*vst %v1,16\(%r3\)
+.*: e7 10 30 10 30 0e [ ]*vst %v1,16\(%r3\),3
+.*: e7 12 00 10 00 0e [ ]*vst %v1,16\(%r2,0\)
+.*: e7 12 00 10 30 0e [ ]*vst %v1,16\(%r2,0\),3
+.*: e7 12 30 10 00 0e [ ]*vst %v1,16\(%r2,%r3\)
+.*: e7 12 30 10 30 0e [ ]*vst %v1,16\(%r2,%r3\),3
+# idte R1,R3,R2[,M4]
+.* b9 8e 30 12 [ ]*idte %r1,%r3,%r2
+.* b9 8e 34 12 [ ]*idte %r1,%r3,%r2,4
+# ipte R1,R2[,R3[,M4]]
+.* b2 21 00 12 [ ]*ipte %r1,%r2
+.* b2 21 30 12 [ ]*ipte %r1,%r2,%r3
+.* b2 21 34 12 [ ]*ipte %r1,%r2,%r3,4
+# vstm V1,V3,D2(B2)[,M4]
+.*: e7 13 00 10 00 3e [ ]*vstm %v1,%v3,16
+.*: e7 13 00 10 40 3e [ ]*vstm %v1,%v3,16,4
+.*: e7 13 20 10 00 3e [ ]*vstm %v1,%v3,16\(%r2\)
+.*: e7 13 20 10 40 3e [ ]*vstm %v1,%v3,16\(%r2\),4
+# risbg R1,R2,I3,I4[,I5]
+.*: ec 12 03 04 00 55 [ ]*risbg %r1,%r2,3,4
+.*: ec 12 03 04 05 55 [ ]*risbg %r1,%r2,3,4,5
+# vfae V1,V2,V3,M4[,M5]
+.*: e7 12 30 00 40 82 [ ]*vfae %v1,%v2,%v3,4
+.*: e7 12 30 50 40 82 [ ]*vfae %v1,%v2,%v3,4,5
+# vstrc V1,V2,V3,V4,M5[,M6]
+.*: e7 12 35 00 40 8a [ ]*vstrc %v1,%v2,%v3,%v4,5
+.*: e7 12 35 60 40 8a [ ]*vstrc %v1,%v2,%v3,%v4,5,6
diff --git a/gas/testsuite/gas/s390/zarch-optargs.s b/gas/testsuite/gas/s390/zarch-optargs.s
index 594ca9f..86d9334 100644
--- a/gas/testsuite/gas/s390/zarch-optargs.s
+++ b/gas/testsuite/gas/s390/zarch-optargs.s
@@ -1,6 +1,44 @@
.text
foo:
- vst %v0,16
- vst %v0,16,3
- vst %v0,16(%r2)
- vst %v0,16(%r2),3
+# nopr [R1]
+ nopr
+ nopr %r1
+# nop [D1(X1,B1)]
+ nop
+ nop 4095
+ nop 4095(%r2)
+ nop 4095(%r1,0)
+ nop 4095(%r1,%r2)
+# cu12 R1,R2[,M3]
+ cu12 %r2,%r4
+ cu12 %r2,%r4,3
+# vst V1,D2(X2,B2)[,M3]
+ vst %v1,16
+ vst %v1,16,3
+ vst %v1,16(%r3)
+ vst %v1,16(%r3),3
+ vst %v1,16(%r2,0)
+ vst %v1,16(%r2,0),3
+ vst %v1,16(%r2,%r3)
+ vst %v1,16(%r2,%r3),3
+# idte R1,R3,R2[,M4]
+ idte %r1,%r3,%r2
+ idte %r1,%r3,%r2,4
+# ipte R1,R2[,R3[,M4]]
+ ipte %r1,%r2
+ ipte %r1,%r2,%r3
+ ipte %r1,%r2,%r3,4
+# vstm V1,V3,D2(B2)[,M4]
+ vstm %v1,%v3,16
+ vstm %v1,%v3,16,4
+ vstm %v1,%v3,16(%r2)
+ vstm %v1,%v3,16(%r2),4
+# risbg R1,R2,I3,I4[,I5]
+ risbg %r1,%r2,3,4
+ risbg %r1,%r2,3,4,5
+# vfae V1,V2,V3,M4[,M5]
+ vfae %v1,%v2,%v3,4
+ vfae %v1,%v2,%v3,4,5
+# vstrc V1,V2,V3,V4,M5[,M6]
+ vstrc %v1,%v2,%v3,%v4,5
+ vstrc %v1,%v2,%v3,%v4,5,6
diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c
index 852d2f6..1a23afc 100644
--- a/opcodes/s390-dis.c
+++ b/opcodes/s390-dis.c
@@ -214,20 +214,29 @@ s390_print_insn_with_opcode (bfd_vma memaddr,
continue;
}
- /* For instructions with a last optional operand don't print it
- if zero. */
- if ((opcode->flags & (S390_INSTR_FLAG_OPTPARM | S390_INSTR_FLAG_OPTPARM2))
- && val.u == 0
- && opindex[1] == 0)
- break;
-
- if ((opcode->flags & S390_INSTR_FLAG_OPTPARM2)
- && val.u == 0 && opindex[1] != 0 && opindex[2] == 0)
+ /* Omit optional last operands with a value of zero, except if
+ within an addressing operand sequence D(X,B), D(B), and D(L,B).
+ Index and base register operands with a value of zero are
+ handled separately, as they may not be omitted unconditionally. */
+ if (!(operand->flags & (S390_OPERAND_BASE
+ | S390_OPERAND_INDEX
+ | S390_OPERAND_LENGTH)))
{
- union operand_value next_op_val =
- s390_extract_operand (buffer, s390_operands + opindex[1]);
- if (next_op_val.u == 0)
+ if ((opcode->flags & (S390_INSTR_FLAG_OPTPARM | S390_INSTR_FLAG_OPTPARM2))
+ && val.u == 0
+ && opindex[1] == 0)
break;
+
+ if ((opcode->flags & S390_INSTR_FLAG_OPTPARM2)
+ && val.u == 0
+ && opindex[1] != 0 && opindex[2] == 0)
+ {
+ union operand_value next_op_val =
+ s390_extract_operand (buffer, s390_operands + opindex[1]);
+
+ if (next_op_val.u == 0)
+ break;
+ }
}
if (flags & S390_OPERAND_GPR)
@@ -312,6 +321,7 @@ s390_print_insn_with_opcode (bfd_vma memaddr,
&& val.u == 0
&& opindex[1] == 0)
break;
+
info->fprintf_styled_func (info->stream, dis_style_text,
"%c", separator);
style = ((flags & S390_OPERAND_DISP)