diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2015-01-16 12:19:21 +0100 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2015-01-16 12:28:58 +0100 |
commit | 1e2e8c529c1cf4fcc8cbae382aa0a653d0b65da6 (patch) | |
tree | 2cc295f864977f3b461a8f8fa80af608dcb8a769 /opcodes/s390-dis.c | |
parent | 9f2850baa3ce341f0ba42bd9519cb3c1bf1287c7 (diff) | |
download | fsf-binutils-gdb-1e2e8c529c1cf4fcc8cbae382aa0a653d0b65da6.zip fsf-binutils-gdb-1e2e8c529c1cf4fcc8cbae382aa0a653d0b65da6.tar.gz fsf-binutils-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.c | 50 |
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 = '('; |