brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 4992f1a Raw
184 lines · cpp
1//===-- M68kDisassembler.cpp - Disassembler for M68k ------------*- 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// This file is part of the M68k Disassembler.10//11//===----------------------------------------------------------------------===//12 13#include "M68k.h"14#include "M68kRegisterInfo.h"15#include "M68kSubtarget.h"16#include "MCTargetDesc/M68kMCCodeEmitter.h"17#include "MCTargetDesc/M68kMCTargetDesc.h"18#include "TargetInfo/M68kTargetInfo.h"19 20#include "llvm/MC/MCAsmInfo.h"21#include "llvm/MC/MCContext.h"22#include "llvm/MC/MCDecoder.h"23#include "llvm/MC/MCDecoderOps.h"24#include "llvm/MC/MCDisassembler/MCDisassembler.h"25#include "llvm/MC/MCInst.h"26#include "llvm/MC/TargetRegistry.h"27#include "llvm/Support/Endian.h"28#include "llvm/Support/ErrorHandling.h"29 30using namespace llvm;31using namespace llvm::MCD;32 33#define DEBUG_TYPE "m68k-disassembler"34 35typedef MCDisassembler::DecodeStatus DecodeStatus;36 37static const unsigned RegisterDecode[] = {38    M68k::D0,    M68k::D1,  M68k::D2,  M68k::D3,  M68k::D4,  M68k::D5,39    M68k::D6,    M68k::D7,  M68k::A0,  M68k::A1,  M68k::A2,  M68k::A3,40    M68k::A4,    M68k::A5,  M68k::A6,  M68k::SP,  M68k::FP0, M68k::FP1,41    M68k::FP2,   M68k::FP3, M68k::FP4, M68k::FP5, M68k::FP6, M68k::FP7,42    M68k::FPIAR, M68k::FPS, M68k::FPC};43 44static DecodeStatus DecodeRegisterClass(MCInst &Inst, uint64_t RegNo,45                                        uint64_t Address, const void *Decoder) {46  if (RegNo >= 24)47    return DecodeStatus::Fail;48  Inst.addOperand(MCOperand::createReg(RegisterDecode[RegNo]));49  return DecodeStatus::Success;50}51 52static DecodeStatus DecodeDR32RegisterClass(MCInst &Inst, uint64_t RegNo,53                                            uint64_t Address,54                                            const void *Decoder) {55  return DecodeRegisterClass(Inst, RegNo, Address, Decoder);56}57 58static DecodeStatus DecodeDR16RegisterClass(MCInst &Inst, uint64_t RegNo,59                                            uint64_t Address,60                                            const void *Decoder) {61  return DecodeRegisterClass(Inst, RegNo, Address, Decoder);62}63 64static DecodeStatus DecodeDR8RegisterClass(MCInst &Inst, uint64_t RegNo,65                                           uint64_t Address,66                                           const void *Decoder) {67  return DecodeRegisterClass(Inst, RegNo, Address, Decoder);68}69 70static DecodeStatus DecodeAR32RegisterClass(MCInst &Inst, uint64_t RegNo,71                                            uint64_t Address,72                                            const void *Decoder) {73  return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);74}75 76static DecodeStatus DecodeAR16RegisterClass(MCInst &Inst, uint64_t RegNo,77                                            uint64_t Address,78                                            const void *Decoder) {79  return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);80}81 82static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, uint64_t RegNo,83                                            uint64_t Address,84                                            const void *Decoder) {85  return DecodeRegisterClass(Inst, RegNo, Address, Decoder);86}87 88static DecodeStatus DecodeXR16RegisterClass(MCInst &Inst, uint64_t RegNo,89                                            uint64_t Address,90                                            const void *Decoder) {91  return DecodeRegisterClass(Inst, RegNo, Address, Decoder);92}93 94static DecodeStatus DecodeFPDRRegisterClass(MCInst &Inst, uint64_t RegNo,95                                            uint64_t Address,96                                            const void *Decoder) {97  return DecodeRegisterClass(Inst, RegNo | 16ULL, Address, Decoder);98}99#define DecodeFPDR32RegisterClass DecodeFPDRRegisterClass100#define DecodeFPDR64RegisterClass DecodeFPDRRegisterClass101#define DecodeFPDR80RegisterClass DecodeFPDRRegisterClass102 103static DecodeStatus DecodeFPCSCRegisterClass(MCInst &Inst, uint64_t RegNo,104                                             uint64_t Address,105                                             const void *Decoder) {106  return DecodeRegisterClass(Inst, (RegNo >> 1) + 24, Address, Decoder);107}108#define DecodeFPICRegisterClass DecodeFPCSCRegisterClass109 110static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst,111                                            const MCDisassembler *Decoder) {112  Inst.addOperand(MCOperand::createReg(M68k::CCR));113  return DecodeStatus::Success;114}115 116static DecodeStatus DecodeSRCRegisterClass(MCInst &Inst,117                                           const MCDisassembler *Decoder) {118  Inst.addOperand(MCOperand::createReg(M68k::SR));119  return DecodeStatus::Success;120}121 122static DecodeStatus DecodeImm32(MCInst &Inst, uint64_t Imm, uint64_t Address,123                                const void *Decoder) {124  Inst.addOperand(MCOperand::createImm(M68k::swapWord<uint32_t>(Imm)));125  return DecodeStatus::Success;126}127 128#include "M68kGenDisassemblerTables.inc"129 130#undef DecodeFPDR32RegisterClass131#undef DecodeFPDR64RegisterClass132#undef DecodeFPDR80RegisterClass133#undef DecodeFPICRegisterClass134 135/// A disassembler class for M68k.136struct M68kDisassembler : public MCDisassembler {137  M68kDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)138      : MCDisassembler(STI, Ctx) {}139  virtual ~M68kDisassembler() {}140 141  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,142                              ArrayRef<uint8_t> Bytes, uint64_t Address,143                              raw_ostream &CStream) const override;144};145 146DecodeStatus M68kDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,147                                              ArrayRef<uint8_t> Bytes,148                                              uint64_t Address,149                                              raw_ostream &CStream) const {150  DecodeStatus Result;151  auto MakeUp = [&](APInt &Insn, unsigned InstrBits) {152    unsigned Idx = Insn.getBitWidth() >> 3;153    unsigned RoundUp = alignTo(InstrBits, Align(16));154    if (RoundUp > Insn.getBitWidth())155      Insn = Insn.zext(RoundUp);156    RoundUp = RoundUp >> 3;157    for (; Idx < RoundUp; Idx += 2) {158      Insn.insertBits(support::endian::read16be(&Bytes[Idx]), Idx * 8, 16);159    }160  };161  APInt Insn(16, support::endian::read16be(Bytes.data()));162  // 2 bytes of data are consumed, so set Size to 2163  // If we don't do this, disassembler may generate result even164  // the encoding is invalid. We need to let it fail correctly.165  Size = 2;166  Result = decodeInstruction(DecoderTable80, Instr, Insn, Address, this, STI,167                             MakeUp);168  if (Result == DecodeStatus::Success)169    Size = InstrLenTable[Instr.getOpcode()] >> 3;170  return Result;171}172 173static MCDisassembler *createM68kDisassembler(const Target &T,174                                              const MCSubtargetInfo &STI,175                                              MCContext &Ctx) {176  return new M68kDisassembler(STI, Ctx);177}178 179extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kDisassembler() {180  // Register the disassembler.181  TargetRegistry::RegisterMCDisassembler(getTheM68kTarget(),182                                         createM68kDisassembler);183}184