LLVM 22.0.0git
LanaiDisassembler.cpp
Go to the documentation of this file.
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"
19#include "llvm/MC/MCDecoder.h"
21#include "llvm/MC/MCInst.h"
25#include "llvm/Support/Debug.h"
27
28#define DEBUG_TYPE "lanai-disassembler"
29
30using namespace llvm;
31
33
35 const MCSubtargetInfo &STI,
36 MCContext &Ctx) {
37 return new LanaiDisassembler(STI, Ctx);
38}
39
42 // Register the disassembler
45}
46
48 : MCDisassembler(STI, Ctx) {}
49
50// clang-format off
51static const unsigned GPRDecoderTable[] = {
52 Lanai::R0, Lanai::R1, Lanai::PC, Lanai::R3, Lanai::SP, Lanai::FP,
53 Lanai::R6, Lanai::R7, Lanai::RV, Lanai::R9, Lanai::RR1, Lanai::RR2,
54 Lanai::R12, Lanai::R13, Lanai::R14, Lanai::RCA, Lanai::R16, Lanai::R17,
55 Lanai::R18, Lanai::R19, Lanai::R20, Lanai::R21, Lanai::R22, Lanai::R23,
56 Lanai::R24, Lanai::R25, Lanai::R26, Lanai::R27, Lanai::R28, Lanai::R29,
57 Lanai::R30, Lanai::R31
58};
59// clang-format on
60
62 uint64_t /*Address*/,
63 const MCDisassembler * /*Decoder*/) {
64 if (RegNo > 31)
66
67 unsigned Reg = GPRDecoderTable[RegNo];
70}
71
72static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
74 const MCDisassembler *Decoder) {
75 // RI memory values encoded using 23 bits:
76 // 5 bit register, 16 bit constant
77 unsigned Register = (Insn >> 18) & 0x1f;
79 unsigned Offset = (Insn & 0xffff);
80 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
81
83}
84
85static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
87 const MCDisassembler *Decoder) {
88 // RR memory values encoded using 20 bits:
89 // 5 bit register, 5 bit register, 2 bit PQ, 3 bit ALU operator, 5 bit JJJJJ
90 unsigned Register = (Insn >> 15) & 0x1f;
92 Register = (Insn >> 10) & 0x1f;
94
96}
97
98static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
100 const MCDisassembler *Decoder) {
101 // RI memory values encoded using 17 bits:
102 // 5 bit register, 10 bit constant
103 unsigned Register = (Insn >> 12) & 0x1f;
105 unsigned Offset = (Insn & 0x3ff);
106 Inst.addOperand(MCOperand::createImm(SignExtend32<10>(Offset)));
107
109}
110
111static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
113 uint64_t Width, MCInst &MI,
114 const MCDisassembler *Decoder) {
115 return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
116 Width, /*InstSize=*/0);
117}
118
120 const MCDisassembler *Decoder) {
121 if (!tryAddingSymbolicOperand(Insn + Address, false, Address, 2, 23, MI,
122 Decoder))
123 MI.addOperand(MCOperand::createImm(Insn));
125}
126
127static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
129 const MCDisassembler *Decoder) {
130 unsigned Offset = (Insn & 0xffff);
131 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
132
134}
135
136static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
138 const MCDisassembler *Decoder) {
139 if (Val >= LPCC::UNKNOWN)
143}
144
145#include "LanaiGenDisassemblerTables.inc"
146
148 uint32_t &Insn) {
149 // We want to read exactly 4 bytes of data.
150 if (Bytes.size() < 4) {
151 Size = 0;
153 }
154
155 // Encoded as big-endian 32-bit word in the stream.
156 Insn =
157 (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 8) | (Bytes[3] << 0);
158
160}
161
162static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn) {
163 unsigned AluOp = LPAC::ADD;
164 // Fix up for pre and post operations.
165 int PqShift = -1;
166 if (isRMOpcode(Instr.getOpcode()))
167 PqShift = 16;
168 else if (isSPLSOpcode(Instr.getOpcode()))
169 PqShift = 10;
170 else if (isRRMOpcode(Instr.getOpcode())) {
171 PqShift = 16;
172 // Determine RRM ALU op.
173 AluOp = (Insn >> 8) & 0x7;
174 if (AluOp == 7)
175 // Handle JJJJJ
176 // 0b10000 or 0b11000
177 AluOp |= 0x20 | (((Insn >> 3) & 0xf) << 1);
178 }
179
180 if (PqShift != -1) {
181 unsigned PQ = (Insn >> PqShift) & 0x3;
182 switch (PQ) {
183 case 0x0:
184 if (Instr.getOperand(2).isReg()) {
185 Instr.getOperand(2).setReg(Lanai::R0);
186 }
187 if (Instr.getOperand(2).isImm())
188 Instr.getOperand(2).setImm(0);
189 break;
190 case 0x1:
191 AluOp = LPAC::makePostOp(AluOp);
192 break;
193 case 0x2:
194 break;
195 case 0x3:
196 AluOp = LPAC::makePreOp(AluOp);
197 break;
198 }
199 Instr.addOperand(MCOperand::createImm(AluOp));
200 }
201}
202
206 raw_ostream & /*CStream*/) const {
207 uint32_t Insn;
208
209 DecodeStatus Result = readInstruction32(Bytes, Size, Insn);
210
211 if (Result == MCDisassembler::Fail)
213
214 // Call auto-generated decoder function
215 Result =
216 decodeInstruction(DecoderTableLanai32, Instr, Insn, Address, this, STI);
217
218 if (Result != MCDisassembler::Fail) {
219 PostOperandDecodeAdjust(Instr, Insn);
220 Size = 4;
221 return Result;
222 }
223
225}
static bool readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value, bool isBranch, uint64_t InstSize, MCInst &MI, const MCDisassembler *Decoder)
tryAddingSymbolicOperand - trys to add a symbolic operand in place of the immediate Value in the MCIn...
static const uint16_t GPRDecoderTable[]
#define LLVM_ABI
Definition: Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
uint64_t Size
IRTranslator LLVM IR MI
MCDisassembler::DecodeStatus DecodeStatus
static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn)
static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static MCDisassembler * createLanaiDisassembler(const Target &, const MCSubtargetInfo &STI, MCContext &Ctx)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiDisassembler()
static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeBranch(MCInst &MI, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
LanaiDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
MCDisassembler::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.
Context object for machine code objects.
Definition: MCContext.h:83
Superclass for all disassemblers.
bool tryAddingSymbolicOperand(MCInst &Inst, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t OpSize, uint64_t InstSize) const
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.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Target - Wrapper for Target specific information.
LLVM Value Representation.
Definition: Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
static unsigned makePostOp(unsigned AluOp)
Definition: LanaiAluCode.h:66
static unsigned makePreOp(unsigned AluOp)
Definition: LanaiAluCode.h:61
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
static bool isRMOpcode(unsigned Opcode)
Target & getTheLanaiTarget()
static bool isRRMOpcode(unsigned Opcode)
static bool isSPLSOpcode(unsigned Opcode)
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.