Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp
35293 views
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/MCDisassembler/MCDisassembler.h"
23
#include "llvm/MC/MCDecoderOps.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 DecodeXR16RegisterClass(MCInst &Inst, uint64_t RegNo,
87
uint64_t Address,
88
const void *Decoder) {
89
return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
90
}
91
92
static DecodeStatus DecodeFPDRRegisterClass(MCInst &Inst, uint64_t RegNo,
93
uint64_t Address,
94
const void *Decoder) {
95
return DecodeRegisterClass(Inst, RegNo | 16ULL, Address, Decoder);
96
}
97
#define DecodeFPDR32RegisterClass DecodeFPDRRegisterClass
98
#define DecodeFPDR64RegisterClass DecodeFPDRRegisterClass
99
#define DecodeFPDR80RegisterClass DecodeFPDRRegisterClass
100
101
static DecodeStatus DecodeFPCSCRegisterClass(MCInst &Inst, uint64_t RegNo,
102
uint64_t Address,
103
const void *Decoder) {
104
return DecodeRegisterClass(Inst, (RegNo >> 1) + 24, Address, Decoder);
105
}
106
#define DecodeFPICRegisterClass DecodeFPCSCRegisterClass
107
108
static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, APInt &Insn,
109
uint64_t Address,
110
const void *Decoder) {
111
llvm_unreachable("unimplemented");
112
}
113
114
static DecodeStatus DecodeImm32(MCInst &Inst, uint64_t Imm, uint64_t Address,
115
const void *Decoder) {
116
Inst.addOperand(MCOperand::createImm(M68k::swapWord<uint32_t>(Imm)));
117
return DecodeStatus::Success;
118
}
119
120
#include "M68kGenDisassemblerTable.inc"
121
122
#undef DecodeFPDR32RegisterClass
123
#undef DecodeFPDR64RegisterClass
124
#undef DecodeFPDR80RegisterClass
125
#undef DecodeFPICRegisterClass
126
127
/// A disassembler class for M68k.
128
struct M68kDisassembler : public MCDisassembler {
129
M68kDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
130
: MCDisassembler(STI, Ctx) {}
131
virtual ~M68kDisassembler() {}
132
133
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
134
ArrayRef<uint8_t> Bytes, uint64_t Address,
135
raw_ostream &CStream) const override;
136
};
137
138
DecodeStatus M68kDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
139
ArrayRef<uint8_t> Bytes,
140
uint64_t Address,
141
raw_ostream &CStream) const {
142
DecodeStatus Result;
143
auto MakeUp = [&](APInt &Insn, unsigned InstrBits) {
144
unsigned Idx = Insn.getBitWidth() >> 3;
145
unsigned RoundUp = alignTo(InstrBits, Align(16));
146
if (RoundUp > Insn.getBitWidth())
147
Insn = Insn.zext(RoundUp);
148
RoundUp = RoundUp >> 3;
149
for (; Idx < RoundUp; Idx += 2) {
150
Insn.insertBits(support::endian::read16be(&Bytes[Idx]), Idx * 8, 16);
151
}
152
};
153
APInt Insn(16, support::endian::read16be(Bytes.data()));
154
// 2 bytes of data are consumed, so set Size to 2
155
// If we don't do this, disassembler may generate result even
156
// the encoding is invalid. We need to let it fail correctly.
157
Size = 2;
158
Result = decodeInstruction(DecoderTable80, Instr, Insn, Address, this, STI,
159
MakeUp);
160
if (Result == DecodeStatus::Success)
161
Size = InstrLenTable[Instr.getOpcode()] >> 3;
162
return Result;
163
}
164
165
static MCDisassembler *createM68kDisassembler(const Target &T,
166
const MCSubtargetInfo &STI,
167
MCContext &Ctx) {
168
return new M68kDisassembler(STI, Ctx);
169
}
170
171
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kDisassembler() {
172
// Register the disassembler.
173
TargetRegistry::RegisterMCDisassembler(getTheM68kTarget(),
174
createM68kDisassembler);
175
}
176
177