summaryrefslogtreecommitdiff
path: root/opcodes/s390-dis.c
diff options
context:
space:
mode:
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>2009-09-10 08:47:20 +0000
committerAndreas Krebbel <Andreas.Krebbel@de.ibm.com>2009-09-10 08:47:20 +0000
commit6ac5a87882ec7c1531354e4c554f4ce63c11dfff (patch)
tree6c7a96bbdbab50ed50e23986d967a5c259d3defa /opcodes/s390-dis.c
parent937362cb402082737738969507859d43c0bc39d4 (diff)
downloadbinutils-redhat-6ac5a87882ec7c1531354e4c554f4ce63c11dfff.tar.gz
2009-09-10 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* s390-dis.c (s390_extract_operand): Remove the shift for pcrel operands. (print_insn_s390): Signextend and shift pcrel operands before printing.
Diffstat (limited to 'opcodes/s390-dis.c')
-rw-r--r--opcodes/s390-dis.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c
index e4e9cad05c..fe208ba9ff 100644
--- a/opcodes/s390-dis.c
+++ b/opcodes/s390-dis.c
@@ -81,6 +81,10 @@ init_disasm (struct disassemble_info *info)
}
/* Extracts an operand value from an instruction. */
+/* We do not perform the shift operation for larl-type address
+ operands here since that would lead to an overflow of the 32 bit
+ integer value. Instead the shift operation is done when printing
+ the operand in print_insn_s390. */
static inline unsigned int
s390_extract_operand (unsigned char *insn, const struct s390_operand *operand)
@@ -111,10 +115,6 @@ s390_extract_operand (unsigned char *insn, const struct s390_operand *operand)
&& (val & (1U << (operand->bits - 1))))
val |= (-1U << (operand->bits - 1)) << 1;
- /* Double value if the operand is pc relative. */
- if (operand->flags & S390_OPERAND_PCREL)
- val <<= 1;
-
/* Length x in an instructions has real length x + 1. */
if (operand->flags & S390_OPERAND_LENGTH)
val++;
@@ -222,7 +222,8 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info)
else if (operand->flags & S390_OPERAND_CR)
(*info->fprintf_func) (info->stream, "%%c%i", value);
else if (operand->flags & S390_OPERAND_PCREL)
- (*info->print_address_func) (memaddr + (int) value, info);
+ (*info->print_address_func) (memaddr +
+ (((long long)(int)value) << 1), info);
else if (operand->flags & S390_OPERAND_SIGNED)
(*info->fprintf_func) (info->stream, "%i", (int) value);
else