src/hotspot/cpu/s390/disassembler_s390.cpp
author lucy
Tue, 21 May 2019 15:51:35 +0200
changeset 54960 e46fe26d7f77
child 58959 b7b170ba3ba9
permissions -rw-r--r--
8213084: Rework and enhance Print[Opto]Assembly output Reviewed-by: kvn, thartmann
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
54960
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
     1
/*
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
     2
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
     3
 * Copyright (c) 2019 SAP SE. All rights reserved.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
     4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
     5
 *
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
     6
 * This code is free software; you can redistribute it and/or modify it
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
     7
 * under the terms of the GNU General Public License version 2 only, as
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
     8
 * published by the Free Software Foundation.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
     9
 *
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    14
 * accompanied this code).
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    15
 *
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    19
 *
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    21
 * or visit www.oracle.com if you need additional information or have any
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    22
 * questions.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    23
 *
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    24
 */
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    25
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    26
#include "asm/assembler.inline.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    27
#include "asm/macroAssembler.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    28
#include "code/codeCache.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    29
#include "compiler/disassembler.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    30
#include "depChecker_s390.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    31
#include "gc/cms/concurrentMarkSweepGeneration.inline.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    32
#include "gc/cms/parOopClosures.inline.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    33
#include "gc/shared/collectedHeap.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    34
#include "gc/shared/cardTableBarrierSet.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    35
#include "gc/shared/genOopClosures.inline.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    36
#include "oops/oop.inline.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    37
#include "runtime/handles.inline.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    38
#include "runtime/stubCodeGenerator.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    39
#include "runtime/stubRoutines.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    40
#include "utilities/align.hpp"
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    41
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    42
// List of all major opcodes, as of
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    43
// Principles of Operation, Eleventh Edition, March 2015
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    44
bool Disassembler::valid_opcodes[] =
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    45
{ true,  true,  false, false, true,  true,  true,  true,  // 0x00..07
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    46
  false, false, true,  true,  true,  true,  true,  true,  // 0x08..0f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    47
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x10..17
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    48
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x18..1f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    49
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x20..27
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    50
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x28..2f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    51
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x30..37
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    52
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x38..3f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    53
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x40..47
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    54
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x48..4f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    55
  true,  true,  false, false, true,  true,  true,  true,  // 0x50..57
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    56
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x58..5f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    57
  true,  false, false, false, false, false, false, true,  // 0x60..67
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    58
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x68..6f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    59
  true,  true,  false, false, false, false, false, false, // 0x70..77
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    60
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x78..7f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    61
  true,  false, true,  true,  true,  true,  true,  true,  // 0x80..87
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    62
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x88..8f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    63
  true,  true,  true,  true,  true,  true,  true,  true,  // 0x90..97
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    64
  true,  true,  true,  true,  false, false, false, false, // 0x98..9f
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    65
  false, false, false, false, false, true,  false, true,  // 0xa0..a7
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    66
  true,  true,  false, false, true,  true,  true,  true,  // 0xa8..af
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    67
  false, true,  true,  true,  false, false, true,  true,  // 0xb0..b7
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    68
  false, true,  true,  true,  false, true,  true,  true,  // 0xb8..bf
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    69
  true,  false, true,  false, true,  false, true,  false, // 0xc0..c7
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    70
  true,  false, false, false, true,  false, false, false, // 0xc8..cf
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    71
  true,  true,  true,  true,  true,  true,  true,  true,  // 0xd0..d7
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    72
  false, true,  true,  true,  true,  true,  true,  true,  // 0xd8..df
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    73
  false, true,  true,  true,  false, true,  false, true,  // 0xe0..e7
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    74
  true,  true,  true,  true,  true,  true,  true,  true,  // 0xe8..ef
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    75
  true,  true,  true,  true,  false, false, false, false, // 0xf0..f7
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    76
  true,  true,  true,  true,  true,  true,  false, false, // 0xf8..ff
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    77
};
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    78
// Check for valid opcodes.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    79
//
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    80
// The major opcode (one byte) at the passed location is inspected.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    81
// If the opcode found is assigned, the function returns true, false otherwise.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    82
// The true indication is not reliable. It may well be that the major opcode is
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    83
// assigned, but there exists a minor opcode field in the instruction which
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    84
// which has unassigned values.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    85
bool Disassembler::is_valid_opcode_at(address here) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    86
  return valid_opcodes[*here];
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    87
}
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    88
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    89
// This method does plain instruction decoding, no frills.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    90
// It may be called before the binutils disassembler kicks in
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    91
// to handle special cases the binutils disassembler does not.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    92
// Instruction address, comments, and the like have to be output by caller.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    93
address Disassembler::decode_instruction0(address here, outputStream * st, address virtual_begin) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    94
  if (is_abstract()) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    95
    // The disassembler library was not loaded (yet),
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    96
    // use AbstractDisassembler's decode-method.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    97
    return decode_instruction_abstract(here, st, Assembler::instr_len(here), Assembler::instr_maxlen());
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    98
  }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
    99
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   100
  // Currently, "special decoding" doesn't work when decoding error files.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   101
  // When decoding an instruction from a hs_err file, the given
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   102
  // instruction address 'start' points to the instruction's virtual address
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   103
  // which is not equal to the address where the instruction is located.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   104
  // Therefore, we will either crash or decode garbage.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   105
  if (is_decode_error_file()) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   106
    return here;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   107
  }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   108
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   109
  //---<  Decode some well-known "instructions"  >---
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   110
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   111
  address  next;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   112
  uint16_t instruction_2bytes = *(uint16_t*)here;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   113
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   114
  if (Assembler::is_z_nop((long)instruction_2bytes)) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   115
