/* s390-dis.c -- Disassemble S390 instructions
- Copyright 2000, 2001 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
- This file is part of GDB, GAS and the GNU binutils.
+ This file is part of the GNU opcodes library.
- This program is free software; you can redistribute it and/or modify
+ This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ It is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ along with this file; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
#include <stdio.h>
#include "ansidecl.h"
static int opc_index[256];
static int current_arch_mask = 0;
-static void init_disasm PARAMS ((struct disassemble_info *));
-static unsigned int s390_extract_operand
- PARAMS ((unsigned char *, const struct s390_operand *));
-
/* Set up index table for first opcode byte. */
static void
-init_disasm (info)
- struct disassemble_info *info;
+init_disasm (struct disassemble_info *info)
{
const struct s390_opcode *opcode;
const struct s390_opcode *opcode_end;
}
switch (info->mach)
{
- case bfd_mach_s390_esa:
+ case bfd_mach_s390_31:
current_arch_mask = 1 << S390_OPCODE_ESA;
break;
- case bfd_mach_s390_esame:
- current_arch_mask = 1 << S390_OPCODE_ESAME;
+ case bfd_mach_s390_64:
+ current_arch_mask = 1 << S390_OPCODE_ZARCH;
break;
default:
abort ();
/* Extracts an operand value from an instruction. */
static inline unsigned int
-s390_extract_operand (insn, operand)
- unsigned char *insn;
- const struct s390_operand *operand;
+s390_extract_operand (unsigned char *insn, const struct s390_operand *operand)
{
unsigned int val;
int bits;
val >>= -bits;
val &= ((1U << (operand->bits - 1)) << 1) - 1;
+ /* Check for special long displacement case. */
+ if (operand->bits == 20 && operand->shift == 20)
+ val = (val & 0xff) << 12 | (val & 0xfff00) >> 8;
+
/* Sign extend value if the operand is signed or pc relative. */
if ((operand->flags & (S390_OPERAND_SIGNED | S390_OPERAND_PCREL))
&& (val & (1U << (operand->bits - 1))))
if (operand->flags & S390_OPERAND_PCREL)
val <<= 1;
- /* Length x in an instructions has real length x+1. */
+ /* Length x in an instructions has real length x + 1. */
if (operand->flags & S390_OPERAND_LENGTH)
val++;
return val;
/* Print a S390 instruction. */
int
-print_insn_s390 (memaddr, info)
- bfd_vma memaddr;
- struct disassemble_info *info;
+print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info)
{
bfd_byte buffer[6];
const struct s390_opcode *opcode;
const unsigned char *opindex;
/* Check architecture. */
- if (!(opcode->architecture & current_arch_mask))
+ if (!(opcode->modes & current_arch_mask))
continue;
/* Check signature of the opcode. */
if ((buffer[1] & opcode->mask[1]) != opcode->opcode[1]
else if (operand->flags & S390_OPERAND_SIGNED)
(*info->fprintf_func) (info->stream, "%i", (int) value);
else
- (*info->fprintf_func) (info->stream, "%i", value);
+ (*info->fprintf_func) (info->stream, "%u", value);
if (operand->flags & S390_OPERAND_DISP)
{