LLVM 23.0.0git
M68kDisassembler.cpp
Go to the documentation of this file.
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"
19
20#include "llvm/MC/MCAsmInfo.h"
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCDecoder.h"
25#include "llvm/MC/MCInst.h"
27#include "llvm/Support/Endian.h"
29
30using namespace llvm;
31using namespace llvm::MCD;
32
33#define DEBUG_TYPE "m68k-disassembler"
34
36
37static const unsigned RegisterDecode[] = {
38 M68k::D0, M68k::D1, M68k::D2, M68k::D3, M68k::D4, M68k::D5,
39 M68k::D6, M68k::D7, M68k::A0, M68k::A1, M68k::A2, M68k::A3,
40 M68k::A4, M68k::A5, M68k::A6, M68k::SP, M68k::FP0, M68k::FP1,
41 M68k::FP2, M68k::FP3, M68k::FP4, M68k::FP5, M68k::FP6, M68k::FP7,
42 M68k::FPIAR, M68k::FPS, M68k::FPC};
43
45 uint64_t Address, const void *Decoder) {
46 if (RegNo >= 24)
47 return DecodeStatus::Fail;
49 return DecodeStatus::Success;
50}
51
53 uint64_t Address,
54 const void *Decoder) {
55 return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
56}
57
59 uint64_t Address,
60 const void *Decoder) {
61 return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
62}
63
65 uint64_t Address,
66 const void *Decoder) {
67 return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
68}
69
71 uint64_t Address,
72 const void *Decoder) {
73 return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);
74}
75
77 uint64_t Address,
78 const void *Decoder) {
79 return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder);
80}
81
83 uint64_t Address,
84 const void *Decoder) {
85 return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
86}
87
89 uint64_t Address,
90 const void *Decoder) {
91 return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
92}
93
95 uint64_t Address,
96 const void *Decoder) {
97 return DecodeRegisterClass(Inst, RegNo | 16ULL, Address, Decoder);
98}
99#define DecodeFPDR32RegisterClass DecodeFPDRRegisterClass
100#define DecodeFPDR64RegisterClass DecodeFPDRRegisterClass
101#define DecodeFPDR80RegisterClass DecodeFPDRRegisterClass
102
104 uint64_t Address,
105 const void *Decoder) {
106 return DecodeRegisterClass(Inst, (RegNo >> 1) + 24, Address, Decoder);
107}
108#define DecodeFPICRegisterClass DecodeFPCSCRegisterClass
109
111 const MCDisassembler *Decoder) {
112 Inst.addOperand(MCOperand::createReg(M68k::CCR));
113 return DecodeStatus::Success;
114}
115
117 const MCDisassembler *Decoder) {
118 Inst.addOperand(MCOperand::createReg(M68k::SR));
119 return DecodeStatus::Success;
120}
121
123 const void *Decoder) {
125 return DecodeStatus::Success;
126}
127
129 const void *Decoder) {
130 assert(isUInt<2>(Imm));
131 Inst.addOperand(MCOperand::createImm(1 << Imm));
132 return DecodeStatus::Success;
133}
134
136 uint64_t Address, const void *Decoder) {
137 // 4 bits actual RegNo + 1 bit index suppress
138 assert(isUInt<5>(IndexReg));
139 if (IndexReg & 0b10000) {
140 // Index suppress, fill in with NoReg
141 Inst.addOperand(MCOperand::createReg(M68k::NoRegister));
142 return DecodeStatus::Success;
143 }
144
145 return DecodeXR32RegisterClass(Inst, IndexReg & 0b1111, Address, Decoder);
146}
147
148#include "M68kGenDisassemblerTables.inc"
149
150#undef DecodeFPDR32RegisterClass
151#undef DecodeFPDR64RegisterClass
152#undef DecodeFPDR80RegisterClass
153#undef DecodeFPICRegisterClass
154
155/// A disassembler class for M68k.
159 virtual ~M68kDisassembler() {}
160
162 ArrayRef<uint8_t> Bytes, uint64_t Address,
163 raw_ostream &CStream) const override;
164};
165
167 ArrayRef<uint8_t> Bytes,
169 raw_ostream &CStream) const {
170 DecodeStatus Result;
171 auto MakeUp = [&](APInt &Insn, unsigned InstrBits) {
172 unsigned Idx = Insn.getBitWidth() >> 3;
173 unsigned RoundUp = alignTo(InstrBits, Align(16));
174 if (RoundUp > Insn.getBitWidth())
175 Insn = Insn.zext(RoundUp);
176 RoundUp = RoundUp >> 3;
177 for (; Idx < RoundUp; Idx += 2) {
178 Insn.insertBits(support::endian::read16be(&Bytes[Idx]), Idx * 8, 16);
179 }
180 };
181 APInt Insn(16, support::endian::read16be(Bytes.data()));
182 // 2 bytes of data are consumed, so set Size to 2
183 // If we don't do this, disassembler may generate result even
184 // the encoding is invalid. We need to let it fail correctly.
185 Size = 2;
186 Result = decodeInstruction(DecoderTable80, Instr, Insn, Address, this, STI,
187 MakeUp);
188 if (Result == DecodeStatus::Success)
189 Size = InstrLenTable[Instr.getOpcode()] >> 3;
190 return Result;
191}
192
194 const MCSubtargetInfo &STI,
195 MCContext &Ctx) {
196 return new M68kDisassembler(STI, Ctx);
197}
198
MCDisassembler::DecodeStatus DecodeStatus
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
static DecodeStatus DecodeIndexRegister(MCInst &Inst, uint64_t IndexReg, uint64_t Address, const void *Decoder)
static const unsigned RegisterDecode[]
static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeFPDRRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeScale(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeDR32RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static MCDisassembler * createM68kDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kDisassembler()
static DecodeStatus DecodeRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeDR8RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeAR32RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeFPCSCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, const MCDisassembler *Decoder)
static DecodeStatus DecodeSRCRegisterClass(MCInst &Inst, const MCDisassembler *Decoder)
static DecodeStatus DecodeXR16RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeAR16RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeDR16RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeImm32(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
This file contains the declarations for the code emitter which are useful outside of the emitter itse...
This file provides M68k specific target descriptions.
This file contains the M68k implementation of the TargetRegisterInfo class.
This file declares the M68k specific subclass of TargetSubtargetInfo.
This file contains the entry points for global functions defined in the M68k target library,...
#define T
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1055
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1511
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
Definition APInt.cpp:398
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T * data() const
Definition ArrayRef.h:138
Context object for machine code objects.
Definition MCContext.h:83
Superclass for all disassemblers.
MCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
const MCSubtargetInfo & STI
DecodeStatus
Ternary decode status.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
void addOperand(const MCOperand Op)
Definition MCInst.h:215
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
Generic base class for all target subtargets.
Target - Wrapper for Target specific information.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
value_t swapWord(value_t Val)
uint16_t read16be(const void *P)
Definition Endian.h:438
This is an optimization pass for GlobalISel generic memory operations.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
Target & getTheM68kTarget()
A disassembler class for M68k.
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &CStream) const override
Returns the disassembly of a single instruction.
M68kDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.