#if 1
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   116
    st->print("nop     ");  // fill up to operand column, leads to better code comment alignment
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   117
    next = here + 2;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   118
#else
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   119
    // Compact disassembler output. Does not work the easy way.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   120
    // Currently unusable, search does not terminate, risk of crash.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   121
    // TODO: rework required.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   122
    // Terminate search loop when reaching CodeEntryAlignment-aligned offset
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   123
    // or, at the latest, when reaching the next page boundary.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   124
    int n_nops = 0;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   125
    while(is_same_page(here, here+2*n_nops) && Assembler::is_z_nop((long)instruction_2bytes)) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   126
      n_nops++;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   127
      instruction_2bytes   = *(uint16_t*)(here+2*n_nops);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   128
    }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   129
    if (n_nops <= 4) { // do not group few subsequent nops
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   130
      st->print("nop     ");  // fill up to operand column, leads to better code comment alignment
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   131
      next = here + 2;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   132
    } else {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   133
      st->print("nop     count=%d", n_nops);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   134
      next = here + 2*n_nops;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   135
    }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   136
#endif
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   137
  } else if (Assembler::is_z_sync((long)instruction_2bytes)) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   138
    // Specific names. Make use of lightweight sync.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   139
    st->print("sync   ");
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   140
    if (Assembler::is_z_sync_full((long)instruction_2bytes) ) st->print("heavyweight");
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   141
    if (Assembler::is_z_sync_light((long)instruction_2bytes)) st->print("lightweight");
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   142
    next = here + 2;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   143
  } else if (instruction_2bytes == 0x0000) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   144
#if 1
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   145
    st->print("illtrap .nodata");
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   146
    next = here + 2;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   147
#else
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   148
    // Compact disassembler output. Does not work the easy way.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   149
    // Currently unusable, search does not terminate, risk of crash.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   150
    // TODO: rework required.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   151
    // Terminate search loop when reaching CodeEntryAlignment-aligned offset
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   152
    // or, at the latest, when reaching the next page boundary.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   153
    int n_traps = 0;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   154
    while(is_same_page(here, here+2*n_nops) && (instruction_2bytes == 0x0000)) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   155
      n_traps++;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   156
      instruction_2bytes   = *(uint16_t*)(here+2*n_traps);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   157
    }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   158
    if (n_traps <= 4) { // do not group few subsequent illtraps
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   159
      st->print("illtrap .nodata");
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   160
      next = here + 2;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   161
    } else {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   162
      st->print("illtrap .nodata count=%d", n_traps);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   163
      next = here + 2*n_traps;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   164
    }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   165
