Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp
35293 views
//===-- M68kDisassembler.cpp - Disassembler for M68k ------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is part of the M68k Disassembler.9//10//===----------------------------------------------------------------------===//1112#include "M68k.h"13#include "M68kRegisterInfo.h"14#include "M68kSubtarget.h"15#include "MCTargetDesc/M68kMCCodeEmitter.h"16#include "MCTargetDesc/M68kMCTargetDesc.h"17#include "TargetInfo/M68kTargetInfo.h"1819#include "llvm/MC/MCAsmInfo.h"20#include "llvm/MC/MCContext.h"21#include "llvm/MC/MCDisassembler/MCDisassembler.h"22#include "llvm/MC/MCDecoderOps.h"23#include "llvm/MC/MCInst.h"24#include "llvm/MC/TargetRegistry.h"25#include "llvm/Support/Endian.h"26#include "llvm/Support/ErrorHandling.h"2728using namespace llvm;2930#define DEBUG_TYPE "m68k-disassembler"3132typedef MCDisassembler::DecodeStatus DecodeStatus;3334static const unsigned RegisterDecode[] = {35M68k::D0, M68k::D1, M68k::D2, M68k::D3, M68k::D4, M68k::D5,36M68k::D6, M68k::D7, M68k::A0, M68k::A1, M68k::A2, M68k::A3,37M68k::A4, M68k::A5, M68k::A6, M68k::SP, M68k::FP0, M68k::FP1,38M68k::FP2, M68k::FP3, M68k::FP4, M68k::FP5, M68k::FP6, M68k::FP7,39M68k::FPIAR, M68k::FPS, M68k::FPC};4041static DecodeStatus DecodeRegisterClass(MCInst &Inst, uint64_t RegNo,42uint64_t Address, const void *Decoder) {43if (RegNo >= 24)44return DecodeStatus::Fail;45Inst.addOperand(MCOperand::createReg(RegisterDecode[RegNo]));46return DecodeStatus::Success;47}4849static DecodeStatus DecodeDR32RegisterClass(MCInst &Inst, uint64_t RegNo,50uint64_t Address,51const void *Decoder) {52return DecodeRegisterClass(Inst, RegNo, Address, Decoder);53}5455static DecodeStatus DecodeDR16RegisterClass(MCInst &Inst, uint64_t RegNo,56uint64_t Address,57const void *Decoder) {58return DecodeRegisterClass(Inst, RegNo, Address, Decoder);59}6061static DecodeStatus DecodeDR8RegisterClass(MCInst &Inst, uint64_t RegNo,62uint64_t Address,63const void *Decoder) {64return DecodeRegisterClass(Inst, RegNo, Address, Decoder);65}6667static DecodeStatus DecodeAR32RegisterClass(MCInst &Inst, uint64_t RegNo,68uint64_t Address,69const void *Decoder) {70return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);71}7273static DecodeStatus DecodeAR16RegisterClass(MCInst &Inst, uint64_t RegNo,74uint64_t Address,75const void *Decoder) {76return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);77}7879static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, uint64_t RegNo,80uint64_t Address,81const void *Decoder) {82return DecodeRegisterClass(Inst, RegNo, Address, Decoder);83}8485static DecodeStatus DecodeXR16RegisterClass(MCInst &Inst, uint64_t RegNo,86uint64_t Address,87const void *Decoder) {88return DecodeRegisterClass(Inst, RegNo, Address, Decoder);89}9091static DecodeStatus DecodeFPDRRegisterClass(MCInst &Inst, uint64_t RegNo,92uint64_t Address,93const void *Decoder) {94return DecodeRegisterClass(Inst, RegNo | 16ULL, Address, Decoder);95}96#define DecodeFPDR32RegisterClass DecodeFPDRRegisterClass97#define DecodeFPDR64RegisterClass DecodeFPDRRegisterClass98#define DecodeFPDR80RegisterClass DecodeFPDRRegisterClass99100static DecodeStatus DecodeFPCSCRegisterClass(MCInst &Inst, uint64_t RegNo,101uint64_t Address,102const void *Decoder) {103return DecodeRegisterClass(Inst, (RegNo >> 1) + 24, Address, Decoder);104}105#define DecodeFPICRegisterClass DecodeFPCSCRegisterClass106107static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, APInt &Insn,108uint64_t Address,109const void *Decoder) {110llvm_unreachable("unimplemented");111}112113static DecodeStatus DecodeImm32(MCInst &Inst, uint64_t Imm, uint64_t Address,114const void *Decoder) {115Inst.addOperand(MCOperand::createImm(M68k::swapWord<uint32_t>(Imm)));116return DecodeStatus::Success;117}118119#include "M68kGenDisassemblerTable.inc"120121#undef DecodeFPDR32RegisterClass122#undef DecodeFPDR64RegisterClass123#undef DecodeFPDR80RegisterClass124#undef DecodeFPICRegisterClass125126/// A disassembler class for M68k.127struct M68kDisassembler : public MCDisassembler {128M68kDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)129: MCDisassembler(STI, Ctx) {}130virtual ~M68kDisassembler() {}131132DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,133ArrayRef<uint8_t> Bytes, uint64_t Address,134raw_ostream &CStream) const override;135};136137DecodeStatus M68kDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,138ArrayRef<uint8_t> Bytes,139uint64_t Address,140raw_ostream &CStream) const {141DecodeStatus Result;142auto MakeUp = [&](APInt &Insn, unsigned InstrBits) {143unsigned Idx = Insn.getBitWidth() >> 3;144unsigned RoundUp = alignTo(InstrBits, Align(16));145if (RoundUp > Insn.getBitWidth())146Insn = Insn.zext(RoundUp);147RoundUp = RoundUp >> 3;148for (; Idx < RoundUp; Idx += 2) {149Insn.insertBits(support::endian::read16be(&Bytes[Idx]), Idx * 8, 16);150}151};152APInt Insn(16, support::endian::read16be(Bytes.data()));153// 2 bytes of data are consumed, so set Size to 2154// If we don't do this, disassembler may generate result even155// the encoding is invalid. We need to let it fail correctly.156Size = 2;157Result = decodeInstruction(DecoderTable80, Instr, Insn, Address, this, STI,158MakeUp);159if (Result == DecodeStatus::Success)160Size = InstrLenTable[Instr.getOpcode()] >> 3;161return Result;162}163164static MCDisassembler *createM68kDisassembler(const Target &T,165const MCSubtargetInfo &STI,166MCContext &Ctx) {167return new M68kDisassembler(STI, Ctx);168}169170extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kDisassembler() {171// Register the disassembler.172TargetRegistry::RegisterMCDisassembler(getTheM68kTarget(),173createM68kDisassembler);174}175176177