Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp
35295 views
1
//===- LanaiDisassembler.cpp - Disassembler for Lanai -----------*- 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 Lanai Disassembler.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "LanaiDisassembler.h"
14
15
#include "LanaiAluCode.h"
16
#include "LanaiCondCode.h"
17
#include "LanaiInstrInfo.h"
18
#include "TargetInfo/LanaiTargetInfo.h"
19
#include "llvm/MC/MCDecoderOps.h"
20
#include "llvm/MC/MCInst.h"
21
#include "llvm/MC/MCSubtargetInfo.h"
22
#include "llvm/MC/TargetRegistry.h"
23
#include "llvm/Support/MathExtras.h"
24
25
using namespace llvm;
26
27
typedef MCDisassembler::DecodeStatus DecodeStatus;
28
29
static MCDisassembler *createLanaiDisassembler(const Target & /*T*/,
30
const MCSubtargetInfo &STI,
31
MCContext &Ctx) {
32
return new LanaiDisassembler(STI, Ctx);
33
}
34
35
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiDisassembler() {
36
// Register the disassembler
37
TargetRegistry::RegisterMCDisassembler(getTheLanaiTarget(),
38
createLanaiDisassembler);
39
}
40
41
LanaiDisassembler::LanaiDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
42
: MCDisassembler(STI, Ctx) {}
43
44
// Forward declare because the autogenerated code will reference this.
45
// Definition is further down.
46
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
47
uint64_t Address,
48
const MCDisassembler *Decoder);
49
50
static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
51
uint64_t Address,
52
const MCDisassembler *Decoder);
53
54
static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
55
uint64_t Address,
56
const MCDisassembler *Decoder);
57
58
static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
59
uint64_t Address,
60
const MCDisassembler *Decoder);
61
62
static DecodeStatus decodeBranch(MCInst &Inst, unsigned Insn, uint64_t Address,
63
const MCDisassembler *Decoder);
64
65
static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
66
uint64_t Address,
67
const MCDisassembler *Decoder);
68
69
static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
70
uint64_t Address,
71
const MCDisassembler *Decoder);
72
73
#include "LanaiGenDisassemblerTables.inc"
74
75
static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t &Size,
76
uint32_t &Insn) {
77
// We want to read exactly 4 bytes of data.
78
if (Bytes.size() < 4) {
79
Size = 0;
80
return MCDisassembler::Fail;
81
}
82
83
// Encoded as big-endian 32-bit word in the stream.
84
Insn =
85
(Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 8) | (Bytes[3] << 0);
86
87
return MCDisassembler::Success;
88
}
89
90
static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn) {
91
unsigned AluOp = LPAC::ADD;
92
// Fix up for pre and post operations.
93
int PqShift = -1;
94
if (isRMOpcode(Instr.getOpcode()))
95
PqShift = 16;
96
else if (isSPLSOpcode(Instr.getOpcode()))
97
PqShift = 10;
98
else if (isRRMOpcode(Instr.getOpcode())) {
99
PqShift = 16;
100
// Determine RRM ALU op.
101
AluOp = (Insn >> 8) & 0x7;
102
if (AluOp == 7)
103
// Handle JJJJJ
104
// 0b10000 or 0b11000
105
AluOp |= 0x20 | (((Insn >> 3) & 0xf) << 1);
106
}
107
108
if (PqShift != -1) {
109
unsigned PQ = (Insn >> PqShift) & 0x3;
110
switch (PQ) {
111
case 0x0:
112
if (Instr.getOperand(2).isReg()) {
113
Instr.getOperand(2).setReg(Lanai::R0);
114
}
115
if (Instr.getOperand(2).isImm())
116
Instr.getOperand(2).setImm(0);
117
break;
118
case 0x1:
119
AluOp = LPAC::makePostOp(AluOp);
120
break;
121
case 0x2:
122
break;
123
case 0x3:
124
AluOp = LPAC::makePreOp(AluOp);
125
break;
126
}
127
Instr.addOperand(MCOperand::createImm(AluOp));
128
}
129
}
130
131
DecodeStatus
132
LanaiDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
133
ArrayRef<uint8_t> Bytes, uint64_t Address,
134
raw_ostream & /*CStream*/) const {
135
uint32_t Insn;
136
137
DecodeStatus Result = readInstruction32(Bytes, Size, Insn);
138
139
if (Result == MCDisassembler::Fail)
140
return MCDisassembler::Fail;
141
142
// Call auto-generated decoder function
143
Result =
144
decodeInstruction(DecoderTableLanai32, Instr, Insn, Address, this, STI);
145
146
if (Result != MCDisassembler::Fail) {
147
PostOperandDecodeAdjust(Instr, Insn);
148
Size = 4;
149
return Result;
150
}
151
152
return MCDisassembler::Fail;
153
}
154
155
static const unsigned GPRDecoderTable[] = {
156
Lanai::R0, Lanai::R1, Lanai::PC, Lanai::R3, Lanai::SP, Lanai::FP,
157
Lanai::R6, Lanai::R7, Lanai::RV, Lanai::R9, Lanai::RR1, Lanai::RR2,
158
Lanai::R12, Lanai::R13, Lanai::R14, Lanai::RCA, Lanai::R16, Lanai::R17,
159
Lanai::R18, Lanai::R19, Lanai::R20, Lanai::R21, Lanai::R22, Lanai::R23,
160
Lanai::R24, Lanai::R25, Lanai::R26, Lanai::R27, Lanai::R28, Lanai::R29,
161
Lanai::R30, Lanai::R31};
162
163
DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
164
uint64_t /*Address*/,
165
const MCDisassembler * /*Decoder*/) {
166
if (RegNo > 31)
167
return MCDisassembler::Fail;
168
169
unsigned Reg = GPRDecoderTable[RegNo];
170
Inst.addOperand(MCOperand::createReg(Reg));
171
return MCDisassembler::Success;
172
}
173
174
static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
175
uint64_t Address,
176
const MCDisassembler *Decoder) {
177
// RI memory values encoded using 23 bits:
178
// 5 bit register, 16 bit constant
179
unsigned Register = (Insn >> 18) & 0x1f;
180
Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
181
unsigned Offset = (Insn & 0xffff);
182
Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
183
184
return MCDisassembler::Success;
185
}
186
187
static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
188
uint64_t Address,
189
const MCDisassembler *Decoder) {
190
// RR memory values encoded using 20 bits:
191
// 5 bit register, 5 bit register, 2 bit PQ, 3 bit ALU operator, 5 bit JJJJJ
192
unsigned Register = (Insn >> 15) & 0x1f;
193
Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
194
Register = (Insn >> 10) & 0x1f;
195
Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
196
197
return MCDisassembler::Success;
198
}
199
200
static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
201
uint64_t Address,
202
const MCDisassembler *Decoder) {
203
// RI memory values encoded using 17 bits:
204
// 5 bit register, 10 bit constant
205
unsigned Register = (Insn >> 12) & 0x1f;
206
Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
207
unsigned Offset = (Insn & 0x3ff);
208
Inst.addOperand(MCOperand::createImm(SignExtend32<10>(Offset)));
209
210
return MCDisassembler::Success;
211
}
212
213
static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
214
uint64_t Address, uint64_t Offset,
215
uint64_t Width, MCInst &MI,
216
const MCDisassembler *Decoder) {
217
return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
218
Width, /*InstSize=*/0);
219
}
220
221
static DecodeStatus decodeBranch(MCInst &MI, unsigned Insn, uint64_t Address,
222
const MCDisassembler *Decoder) {
223
if (!tryAddingSymbolicOperand(Insn + Address, false, Address, 2, 23, MI,
224
Decoder))
225
MI.addOperand(MCOperand::createImm(Insn));
226
return MCDisassembler::Success;
227
}
228
229
static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
230
uint64_t Address,
231
const MCDisassembler *Decoder) {
232
unsigned Offset = (Insn & 0xffff);
233
Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
234
235
return MCDisassembler::Success;
236
}
237
238
static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
239
uint64_t Address,
240
const MCDisassembler *Decoder) {
241
if (Val >= LPCC::UNKNOWN)
242
return MCDisassembler::Fail;
243
Inst.addOperand(MCOperand::createImm(Val));
244
return MCDisassembler::Success;
245
}
246
247