aboutsummaryrefslogtreecommitdiff
path: root/opcodes/s390-dis.c
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-01-16 12:19:21 +0100
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-01-16 12:28:58 +0100
commit1e2e8c529c1cf4fcc8cbae382aa0a653d0b65da6 (patch)
tree2cc295f864977f3b461a8f8fa80af608dcb8a769 /opcodes/s390-dis.c
parent9f2850baa3ce341f0ba42bd9519cb3c1bf1287c7 (diff)
downloadgdb-1e2e8c529c1cf4fcc8cbae382aa0a653d0b65da6.zip
gdb-1e2e8c529c1cf4fcc8cbae382aa0a653d0b65da6.tar.gz
gdb-1e2e8c529c1cf4fcc8cbae382aa0a653d0b65da6.tar.bz2
S/390: Add support for IBM z13.
- 32 128 bit vector registers (overlapping with the existing 16 64 bit floating point registers) - vector double instructions - vector integer instructions - scalar vector instructions (allowing to have more floating point registers for scalar operations) - vector string instructions gas/ChangeLog: * config/tc-s390.c (struct pd_reg): Remove. (pre_defined_registers): Remove. (REG_NAME_CNT): Remove. (reg_name_search): Calculate the register number instead of doing a lookup. (register_name, tc_s390_regname_to_dw2regnum): Adopt to the new reg_name_search signature. (s390_parse_cpu): Support the new arch string z13. (s390_insert_operand): Support for vector registers with the extra field for the fifth bit of each vector register operand. (md_gather_operand): Adjust to the new handling of optional parameters. * doc/as.texinfo: Document the z13 cpu string. gas/testsuite/ChangeLog: * gas/s390/esa-g5.d: Add a variant without the optional operand. * gas/s390/esa-g5.s: Likewise. * gas/s390/esa-z9-109.d: Likewise. * gas/s390/esa-z9-109.s: Likewise. * gas/s390/zarch-z9-109.d: Likewise. * gas/s390/zarch-z9-109.s: Likewise. * gas/s390/zarch-z10.d: For variants with a zero optional argument it is not dumped by objdump anymore. * gas/s390/zarch-zEC12.d: Likewise. * gas/s390/zarch-z13.d: New file. * gas/s390/zarch-z13.s: New file. * gas/s390/s390.exp: Run the test for the z13 files. include/opcode/ChangeLog: * s390.h (s390_opcode_cpu_val): Add S390_OPCODE_Z13. ld/testsuite/ChangeLog: * ld-s390/tlsbin.dd: The nopr register operand is optional and not printed if 0 anymore. opcodes/ChangeLog: * s390-dis.c (s390_extract_operand): Support vector register operands. (s390_print_insn_with_opcode): Support new operands types and add new handling of optional operands. * s390-mkopc.c (s390_opcode_mode_val, s390_opcode_cpu_val): Remove and include opcode/s390.h instead. (struct op_struct): New field `flags'. (insertOpcode, insertExpandedMnemonic): New parameter `flags'. (dumpTable): Dump flags. (main): Parse flags from the s390-opc.txt file. Add z13 as cpu string. * s390-opc.c: Add new operands types, instruction formats, and instruction masks. (s390_opformats): Add new formats for .insn. * s390-opc.txt: Add new instructions.
Diffstat (limited to 'opcodes/s390-dis.c')
-rw-r--r--opcodes/s390-dis.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c
index 7c47c94..1521665 100644
--- a/opcodes/s390-dis.c
+++ b/opcodes/s390-dis.c
@@ -107,6 +107,7 @@ s390_extract_operand (const bfd_byte *insn,
union operand_value ret;
unsigned int val;
int bits;
+ const bfd_byte *orig_insn = insn;
/* Extract fragments of the operand byte for byte. */
insn += operand->shift / 8;
@@ -140,6 +141,16 @@ s390_extract_operand (const bfd_byte *insn,
else if (operand->flags & S390_OPERAND_LENGTH)
/* Length x in an instruction has real length x + 1. */
ret.u = val + 1;
+
+ else if (operand->flags & S390_OPERAND_VR)
+ {
+ /* Extract the extra bits for a vector register operand stored
+ in the RXB field. */
+ unsigned vr = operand->shift == 32 ? 3
+ : (unsigned) operand->shift / 4 - 2;
+
+ ret.u = val | ((orig_insn[4] & (1 << (3 - vr))) << (vr + 1));
+ }
else
ret.u = val;
@@ -178,22 +189,45 @@ s390_print_insn_with_opcode (bfd_vma memaddr,
continue;
}
- info->fprintf_func (info->stream, "%c", separator);
+ /* For instructions with a last optional operand don't print it
+ if zero. */
+ if ((opcode->flags & S390_INSTR_FLAG_OPTPARM)
+ && val.u == 0
+ && opindex[1] == 0)
+ break;
if (flags & S390_OPERAND_GPR)
- info->fprintf_func (info->stream, "%%r%u", val.u);
+ info->fprintf_func (info->stream, "%c%%r%u", separator, val.u);
else if (flags & S390_OPERAND_FPR)
- info->fprintf_func (info->stream, "%%f%u", val.u);
+ info->fprintf_func (info->stream, "%c%%f%u", separator, val.u);
+ else if (flags & S390_OPERAND_VR)
+ info->fprintf_func (info->stream, "%c%%v%i", separator, val.u);
else if (flags & S390_OPERAND_AR)
- info->fprintf_func (info->stream, "%%a%u", val.u);
+ info->fprintf_func (info->stream, "%c%%a%u", separator, val.u);
else if (flags & S390_OPERAND_CR)
- info->fprintf_func (info->stream, "%%c%u", val.u);
+ info->fprintf_func (info->stream, "%c%%c%u", separator, val.u);
else if (flags & S390_OPERAND_PCREL)
- info->print_address_func (memaddr + val.i + val.i, info);
+ {
+ info->fprintf_func (info->stream, "%c", separator);
+ info->print_address_func (memaddr + val.i + val.i, info);
+ }
else if (flags & S390_OPERAND_SIGNED)
- info->fprintf_func (info->stream, "%i", val.i);
+ info->fprintf_func (info->stream, "%c%i", separator, val.i);
else
- info->fprintf_func (info->stream, "%u", val.u);
+ {
+ if (flags & S390_OPERAND_OR1)
+ val.u &= ~1;
+ if (flags & S390_OPERAND_OR2)
+ val.u &= ~2;
+ if (flags & S390_OPERAND_OR8)
+ val.u &= ~8;
+
+ if ((opcode->flags & S390_INSTR_FLAG_OPTPARM)
+ && val.u == 0
+ && opindex[1] == 0)
+ break;
+ info->fprintf_func (info->stream, "%c%u", separator, val.u);
+ }
if (flags & S390_OPERAND_DISP)
separator = '(';