LLVM  8.0.1
LanaiDisassembler.cpp
Go to the documentation of this file.
1 //===- LanaiDisassembler.cpp - Disassembler for Lanai -----------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is part of the Lanai Disassembler.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "LanaiDisassembler.h"
15 
16 #include "Lanai.h"
17 #include "LanaiSubtarget.h"
19 #include "llvm/MC/MCInst.h"
23 
24 using namespace llvm;
25 
27 
28 namespace llvm {
30 }
31 
33  const MCSubtargetInfo &STI,
34  MCContext &Ctx) {
35  return new LanaiDisassembler(STI, Ctx);
36 }
37 
39  // Register the disassembler
42 }
43 
45  : MCDisassembler(STI, Ctx) {}
46 
47 // Forward declare because the autogenerated code will reference this.
48 // Definition is further down.
49 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
50  uint64_t Address,
51  const void *Decoder);
52 
53 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
54  uint64_t Address, const void *Decoder);
55 
56 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
57  uint64_t Address, const void *Decoder);
58 
59 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
60  uint64_t Address, const void *Decoder);
61 
62 static DecodeStatus decodeBranch(MCInst &Inst, unsigned Insn, uint64_t Address,
63  const void *Decoder);
64 
65 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
66  uint64_t Address,
67  const void *Decoder);
68 
69 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
70  uint64_t Address, const void *Decoder);
71 
72 #include "LanaiGenDisassemblerTables.inc"
73 
75  uint32_t &Insn) {
76  // We want to read exactly 4 bytes of data.
77  if (Bytes.size() < 4) {
78  Size = 0;
79  return MCDisassembler::Fail;
80  }
81 
82  // Encoded as big-endian 32-bit word in the stream.
83  Insn =
84  (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 8) | (Bytes[3] << 0);
85 
87 }
88 
89 static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn) {
90  unsigned AluOp = LPAC::ADD;
91  // Fix up for pre and post operations.
92  int PqShift = -1;
93  if (isRMOpcode(Instr.getOpcode()))
94  PqShift = 16;
95  else if (isSPLSOpcode(Instr.getOpcode()))
96  PqShift = 10;
97  else if (isRRMOpcode(Instr.getOpcode())) {
98  PqShift = 16;
99  // Determine RRM ALU op.
100  AluOp = (Insn >> 8) & 0x7;
101  if (AluOp == 7)
102  // Handle JJJJJ
103  // 0b10000 or 0b11000
104  AluOp |= 0x20 | (((Insn >> 3) & 0xf) << 1);
105  }
106 
107  if (PqShift != -1) {
108  unsigned PQ = (Insn >> PqShift) & 0x3;
109  switch (PQ) {
110  case 0x0:
111  if (Instr.getOperand(2).isReg()) {
112  Instr.getOperand(2).setReg(Lanai::R0);
113  }
114  if (Instr.getOperand(2).isImm())
115  Instr.getOperand(2).setImm(0);
116  break;
117  case 0x1:
118  AluOp = LPAC::makePostOp(AluOp);
119  break;
120  case 0x2:
121  break;
122  case 0x3:
123  AluOp = LPAC::makePreOp(AluOp);
124  break;
125  }
126  Instr.addOperand(MCOperand::createImm(AluOp));
127  }
128 }
129 
131  MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address,
132  raw_ostream & /*VStream*/, raw_ostream & /*CStream*/) const {
133  uint32_t Insn;
134 
135  DecodeStatus Result = readInstruction32(Bytes, Size, Insn);
136 
137  if (Result == MCDisassembler::Fail)
138  return MCDisassembler::Fail;
139 
140  // Call auto-generated decoder function
141  Result =
142  decodeInstruction(DecoderTableLanai32, Instr, Insn, Address, this, STI);
143 
144  if (Result != MCDisassembler::Fail) {
145  PostOperandDecodeAdjust(Instr, Insn);
146  Size = 4;
147  return Result;
148  }
149 
150  return MCDisassembler::Fail;
151 }
152 
153 static const unsigned GPRDecoderTable[] = {
154  Lanai::R0, Lanai::R1, Lanai::PC, Lanai::R3, Lanai::SP, Lanai::FP,
155  Lanai::R6, Lanai::R7, Lanai::RV, Lanai::R9, Lanai::RR1, Lanai::RR2,
156  Lanai::R12, Lanai::R13, Lanai::R14, Lanai::RCA, Lanai::R16, Lanai::R17,
157  Lanai::R18, Lanai::R19, Lanai::R20, Lanai::R21, Lanai::R22, Lanai::R23,
158  Lanai::R24, Lanai::R25, Lanai::R26, Lanai::R27, Lanai::R28, Lanai::R29,
159  Lanai::R30, Lanai::R31};
160 
162  uint64_t /*Address*/,
163  const void * /*Decoder*/) {
164  if (RegNo > 31)
165  return MCDisassembler::Fail;
166 
167  unsigned Reg = GPRDecoderTable[RegNo];
168  Inst.addOperand(MCOperand::createReg(Reg));
170 }
171 
172 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
173  uint64_t Address, const void *Decoder) {
174  // RI memory values encoded using 23 bits:
175  // 5 bit register, 16 bit constant
176  unsigned Register = (Insn >> 18) & 0x1f;
177  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
178  unsigned Offset = (Insn & 0xffff);
179  Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
180 
182 }
183 
184 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
185  uint64_t Address, const void *Decoder) {
186  // RR memory values encoded using 20 bits:
187  // 5 bit register, 5 bit register, 2 bit PQ, 3 bit ALU operator, 5 bit JJJJJ
188  unsigned Register = (Insn >> 15) & 0x1f;
189  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
190  Register = (Insn >> 10) & 0x1f;
191  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
192 
194 }
195 
196 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
197  uint64_t Address, const void *Decoder) {
198  // RI memory values encoded using 17 bits:
199  // 5 bit register, 10 bit constant
200  unsigned Register = (Insn >> 12) & 0x1f;
201  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
202  unsigned Offset = (Insn & 0x3ff);
203  Inst.addOperand(MCOperand::createImm(SignExtend32<10>(Offset)));
204 
206 }
207 
208 static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
209  uint64_t Address, uint64_t Offset,
210  uint64_t Width, MCInst &MI,
211  const void *Decoder) {
212  const MCDisassembler *Dis = static_cast<const MCDisassembler *>(Decoder);
213  return Dis->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
214  Width);
215 }
216 
217 static DecodeStatus decodeBranch(MCInst &MI, unsigned Insn, uint64_t Address,
218  const void *Decoder) {
219  if (!tryAddingSymbolicOperand(Insn + Address, false, Address, 2, 23, MI,
220  Decoder))
223 }
224 
225 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
226  uint64_t Address, const void *Decoder) {
227  unsigned Offset = (Insn & 0xffff);
228  Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
229 
231 }
232 
233 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
234  uint64_t Address,
235  const void *Decoder) {
236  if (Val >= LPCC::UNKNOWN)
237  return MCDisassembler::Fail;
238  Inst.addOperand(MCOperand::createImm(Val));
240 }
bool isImm() const
Definition: MCInst.h:59
static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
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:58
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:68
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
Context object for machine code objects.
Definition: MCContext.h:63
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:161
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:81
static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn)
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
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:182
Promote Memory to Register
Definition: Mem2Reg.cpp:110
Target - Wrapper for Target specific information.
static unsigned makePreOp(unsigned AluOp)
Definition: LanaiAluCode.h:63
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:47
void setReg(unsigned Reg)
Set the register number.
Definition: MCInst.h:71
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:73
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:186
void LLVMInitializeLanaiDisassembler()
unsigned getOpcode() const
Definition: MCInst.h:174
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123