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