LLVM  10.0.0svn
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"
20 #include "llvm/MC/MCInst.h"
24 
25 using namespace llvm;
26 
28 
29 namespace llvm {
31 }
32 
34  const MCSubtargetInfo &STI,
35  MCContext &Ctx) {
36  return new LanaiDisassembler(STI, Ctx);
37 }
38 
40  // Register the disassembler
43 }
44 
46  : MCDisassembler(STI, Ctx) {}
47 
48 // Forward declare because the autogenerated code will reference this.
49 // Definition is further down.
50 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
51  uint64_t Address,
52  const void *Decoder);
53 
54 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
55  uint64_t Address, const void *Decoder);
56 
57 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
58  uint64_t Address, const void *Decoder);
59 
60 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
61  uint64_t Address, const void *Decoder);
62 
63 static DecodeStatus decodeBranch(MCInst &Inst, unsigned Insn, uint64_t Address,
64  const void *Decoder);
65 
66 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
67  uint64_t Address,
68  const void *Decoder);
69 
70 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
71  uint64_t Address, const void *Decoder);
72 
73 #include "LanaiGenDisassemblerTables.inc"
74 
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 
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 
132  MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address,
133  raw_ostream & /*VStream*/, raw_ostream & /*CStream*/) const {
134  uint32_t Insn;
135 
136  DecodeStatus Result = readInstruction32(Bytes, Size, Insn);
137 
138  if (Result == MCDisassembler::Fail)
139  return MCDisassembler::Fail;
140 
141  // Call auto-generated decoder function
142  Result =
143  decodeInstruction(DecoderTableLanai32, Instr, Insn, Address, this, STI);
144 
145  if (Result != MCDisassembler::Fail) {
146  PostOperandDecodeAdjust(Instr, Insn);
147  Size = 4;
148  return Result;
149  }
150 
151  return MCDisassembler::Fail;
152 }
153 
154 static const unsigned GPRDecoderTable[] = {
155  Lanai::R0, Lanai::R1, Lanai::PC, Lanai::R3, Lanai::SP, Lanai::FP,
156  Lanai::R6, Lanai::R7, Lanai::RV, Lanai::R9, Lanai::RR1, Lanai::RR2,
157  Lanai::R12, Lanai::R13, Lanai::R14, Lanai::RCA, Lanai::R16, Lanai::R17,
158  Lanai::R18, Lanai::R19, Lanai::R20, Lanai::R21, Lanai::R22, Lanai::R23,
159  Lanai::R24, Lanai::R25, Lanai::R26, Lanai::R27, Lanai::R28, Lanai::R29,
160  Lanai::R30, Lanai::R31};
161 
163  uint64_t /*Address*/,
164  const void * /*Decoder*/) {
165  if (RegNo > 31)
166  return MCDisassembler::Fail;
167 
168  unsigned Reg = GPRDecoderTable[RegNo];
169  Inst.addOperand(MCOperand::createReg(Reg));
171 }
172 
173 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
174  uint64_t Address, const void *Decoder) {
175  // RI memory values encoded using 23 bits:
176  // 5 bit register, 16 bit constant
177  unsigned Register = (Insn >> 18) & 0x1f;
178  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
179  unsigned Offset = (Insn & 0xffff);
180  Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
181 
183 }
184 
185 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
186  uint64_t Address, const void *Decoder) {
187  // RR memory values encoded using 20 bits:
188  // 5 bit register, 5 bit register, 2 bit PQ, 3 bit ALU operator, 5 bit JJJJJ
189  unsigned Register = (Insn >> 15) & 0x1f;
190  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
191  Register = (Insn >> 10) & 0x1f;
192  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
193 
195 }
196 
197 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
198  uint64_t Address, const void *Decoder) {
199  // RI memory values encoded using 17 bits:
200  // 5 bit register, 10 bit constant
201  unsigned Register = (Insn >> 12) & 0x1f;
202  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
203  unsigned Offset = (Insn & 0x3ff);
204  Inst.addOperand(MCOperand::createImm(SignExtend32<10>(Offset)));
205 
207 }
208 
209 static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
210  uint64_t Address, uint64_t Offset,
211  uint64_t Width, MCInst &MI,
212  const void *Decoder) {
213  const MCDisassembler *Dis = static_cast<const MCDisassembler *>(Decoder);
214  return Dis->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
215  Width);
216 }
217 
218 static DecodeStatus decodeBranch(MCInst &MI, unsigned Insn, uint64_t Address,
219  const void *Decoder) {
220  if (!tryAddingSymbolicOperand(Insn + Address, false, Address, 2, 23, MI,
221  Decoder))
224 }
225 
226 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
227  uint64_t Address, const void *Decoder) {
228  unsigned Offset = (Insn & 0xffff);
229  Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
230 
232 }
233 
234 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
235  uint64_t Address,
236  const void *Decoder) {
237  if (Val >= LPCC::UNKNOWN)
238  return MCDisassembler::Fail;
239  Inst.addOperand(MCOperand::createImm(Val));
241 }
bool isImm() const
Definition: MCInst.h:58
static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Target & getTheLanaiTarget()
static bool isRRMOpcode(unsigned Opcode)
DecodeStatus
Ternary decode status.
Superclass for all disassemblers.
bool tryAddingSymbolicOperand(MCInst &Inst, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t InstSize) const
unsigned Reg
bool isReg() const
Definition: MCInst.h:57
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
static unsigned makePostOp(unsigned AluOp)
Definition: LanaiAluCode.h:67
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:115
Context object for machine code objects.
Definition: MCContext.h:64
const MCSubtargetInfo & STI
int decodeInstruction(InternalInstruction *insn, byteReader_t reader, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg, uint64_t startLoc, DisassemblerMode mode)
Decode one instruction and store the decoding results in a buffer provided by the consumer...
static DecodeStatus decodeBranch(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
MCDisassembler::DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &VStream, raw_ostream &CStream) const override
Returns the disassembly of a single instruction.
static const unsigned GPRDecoderTable[]
static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder)
void setImm(int64_t Val)
Definition: MCInst.h:80
static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn)
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t &Size, uint32_t &Insn)
MCDisassembler::DecodeStatus DecodeStatus
LanaiDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
#define R6(n)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
Target - Wrapper for Target specific information.
static unsigned makePreOp(unsigned AluOp)
Definition: LanaiAluCode.h:62
static bool isRMOpcode(unsigned Opcode)
static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Generic base class for all target subtargets.
uint32_t Size
Definition: Profile.cpp:46
void setReg(unsigned Reg)
Set the register number.
Definition: MCInst.h:70
static MCDisassembler * createLanaiDisassembler(const Target &, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
static bool isSPLSOpcode(unsigned Opcode)
LLVM Value Representation.
Definition: Value.h:72
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
void LLVMInitializeLanaiDisassembler()
unsigned getOpcode() const
Definition: MCInst.h:171
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:122
Wrapper class representing virtual and physical registers.
Definition: Register.h:18