11cb0ef41Sopenharmony_ci// Copyright 2014 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci// A Disassembler object is used to disassemble a block of code instruction by
61cb0ef41Sopenharmony_ci// instruction. The default implementation of the NameConverter object can be
71cb0ef41Sopenharmony_ci// overriden to modify register names or to do symbol lookup on addresses.
81cb0ef41Sopenharmony_ci//
91cb0ef41Sopenharmony_ci// The example below will disassemble a block of code and print it to stdout.
101cb0ef41Sopenharmony_ci//
111cb0ef41Sopenharmony_ci//   NameConverter converter;
121cb0ef41Sopenharmony_ci//   Disassembler d(converter);
131cb0ef41Sopenharmony_ci//   for (byte* pc = begin; pc < end;) {
141cb0ef41Sopenharmony_ci//     v8::base::EmbeddedVector<char, 256> buffer;
151cb0ef41Sopenharmony_ci//     byte* prev_pc = pc;
161cb0ef41Sopenharmony_ci//     pc += d.InstructionDecode(buffer, pc);
171cb0ef41Sopenharmony_ci//     printf("%p    %08x      %s\n",
181cb0ef41Sopenharmony_ci//            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
191cb0ef41Sopenharmony_ci//   }
201cb0ef41Sopenharmony_ci//
211cb0ef41Sopenharmony_ci// The Disassembler class also has a convenience method to disassemble a block
221cb0ef41Sopenharmony_ci// of code into a FILE*, meaning that the above functionality could also be
231cb0ef41Sopenharmony_ci// achieved by just calling Disassembler::Disassemble(stdout, begin, end);
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci#include <assert.h>
261cb0ef41Sopenharmony_ci#include <stdarg.h>
271cb0ef41Sopenharmony_ci#include <stdio.h>
281cb0ef41Sopenharmony_ci#include <string.h>
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_S390
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h"
331cb0ef41Sopenharmony_ci#include "src/base/strings.h"
341cb0ef41Sopenharmony_ci#include "src/base/vector.h"
351cb0ef41Sopenharmony_ci#include "src/codegen/macro-assembler.h"
361cb0ef41Sopenharmony_ci#include "src/codegen/register-configuration.h"
371cb0ef41Sopenharmony_ci#include "src/codegen/s390/constants-s390.h"
381cb0ef41Sopenharmony_ci#include "src/diagnostics/disasm.h"
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_cinamespace v8 {
411cb0ef41Sopenharmony_cinamespace internal {
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci//------------------------------------------------------------------------------
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci// Decoder decodes and disassembles instructions into an output buffer.
461cb0ef41Sopenharmony_ci// It uses the converter to convert register names and call destinations into
471cb0ef41Sopenharmony_ci// more informative description.
481cb0ef41Sopenharmony_ciclass Decoder {
491cb0ef41Sopenharmony_ci public:
501cb0ef41Sopenharmony_ci  Decoder(const disasm::NameConverter& converter, base::Vector<char> out_buffer)
511cb0ef41Sopenharmony_ci      : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
521cb0ef41Sopenharmony_ci    out_buffer_[out_buffer_pos_] = '\0';
531cb0ef41Sopenharmony_ci  }
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  ~Decoder() {}
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  Decoder(const Decoder&) = delete;
581cb0ef41Sopenharmony_ci  Decoder& operator=(const Decoder&) = delete;
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  // Writes one disassembled instruction into 'buffer' (0-terminated).
611cb0ef41Sopenharmony_ci  // Returns the length of the disassembled machine instruction in bytes.
621cb0ef41Sopenharmony_ci  int InstructionDecode(byte* instruction);
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci private:
651cb0ef41Sopenharmony_ci  // Bottleneck functions to print into the out_buffer.
661cb0ef41Sopenharmony_ci  void PrintChar(const char ch);
671cb0ef41Sopenharmony_ci  void Print(const char* str);
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  // Printing of common values.
701cb0ef41Sopenharmony_ci  void PrintRegister(int reg);
711cb0ef41Sopenharmony_ci  void PrintDRegister(int reg);
721cb0ef41Sopenharmony_ci  void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  // Handle formatting of instructions and their options.
751cb0ef41Sopenharmony_ci  int FormatRegister(Instruction* instr, const char* option);
761cb0ef41Sopenharmony_ci  int FormatFloatingRegister(Instruction* instr, const char* option);
771cb0ef41Sopenharmony_ci  int FormatMask(Instruction* instr, const char* option);
781cb0ef41Sopenharmony_ci  int FormatDisplacement(Instruction* instr, const char* option);
791cb0ef41Sopenharmony_ci  int FormatImmediate(Instruction* instr, const char* option);
801cb0ef41Sopenharmony_ci  int FormatOption(Instruction* instr, const char* option);
811cb0ef41Sopenharmony_ci  void Format(Instruction* instr, const char* format);
821cb0ef41Sopenharmony_ci  void Unknown(Instruction* instr);
831cb0ef41Sopenharmony_ci  void UnknownFormat(Instruction* instr, const char* opcname);
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  bool DecodeSpecial(Instruction* instr);
861cb0ef41Sopenharmony_ci  bool DecodeGeneric(Instruction* instr);
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  const disasm::NameConverter& converter_;
891cb0ef41Sopenharmony_ci  base::Vector<char> out_buffer_;
901cb0ef41Sopenharmony_ci  int out_buffer_pos_;
911cb0ef41Sopenharmony_ci};
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci// Support for assertions in the Decoder formatting functions.
941cb0ef41Sopenharmony_ci#define STRING_STARTS_WITH(string, compare_string) \
951cb0ef41Sopenharmony_ci  (strncmp(string, compare_string, strlen(compare_string)) == 0)
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci// Append the ch to the output buffer.
981cb0ef41Sopenharmony_civoid Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci// Append the str to the output buffer.
1011cb0ef41Sopenharmony_civoid Decoder::Print(const char* str) {
1021cb0ef41Sopenharmony_ci  char cur = *str++;
1031cb0ef41Sopenharmony_ci  while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
1041cb0ef41Sopenharmony_ci    PrintChar(cur);
1051cb0ef41Sopenharmony_ci    cur = *str++;
1061cb0ef41Sopenharmony_ci  }
1071cb0ef41Sopenharmony_ci  out_buffer_[out_buffer_pos_] = 0;
1081cb0ef41Sopenharmony_ci}
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci// Print the register name according to the active name converter.
1111cb0ef41Sopenharmony_civoid Decoder::PrintRegister(int reg) {
1121cb0ef41Sopenharmony_ci  Print(converter_.NameOfCPURegister(reg));
1131cb0ef41Sopenharmony_ci}
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci// Print the double FP register name according to the active name converter.
1161cb0ef41Sopenharmony_civoid Decoder::PrintDRegister(int reg) {
1171cb0ef41Sopenharmony_ci  Print(RegisterName(DoubleRegister::from_code(reg)));
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
1211cb0ef41Sopenharmony_ci// the FormatOption method.
1221cb0ef41Sopenharmony_civoid Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
1231cb0ef41Sopenharmony_ci  switch (svc) {
1241cb0ef41Sopenharmony_ci    case kCallRtRedirected:
1251cb0ef41Sopenharmony_ci      Print("call rt redirected");
1261cb0ef41Sopenharmony_ci      return;
1271cb0ef41Sopenharmony_ci    case kBreakpoint:
1281cb0ef41Sopenharmony_ci      Print("breakpoint");
1291cb0ef41Sopenharmony_ci      return;
1301cb0ef41Sopenharmony_ci    default:
1311cb0ef41Sopenharmony_ci      if (svc >= kStopCode) {
1321cb0ef41Sopenharmony_ci        out_buffer_pos_ +=
1331cb0ef41Sopenharmony_ci            base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d - 0x%x",
1341cb0ef41Sopenharmony_ci                           svc & kStopCodeMask, svc & kStopCodeMask);
1351cb0ef41Sopenharmony_ci      } else {
1361cb0ef41Sopenharmony_ci        out_buffer_pos_ +=
1371cb0ef41Sopenharmony_ci            base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", svc);
1381cb0ef41Sopenharmony_ci      }
1391cb0ef41Sopenharmony_ci      return;
1401cb0ef41Sopenharmony_ci  }
1411cb0ef41Sopenharmony_ci}
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci// Handle all register based formatting in this function to reduce the
1441cb0ef41Sopenharmony_ci// complexity of FormatOption.
1451cb0ef41Sopenharmony_ciint Decoder::FormatRegister(Instruction* instr, const char* format) {
1461cb0ef41Sopenharmony_ci  DCHECK_EQ(format[0], 'r');
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  if (format[1] == '1') {  // 'r1: register resides in bit 8-11
1491cb0ef41Sopenharmony_ci    int reg = instr->Bits<SixByteInstr, int>(39, 36);
1501cb0ef41Sopenharmony_ci    PrintRegister(reg);
1511cb0ef41Sopenharmony_ci    return 2;
1521cb0ef41Sopenharmony_ci  } else if (format[1] == '2') {  // 'r2: register resides in bit 12-15
1531cb0ef41Sopenharmony_ci    int reg = instr->Bits<SixByteInstr, int>(35, 32);
1541cb0ef41Sopenharmony_ci    // indicating it is a r0 for displacement, in which case the offset
1551cb0ef41Sopenharmony_ci    // should be 0.
1561cb0ef41Sopenharmony_ci    if (format[2] == 'd') {
1571cb0ef41Sopenharmony_ci      if (reg == 0) return 4;
1581cb0ef41Sopenharmony_ci      PrintRegister(reg);
1591cb0ef41Sopenharmony_ci      return 3;
1601cb0ef41Sopenharmony_ci    } else {
1611cb0ef41Sopenharmony_ci      PrintRegister(reg);
1621cb0ef41Sopenharmony_ci      return 2;
1631cb0ef41Sopenharmony_ci    }
1641cb0ef41Sopenharmony_ci  } else if (format[1] == '3') {  // 'r3: register resides in bit 16-19
1651cb0ef41Sopenharmony_ci    int reg = instr->Bits<SixByteInstr, int>(31, 28);
1661cb0ef41Sopenharmony_ci    PrintRegister(reg);
1671cb0ef41Sopenharmony_ci    return 2;
1681cb0ef41Sopenharmony_ci  } else if (format[1] == '4') {  // 'r4: register resides in bit 20-23
1691cb0ef41Sopenharmony_ci    int reg = instr->Bits<SixByteInstr, int>(27, 24);
1701cb0ef41Sopenharmony_ci    PrintRegister(reg);
1711cb0ef41Sopenharmony_ci    return 2;
1721cb0ef41Sopenharmony_ci  } else if (format[1] == '5') {  // 'r5: register resides in bit 24-27
1731cb0ef41Sopenharmony_ci    int reg = instr->Bits<SixByteInstr, int>(23, 20);
1741cb0ef41Sopenharmony_ci    PrintRegister(reg);
1751cb0ef41Sopenharmony_ci    return 2;
1761cb0ef41Sopenharmony_ci  } else if (format[1] == '6') {  // 'r6: register resides in bit 28-31
1771cb0ef41Sopenharmony_ci    int reg = instr->Bits<SixByteInstr, int>(19, 16);
1781cb0ef41Sopenharmony_ci    PrintRegister(reg);
1791cb0ef41Sopenharmony_ci    return 2;
1801cb0ef41Sopenharmony_ci  } else if (format[1] == '7') {  // 'r6: register resides in bit 32-35
1811cb0ef41Sopenharmony_ci    int reg = instr->Bits<SixByteInstr, int>(15, 12);
1821cb0ef41Sopenharmony_ci    PrintRegister(reg);
1831cb0ef41Sopenharmony_ci    return 2;
1841cb0ef41Sopenharmony_ci  }
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ci  UNREACHABLE();
1871cb0ef41Sopenharmony_ci}
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ciint Decoder::FormatFloatingRegister(Instruction* instr, const char* format) {
1901cb0ef41Sopenharmony_ci  DCHECK_EQ(format[0], 'f');
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ci  // reuse 1, 5 and 6 because it is coresponding
1931cb0ef41Sopenharmony_ci  if (format[1] == '1') {  // 'r1: register resides in bit 8-11
1941cb0ef41Sopenharmony_ci    RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr);
1951cb0ef41Sopenharmony_ci    int reg = rrinstr->R1Value();
1961cb0ef41Sopenharmony_ci    PrintDRegister(reg);
1971cb0ef41Sopenharmony_ci    return 2;
1981cb0ef41Sopenharmony_ci  } else if (format[1] == '2') {  // 'f2: register resides in bit 12-15
1991cb0ef41Sopenharmony_ci    RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr);
2001cb0ef41Sopenharmony_ci    int reg = rrinstr->R2Value();
2011cb0ef41Sopenharmony_ci    PrintDRegister(reg);
2021cb0ef41Sopenharmony_ci    return 2;
2031cb0ef41Sopenharmony_ci  } else if (format[1] == '3') {  // 'f3: register resides in bit 16-19
2041cb0ef41Sopenharmony_ci    RRDInstruction* rrdinstr = reinterpret_cast<RRDInstruction*>(instr);
2051cb0ef41Sopenharmony_ci    int reg = rrdinstr->R1Value();
2061cb0ef41Sopenharmony_ci    PrintDRegister(reg);
2071cb0ef41Sopenharmony_ci    return 2;
2081cb0ef41Sopenharmony_ci  } else if (format[1] == '5') {  // 'f5: register resides in bit 24-28
2091cb0ef41Sopenharmony_ci    RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr);
2101cb0ef41Sopenharmony_ci    int reg = rreinstr->R1Value();
2111cb0ef41Sopenharmony_ci    PrintDRegister(reg);
2121cb0ef41Sopenharmony_ci    return 2;
2131cb0ef41Sopenharmony_ci  } else if (format[1] == '6') {  // 'f6: register resides in bit 29-32
2141cb0ef41Sopenharmony_ci    RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr);
2151cb0ef41Sopenharmony_ci    int reg = rreinstr->R2Value();
2161cb0ef41Sopenharmony_ci    PrintDRegister(reg);
2171cb0ef41Sopenharmony_ci    return 2;
2181cb0ef41Sopenharmony_ci  } else if (format[1] == '4') {
2191cb0ef41Sopenharmony_ci    VRR_E_Instruction* vrreinstr = reinterpret_cast<VRR_E_Instruction*>(instr);
2201cb0ef41Sopenharmony_ci    int reg = vrreinstr->R4Value();
2211cb0ef41Sopenharmony_ci    PrintDRegister(reg);
2221cb0ef41Sopenharmony_ci    return 2;
2231cb0ef41Sopenharmony_ci  }
2241cb0ef41Sopenharmony_ci  UNREACHABLE();
2251cb0ef41Sopenharmony_ci}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ci// FormatOption takes a formatting string and interprets it based on
2281cb0ef41Sopenharmony_ci// the current instructions. The format string points to the first
2291cb0ef41Sopenharmony_ci// character of the option string (the option escape has already been
2301cb0ef41Sopenharmony_ci// consumed by the caller.)  FormatOption returns the number of
2311cb0ef41Sopenharmony_ci// characters that were consumed from the formatting string.
2321cb0ef41Sopenharmony_ciint Decoder::FormatOption(Instruction* instr, const char* format) {
2331cb0ef41Sopenharmony_ci  switch (format[0]) {
2341cb0ef41Sopenharmony_ci    case 'o': {
2351cb0ef41Sopenharmony_ci      if (instr->Bit(10) == 1) {
2361cb0ef41Sopenharmony_ci        Print("o");
2371cb0ef41Sopenharmony_ci      }
2381cb0ef41Sopenharmony_ci      return 1;
2391cb0ef41Sopenharmony_ci    }
2401cb0ef41Sopenharmony_ci    case '.': {
2411cb0ef41Sopenharmony_ci      if (instr->Bit(0) == 1) {
2421cb0ef41Sopenharmony_ci        Print(".");
2431cb0ef41Sopenharmony_ci      } else {
2441cb0ef41Sopenharmony_ci        Print(" ");  // ensure consistent spacing
2451cb0ef41Sopenharmony_ci      }
2461cb0ef41Sopenharmony_ci      return 1;
2471cb0ef41Sopenharmony_ci    }
2481cb0ef41Sopenharmony_ci    case 'r': {
2491cb0ef41Sopenharmony_ci      return FormatRegister(instr, format);
2501cb0ef41Sopenharmony_ci    }
2511cb0ef41Sopenharmony_ci    case 'f': {
2521cb0ef41Sopenharmony_ci      return FormatFloatingRegister(instr, format);
2531cb0ef41Sopenharmony_ci    }
2541cb0ef41Sopenharmony_ci    case 'i': {  // int16
2551cb0ef41Sopenharmony_ci      return FormatImmediate(instr, format);
2561cb0ef41Sopenharmony_ci    }
2571cb0ef41Sopenharmony_ci    case 'u': {  // uint16
2581cb0ef41Sopenharmony_ci      int32_t value = instr->Bits(15, 0);
2591cb0ef41Sopenharmony_ci      out_buffer_pos_ +=
2601cb0ef41Sopenharmony_ci          base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
2611cb0ef41Sopenharmony_ci      return 6;
2621cb0ef41Sopenharmony_ci    }
2631cb0ef41Sopenharmony_ci    case 'l': {
2641cb0ef41Sopenharmony_ci      // Link (LK) Bit 0
2651cb0ef41Sopenharmony_ci      if (instr->Bit(0) == 1) {
2661cb0ef41Sopenharmony_ci        Print("l");
2671cb0ef41Sopenharmony_ci      }
2681cb0ef41Sopenharmony_ci      return 1;
2691cb0ef41Sopenharmony_ci    }
2701cb0ef41Sopenharmony_ci    case 'a': {
2711cb0ef41Sopenharmony_ci      // Absolute Address Bit 1
2721cb0ef41Sopenharmony_ci      if (instr->Bit(1) == 1) {
2731cb0ef41Sopenharmony_ci        Print("a");
2741cb0ef41Sopenharmony_ci      }
2751cb0ef41Sopenharmony_ci      return 1;
2761cb0ef41Sopenharmony_ci    }
2771cb0ef41Sopenharmony_ci    case 't': {  // 'target: target of branch instructions
2781cb0ef41Sopenharmony_ci      // target26 or target16
2791cb0ef41Sopenharmony_ci      DCHECK(STRING_STARTS_WITH(format, "target"));
2801cb0ef41Sopenharmony_ci      if ((format[6] == '2') && (format[7] == '6')) {
2811cb0ef41Sopenharmony_ci        int off = ((instr->Bits(25, 2)) << 8) >> 6;
2821cb0ef41Sopenharmony_ci        out_buffer_pos_ += base::SNPrintF(
2831cb0ef41Sopenharmony_ci            out_buffer_ + out_buffer_pos_, "%+d -> %s", off,
2841cb0ef41Sopenharmony_ci            converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
2851cb0ef41Sopenharmony_ci        return 8;
2861cb0ef41Sopenharmony_ci      } else if ((format[6] == '1') && (format[7] == '6')) {
2871cb0ef41Sopenharmony_ci        int off = ((instr->Bits(15, 2)) << 18) >> 16;
2881cb0ef41Sopenharmony_ci        out_buffer_pos_ += base::SNPrintF(
2891cb0ef41Sopenharmony_ci            out_buffer_ + out_buffer_pos_, "%+d -> %s", off,
2901cb0ef41Sopenharmony_ci            converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
2911cb0ef41Sopenharmony_ci        return 8;
2921cb0ef41Sopenharmony_ci      }
2931cb0ef41Sopenharmony_ci      break;
2941cb0ef41Sopenharmony_ci      case 'm': {
2951cb0ef41Sopenharmony_ci        return FormatMask(instr, format);
2961cb0ef41Sopenharmony_ci      }
2971cb0ef41Sopenharmony_ci    }
2981cb0ef41Sopenharmony_ci    case 'd': {  // ds value for offset
2991cb0ef41Sopenharmony_ci      return FormatDisplacement(instr, format);
3001cb0ef41Sopenharmony_ci    }
3011cb0ef41Sopenharmony_ci    default: {
3021cb0ef41Sopenharmony_ci      UNREACHABLE();
3031cb0ef41Sopenharmony_ci    }
3041cb0ef41Sopenharmony_ci  }
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci  UNREACHABLE();
3071cb0ef41Sopenharmony_ci}
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ciint Decoder::FormatMask(Instruction* instr, const char* format) {
3101cb0ef41Sopenharmony_ci  DCHECK_EQ(format[0], 'm');
3111cb0ef41Sopenharmony_ci  int32_t value = 0;
3121cb0ef41Sopenharmony_ci  if ((format[1] == '1')) {  // prints the mask format in bits 8-12
3131cb0ef41Sopenharmony_ci    value = reinterpret_cast<RRInstruction*>(instr)->R1Value();
3141cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3151cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
3161cb0ef41Sopenharmony_ci    return 2;
3171cb0ef41Sopenharmony_ci  } else if (format[1] == '2') {  // mask format in bits 16-19
3181cb0ef41Sopenharmony_ci    value = reinterpret_cast<RXInstruction*>(instr)->B2Value();
3191cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3201cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
3211cb0ef41Sopenharmony_ci    return 2;
3221cb0ef41Sopenharmony_ci  } else if (format[1] == '3') {  // mask format in bits 20-23
3231cb0ef41Sopenharmony_ci    value = reinterpret_cast<RRFInstruction*>(instr)->M4Value();
3241cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3251cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
3261cb0ef41Sopenharmony_ci    return 2;
3271cb0ef41Sopenharmony_ci  } else if (format[1] == '4') {  // mask format in bits 32-35
3281cb0ef41Sopenharmony_ci    value = reinterpret_cast<VRR_C_Instruction*>(instr)->M4Value();
3291cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3301cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
3311cb0ef41Sopenharmony_ci    return 2;
3321cb0ef41Sopenharmony_ci  } else if (format[1] == '5') {  // mask format in bits 28-31
3331cb0ef41Sopenharmony_ci    value = reinterpret_cast<VRR_C_Instruction*>(instr)->M5Value();
3341cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3351cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
3361cb0ef41Sopenharmony_ci    return 2;
3371cb0ef41Sopenharmony_ci  } else if (format[1] == '6') {  // mask format in bits 24-27
3381cb0ef41Sopenharmony_ci    value = reinterpret_cast<VRR_C_Instruction*>(instr)->M6Value();
3391cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3401cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
3411cb0ef41Sopenharmony_ci    return 2;
3421cb0ef41Sopenharmony_ci  }
3431cb0ef41Sopenharmony_ci  out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
3441cb0ef41Sopenharmony_ci  return 2;
3451cb0ef41Sopenharmony_ci}
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ciint Decoder::FormatDisplacement(Instruction* instr, const char* format) {
3481cb0ef41Sopenharmony_ci  DCHECK_EQ(format[0], 'd');
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ci  if (format[1] == '1') {  // displacement in 20-31
3511cb0ef41Sopenharmony_ci    RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr);
3521cb0ef41Sopenharmony_ci    uint16_t value = rsinstr->D2Value();
3531cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3541cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_ci    return 2;
3571cb0ef41Sopenharmony_ci  } else if (format[1] == '2') {  // displacement in 20-39
3581cb0ef41Sopenharmony_ci    RXYInstruction* rxyinstr = reinterpret_cast<RXYInstruction*>(instr);
3591cb0ef41Sopenharmony_ci    int32_t value = rxyinstr->D2Value();
3601cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3611cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
3621cb0ef41Sopenharmony_ci    return 2;
3631cb0ef41Sopenharmony_ci  } else if (format[1] == '4') {  // SS displacement 2 36-47
3641cb0ef41Sopenharmony_ci    SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr);
3651cb0ef41Sopenharmony_ci    uint16_t value = ssInstr->D2Value();
3661cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3671cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
3681cb0ef41Sopenharmony_ci    return 2;
3691cb0ef41Sopenharmony_ci  } else if (format[1] == '3') {  // SS displacement 1 20 - 32
3701cb0ef41Sopenharmony_ci    SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr);
3711cb0ef41Sopenharmony_ci    uint16_t value = ssInstr->D1Value();
3721cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3731cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
3741cb0ef41Sopenharmony_ci    return 2;
3751cb0ef41Sopenharmony_ci  } else {  // s390 specific
3761cb0ef41Sopenharmony_ci    int32_t value = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
3771cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3781cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
3791cb0ef41Sopenharmony_ci    return 1;
3801cb0ef41Sopenharmony_ci  }
3811cb0ef41Sopenharmony_ci}
3821cb0ef41Sopenharmony_ci
3831cb0ef41Sopenharmony_ciint Decoder::FormatImmediate(Instruction* instr, const char* format) {
3841cb0ef41Sopenharmony_ci  DCHECK_EQ(format[0], 'i');
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ci  if (format[1] == '1') {  // immediate in 16-31
3871cb0ef41Sopenharmony_ci    RIInstruction* riinstr = reinterpret_cast<RIInstruction*>(instr);
3881cb0ef41Sopenharmony_ci    int16_t value = riinstr->I2Value();
3891cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3901cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
3911cb0ef41Sopenharmony_ci    return 2;
3921cb0ef41Sopenharmony_ci  } else if (format[1] == '2') {  // immediate in 16-48
3931cb0ef41Sopenharmony_ci    RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr);
3941cb0ef41Sopenharmony_ci    int32_t value = rilinstr->I2Value();
3951cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
3961cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
3971cb0ef41Sopenharmony_ci    return 2;
3981cb0ef41Sopenharmony_ci  } else if (format[1] == '3') {  // immediate in I format
3991cb0ef41Sopenharmony_ci    IInstruction* iinstr = reinterpret_cast<IInstruction*>(instr);
4001cb0ef41Sopenharmony_ci    int8_t value = iinstr->IValue();
4011cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
4021cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
4031cb0ef41Sopenharmony_ci    return 2;
4041cb0ef41Sopenharmony_ci  } else if (format[1] == '4') {  // immediate in 16-31, but outputs as offset
4051cb0ef41Sopenharmony_ci    RIInstruction* riinstr = reinterpret_cast<RIInstruction*>(instr);
4061cb0ef41Sopenharmony_ci    int16_t value = riinstr->I2Value() * 2;
4071cb0ef41Sopenharmony_ci    if (value >= 0)
4081cb0ef41Sopenharmony_ci      out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*+");
4091cb0ef41Sopenharmony_ci    else
4101cb0ef41Sopenharmony_ci      out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*");
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci    out_buffer_pos_ += base::SNPrintF(
4131cb0ef41Sopenharmony_ci        out_buffer_ + out_buffer_pos_, "%d -> %s", value,
4141cb0ef41Sopenharmony_ci        converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + value));
4151cb0ef41Sopenharmony_ci    return 2;
4161cb0ef41Sopenharmony_ci  } else if (format[1] == '5') {  // immediate in 16-31, but outputs as offset
4171cb0ef41Sopenharmony_ci    RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr);
4181cb0ef41Sopenharmony_ci    int32_t value = rilinstr->I2Value() * 2;
4191cb0ef41Sopenharmony_ci    if (value >= 0)
4201cb0ef41Sopenharmony_ci      out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*+");
4211cb0ef41Sopenharmony_ci    else
4221cb0ef41Sopenharmony_ci      out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*");
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci    out_buffer_pos_ += base::SNPrintF(
4251cb0ef41Sopenharmony_ci        out_buffer_ + out_buffer_pos_, "%d -> %s", value,
4261cb0ef41Sopenharmony_ci        converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + value));
4271cb0ef41Sopenharmony_ci    return 2;
4281cb0ef41Sopenharmony_ci  } else if (format[1] == '6') {  // unsigned immediate in 16-31
4291cb0ef41Sopenharmony_ci    RIInstruction* riinstr = reinterpret_cast<RIInstruction*>(instr);
4301cb0ef41Sopenharmony_ci    uint16_t value = riinstr->I2UnsignedValue();
4311cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
4321cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
4331cb0ef41Sopenharmony_ci    return 2;
4341cb0ef41Sopenharmony_ci  } else if (format[1] == '7') {  // unsigned immediate in 16-47
4351cb0ef41Sopenharmony_ci    RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr);
4361cb0ef41Sopenharmony_ci    uint32_t value = rilinstr->I2UnsignedValue();
4371cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
4381cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
4391cb0ef41Sopenharmony_ci    return 2;
4401cb0ef41Sopenharmony_ci  } else if (format[1] == '8') {  // unsigned immediate in 8-15
4411cb0ef41Sopenharmony_ci    SSInstruction* ssinstr = reinterpret_cast<SSInstruction*>(instr);
4421cb0ef41Sopenharmony_ci    uint8_t value = ssinstr->Length();
4431cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
4441cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
4451cb0ef41Sopenharmony_ci    return 2;
4461cb0ef41Sopenharmony_ci  } else if (format[1] == '9') {  // unsigned immediate in 16-23
4471cb0ef41Sopenharmony_ci    RIEInstruction* rie_instr = reinterpret_cast<RIEInstruction*>(instr);
4481cb0ef41Sopenharmony_ci    uint8_t value = rie_instr->I3Value();
4491cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
4501cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
4511cb0ef41Sopenharmony_ci    return 2;
4521cb0ef41Sopenharmony_ci  } else if (format[1] == 'a') {  // unsigned immediate in 24-31
4531cb0ef41Sopenharmony_ci    RIEInstruction* rie_instr = reinterpret_cast<RIEInstruction*>(instr);
4541cb0ef41Sopenharmony_ci    uint8_t value = rie_instr->I4Value();
4551cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
4561cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
4571cb0ef41Sopenharmony_ci    return 2;
4581cb0ef41Sopenharmony_ci  } else if (format[1] == 'b') {  // unsigned immediate in 32-39
4591cb0ef41Sopenharmony_ci    RIEInstruction* rie_instr = reinterpret_cast<RIEInstruction*>(instr);
4601cb0ef41Sopenharmony_ci    uint8_t value = rie_instr->I5Value();
4611cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
4621cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
4631cb0ef41Sopenharmony_ci    return 2;
4641cb0ef41Sopenharmony_ci  } else if (format[1] == 'c') {  // signed immediate in 8-15
4651cb0ef41Sopenharmony_ci    SSInstruction* ssinstr = reinterpret_cast<SSInstruction*>(instr);
4661cb0ef41Sopenharmony_ci    int8_t value = ssinstr->Length();
4671cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
4681cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
4691cb0ef41Sopenharmony_ci    return 2;
4701cb0ef41Sopenharmony_ci  } else if (format[1] == 'd') {  // signed immediate in 32-47
4711cb0ef41Sopenharmony_ci    SILInstruction* silinstr = reinterpret_cast<SILInstruction*>(instr);
4721cb0ef41Sopenharmony_ci    int16_t value = silinstr->I2Value();
4731cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
4741cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
4751cb0ef41Sopenharmony_ci    return 2;
4761cb0ef41Sopenharmony_ci  } else if (format[1] == 'e') {  // immediate in 16-47, but outputs as offset
4771cb0ef41Sopenharmony_ci    RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr);
4781cb0ef41Sopenharmony_ci    int32_t value = rilinstr->I2Value() * 2;
4791cb0ef41Sopenharmony_ci    if (value >= 0)
4801cb0ef41Sopenharmony_ci      out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*+");
4811cb0ef41Sopenharmony_ci    else
4821cb0ef41Sopenharmony_ci      out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*");
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ci    out_buffer_pos_ += base::SNPrintF(
4851cb0ef41Sopenharmony_ci        out_buffer_ + out_buffer_pos_, "%d -> %s", value,
4861cb0ef41Sopenharmony_ci        converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + value));
4871cb0ef41Sopenharmony_ci    return 2;
4881cb0ef41Sopenharmony_ci  }
4891cb0ef41Sopenharmony_ci
4901cb0ef41Sopenharmony_ci  UNREACHABLE();
4911cb0ef41Sopenharmony_ci}
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci// Format takes a formatting string for a whole instruction and prints it into
4941cb0ef41Sopenharmony_ci// the output buffer. All escaped options are handed to FormatOption to be
4951cb0ef41Sopenharmony_ci// parsed further.
4961cb0ef41Sopenharmony_civoid Decoder::Format(Instruction* instr, const char* format) {
4971cb0ef41Sopenharmony_ci  char cur = *format++;
4981cb0ef41Sopenharmony_ci  while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
4991cb0ef41Sopenharmony_ci    if (cur == '\'') {  // Single quote is used as the formatting escape.
5001cb0ef41Sopenharmony_ci      format += FormatOption(instr, format);
5011cb0ef41Sopenharmony_ci    } else {
5021cb0ef41Sopenharmony_ci      out_buffer_[out_buffer_pos_++] = cur;
5031cb0ef41Sopenharmony_ci    }
5041cb0ef41Sopenharmony_ci    cur = *format++;
5051cb0ef41Sopenharmony_ci  }
5061cb0ef41Sopenharmony_ci  out_buffer_[out_buffer_pos_] = '\0';
5071cb0ef41Sopenharmony_ci}
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci// The disassembler may end up decoding data inlined in the code. We do not want
5101cb0ef41Sopenharmony_ci// it to crash if the data does not resemble any known instruction.
5111cb0ef41Sopenharmony_ci#define VERIFY(condition) \
5121cb0ef41Sopenharmony_ci  if (!(condition)) {     \
5131cb0ef41Sopenharmony_ci    Unknown(instr);       \
5141cb0ef41Sopenharmony_ci    return;               \
5151cb0ef41Sopenharmony_ci  }
5161cb0ef41Sopenharmony_ci
5171cb0ef41Sopenharmony_ci// For currently unimplemented decodings the disassembler calls Unknown(instr)
5181cb0ef41Sopenharmony_ci// which will just print "unknown" of the instruction bits.
5191cb0ef41Sopenharmony_civoid Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ci// For currently unimplemented decodings the disassembler calls
5221cb0ef41Sopenharmony_ci// UnknownFormat(instr) which will just print opcode name of the
5231cb0ef41Sopenharmony_ci// instruction bits.
5241cb0ef41Sopenharmony_civoid Decoder::UnknownFormat(Instruction* instr, const char* name) {
5251cb0ef41Sopenharmony_ci  char buffer[100];
5261cb0ef41Sopenharmony_ci  snprintf(buffer, sizeof(buffer), "%s (unknown-format)", name);
5271cb0ef41Sopenharmony_ci  Format(instr, buffer);
5281cb0ef41Sopenharmony_ci}
5291cb0ef41Sopenharmony_ci
5301cb0ef41Sopenharmony_ci#undef VERIFY
5311cb0ef41Sopenharmony_ci#undef STRING_STARTS_WITH
5321cb0ef41Sopenharmony_ci
5331cb0ef41Sopenharmony_ci// Handles special cases of instructions;
5341cb0ef41Sopenharmony_ci// @return true if successfully decoded
5351cb0ef41Sopenharmony_cibool Decoder::DecodeSpecial(Instruction* instr) {
5361cb0ef41Sopenharmony_ci  Opcode opcode = instr->S390OpcodeValue();
5371cb0ef41Sopenharmony_ci  switch (opcode) {
5381cb0ef41Sopenharmony_ci    case BKPT:
5391cb0ef41Sopenharmony_ci      Format(instr, "bkpt");
5401cb0ef41Sopenharmony_ci      break;
5411cb0ef41Sopenharmony_ci    case DUMY:
5421cb0ef41Sopenharmony_ci      Format(instr, "dumy\t'r1, 'd2 ( 'r2d, 'r3 )");
5431cb0ef41Sopenharmony_ci      break;
5441cb0ef41Sopenharmony_ci    /* RR format */
5451cb0ef41Sopenharmony_ci    case LDR:
5461cb0ef41Sopenharmony_ci      Format(instr, "ldr\t'f1,'f2");
5471cb0ef41Sopenharmony_ci      break;
5481cb0ef41Sopenharmony_ci    case BCR:
5491cb0ef41Sopenharmony_ci      Format(instr, "bcr\t'm1,'r2");
5501cb0ef41Sopenharmony_ci      break;
5511cb0ef41Sopenharmony_ci    case OR:
5521cb0ef41Sopenharmony_ci      Format(instr, "or\t'r1,'r2");
5531cb0ef41Sopenharmony_ci      break;
5541cb0ef41Sopenharmony_ci    case CR:
5551cb0ef41Sopenharmony_ci      Format(instr, "cr\t'r1,'r2");
5561cb0ef41Sopenharmony_ci      break;
5571cb0ef41Sopenharmony_ci    case MR:
5581cb0ef41Sopenharmony_ci      Format(instr, "mr\t'r1,'r2");
5591cb0ef41Sopenharmony_ci      break;
5601cb0ef41Sopenharmony_ci    case HER_Z:
5611cb0ef41Sopenharmony_ci      Format(instr, "her\t'r1,'r2");
5621cb0ef41Sopenharmony_ci      break;
5631cb0ef41Sopenharmony_ci    /* RI-b format */
5641cb0ef41Sopenharmony_ci    case BRAS:
5651cb0ef41Sopenharmony_ci      Format(instr, "bras\t'r1,'i1");
5661cb0ef41Sopenharmony_ci      break;
5671cb0ef41Sopenharmony_ci    /* RRE format */
5681cb0ef41Sopenharmony_ci    case MDBR:
5691cb0ef41Sopenharmony_ci      Format(instr, "mdbr\t'f5,'f6");
5701cb0ef41Sopenharmony_ci      break;
5711cb0ef41Sopenharmony_ci    case SDBR:
5721cb0ef41Sopenharmony_ci      Format(instr, "sdbr\t'f5,'f6");
5731cb0ef41Sopenharmony_ci      break;
5741cb0ef41Sopenharmony_ci    case ADBR:
5751cb0ef41Sopenharmony_ci      Format(instr, "adbr\t'f5,'f6");
5761cb0ef41Sopenharmony_ci      break;
5771cb0ef41Sopenharmony_ci    case CDBR:
5781cb0ef41Sopenharmony_ci      Format(instr, "cdbr\t'f5,'f6");
5791cb0ef41Sopenharmony_ci      break;
5801cb0ef41Sopenharmony_ci    case MEEBR:
5811cb0ef41Sopenharmony_ci      Format(instr, "meebr\t'f5,'f6");
5821cb0ef41Sopenharmony_ci      break;
5831cb0ef41Sopenharmony_ci    case SQDBR:
5841cb0ef41Sopenharmony_ci      Format(instr, "sqdbr\t'f5,'f6");
5851cb0ef41Sopenharmony_ci      break;
5861cb0ef41Sopenharmony_ci    case SQEBR:
5871cb0ef41Sopenharmony_ci      Format(instr, "sqebr\t'f5,'f6");
5881cb0ef41Sopenharmony_ci      break;
5891cb0ef41Sopenharmony_ci    case LCDBR:
5901cb0ef41Sopenharmony_ci      Format(instr, "lcdbr\t'f5,'f6");
5911cb0ef41Sopenharmony_ci      break;
5921cb0ef41Sopenharmony_ci    case LCEBR:
5931cb0ef41Sopenharmony_ci      Format(instr, "lcebr\t'f5,'f6");
5941cb0ef41Sopenharmony_ci      break;
5951cb0ef41Sopenharmony_ci    case LTEBR:
5961cb0ef41Sopenharmony_ci      Format(instr, "ltebr\t'f5,'f6");
5971cb0ef41Sopenharmony_ci      break;
5981cb0ef41Sopenharmony_ci    case LDEBR:
5991cb0ef41Sopenharmony_ci      Format(instr, "ldebr\t'f5,'f6");
6001cb0ef41Sopenharmony_ci      break;
6011cb0ef41Sopenharmony_ci    case CEBR:
6021cb0ef41Sopenharmony_ci      Format(instr, "cebr\t'f5,'f6");
6031cb0ef41Sopenharmony_ci      break;
6041cb0ef41Sopenharmony_ci    case AEBR:
6051cb0ef41Sopenharmony_ci      Format(instr, "aebr\t'f5,'f6");
6061cb0ef41Sopenharmony_ci      break;
6071cb0ef41Sopenharmony_ci    case SEBR:
6081cb0ef41Sopenharmony_ci      Format(instr, "sebr\t'f5,'f6");
6091cb0ef41Sopenharmony_ci      break;
6101cb0ef41Sopenharmony_ci    case DEBR:
6111cb0ef41Sopenharmony_ci      Format(instr, "debr\t'f5,'f6");
6121cb0ef41Sopenharmony_ci      break;
6131cb0ef41Sopenharmony_ci    case LTDBR:
6141cb0ef41Sopenharmony_ci      Format(instr, "ltdbr\t'f5,'f6");
6151cb0ef41Sopenharmony_ci      break;
6161cb0ef41Sopenharmony_ci    case LDGR:
6171cb0ef41Sopenharmony_ci      Format(instr, "ldgr\t'f5,'f6");
6181cb0ef41Sopenharmony_ci      break;
6191cb0ef41Sopenharmony_ci    case DDBR:
6201cb0ef41Sopenharmony_ci      Format(instr, "ddbr\t'f5,'f6");
6211cb0ef41Sopenharmony_ci      break;
6221cb0ef41Sopenharmony_ci    case LZDR:
6231cb0ef41Sopenharmony_ci      Format(instr, "lzdr\t'f5");
6241cb0ef41Sopenharmony_ci      break;
6251cb0ef41Sopenharmony_ci    /* RRF-e format */
6261cb0ef41Sopenharmony_ci    case FIEBRA:
6271cb0ef41Sopenharmony_ci      Format(instr, "fiebra\t'f5,'m2,'f6,'m3");
6281cb0ef41Sopenharmony_ci      break;
6291cb0ef41Sopenharmony_ci    case FIDBRA:
6301cb0ef41Sopenharmony_ci      Format(instr, "fidbra\t'f5,'m2,'f6,'m3");
6311cb0ef41Sopenharmony_ci      break;
6321cb0ef41Sopenharmony_ci    /* RX-a format */
6331cb0ef41Sopenharmony_ci    case IC_z:
6341cb0ef41Sopenharmony_ci      Format(instr, "ic\t'r1,'d1('r2d,'r3)");
6351cb0ef41Sopenharmony_ci      break;
6361cb0ef41Sopenharmony_ci    case AL:
6371cb0ef41Sopenharmony_ci      Format(instr, "al\t'r1,'d1('r2d,'r3)");
6381cb0ef41Sopenharmony_ci      break;
6391cb0ef41Sopenharmony_ci    case LE:
6401cb0ef41Sopenharmony_ci      Format(instr, "le\t'f1,'d1('r2d,'r3)");
6411cb0ef41Sopenharmony_ci      break;
6421cb0ef41Sopenharmony_ci    case LD:
6431cb0ef41Sopenharmony_ci      Format(instr, "ld\t'f1,'d1('r2d,'r3)");
6441cb0ef41Sopenharmony_ci      break;
6451cb0ef41Sopenharmony_ci    case STE:
6461cb0ef41Sopenharmony_ci      Format(instr, "ste\t'f1,'d1('r2d,'r3)");
6471cb0ef41Sopenharmony_ci      break;
6481cb0ef41Sopenharmony_ci    case STD:
6491cb0ef41Sopenharmony_ci      Format(instr, "std\t'f1,'d1('r2d,'r3)");
6501cb0ef41Sopenharmony_ci      break;
6511cb0ef41Sopenharmony_ci    /* S format */
6521cb0ef41Sopenharmony_ci    // TRAP4 is used in calling to native function. it will not be generated
6531cb0ef41Sopenharmony_ci    // in native code.
6541cb0ef41Sopenharmony_ci    case TRAP4:
6551cb0ef41Sopenharmony_ci      Format(instr, "trap4");
6561cb0ef41Sopenharmony_ci      break;
6571cb0ef41Sopenharmony_ci    /* RIL-a format */
6581cb0ef41Sopenharmony_ci    case CFI:
6591cb0ef41Sopenharmony_ci      Format(instr, "cfi\t'r1,'i2");
6601cb0ef41Sopenharmony_ci      break;
6611cb0ef41Sopenharmony_ci    case CGFI:
6621cb0ef41Sopenharmony_ci      Format(instr, "cgfi\t'r1,'i2");
6631cb0ef41Sopenharmony_ci      break;
6641cb0ef41Sopenharmony_ci    case AFI:
6651cb0ef41Sopenharmony_ci      Format(instr, "afi\t'r1,'i2");
6661cb0ef41Sopenharmony_ci      break;
6671cb0ef41Sopenharmony_ci    case AGFI:
6681cb0ef41Sopenharmony_ci      Format(instr, "agfi\t'r1,'i2");
6691cb0ef41Sopenharmony_ci      break;
6701cb0ef41Sopenharmony_ci    case MSFI:
6711cb0ef41Sopenharmony_ci      Format(instr, "msfi\t'r1,'i2");
6721cb0ef41Sopenharmony_ci      break;
6731cb0ef41Sopenharmony_ci    case MSGFI:
6741cb0ef41Sopenharmony_ci      Format(instr, "msgfi\t'r1,'i2");
6751cb0ef41Sopenharmony_ci      break;
6761cb0ef41Sopenharmony_ci    case ALSIH:
6771cb0ef41Sopenharmony_ci      Format(instr, "alsih\t'r1,'i2");
6781cb0ef41Sopenharmony_ci      break;
6791cb0ef41Sopenharmony_ci    case ALSIHN:
6801cb0ef41Sopenharmony_ci      Format(instr, "alsihn\t'r1,'i2");
6811cb0ef41Sopenharmony_ci      break;
6821cb0ef41Sopenharmony_ci    case CIH:
6831cb0ef41Sopenharmony_ci      Format(instr, "cih\t'r1,'i2");
6841cb0ef41Sopenharmony_ci      break;
6851cb0ef41Sopenharmony_ci    case AIH:
6861cb0ef41Sopenharmony_ci      Format(instr, "aih\t'r1,'i2");
6871cb0ef41Sopenharmony_ci      break;
6881cb0ef41Sopenharmony_ci    case LGFI:
6891cb0ef41Sopenharmony_ci      Format(instr, "lgfi\t'r1,'i2");
6901cb0ef41Sopenharmony_ci      break;
6911cb0ef41Sopenharmony_ci    /* SIY format */
6921cb0ef41Sopenharmony_ci    case ASI:
6931cb0ef41Sopenharmony_ci      Format(instr, "asi\t'd2('r3),'ic");
6941cb0ef41Sopenharmony_ci      break;
6951cb0ef41Sopenharmony_ci    case AGSI:
6961cb0ef41Sopenharmony_ci      Format(instr, "agsi\t'd2('r3),'ic");
6971cb0ef41Sopenharmony_ci      break;
6981cb0ef41Sopenharmony_ci    /* RXY-a format */
6991cb0ef41Sopenharmony_ci    case LT:
7001cb0ef41Sopenharmony_ci      Format(instr, "lt\t'r1,'d2('r2d,'r3)");
7011cb0ef41Sopenharmony_ci      break;
7021cb0ef41Sopenharmony_ci    case LDY:
7031cb0ef41Sopenharmony_ci      Format(instr, "ldy\t'f1,'d2('r2d,'r3)");
7041cb0ef41Sopenharmony_ci      break;
7051cb0ef41Sopenharmony_ci    case LEY:
7061cb0ef41Sopenharmony_ci      Format(instr, "ley\t'f1,'d2('r2d,'r3)");
7071cb0ef41Sopenharmony_ci      break;
7081cb0ef41Sopenharmony_ci    case STDY:
7091cb0ef41Sopenharmony_ci      Format(instr, "stdy\t'f1,'d2('r2d,'r3)");
7101cb0ef41Sopenharmony_ci      break;
7111cb0ef41Sopenharmony_ci    case STEY:
7121cb0ef41Sopenharmony_ci      Format(instr, "stey\t'f1,'d2('r2d,'r3)");
7131cb0ef41Sopenharmony_ci      break;
7141cb0ef41Sopenharmony_ci    /* RXE format */
7151cb0ef41Sopenharmony_ci    case LDEB:
7161cb0ef41Sopenharmony_ci      Format(instr, "ldeb\t'f1,'d2('r2d,'r3)");
7171cb0ef41Sopenharmony_ci      break;
7181cb0ef41Sopenharmony_ci    default:
7191cb0ef41Sopenharmony_ci      return false;
7201cb0ef41Sopenharmony_ci  }
7211cb0ef41Sopenharmony_ci  return true;
7221cb0ef41Sopenharmony_ci}
7231cb0ef41Sopenharmony_ci
7241cb0ef41Sopenharmony_ci// Handles common cases of instructions;
7251cb0ef41Sopenharmony_ci// @return true if successfully decoded
7261cb0ef41Sopenharmony_cibool Decoder::DecodeGeneric(Instruction* instr) {
7271cb0ef41Sopenharmony_ci  Opcode opcode = instr->S390OpcodeValue();
7281cb0ef41Sopenharmony_ci  switch (opcode) {
7291cb0ef41Sopenharmony_ci    /* 2 bytes */
7301cb0ef41Sopenharmony_ci#define DECODE_RR_INSTRUCTIONS(name, opcode_name, opcode_value) \
7311cb0ef41Sopenharmony_ci  case opcode_name:                                             \
7321cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'r2");                           \
7331cb0ef41Sopenharmony_ci    break;
7341cb0ef41Sopenharmony_ci    S390_RR_OPCODE_LIST(DECODE_RR_INSTRUCTIONS)
7351cb0ef41Sopenharmony_ci#undef DECODE_RR_INSTRUCTIONS
7361cb0ef41Sopenharmony_ci
7371cb0ef41Sopenharmony_ci    /* 4 bytes */
7381cb0ef41Sopenharmony_ci#define DECODE_RS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
7391cb0ef41Sopenharmony_ci  case opcode_name:                                               \
7401cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'r2,'d1('r3)");                    \
7411cb0ef41Sopenharmony_ci    break;
7421cb0ef41Sopenharmony_ci    S390_RS_A_OPCODE_LIST(DECODE_RS_A_INSTRUCTIONS)
7431cb0ef41Sopenharmony_ci#undef DECODE_RS_A_INSTRUCTIONS
7441cb0ef41Sopenharmony_ci
7451cb0ef41Sopenharmony_ci#define DECODE_RSI_INSTRUCTIONS(name, opcode_name, opcode_value) \
7461cb0ef41Sopenharmony_ci  case opcode_name:                                              \
7471cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'r2,'i4");                        \
7481cb0ef41Sopenharmony_ci    break;
7491cb0ef41Sopenharmony_ci    S390_RSI_OPCODE_LIST(DECODE_RSI_INSTRUCTIONS)
7501cb0ef41Sopenharmony_ci#undef DECODE_RSI_INSTRUCTIONS
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_ci#define DECODE_RI_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
7531cb0ef41Sopenharmony_ci  case opcode_name:                                               \
7541cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'i1");                             \
7551cb0ef41Sopenharmony_ci    break;
7561cb0ef41Sopenharmony_ci    S390_RI_A_OPCODE_LIST(DECODE_RI_A_INSTRUCTIONS)
7571cb0ef41Sopenharmony_ci#undef DECODE_RI_A_INSTRUCTIONS
7581cb0ef41Sopenharmony_ci
7591cb0ef41Sopenharmony_ci#define DECODE_RI_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
7601cb0ef41Sopenharmony_ci  case opcode_name:                                               \
7611cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'i4");                             \
7621cb0ef41Sopenharmony_ci    break;
7631cb0ef41Sopenharmony_ci    S390_RI_B_OPCODE_LIST(DECODE_RI_B_INSTRUCTIONS)
7641cb0ef41Sopenharmony_ci#undef DECODE_RI_B_INSTRUCTIONS
7651cb0ef41Sopenharmony_ci
7661cb0ef41Sopenharmony_ci#define DECODE_RI_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
7671cb0ef41Sopenharmony_ci  case opcode_name:                                               \
7681cb0ef41Sopenharmony_ci    Format(instr, #name "\t'm1,'i4");                             \
7691cb0ef41Sopenharmony_ci    break;
7701cb0ef41Sopenharmony_ci    S390_RI_C_OPCODE_LIST(DECODE_RI_C_INSTRUCTIONS)
7711cb0ef41Sopenharmony_ci#undef DECODE_RI_C_INSTRUCTIONS
7721cb0ef41Sopenharmony_ci
7731cb0ef41Sopenharmony_ci#define DECODE_RRE_INSTRUCTIONS(name, opcode_name, opcode_value) \
7741cb0ef41Sopenharmony_ci  case opcode_name:                                              \
7751cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r5,'r6");                            \
7761cb0ef41Sopenharmony_ci    break;
7771cb0ef41Sopenharmony_ci    S390_RRE_OPCODE_LIST(DECODE_RRE_INSTRUCTIONS)
7781cb0ef41Sopenharmony_ci#undef DECODE_RRE_INSTRUCTIONS
7791cb0ef41Sopenharmony_ci
7801cb0ef41Sopenharmony_ci#define DECODE_RRF_A_INSTRUCTIONS(name, opcode_name, opcode_val) \
7811cb0ef41Sopenharmony_ci  case opcode_name:                                              \
7821cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r5,'r6,'r3");                        \
7831cb0ef41Sopenharmony_ci    break;
7841cb0ef41Sopenharmony_ci    S390_RRF_A_OPCODE_LIST(DECODE_RRF_A_INSTRUCTIONS)
7851cb0ef41Sopenharmony_ci#undef DECODE_RRF_A_INSTRUCTIONS
7861cb0ef41Sopenharmony_ci
7871cb0ef41Sopenharmony_ci#define DECODE_RRF_C_INSTRUCTIONS(name, opcode_name, opcode_val) \
7881cb0ef41Sopenharmony_ci  case opcode_name:                                              \
7891cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r5,'r6,'m2");                        \
7901cb0ef41Sopenharmony_ci    break;
7911cb0ef41Sopenharmony_ci    S390_RRF_C_OPCODE_LIST(DECODE_RRF_C_INSTRUCTIONS)
7921cb0ef41Sopenharmony_ci#undef DECODE_RRF_C_INSTRUCTIONS
7931cb0ef41Sopenharmony_ci
7941cb0ef41Sopenharmony_ci#define DECODE_RRF_E_INSTRUCTIONS(name, opcode_name, opcode_val) \
7951cb0ef41Sopenharmony_ci  case opcode_name:                                              \
7961cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r5,'m2,'f6");                        \
7971cb0ef41Sopenharmony_ci    break;
7981cb0ef41Sopenharmony_ci    S390_RRF_E_OPCODE_LIST(DECODE_RRF_E_INSTRUCTIONS)
7991cb0ef41Sopenharmony_ci#undef DECODE_RRF_E_INSTRUCTIONS
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_ci#define DECODE_RX_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
8021cb0ef41Sopenharmony_ci  case opcode_name:                                               \
8031cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'d1('r2d,'r3)");                   \
8041cb0ef41Sopenharmony_ci    break;
8051cb0ef41Sopenharmony_ci    S390_RX_A_OPCODE_LIST(DECODE_RX_A_INSTRUCTIONS)
8061cb0ef41Sopenharmony_ci#undef DECODE_RX_A_INSTRUCTIONS
8071cb0ef41Sopenharmony_ci
8081cb0ef41Sopenharmony_ci#define DECODE_RX_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
8091cb0ef41Sopenharmony_ci  case opcode_name:                                               \
8101cb0ef41Sopenharmony_ci    Format(instr, #name "\t'm1,'d1('r2d,'r3)");                   \
8111cb0ef41Sopenharmony_ci    break;
8121cb0ef41Sopenharmony_ci    S390_RX_B_OPCODE_LIST(DECODE_RX_B_INSTRUCTIONS)
8131cb0ef41Sopenharmony_ci#undef DECODE_RX_B_INSTRUCTIONS
8141cb0ef41Sopenharmony_ci
8151cb0ef41Sopenharmony_ci#define DECODE_RRD_INSTRUCTIONS(name, opcode_name, opcode_value) \
8161cb0ef41Sopenharmony_ci  case opcode_name:                                              \
8171cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f3,'f5,'f6");                        \
8181cb0ef41Sopenharmony_ci    break;
8191cb0ef41Sopenharmony_ci    S390_RRD_OPCODE_LIST(DECODE_RRD_INSTRUCTIONS)
8201cb0ef41Sopenharmony_ci#undef DECODE_RRD_INSTRUCTIONS
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci#define DECODE_SI_INSTRUCTIONS(name, opcode_name, opcode_value) \
8231cb0ef41Sopenharmony_ci  case opcode_name:                                             \
8241cb0ef41Sopenharmony_ci    Format(instr, #name "\t'd1('r3),'i8");                      \
8251cb0ef41Sopenharmony_ci    break;
8261cb0ef41Sopenharmony_ci    S390_SI_OPCODE_LIST(DECODE_SI_INSTRUCTIONS)
8271cb0ef41Sopenharmony_ci#undef DECODE_SI_INSTRUCTIONS
8281cb0ef41Sopenharmony_ci
8291cb0ef41Sopenharmony_ci    /* 6 bytes */
8301cb0ef41Sopenharmony_ci#define DECODE_VRR_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
8311cb0ef41Sopenharmony_ci  case opcode_name:                                                \
8321cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'f2,'m4,'m5,'m6");                  \
8331cb0ef41Sopenharmony_ci    break;
8341cb0ef41Sopenharmony_ci    S390_VRR_A_OPCODE_LIST(DECODE_VRR_A_INSTRUCTIONS)
8351cb0ef41Sopenharmony_ci#undef DECODE_VRR_A_INSTRUCTIONS
8361cb0ef41Sopenharmony_ci
8371cb0ef41Sopenharmony_ci#define DECODE_VRR_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
8381cb0ef41Sopenharmony_ci  case opcode_name:                                                \
8391cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'f2,'f3,'m4,'m6");                  \
8401cb0ef41Sopenharmony_ci    break;
8411cb0ef41Sopenharmony_ci    S390_VRR_B_OPCODE_LIST(DECODE_VRR_B_INSTRUCTIONS)
8421cb0ef41Sopenharmony_ci#undef DECODE_VRR_B_INSTRUCTIONS
8431cb0ef41Sopenharmony_ci
8441cb0ef41Sopenharmony_ci#define DECODE_VRR_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
8451cb0ef41Sopenharmony_ci  case opcode_name:                                                \
8461cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'f2,'f3,'m4");                      \
8471cb0ef41Sopenharmony_ci    break;
8481cb0ef41Sopenharmony_ci    S390_VRR_C_OPCODE_LIST(DECODE_VRR_C_INSTRUCTIONS)
8491cb0ef41Sopenharmony_ci#undef DECODE_VRR_C_INSTRUCTIONS
8501cb0ef41Sopenharmony_ci
8511cb0ef41Sopenharmony_ci#define DECODE_VRR_E_INSTRUCTIONS(name, opcode_name, opcode_value) \
8521cb0ef41Sopenharmony_ci  case opcode_name:                                                \
8531cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'f2,'f3,'f4,'m5,'m3");              \
8541cb0ef41Sopenharmony_ci    break;
8551cb0ef41Sopenharmony_ci    S390_VRR_E_OPCODE_LIST(DECODE_VRR_E_INSTRUCTIONS)
8561cb0ef41Sopenharmony_ci#undef DECODE_VRR_E_INSTRUCTIONS
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci#define DECODE_VRR_F_INSTRUCTIONS(name, opcode_name, opcode_value) \
8591cb0ef41Sopenharmony_ci  case opcode_name:                                                \
8601cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'r1,'r2");                          \
8611cb0ef41Sopenharmony_ci    break;
8621cb0ef41Sopenharmony_ci    S390_VRR_F_OPCODE_LIST(DECODE_VRR_F_INSTRUCTIONS)
8631cb0ef41Sopenharmony_ci#undef DECODE_VRR_F_INSTRUCTIONS
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_ci#define DECODE_VRX_INSTRUCTIONS(name, opcode_name, opcode_value) \
8661cb0ef41Sopenharmony_ci  case opcode_name:                                              \
8671cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'d1('r2d,'r3),'m4");              \
8681cb0ef41Sopenharmony_ci    break;
8691cb0ef41Sopenharmony_ci    S390_VRX_OPCODE_LIST(DECODE_VRX_INSTRUCTIONS)
8701cb0ef41Sopenharmony_ci#undef DECODE_VRX_INSTRUCTIONS
8711cb0ef41Sopenharmony_ci
8721cb0ef41Sopenharmony_ci#define DECODE_VRS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
8731cb0ef41Sopenharmony_ci  case opcode_name:                                                \
8741cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'f2,'d1('r3),'m4");                 \
8751cb0ef41Sopenharmony_ci    break;
8761cb0ef41Sopenharmony_ci    S390_VRS_A_OPCODE_LIST(DECODE_VRS_A_INSTRUCTIONS)
8771cb0ef41Sopenharmony_ci#undef DECODE_VRS_A_INSTRUCTIONS
8781cb0ef41Sopenharmony_ci
8791cb0ef41Sopenharmony_ci#define DECODE_VRS_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
8801cb0ef41Sopenharmony_ci  case opcode_name:                                                \
8811cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'r2,'d1('r3),'m4");                 \
8821cb0ef41Sopenharmony_ci    break;
8831cb0ef41Sopenharmony_ci    S390_VRS_B_OPCODE_LIST(DECODE_VRS_B_INSTRUCTIONS)
8841cb0ef41Sopenharmony_ci#undef DECODE_VRS_B_INSTRUCTIONS
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_ci#define DECODE_VRS_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
8871cb0ef41Sopenharmony_ci  case opcode_name:                                                \
8881cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'f2,'d1('r3),'m4");                 \
8891cb0ef41Sopenharmony_ci    break;
8901cb0ef41Sopenharmony_ci    S390_VRS_C_OPCODE_LIST(DECODE_VRS_C_INSTRUCTIONS)
8911cb0ef41Sopenharmony_ci#undef DECODE_VRS_C_INSTRUCTIONS
8921cb0ef41Sopenharmony_ci
8931cb0ef41Sopenharmony_ci#define DECODE_VRI_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
8941cb0ef41Sopenharmony_ci  case opcode_name:                                                \
8951cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'i1,'m4");                          \
8961cb0ef41Sopenharmony_ci    break;
8971cb0ef41Sopenharmony_ci    S390_VRI_A_OPCODE_LIST(DECODE_VRI_A_INSTRUCTIONS)
8981cb0ef41Sopenharmony_ci#undef DECODE_VRI_A_INSTRUCTIONS
8991cb0ef41Sopenharmony_ci
9001cb0ef41Sopenharmony_ci#define DECODE_VRI_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
9011cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9021cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'f2,'i1,'m4");                      \
9031cb0ef41Sopenharmony_ci    break;
9041cb0ef41Sopenharmony_ci    S390_VRI_C_OPCODE_LIST(DECODE_VRI_C_INSTRUCTIONS)
9051cb0ef41Sopenharmony_ci#undef DECODE_VRI_C_INSTRUCTIONS
9061cb0ef41Sopenharmony_ci
9071cb0ef41Sopenharmony_ci#define DECODE_RIL_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
9081cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9091cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'i7");                              \
9101cb0ef41Sopenharmony_ci    break;
9111cb0ef41Sopenharmony_ci    S390_RIL_A_OPCODE_LIST(DECODE_RIL_A_INSTRUCTIONS)
9121cb0ef41Sopenharmony_ci#undef DECODE_RIL_A_INSTRUCTIONS
9131cb0ef41Sopenharmony_ci
9141cb0ef41Sopenharmony_ci#define DECODE_RIL_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
9151cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9161cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'ie");                              \
9171cb0ef41Sopenharmony_ci    break;
9181cb0ef41Sopenharmony_ci    S390_RIL_B_OPCODE_LIST(DECODE_RIL_B_INSTRUCTIONS)
9191cb0ef41Sopenharmony_ci#undef DECODE_RIL_B_INSTRUCTIONS
9201cb0ef41Sopenharmony_ci
9211cb0ef41Sopenharmony_ci#define DECODE_RIL_C_INSTRUCTIONS(name, opcode_name, opcode_value) \
9221cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9231cb0ef41Sopenharmony_ci    Format(instr, #name "\t'm1,'ie");                              \
9241cb0ef41Sopenharmony_ci    break;
9251cb0ef41Sopenharmony_ci    S390_RIL_C_OPCODE_LIST(DECODE_RIL_C_INSTRUCTIONS)
9261cb0ef41Sopenharmony_ci#undef DECODE_RIL_C_INSTRUCTIONS
9271cb0ef41Sopenharmony_ci
9281cb0ef41Sopenharmony_ci#define DECODE_SIY_INSTRUCTIONS(name, opcode_name, opcode_value) \
9291cb0ef41Sopenharmony_ci  case opcode_name:                                              \
9301cb0ef41Sopenharmony_ci    Format(instr, #name "\t'd2('r3),'i8");                       \
9311cb0ef41Sopenharmony_ci    break;
9321cb0ef41Sopenharmony_ci    S390_SIY_OPCODE_LIST(DECODE_SIY_INSTRUCTIONS)
9331cb0ef41Sopenharmony_ci#undef DECODE_SIY_INSTRUCTIONS
9341cb0ef41Sopenharmony_ci
9351cb0ef41Sopenharmony_ci#define DECODE_RIE_D_INSTRUCTIONS(name, opcode_name, opcode_value) \
9361cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9371cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'r2,'i1");                          \
9381cb0ef41Sopenharmony_ci    break;
9391cb0ef41Sopenharmony_ci    S390_RIE_D_OPCODE_LIST(DECODE_RIE_D_INSTRUCTIONS)
9401cb0ef41Sopenharmony_ci#undef DECODE_RIE_D_INSTRUCTIONS
9411cb0ef41Sopenharmony_ci
9421cb0ef41Sopenharmony_ci#define DECODE_RIE_E_INSTRUCTIONS(name, opcode_name, opcode_value) \
9431cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9441cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'r2,'i4");                          \
9451cb0ef41Sopenharmony_ci    break;
9461cb0ef41Sopenharmony_ci    S390_RIE_E_OPCODE_LIST(DECODE_RIE_E_INSTRUCTIONS)
9471cb0ef41Sopenharmony_ci#undef DECODE_RIE_E_INSTRUCTIONS
9481cb0ef41Sopenharmony_ci
9491cb0ef41Sopenharmony_ci#define DECODE_RIE_F_INSTRUCTIONS(name, opcode_name, opcode_value) \
9501cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9511cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'r2,'i9,'ia,'ib");                  \
9521cb0ef41Sopenharmony_ci    break;
9531cb0ef41Sopenharmony_ci    S390_RIE_F_OPCODE_LIST(DECODE_RIE_F_INSTRUCTIONS)
9541cb0ef41Sopenharmony_ci#undef DECODE_RIE_F_INSTRUCTIONS
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_ci#define DECODE_RSY_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
9571cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9581cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'r2,'d2('r3)");                     \
9591cb0ef41Sopenharmony_ci    break;
9601cb0ef41Sopenharmony_ci    S390_RSY_A_OPCODE_LIST(DECODE_RSY_A_INSTRUCTIONS)
9611cb0ef41Sopenharmony_ci#undef DECODE_RSY_A_INSTRUCTIONS
9621cb0ef41Sopenharmony_ci
9631cb0ef41Sopenharmony_ci#define DECODE_RSY_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
9641cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9651cb0ef41Sopenharmony_ci    Format(instr, #name "\t'm2,'r1,'d2('r3)");                     \
9661cb0ef41Sopenharmony_ci    break;
9671cb0ef41Sopenharmony_ci    S390_RSY_B_OPCODE_LIST(DECODE_RSY_B_INSTRUCTIONS)
9681cb0ef41Sopenharmony_ci#undef DECODE_RSY_B_INSTRUCTIONS
9691cb0ef41Sopenharmony_ci
9701cb0ef41Sopenharmony_ci#define DECODE_RXY_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
9711cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9721cb0ef41Sopenharmony_ci    Format(instr, #name "\t'r1,'d2('r2d,'r3)");                    \
9731cb0ef41Sopenharmony_ci    break;
9741cb0ef41Sopenharmony_ci    S390_RXY_A_OPCODE_LIST(DECODE_RXY_A_INSTRUCTIONS)
9751cb0ef41Sopenharmony_ci#undef DECODE_RXY_A_INSTRUCTIONS
9761cb0ef41Sopenharmony_ci
9771cb0ef41Sopenharmony_ci#define DECODE_RXY_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
9781cb0ef41Sopenharmony_ci  case opcode_name:                                                \
9791cb0ef41Sopenharmony_ci    Format(instr, #name "\t'm1,'d2('r2d,'r3)");                    \
9801cb0ef41Sopenharmony_ci    break;
9811cb0ef41Sopenharmony_ci    S390_RXY_B_OPCODE_LIST(DECODE_RXY_B_INSTRUCTIONS)
9821cb0ef41Sopenharmony_ci#undef DECODE_RXY_B_INSTRUCTIONS
9831cb0ef41Sopenharmony_ci
9841cb0ef41Sopenharmony_ci#define DECODE_RXE_INSTRUCTIONS(name, opcode_name, opcode_value) \
9851cb0ef41Sopenharmony_ci  case opcode_name:                                              \
9861cb0ef41Sopenharmony_ci    Format(instr, #name "\t'f1,'d1('r2d, 'r3)");                 \
9871cb0ef41Sopenharmony_ci    break;
9881cb0ef41Sopenharmony_ci    S390_RXE_OPCODE_LIST(DECODE_RXE_INSTRUCTIONS)
9891cb0ef41Sopenharmony_ci#undef DECODE_RXE_INSTRUCTIONS
9901cb0ef41Sopenharmony_ci
9911cb0ef41Sopenharmony_ci#define DECODE_SIL_INSTRUCTIONS(name, opcode_name, opcode_value) \
9921cb0ef41Sopenharmony_ci  case opcode_name:                                              \
9931cb0ef41Sopenharmony_ci    Format(instr, #name "\t'd3('r3),'id");                       \
9941cb0ef41Sopenharmony_ci    break;
9951cb0ef41Sopenharmony_ci    S390_SIL_OPCODE_LIST(DECODE_SIL_INSTRUCTIONS)
9961cb0ef41Sopenharmony_ci#undef DECODE_SIL_INSTRUCTIONS
9971cb0ef41Sopenharmony_ci
9981cb0ef41Sopenharmony_ci#define DECODE_SS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
9991cb0ef41Sopenharmony_ci  case opcode_name:                                               \
10001cb0ef41Sopenharmony_ci    Format(instr, #name "\t'd3('i8,'r3),'d4('r7)");               \
10011cb0ef41Sopenharmony_ci    break;
10021cb0ef41Sopenharmony_ci    S390_SS_A_OPCODE_LIST(DECODE_SS_A_INSTRUCTIONS)
10031cb0ef41Sopenharmony_ci#undef DECODE_SS_A_INSTRUCTIONS
10041cb0ef41Sopenharmony_ci
10051cb0ef41Sopenharmony_ci    default:
10061cb0ef41Sopenharmony_ci      return false;
10071cb0ef41Sopenharmony_ci  }
10081cb0ef41Sopenharmony_ci  return true;
10091cb0ef41Sopenharmony_ci}
10101cb0ef41Sopenharmony_ci
10111cb0ef41Sopenharmony_ci// Disassemble the instruction at *instr_ptr into the output buffer.
10121cb0ef41Sopenharmony_ciint Decoder::InstructionDecode(byte* instr_ptr) {
10131cb0ef41Sopenharmony_ci  Instruction* instr = Instruction::At(instr_ptr);
10141cb0ef41Sopenharmony_ci  int instrLength = instr->InstructionLength();
10151cb0ef41Sopenharmony_ci
10161cb0ef41Sopenharmony_ci  // Print the Instruction bits.
10171cb0ef41Sopenharmony_ci  if (instrLength == 2) {
10181cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
10191cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%04x           ",
10201cb0ef41Sopenharmony_ci                       instr->InstructionBits<TwoByteInstr>());
10211cb0ef41Sopenharmony_ci  } else if (instrLength == 4) {
10221cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
10231cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%08x       ",
10241cb0ef41Sopenharmony_ci                       instr->InstructionBits<FourByteInstr>());
10251cb0ef41Sopenharmony_ci  } else {
10261cb0ef41Sopenharmony_ci    out_buffer_pos_ +=
10271cb0ef41Sopenharmony_ci        base::SNPrintF(out_buffer_ + out_buffer_pos_, "%012" PRIx64 "   ",
10281cb0ef41Sopenharmony_ci                       instr->InstructionBits<SixByteInstr>());
10291cb0ef41Sopenharmony_ci  }
10301cb0ef41Sopenharmony_ci
10311cb0ef41Sopenharmony_ci  bool decoded = DecodeSpecial(instr);
10321cb0ef41Sopenharmony_ci  if (!decoded) decoded = DecodeGeneric(instr);
10331cb0ef41Sopenharmony_ci  if (!decoded) Unknown(instr);
10341cb0ef41Sopenharmony_ci  return instrLength;
10351cb0ef41Sopenharmony_ci}
10361cb0ef41Sopenharmony_ci
10371cb0ef41Sopenharmony_ci}  // namespace internal
10381cb0ef41Sopenharmony_ci}  // namespace v8
10391cb0ef41Sopenharmony_ci
10401cb0ef41Sopenharmony_ci//------------------------------------------------------------------------------
10411cb0ef41Sopenharmony_ci
10421cb0ef41Sopenharmony_cinamespace disasm {
10431cb0ef41Sopenharmony_ci
10441cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfAddress(byte* addr) const {
10451cb0ef41Sopenharmony_ci  v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
10461cb0ef41Sopenharmony_ci  return tmp_buffer_.begin();
10471cb0ef41Sopenharmony_ci}
10481cb0ef41Sopenharmony_ci
10491cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfConstant(byte* addr) const {
10501cb0ef41Sopenharmony_ci  return NameOfAddress(addr);
10511cb0ef41Sopenharmony_ci}
10521cb0ef41Sopenharmony_ci
10531cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfCPURegister(int reg) const {
10541cb0ef41Sopenharmony_ci  return RegisterName(i::Register::from_code(reg));
10551cb0ef41Sopenharmony_ci}
10561cb0ef41Sopenharmony_ci
10571cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfByteCPURegister(int reg) const {
10581cb0ef41Sopenharmony_ci  UNREACHABLE();  // S390 does not have the concept of a byte register
10591cb0ef41Sopenharmony_ci}
10601cb0ef41Sopenharmony_ci
10611cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfXMMRegister(int reg) const {
10621cb0ef41Sopenharmony_ci  // S390 does not have XMM register
10631cb0ef41Sopenharmony_ci  // TODO(joransiu): Consider update this for Vector Regs
10641cb0ef41Sopenharmony_ci  UNREACHABLE();
10651cb0ef41Sopenharmony_ci}
10661cb0ef41Sopenharmony_ci
10671cb0ef41Sopenharmony_ciconst char* NameConverter::NameInCode(byte* addr) const {
10681cb0ef41Sopenharmony_ci  // The default name converter is called for unknown code. So we will not try
10691cb0ef41Sopenharmony_ci  // to access any memory.
10701cb0ef41Sopenharmony_ci  return "";
10711cb0ef41Sopenharmony_ci}
10721cb0ef41Sopenharmony_ci
10731cb0ef41Sopenharmony_ci//------------------------------------------------------------------------------
10741cb0ef41Sopenharmony_ci
10751cb0ef41Sopenharmony_ciint Disassembler::InstructionDecode(v8::base::Vector<char> buffer,
10761cb0ef41Sopenharmony_ci                                    byte* instruction) {
10771cb0ef41Sopenharmony_ci  v8::internal::Decoder d(converter_, buffer);
10781cb0ef41Sopenharmony_ci  return d.InstructionDecode(instruction);
10791cb0ef41Sopenharmony_ci}
10801cb0ef41Sopenharmony_ci
10811cb0ef41Sopenharmony_ci// The S390 assembler does not currently use constant pools.
10821cb0ef41Sopenharmony_ciint Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
10831cb0ef41Sopenharmony_ci
10841cb0ef41Sopenharmony_civoid Disassembler::Disassemble(FILE* f, byte* begin, byte* end,
10851cb0ef41Sopenharmony_ci                               UnimplementedOpcodeAction unimplemented_action) {
10861cb0ef41Sopenharmony_ci  NameConverter converter;
10871cb0ef41Sopenharmony_ci  Disassembler d(converter, unimplemented_action);
10881cb0ef41Sopenharmony_ci  for (byte* pc = begin; pc < end;) {
10891cb0ef41Sopenharmony_ci    v8::base::EmbeddedVector<char, 128> buffer;
10901cb0ef41Sopenharmony_ci    buffer[0] = '\0';
10911cb0ef41Sopenharmony_ci    byte* prev_pc = pc;
10921cb0ef41Sopenharmony_ci    pc += d.InstructionDecode(buffer, pc);
10931cb0ef41Sopenharmony_ci    v8::internal::PrintF(f, "%p    %08x      %s\n", static_cast<void*>(prev_pc),
10941cb0ef41Sopenharmony_ci                         *reinterpret_cast<int32_t*>(prev_pc), buffer.begin());
10951cb0ef41Sopenharmony_ci  }
10961cb0ef41Sopenharmony_ci}
10971cb0ef41Sopenharmony_ci
10981cb0ef41Sopenharmony_ci}  // namespace disasm
10991cb0ef41Sopenharmony_ci
11001cb0ef41Sopenharmony_ci#endif  // V8_TARGET_ARCH_S390
1101