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
DecodeRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeDR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeDR16RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeDR8RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeAR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeAR16RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeXR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeXR32RegisterClass(MCInst & Inst,APInt RegNo,uint64_t Address,const void * Decoder)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
DecodeXR16RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFPDRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFPCSCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeCCRCRegisterClass(MCInst & Inst,APInt & Insn,uint64_t Address,const void * Decoder)114 static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, APInt &Insn,
115 uint64_t Address,
116 const void *Decoder) {
117 llvm_unreachable("unimplemented");
118 }
119
DecodeSRCRegisterClass(MCInst & Inst,APInt & Insn,uint64_t Address,const void * Decoder)120 static DecodeStatus DecodeSRCRegisterClass(MCInst &Inst, APInt &Insn,
121 uint64_t Address,
122 const void *Decoder) {
123 llvm_unreachable("unimplemented");
124 }
125
DecodeImm32(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)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 {
M68kDisassemblerM68kDisassembler141 M68kDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
142 : MCDisassembler(STI, Ctx) {}
~M68kDisassemblerM68kDisassembler143 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
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const150 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
createM68kDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)177 static MCDisassembler *createM68kDisassembler(const Target &T,
178 const MCSubtargetInfo &STI,
179 MCContext &Ctx) {
180 return new M68kDisassembler(STI, Ctx);
181 }
182
LLVMInitializeM68kDisassembler()183 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kDisassembler() {
184 // Register the disassembler.
185 TargetRegistry::RegisterMCDisassembler(getTheM68kTarget(),
186 createM68kDisassembler);
187 }
188