xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
104eeddc0SDimitry Andric //===-- M68kDisassembler.cpp - Disassembler for M68k ------------*- C++ -*-===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric //
9fe6060f1SDimitry Andric // This file is part of the M68k Disassembler.
10fe6060f1SDimitry Andric //
11fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
12fe6060f1SDimitry Andric 
13fe6060f1SDimitry Andric #include "M68k.h"
14fe6060f1SDimitry Andric #include "M68kRegisterInfo.h"
15fe6060f1SDimitry Andric #include "M68kSubtarget.h"
16fe6060f1SDimitry Andric #include "MCTargetDesc/M68kMCCodeEmitter.h"
17fe6060f1SDimitry Andric #include "MCTargetDesc/M68kMCTargetDesc.h"
18fe6060f1SDimitry Andric #include "TargetInfo/M68kTargetInfo.h"
19fe6060f1SDimitry Andric 
20fe6060f1SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
21fe6060f1SDimitry Andric #include "llvm/MC/MCContext.h"
22fe6060f1SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
2381ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
24fe6060f1SDimitry Andric #include "llvm/MC/MCInst.h"
25349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
2681ad6265SDimitry Andric #include "llvm/Support/Endian.h"
2781ad6265SDimitry Andric #include "llvm/Support/ErrorHandling.h"
28fe6060f1SDimitry Andric 
29fe6060f1SDimitry Andric using namespace llvm;
30fe6060f1SDimitry Andric 
31fe6060f1SDimitry Andric #define DEBUG_TYPE "m68k-disassembler"
32fe6060f1SDimitry Andric 
33fe6060f1SDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
34fe6060f1SDimitry Andric 
3581ad6265SDimitry Andric static const unsigned RegisterDecode[] = {
3681ad6265SDimitry Andric     M68k::D0, M68k::D1, M68k::D2, M68k::D3, M68k::D4, M68k::D5,
3781ad6265SDimitry Andric     M68k::D6, M68k::D7, M68k::A0, M68k::A1, M68k::A2, M68k::A3,
3881ad6265SDimitry Andric     M68k::A4, M68k::A5, M68k::A6, M68k::SP,
39fe6060f1SDimitry Andric };
40fe6060f1SDimitry Andric 
4181ad6265SDimitry Andric static DecodeStatus DecodeRegisterClass(MCInst &Inst, uint64_t RegNo,
4281ad6265SDimitry Andric                                         uint64_t Address, const void *Decoder) {
4381ad6265SDimitry Andric   if (RegNo >= 16)
4481ad6265SDimitry Andric     return DecodeStatus::Fail;
4581ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(RegisterDecode[RegNo]));
4681ad6265SDimitry Andric   return DecodeStatus::Success;
47fe6060f1SDimitry Andric }
48fe6060f1SDimitry Andric 
4981ad6265SDimitry Andric static DecodeStatus DecodeDR32RegisterClass(MCInst &Inst, uint64_t RegNo,
5081ad6265SDimitry Andric                                             uint64_t Address,
5181ad6265SDimitry Andric                                             const void *Decoder) {
5281ad6265SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
53fe6060f1SDimitry Andric }
54fe6060f1SDimitry Andric 
5581ad6265SDimitry Andric static DecodeStatus DecodeDR16RegisterClass(MCInst &Inst, uint64_t RegNo,
5681ad6265SDimitry Andric                                             uint64_t Address,
5781ad6265SDimitry Andric                                             const void *Decoder) {
5881ad6265SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
5981ad6265SDimitry Andric }
6081ad6265SDimitry Andric 
6181ad6265SDimitry Andric static DecodeStatus DecodeDR8RegisterClass(MCInst &Inst, uint64_t RegNo,
6281ad6265SDimitry Andric                                            uint64_t Address,
6381ad6265SDimitry Andric                                            const void *Decoder) {
6481ad6265SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
6581ad6265SDimitry Andric }
6681ad6265SDimitry Andric 
6781ad6265SDimitry Andric static DecodeStatus DecodeAR32RegisterClass(MCInst &Inst, uint64_t RegNo,
6881ad6265SDimitry Andric                                             uint64_t Address,
6981ad6265SDimitry Andric                                             const void *Decoder) {
7081ad6265SDimitry Andric   return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);
7181ad6265SDimitry Andric }
7281ad6265SDimitry Andric 
7381ad6265SDimitry Andric static DecodeStatus DecodeAR16RegisterClass(MCInst &Inst, uint64_t RegNo,
7481ad6265SDimitry Andric                                             uint64_t Address,
7581ad6265SDimitry Andric                                             const void *Decoder) {
7681ad6265SDimitry Andric   return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);
7781ad6265SDimitry Andric }
7881ad6265SDimitry Andric 
7981ad6265SDimitry Andric static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, uint64_t RegNo,
8081ad6265SDimitry Andric                                             uint64_t Address,
8181ad6265SDimitry Andric                                             const void *Decoder) {
8281ad6265SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
8381ad6265SDimitry Andric }
8481ad6265SDimitry Andric 
8581ad6265SDimitry Andric static DecodeStatus DecodeXR16RegisterClass(MCInst &Inst, uint64_t RegNo,
8681ad6265SDimitry Andric                                             uint64_t Address,
8781ad6265SDimitry Andric                                             const void *Decoder) {
8881ad6265SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
8981ad6265SDimitry Andric }
9081ad6265SDimitry Andric 
9181ad6265SDimitry Andric static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, APInt &Insn,
9281ad6265SDimitry Andric                                             uint64_t Address,
9381ad6265SDimitry Andric                                             const void *Decoder) {
9481ad6265SDimitry Andric   llvm_unreachable("unimplemented");
9581ad6265SDimitry Andric }
9681ad6265SDimitry Andric 
97*bdd1243dSDimitry Andric static DecodeStatus DecodeImm32(MCInst &Inst, uint64_t Imm, uint64_t Address,
98*bdd1243dSDimitry Andric                                 const void *Decoder) {
99*bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(M68k::swapWord<uint32_t>(Imm)));
100*bdd1243dSDimitry Andric   return DecodeStatus::Success;
101*bdd1243dSDimitry Andric }
102*bdd1243dSDimitry Andric 
10381ad6265SDimitry Andric #include "M68kGenDisassemblerTable.inc"
104fe6060f1SDimitry Andric 
105fe6060f1SDimitry Andric /// A disassembler class for M68k.
10681ad6265SDimitry Andric struct M68kDisassembler : public MCDisassembler {
10781ad6265SDimitry Andric   M68kDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
10881ad6265SDimitry Andric       : MCDisassembler(STI, Ctx) {}
109fe6060f1SDimitry Andric   virtual ~M68kDisassembler() {}
110fe6060f1SDimitry Andric 
111fe6060f1SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
112fe6060f1SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
113fe6060f1SDimitry Andric                               raw_ostream &CStream) const override;
114fe6060f1SDimitry Andric };
115fe6060f1SDimitry Andric 
116fe6060f1SDimitry Andric DecodeStatus M68kDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
117fe6060f1SDimitry Andric                                               ArrayRef<uint8_t> Bytes,
118fe6060f1SDimitry Andric                                               uint64_t Address,
119fe6060f1SDimitry Andric                                               raw_ostream &CStream) const {
12081ad6265SDimitry Andric   DecodeStatus Result;
12181ad6265SDimitry Andric   auto MakeUp = [&](APInt &Insn, unsigned InstrBits) {
12281ad6265SDimitry Andric     unsigned Idx = Insn.getBitWidth() >> 3;
12381ad6265SDimitry Andric     unsigned RoundUp = alignTo(InstrBits, Align(16));
12481ad6265SDimitry Andric     if (RoundUp > Insn.getBitWidth())
12581ad6265SDimitry Andric       Insn = Insn.zext(RoundUp);
12681ad6265SDimitry Andric     RoundUp = RoundUp >> 3;
12781ad6265SDimitry Andric     for (; Idx < RoundUp; Idx += 2) {
12881ad6265SDimitry Andric       Insn.insertBits(support::endian::read16be(&Bytes[Idx]), Idx * 8, 16);
129fe6060f1SDimitry Andric     }
130fe6060f1SDimitry Andric   };
13181ad6265SDimitry Andric   APInt Insn(16, support::endian::read16be(Bytes.data()));
13281ad6265SDimitry Andric   // 2 bytes of data are consumed, so set Size to 2
13381ad6265SDimitry Andric   // If we don't do this, disassembler may generate result even
13481ad6265SDimitry Andric   // the encoding is invalid. We need to let it fail correctly.
13581ad6265SDimitry Andric   Size = 2;
13681ad6265SDimitry Andric   Result = decodeInstruction(DecoderTable80, Instr, Insn, Address, this, STI,
13781ad6265SDimitry Andric                              MakeUp);
13881ad6265SDimitry Andric   if (Result == DecodeStatus::Success)
13981ad6265SDimitry Andric     Size = InstrLenTable[Instr.getOpcode()] >> 3;
14081ad6265SDimitry Andric   return Result;
141fe6060f1SDimitry Andric }
142fe6060f1SDimitry Andric 
143fe6060f1SDimitry Andric static MCDisassembler *createM68kDisassembler(const Target &T,
144fe6060f1SDimitry Andric                                               const MCSubtargetInfo &STI,
145fe6060f1SDimitry Andric                                               MCContext &Ctx) {
14681ad6265SDimitry Andric   return new M68kDisassembler(STI, Ctx);
147fe6060f1SDimitry Andric }
148fe6060f1SDimitry Andric 
149fe6060f1SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kDisassembler() {
150fe6060f1SDimitry Andric   // Register the disassembler.
151fe6060f1SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheM68kTarget(),
152fe6060f1SDimitry Andric                                          createM68kDisassembler);
153fe6060f1SDimitry Andric }
154