16bf22ae4SJim Lin //===-- M68kDisassembler.cpp - Disassembler for M68k ------------*- C++ -*-===//
222211857SRicky Taylor //
322211857SRicky Taylor // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422211857SRicky Taylor // See https://llvm.org/LICENSE.txt for license information.
522211857SRicky Taylor // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
622211857SRicky Taylor //
722211857SRicky Taylor //===----------------------------------------------------------------------===//
822211857SRicky Taylor //
922211857SRicky Taylor // This file is part of the M68k Disassembler.
1022211857SRicky Taylor //
1122211857SRicky Taylor //===----------------------------------------------------------------------===//
1222211857SRicky Taylor
1322211857SRicky Taylor #include "M68k.h"
1422211857SRicky Taylor #include "M68kRegisterInfo.h"
1522211857SRicky Taylor #include "M68kSubtarget.h"
1622211857SRicky Taylor #include "MCTargetDesc/M68kMCCodeEmitter.h"
1722211857SRicky Taylor #include "MCTargetDesc/M68kMCTargetDesc.h"
1822211857SRicky Taylor #include "TargetInfo/M68kTargetInfo.h"
1922211857SRicky Taylor
2022211857SRicky Taylor #include "llvm/MC/MCAsmInfo.h"
2122211857SRicky Taylor #include "llvm/MC/MCContext.h"
2222211857SRicky Taylor #include "llvm/MC/MCDisassembler/MCDisassembler.h"
23cf0b6df6SSheng #include "llvm/MC/MCDecoderOps.h"
2422211857SRicky Taylor #include "llvm/MC/MCInst.h"
2589b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
26cf0b6df6SSheng #include "llvm/Support/Endian.h"
27cf0b6df6SSheng #include "llvm/Support/ErrorHandling.h"
2822211857SRicky Taylor
2922211857SRicky Taylor using namespace llvm;
3022211857SRicky Taylor
3122211857SRicky Taylor #define DEBUG_TYPE "m68k-disassembler"
3222211857SRicky Taylor
3322211857SRicky Taylor typedef MCDisassembler::DecodeStatus DecodeStatus;
3422211857SRicky Taylor
35cf0b6df6SSheng static const unsigned RegisterDecode[] = {
36cf0b6df6SSheng M68k::D0, M68k::D1, M68k::D2, M68k::D3, M68k::D4, M68k::D5,
37cf0b6df6SSheng M68k::D6, M68k::D7, M68k::A0, M68k::A1, M68k::A2, M68k::A3,
38cf0b6df6SSheng M68k::A4, M68k::A5, M68k::A6, M68k::SP,
3922211857SRicky Taylor };
4022211857SRicky Taylor
DecodeRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)41cf0b6df6SSheng static DecodeStatus DecodeRegisterClass(MCInst &Inst, uint64_t RegNo,
42cf0b6df6SSheng uint64_t Address, const void *Decoder) {
43cf0b6df6SSheng if (RegNo >= 16)
44cf0b6df6SSheng return DecodeStatus::Fail;
45cf0b6df6SSheng Inst.addOperand(MCOperand::createReg(RegisterDecode[RegNo]));
46cf0b6df6SSheng return DecodeStatus::Success;
4722211857SRicky Taylor }
4822211857SRicky Taylor
DecodeDR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)49cf0b6df6SSheng static DecodeStatus DecodeDR32RegisterClass(MCInst &Inst, uint64_t RegNo,
50cf0b6df6SSheng uint64_t Address,
51cf0b6df6SSheng const void *Decoder) {
52cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
5322211857SRicky Taylor }
5422211857SRicky Taylor
DecodeDR16RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)55cf0b6df6SSheng static DecodeStatus DecodeDR16RegisterClass(MCInst &Inst, uint64_t RegNo,
56cf0b6df6SSheng uint64_t Address,
57cf0b6df6SSheng const void *Decoder) {
58cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
59cf0b6df6SSheng }
60cf0b6df6SSheng
DecodeDR8RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)61cf0b6df6SSheng static DecodeStatus DecodeDR8RegisterClass(MCInst &Inst, uint64_t RegNo,
62cf0b6df6SSheng uint64_t Address,
63cf0b6df6SSheng const void *Decoder) {
64cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
65cf0b6df6SSheng }
66cf0b6df6SSheng
DecodeAR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)67cf0b6df6SSheng static DecodeStatus DecodeAR32RegisterClass(MCInst &Inst, uint64_t RegNo,
68cf0b6df6SSheng uint64_t Address,
69cf0b6df6SSheng const void *Decoder) {
70cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);
71cf0b6df6SSheng }
72cf0b6df6SSheng
DecodeAR16RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)73cf0b6df6SSheng static DecodeStatus DecodeAR16RegisterClass(MCInst &Inst, uint64_t RegNo,
74cf0b6df6SSheng uint64_t Address,
75cf0b6df6SSheng const void *Decoder) {
76cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);
77cf0b6df6SSheng }
78cf0b6df6SSheng
DecodeXR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)79cf0b6df6SSheng static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, uint64_t RegNo,
80cf0b6df6SSheng uint64_t Address,
81cf0b6df6SSheng const void *Decoder) {
82cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
83cf0b6df6SSheng }
84cf0b6df6SSheng
DecodeXR16RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)85cf0b6df6SSheng static DecodeStatus DecodeXR16RegisterClass(MCInst &Inst, uint64_t RegNo,
86cf0b6df6SSheng uint64_t Address,
87cf0b6df6SSheng const void *Decoder) {
88cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
89cf0b6df6SSheng }
90cf0b6df6SSheng
DecodeCCRCRegisterClass(MCInst & Inst,APInt & Insn,uint64_t Address,const void * Decoder)91cf0b6df6SSheng static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, APInt &Insn,
92cf0b6df6SSheng uint64_t Address,
93cf0b6df6SSheng const void *Decoder) {
94cf0b6df6SSheng llvm_unreachable("unimplemented");
95cf0b6df6SSheng }
96cf0b6df6SSheng
97cf0b6df6SSheng #include "M68kGenDisassemblerTable.inc"
9822211857SRicky Taylor
9922211857SRicky Taylor /// A disassembler class for M68k.
100*52d509f3SMin-Yih Hsu struct M68kDisassembler : public MCDisassembler {
M68kDisassemblerM68kDisassembler101*52d509f3SMin-Yih Hsu M68kDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
102*52d509f3SMin-Yih Hsu : MCDisassembler(STI, Ctx) {}
~M68kDisassemblerM68kDisassembler10322211857SRicky Taylor virtual ~M68kDisassembler() {}
10422211857SRicky Taylor
10522211857SRicky Taylor DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
10622211857SRicky Taylor ArrayRef<uint8_t> Bytes, uint64_t Address,
10722211857SRicky Taylor raw_ostream &CStream) const override;
10822211857SRicky Taylor };
10922211857SRicky Taylor
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const11022211857SRicky Taylor DecodeStatus M68kDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
11122211857SRicky Taylor ArrayRef<uint8_t> Bytes,
11222211857SRicky Taylor uint64_t Address,
11322211857SRicky Taylor raw_ostream &CStream) const {
114cf0b6df6SSheng DecodeStatus Result;
115cf0b6df6SSheng auto MakeUp = [&](APInt &Insn, unsigned InstrBits) {
116cf0b6df6SSheng unsigned Idx = Insn.getBitWidth() >> 3;
117cf0b6df6SSheng unsigned RoundUp = alignTo(InstrBits, Align(16));
118df25f0d5SSheng if (RoundUp > Insn.getBitWidth())
119017c9827SSheng Insn = Insn.zext(RoundUp);
120cf0b6df6SSheng RoundUp = RoundUp >> 3;
121cf0b6df6SSheng for (; Idx < RoundUp; Idx += 2) {
122cf0b6df6SSheng Insn.insertBits(support::endian::read16be(&Bytes[Idx]), Idx * 8, 16);
12322211857SRicky Taylor }
12422211857SRicky Taylor };
125cf0b6df6SSheng APInt Insn(16, support::endian::read16be(Bytes.data()));
126a5d618b3SSheng // 2 bytes of data are consumed, so set Size to 2
127a5d618b3SSheng // If we don't do this, disassembler may generate result even
128a5d618b3SSheng // the encoding is invalid. We need to let it fail correctly.
129a5d618b3SSheng Size = 2;
130cf0b6df6SSheng Result = decodeInstruction(DecoderTable80, Instr, Insn, Address, this, STI,
131cf0b6df6SSheng MakeUp);
132cf0b6df6SSheng if (Result == DecodeStatus::Success)
133cf0b6df6SSheng Size = InstrLenTable[Instr.getOpcode()] >> 3;
134cf0b6df6SSheng return Result;
13522211857SRicky Taylor }
13622211857SRicky Taylor
createM68kDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)13722211857SRicky Taylor static MCDisassembler *createM68kDisassembler(const Target &T,
13822211857SRicky Taylor const MCSubtargetInfo &STI,
13922211857SRicky Taylor MCContext &Ctx) {
140*52d509f3SMin-Yih Hsu return new M68kDisassembler(STI, Ctx);
14122211857SRicky Taylor }
14222211857SRicky Taylor
LLVMInitializeM68kDisassembler()14322211857SRicky Taylor extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kDisassembler() {
14422211857SRicky Taylor // Register the disassembler.
14522211857SRicky Taylor TargetRegistry::RegisterMCDisassembler(getTheM68kTarget(),
14622211857SRicky Taylor createM68kDisassembler);
14722211857SRicky Taylor }
148