brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.5 KiB · a724c5a Raw
365 lines · cpp
1//===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "MCTargetDesc/SystemZMCTargetDesc.h"10#include "TargetInfo/SystemZTargetInfo.h"11#include "llvm/MC/MCDecoder.h"12#include "llvm/MC/MCDecoderOps.h"13#include "llvm/MC/MCDisassembler/MCDisassembler.h"14#include "llvm/MC/MCInst.h"15#include "llvm/MC/MCSubtargetInfo.h"16#include "llvm/MC/TargetRegistry.h"17#include "llvm/Support/Compiler.h"18#include "llvm/Support/MathExtras.h"19#include <cassert>20#include <cstdint>21 22using namespace llvm;23using namespace llvm::MCD;24 25#define DEBUG_TYPE "systemz-disassembler"26 27typedef MCDisassembler::DecodeStatus DecodeStatus;28 29namespace {30 31class SystemZDisassembler : public MCDisassembler {32public:33  SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)34    : MCDisassembler(STI, Ctx) {}35  ~SystemZDisassembler() override = default;36 37  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,38                              ArrayRef<uint8_t> Bytes, uint64_t Address,39                              raw_ostream &CStream) const override;40};41 42} // end anonymous namespace43 44static MCDisassembler *createSystemZDisassembler(const Target &T,45                                                 const MCSubtargetInfo &STI,46                                                 MCContext &Ctx) {47  return new SystemZDisassembler(STI, Ctx);48}49 50// NOLINTNEXTLINE(readability-identifier-naming)51extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void52LLVMInitializeSystemZDisassembler() {53  // Register the disassembler.54  TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(),55                                         createSystemZDisassembler);56}57 58/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the59/// immediate Value in the MCInst.60///61/// @param Value      - The immediate Value, has had any PC adjustment made by62///                     the caller.63/// @param isBranch   - If the instruction is a branch instruction64/// @param Address    - The starting address of the instruction65/// @param Offset     - The byte offset to this immediate in the instruction66/// @param Width      - The byte width of this immediate in the instruction67///68/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was69/// called then that function is called to get any symbolic information for the70/// immediate in the instruction using the Address, Offset and Width.  If that71/// returns non-zero then the symbolic information it returns is used to create72/// an MCExpr and that is added as an operand to the MCInst.  If getOpInfo()73/// returns zero and isBranch is true then a symbol look up for immediate Value74/// is done and if a symbol is found an MCExpr is created with that, else75/// an MCExpr with the immediate Value is created.  This function returns true76/// if it adds an operand to the MCInst and false otherwise.77static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,78                                     uint64_t Address, uint64_t Offset,79                                     uint64_t Width, MCInst &MI,80                                     const MCDisassembler *Decoder) {81  return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,82                                           Width, /*InstSize=*/0);83}84 85static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,86                                        const unsigned *Regs, unsigned Size,87                                        bool IsAddr = false) {88  assert(RegNo < Size && "Invalid register");89  if (IsAddr && RegNo == 0) {90    RegNo = SystemZ::NoRegister;91  } else {92    RegNo = Regs[RegNo];93    if (RegNo == 0)94      return MCDisassembler::Fail;95  }96  Inst.addOperand(MCOperand::createReg(RegNo));97  return MCDisassembler::Success;98}99 100static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,101                                               uint64_t Address,102                                               const MCDisassembler *Decoder) {103  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);104}105 106static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,107                                                uint64_t Address,108                                                const MCDisassembler *Decoder) {109  return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);110}111 112static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,113                                               uint64_t Address,114                                               const MCDisassembler *Decoder) {115  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);116}117 118static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,119                                                uint64_t Address,120                                                const MCDisassembler *Decoder) {121  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);122}123 124static DecodeStatus125DecodeADDR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,126                             const MCDisassembler *Decoder) {127  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16, true);128}129 130static DecodeStatus131DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,132                             const MCDisassembler *Decoder) {133  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16, true);134}135 136static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,137                                               uint64_t Address,138                                               const MCDisassembler *Decoder) {139  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);140}141 142static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,143                                               uint64_t Address,144                                               const MCDisassembler *Decoder) {145  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);146}147 148static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,149                                                uint64_t Address,150                                                const MCDisassembler *Decoder) {151  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);152}153 154static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,155                                               uint64_t Address,156                                               const MCDisassembler *Decoder) {157  return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);158}159 160static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,161                                               uint64_t Address,162                                               const MCDisassembler *Decoder) {163  return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);164}165 166static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,167                                                uint64_t Address,168                                                const MCDisassembler *Decoder) {169  return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);170}171 172static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,173                                               uint64_t Address,174                                               const MCDisassembler *Decoder) {175  return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);176}177 178static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,179                                               uint64_t Address,180                                               const MCDisassembler *Decoder) {181  return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16);182}183 184template<unsigned N>185static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {186  if (!isUInt<N>(Imm))187    return MCDisassembler::Fail;188  Inst.addOperand(MCOperand::createImm(Imm));189  return MCDisassembler::Success;190}191 192template<unsigned N>193static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {194  if (!isUInt<N>(Imm))195    return MCDisassembler::Fail;196  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));197  return MCDisassembler::Success;198}199 200static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,201                                       uint64_t Address,202                                       const MCDisassembler *Decoder) {203  return decodeUImmOperand<1>(Inst, Imm);204}205 206static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,207                                       uint64_t Address,208                                       const MCDisassembler *Decoder) {209  return decodeUImmOperand<2>(Inst, Imm);210}211 212static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,213                                       uint64_t Address,214                                       const MCDisassembler *Decoder) {215  return decodeUImmOperand<3>(Inst, Imm);216}217 218static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,219                                       uint64_t Address,220                                       const MCDisassembler *Decoder) {221  return decodeUImmOperand<4>(Inst, Imm);222}223 224static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,225                                       uint64_t Address,226                                       const MCDisassembler *Decoder) {227  return decodeUImmOperand<8>(Inst, Imm);228}229 230static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,231                                        uint64_t Address,232                                        const MCDisassembler *Decoder) {233  return decodeUImmOperand<12>(Inst, Imm);234}235 236static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,237                                        uint64_t Address,238                                        const MCDisassembler *Decoder) {239  return decodeUImmOperand<16>(Inst, Imm);240}241 242static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,243                                        uint64_t Address,244                                        const MCDisassembler *Decoder) {245  return decodeUImmOperand<32>(Inst, Imm);246}247 248static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,249                                       uint64_t Address,250                                       const MCDisassembler *Decoder) {251  return decodeSImmOperand<8>(Inst, Imm);252}253 254static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,255                                        uint64_t Address,256                                        const MCDisassembler *Decoder) {257  return decodeSImmOperand<16>(Inst, Imm);258}259 260static DecodeStatus decodeS20ImmOperand(MCInst &Inst, uint64_t Imm,261                                        uint64_t Address,262                                        const MCDisassembler *Decoder) {263  return decodeSImmOperand<20>(Inst, Imm);264}265 266static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,267                                        uint64_t Address,268                                        const MCDisassembler *Decoder) {269  return decodeSImmOperand<32>(Inst, Imm);270}271 272template <unsigned N>273static DecodeStatus decodeLenOperand(MCInst &Inst, uint64_t Imm,274                                     uint64_t Address,275                                     const MCDisassembler *Decoder) {276  if (!isUInt<N>(Imm))277    return MCDisassembler::Fail;278  Inst.addOperand(MCOperand::createImm(Imm + 1));279  return MCDisassembler::Success;280}281 282template <unsigned N>283static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,284                                       uint64_t Address, bool isBranch,285                                       const MCDisassembler *Decoder) {286  assert(isUInt<N>(Imm) && "Invalid PC-relative offset");287  uint64_t Value = SignExtend64<N>(Imm) * 2;288 289  if (!tryAddingSymbolicOperand(Value + Address, isBranch, Address, 2, N / 8,290                                Inst, Decoder))291    Inst.addOperand(MCOperand::createImm(Value));292 293  return MCDisassembler::Success;294}295 296static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm,297                                               uint64_t Address,298                                               const MCDisassembler *Decoder) {299  return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);300}301 302static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,303                                               uint64_t Address,304                                               const MCDisassembler *Decoder) {305  return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);306}307 308static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm,309                                               uint64_t Address,310                                               const MCDisassembler *Decoder) {311  return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);312}313 314static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,315                                               uint64_t Address,316                                               const MCDisassembler *Decoder) {317  return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);318}319 320static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,321                                         uint64_t Address,322                                         const MCDisassembler *Decoder) {323  return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);324}325 326#include "SystemZGenDisassemblerTables.inc"327 328DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,329                                                 ArrayRef<uint8_t> Bytes,330                                                 uint64_t Address,331                                                 raw_ostream &CS) const {332  CommentStream = &CS;333 334  // Get the first two bytes of the instruction.335  Size = 0;336  if (Bytes.size() < 2)337    return MCDisassembler::Fail;338 339  // The top 2 bits of the first byte specify the size.340  const uint8_t *Table;341  if (Bytes[0] < 0x40) {342    Size = 2;343    Table = DecoderTable16;344  } else if (Bytes[0] < 0xc0) {345    Size = 4;346    Table = DecoderTable32;347  } else {348    Size = 6;349    Table = DecoderTable48;350  }351 352  // Read any remaining bytes.353  if (Bytes.size() < Size) {354    Size = Bytes.size();355    return MCDisassembler::Fail;356  }357 358  // Construct the instruction.359  uint64_t Inst = 0;360  for (uint64_t I = 0; I < Size; ++I)361    Inst = (Inst << 8) | Bytes[I];362 363  return decodeInstruction(Table, MI, Inst, Address, this, STI);364}365