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" 22cf0b6df6SSheng #include "llvm/MC/MCDecoderOps.h" 234cce1074Sknickish #include "llvm/MC/MCDisassembler/MCDisassembler.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, 387486b7b6SMin-Yih Hsu M68k::A4, M68k::A5, M68k::A6, M68k::SP, M68k::FP0, M68k::FP1, 39d2672a55SMin-Yih Hsu M68k::FP2, M68k::FP3, M68k::FP4, M68k::FP5, M68k::FP6, M68k::FP7, 40d2672a55SMin-Yih Hsu M68k::FPIAR, M68k::FPS, M68k::FPC}; 4122211857SRicky Taylor 42cf0b6df6SSheng static DecodeStatus DecodeRegisterClass(MCInst &Inst, uint64_t RegNo, 43cf0b6df6SSheng uint64_t Address, const void *Decoder) { 447486b7b6SMin-Yih Hsu if (RegNo >= 24) 45cf0b6df6SSheng return DecodeStatus::Fail; 46cf0b6df6SSheng Inst.addOperand(MCOperand::createReg(RegisterDecode[RegNo])); 47cf0b6df6SSheng return DecodeStatus::Success; 4822211857SRicky Taylor } 4922211857SRicky Taylor 50cf0b6df6SSheng static DecodeStatus DecodeDR32RegisterClass(MCInst &Inst, uint64_t RegNo, 51cf0b6df6SSheng uint64_t Address, 52cf0b6df6SSheng const void *Decoder) { 53cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder); 5422211857SRicky Taylor } 5522211857SRicky Taylor 56cf0b6df6SSheng static DecodeStatus DecodeDR16RegisterClass(MCInst &Inst, uint64_t RegNo, 57cf0b6df6SSheng uint64_t Address, 58cf0b6df6SSheng const void *Decoder) { 59cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder); 60cf0b6df6SSheng } 61cf0b6df6SSheng 62cf0b6df6SSheng static DecodeStatus DecodeDR8RegisterClass(MCInst &Inst, uint64_t RegNo, 63cf0b6df6SSheng uint64_t Address, 64cf0b6df6SSheng const void *Decoder) { 65cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder); 66cf0b6df6SSheng } 67cf0b6df6SSheng 68cf0b6df6SSheng static DecodeStatus DecodeAR32RegisterClass(MCInst &Inst, uint64_t RegNo, 69cf0b6df6SSheng uint64_t Address, 70cf0b6df6SSheng const void *Decoder) { 71cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder); 72cf0b6df6SSheng } 73cf0b6df6SSheng 74cf0b6df6SSheng static DecodeStatus DecodeAR16RegisterClass(MCInst &Inst, uint64_t RegNo, 75cf0b6df6SSheng uint64_t Address, 76cf0b6df6SSheng const void *Decoder) { 77cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder); 78cf0b6df6SSheng } 79cf0b6df6SSheng 80cf0b6df6SSheng static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, uint64_t RegNo, 81cf0b6df6SSheng uint64_t Address, 82cf0b6df6SSheng const void *Decoder) { 83cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder); 84cf0b6df6SSheng } 85cf0b6df6SSheng 864cce1074Sknickish static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, APInt RegNo, 874cce1074Sknickish uint64_t Address, 884cce1074Sknickish const void *Decoder) { 894cce1074Sknickish return DecodeRegisterClass(Inst, RegNo.getZExtValue(), Address, Decoder); 904cce1074Sknickish } 914cce1074Sknickish 92cf0b6df6SSheng static DecodeStatus DecodeXR16RegisterClass(MCInst &Inst, uint64_t RegNo, 93cf0b6df6SSheng uint64_t Address, 94cf0b6df6SSheng const void *Decoder) { 95cf0b6df6SSheng return DecodeRegisterClass(Inst, RegNo, Address, Decoder); 96cf0b6df6SSheng } 97cf0b6df6SSheng 987486b7b6SMin-Yih Hsu static DecodeStatus DecodeFPDRRegisterClass(MCInst &Inst, uint64_t RegNo, 997486b7b6SMin-Yih Hsu uint64_t Address, 1007486b7b6SMin-Yih Hsu const void *Decoder) { 1017486b7b6SMin-Yih Hsu return DecodeRegisterClass(Inst, RegNo | 16ULL, Address, Decoder); 1027486b7b6SMin-Yih Hsu } 1037486b7b6SMin-Yih Hsu #define DecodeFPDR32RegisterClass DecodeFPDRRegisterClass 1047486b7b6SMin-Yih Hsu #define DecodeFPDR64RegisterClass DecodeFPDRRegisterClass 1057486b7b6SMin-Yih Hsu #define DecodeFPDR80RegisterClass DecodeFPDRRegisterClass 1067486b7b6SMin-Yih Hsu 107d2672a55SMin-Yih Hsu static DecodeStatus DecodeFPCSCRegisterClass(MCInst &Inst, uint64_t RegNo, 108d2672a55SMin-Yih Hsu uint64_t Address, 109d2672a55SMin-Yih Hsu const void *Decoder) { 110d2672a55SMin-Yih Hsu return DecodeRegisterClass(Inst, (RegNo >> 1) + 24, Address, Decoder); 111d2672a55SMin-Yih Hsu } 112d2672a55SMin-Yih Hsu #define DecodeFPICRegisterClass DecodeFPCSCRegisterClass 113d2672a55SMin-Yih Hsu 114cf0b6df6SSheng static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, APInt &Insn, 115cf0b6df6SSheng uint64_t Address, 116cf0b6df6SSheng const void *Decoder) { 117cf0b6df6SSheng llvm_unreachable("unimplemented"); 118cf0b6df6SSheng } 119cf0b6df6SSheng 120*a0d77492SJanis Heims static DecodeStatus DecodeSRCRegisterClass(MCInst &Inst, APInt &Insn, 121*a0d77492SJanis Heims uint64_t Address, 122*a0d77492SJanis Heims const void *Decoder) { 123*a0d77492SJanis Heims llvm_unreachable("unimplemented"); 124*a0d77492SJanis Heims } 125*a0d77492SJanis Heims 126c40b158eSMin-Yih Hsu static DecodeStatus DecodeImm32(MCInst &Inst, uint64_t Imm, uint64_t Address, 127c40b158eSMin-Yih Hsu const void *Decoder) { 128c40b158eSMin-Yih Hsu Inst.addOperand(MCOperand::createImm(M68k::swapWord<uint32_t>(Imm))); 129c40b158eSMin-Yih Hsu return DecodeStatus::Success; 130c40b158eSMin-Yih Hsu } 131c40b158eSMin-Yih Hsu 132cf0b6df6SSheng #include "M68kGenDisassemblerTable.inc" 13322211857SRicky Taylor 1347486b7b6SMin-Yih Hsu #undef DecodeFPDR32RegisterClass 1357486b7b6SMin-Yih Hsu #undef DecodeFPDR64RegisterClass 1367486b7b6SMin-Yih Hsu #undef DecodeFPDR80RegisterClass 137d2672a55SMin-Yih Hsu #undef DecodeFPICRegisterClass 1387486b7b6SMin-Yih Hsu 13922211857SRicky Taylor /// A disassembler class for M68k. 14052d509f3SMin-Yih Hsu struct M68kDisassembler : public MCDisassembler { 14152d509f3SMin-Yih Hsu M68kDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 14252d509f3SMin-Yih Hsu : MCDisassembler(STI, Ctx) {} 14322211857SRicky Taylor virtual ~M68kDisassembler() {} 14422211857SRicky Taylor 14522211857SRicky Taylor DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 14622211857SRicky Taylor ArrayRef<uint8_t> Bytes, uint64_t Address, 14722211857SRicky Taylor raw_ostream &CStream) const override; 14822211857SRicky Taylor }; 14922211857SRicky Taylor 15022211857SRicky Taylor DecodeStatus M68kDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 15122211857SRicky Taylor ArrayRef<uint8_t> Bytes, 15222211857SRicky Taylor uint64_t Address, 15322211857SRicky Taylor raw_ostream &CStream) const { 154cf0b6df6SSheng DecodeStatus Result; 155cf0b6df6SSheng auto MakeUp = [&](APInt &Insn, unsigned InstrBits) { 156cf0b6df6SSheng unsigned Idx = Insn.getBitWidth() >> 3; 157cf0b6df6SSheng unsigned RoundUp = alignTo(InstrBits, Align(16)); 158df25f0d5SSheng if (RoundUp > Insn.getBitWidth()) 159017c9827SSheng Insn = Insn.zext(RoundUp); 160cf0b6df6SSheng RoundUp = RoundUp >> 3; 161cf0b6df6SSheng for (; Idx < RoundUp; Idx += 2) { 162cf0b6df6SSheng Insn.insertBits(support::endian::read16be(&Bytes[Idx]), Idx * 8, 16); 16322211857SRicky Taylor } 16422211857SRicky Taylor }; 165cf0b6df6SSheng APInt Insn(16, support::endian::read16be(Bytes.data())); 166a5d618b3SSheng // 2 bytes of data are consumed, so set Size to 2 167a5d618b3SSheng // If we don't do this, disassembler may generate result even 168a5d618b3SSheng // the encoding is invalid. We need to let it fail correctly. 169a5d618b3SSheng Size = 2; 170cf0b6df6SSheng Result = decodeInstruction(DecoderTable80, Instr, Insn, Address, this, STI, 171cf0b6df6SSheng MakeUp); 172cf0b6df6SSheng if (Result == DecodeStatus::Success) 173cf0b6df6SSheng Size = InstrLenTable[Instr.getOpcode()] >> 3; 174cf0b6df6SSheng return Result; 17522211857SRicky Taylor } 17622211857SRicky Taylor 17722211857SRicky Taylor static MCDisassembler *createM68kDisassembler(const Target &T, 17822211857SRicky Taylor const MCSubtargetInfo &STI, 17922211857SRicky Taylor MCContext &Ctx) { 18052d509f3SMin-Yih Hsu return new M68kDisassembler(STI, Ctx); 18122211857SRicky Taylor } 18222211857SRicky Taylor 18322211857SRicky Taylor extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kDisassembler() { 18422211857SRicky Taylor // Register the disassembler. 18522211857SRicky Taylor TargetRegistry::RegisterMCDisassembler(getTheM68kTarget(), 18622211857SRicky Taylor createM68kDisassembler); 18722211857SRicky Taylor } 188