#endif
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   166
  } else if ((instruction_2bytes & 0xff00) == 0x0000) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   167
    st->print("illtrap .data 0x%2.2x", instruction_2bytes & 0x00ff);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   168
    next = here + 2;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   169
  } else {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   170
     next = here;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   171
  }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   172
  return next;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   173
}
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   174
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   175
// Count the instructions contained in the range [begin..end).
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   176
// The range must exactly contain the instructions, i.e.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   177
//  - the first instruction starts @begin
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   178
//  - the last instruction ends @(end-1)
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   179
// The caller has to make sure that the given range is readable.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   180
// This function performs no safety checks!
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   181
// Return value:
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   182
//  - The number of instructions, if there was exact containment.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   183
//  - If there is no exact containment, a negative value is returned.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   184
//    Its absolute value is the number of instructions from begin to end,
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   185
//    where the last instruction counted runs over the range end.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   186
//  - 0 (zero) is returned if there was a parameter error
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   187
//    (inverted range, bad starting point).
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   188
int Disassembler::count_instr(address begin, address end) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   189
  if (end < begin+2) return 0; // no instructions in range
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   190
  if (!Disassembler::is_valid_opcode_at(begin)) return 0; // bad starting point
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   191
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   192
  address p = begin;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   193
  int     n = 0;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   194
  while(p < end) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   195
    p += Assembler::instr_len(p);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   196
    n++;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   197
  }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   198
  return (p == end) ? n : -n;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   199
}
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   200
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   201
// Find preceding instruction.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   202
//
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   203
// Starting at the passed location, the n-th preceding (towards lower addresses)
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   204
// instruction is searched. With variable length instructions, there may be
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   205
// more than one solution, or no solution at all (if the passed location
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   206
// does not point to the start of an instruction or if the storage area
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   207
// does not contain instructions at all).
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   208
// instructions - has the passed location as n-th successor.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   209
//  - If multiple such locations exist between (here-n*instr_maxlen()) and here,
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   210
//    the most distant location is selected.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   211
//  - If no such location exists, NULL is returned. The caller should then
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   212
//    terminate its search and react properly.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   213
// Must be placed here in disassembler_s390.cpp. It does not compile
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   214
// in the header. There the class 'Assembler' is not available.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   215
address Disassembler::find_prev_instr(address here, int n_instr) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   216
  if (!os::is_readable_pointer(here)) return NULL;    // obviously a bad location to decode
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   217
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   218
  // Find most distant possible starting point.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   219
  // Narrow down because we don't want to SEGV while printing.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   220
  address start = here - n_instr*Assembler::instr_maxlen(); // starting point can't be further away.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   221
  while ((start < here) && !os::is_readable_range(start, here)) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   222
    start = align_down(start, os::min_page_size()) + os::min_page_size();
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   223
  }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   224
  if (start >= here) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   225
    // Strange. Can only happen with here on page boundary.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   226
    return NULL;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   227
  }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   228
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   229
  //---<  Find a starting point  >---
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   230
  int i_count = 0;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   231
  while ((start < here) && ((i_count = count_instr(start, here)) <= 0)) start += 2;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   232
  if (i_count == 0) return NULL; // There is something seriously wrong
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   233
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   234
  //---<  Narrow down distance (estimate was too large)  >---
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   235
  while(i_count-- > n_instr) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   236
    start   += Assembler::instr_len(start);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   237
  }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   238
  assert(n_instr >= count_instr(start, here), "just checking");
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   239
  return start;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   240
}
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   241
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   242
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   243
// Print annotations (value of loaded constant)
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   244
void Disassembler::annotate(address here, outputStream* st) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   245
  // Currently, annotation doesn't work when decoding error files.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   246
  // When decoding an instruction from a hs_err file, the given
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   247
  // instruction address 'start' points to the instruction's virtual address
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   248
  // which is not equal to the address where the instruction is located.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   249
  // Therefore, we will either crash or decode garbage.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   250
  if (is_decode_error_file()) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   251
    return;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   252
  }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   253
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   254
  if (MacroAssembler::is_load_const(here)) {
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   255
    long      value = MacroAssembler::get_const(here);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   256
    const int tsize = 8;
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   257
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   258
    st->fill_to(60);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   259
    st->print(";const %p | %ld | %23.15e", (void *)value, value, (double)value);
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   260
  }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents:
diff changeset
   261
}