]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARC / Disassembler / ARCDisassembler.cpp
1 //===- ARCDisassembler.cpp - Disassembler for ARC ---------------*- 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 /// \file
11 /// This file is part of the ARC Disassembler.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "ARC.h"
16 #include "ARCRegisterInfo.h"
17 #include "MCTargetDesc/ARCMCTargetDesc.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
20 #include "llvm/MC/MCFixedLenDisassembler.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/Support/TargetRegistry.h"
25
26 using namespace llvm;
27
28 #define DEBUG_TYPE "arc-disassembler"
29
30 using DecodeStatus = MCDisassembler::DecodeStatus;
31
32 namespace {
33
34 /// A disassembler class for ARC.
35 class ARCDisassembler : public MCDisassembler {
36 public:
37   std::unique_ptr<MCInstrInfo const> const MCII;
38
39   ARCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
40                   MCInstrInfo const *MCII)
41       : MCDisassembler(STI, Ctx), MCII(MCII) {}
42
43   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
44                               ArrayRef<uint8_t> Bytes, uint64_t Address,
45                               raw_ostream &VStream,
46                               raw_ostream &CStream) const override;
47 };
48
49 } // end anonymous namespace
50
51 static bool readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
52                               uint64_t &Size, uint32_t &Insn) {
53   Size = 4;
54   // Read 2 16-bit values, but swap hi/lo parts.
55   Insn =
56       (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
57   return true;
58 }
59
60 static bool readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address,
61                               uint64_t &Size, uint64_t &Insn) {
62   Size = 8;
63   Insn = ((uint64_t)Bytes[0] << 16) | ((uint64_t)Bytes[1] << 24) |
64          ((uint64_t)Bytes[2] << 0) | ((uint64_t)Bytes[3] << 8) |
65          ((uint64_t)Bytes[4] << 48) | ((uint64_t)Bytes[5] << 56) |
66          ((uint64_t)Bytes[6] << 32) | ((uint64_t)Bytes[7] << 40);
67   return true;
68 }
69
70 static bool readInstruction48(ArrayRef<uint8_t> Bytes, uint64_t Address,
71                               uint64_t &Size, uint64_t &Insn) {
72   Size = 6;
73   Insn = ((uint64_t)Bytes[0] << 0) | ((uint64_t)Bytes[1] << 8) |
74          ((uint64_t)Bytes[2] << 32) | ((uint64_t)Bytes[3] << 40) |
75          ((uint64_t)Bytes[4] << 16) | ((uint64_t)Bytes[5] << 24);
76   return true;
77 }
78
79 static bool readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
80                               uint64_t &Size, uint32_t &Insn) {
81   Size = 2;
82   Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
83   return true;
84 }
85
86 template <unsigned B>
87 static DecodeStatus DecodeSignedOperand(MCInst &Inst, unsigned InsnS,
88                                         uint64_t Address = 0,
89                                         const void *Decoder = nullptr);
90
91 template <unsigned B>
92 static DecodeStatus DecodeFromCyclicRange(MCInst &Inst, unsigned InsnS,
93                                         uint64_t Address = 0,
94                                         const void *Decoder = nullptr);
95
96 template <unsigned B>
97 static DecodeStatus DecodeBranchTargetS(MCInst &Inst, unsigned InsnS,
98                                         uint64_t Address, const void *Decoder);
99
100 static DecodeStatus DecodeMEMrs9(MCInst &, unsigned, uint64_t, const void *);
101
102 static DecodeStatus DecodeLdLImmInstruction(MCInst &, uint64_t, uint64_t,
103                                             const void *);
104
105 static DecodeStatus DecodeStLImmInstruction(MCInst &, uint64_t, uint64_t,
106                                             const void *);
107
108 static DecodeStatus DecodeLdRLImmInstruction(MCInst &, uint64_t, uint64_t,
109                                              const void *);
110
111 static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t, uint64_t,
112                                               const void *);
113
114 static const uint16_t GPR32DecoderTable[] = {
115     ARC::R0,  ARC::R1,    ARC::R2,  ARC::R3,   ARC::R4,  ARC::R5,  ARC::R6,
116     ARC::R7,  ARC::R8,    ARC::R9,  ARC::R10,  ARC::R11, ARC::R12, ARC::R13,
117     ARC::R14, ARC::R15,   ARC::R16, ARC::R17,  ARC::R18, ARC::R19, ARC::R20,
118     ARC::R21, ARC::R22,   ARC::R23, ARC::R24,  ARC::R25, ARC::GP,  ARC::FP,
119     ARC::SP,  ARC::ILINK, ARC::R30, ARC::BLINK};
120
121 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
122                                              uint64_t Address,
123                                              const void *Decoder) {
124   if (RegNo >= 32) {
125     LLVM_DEBUG(dbgs() << "Not a GPR32 register.");
126     return MCDisassembler::Fail;
127   }
128
129   unsigned Reg = GPR32DecoderTable[RegNo];
130   Inst.addOperand(MCOperand::createReg(Reg));
131   return MCDisassembler::Success;
132 }
133
134 static DecodeStatus DecodeGBR32ShortRegister(MCInst &Inst, unsigned RegNo,
135                                                uint64_t Address,
136                                                const void *Decoder) {
137   // Enumerates registers from ranges [r0-r3],[r12-r15].
138   if (RegNo > 3)
139     RegNo += 8; // 4 for r12, etc...
140
141   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
142 }
143
144 #include "ARCGenDisassemblerTables.inc"
145
146 static unsigned decodeCField(unsigned Insn) {
147   return fieldFromInstruction(Insn, 6, 6);
148 }
149
150 static unsigned decodeBField(unsigned Insn) {
151   return (fieldFromInstruction(Insn, 12, 3) << 3) |
152          fieldFromInstruction(Insn, 24, 3);
153 }
154
155 static unsigned decodeAField(unsigned Insn) {
156   return fieldFromInstruction(Insn, 0, 6);
157 }
158
159 static DecodeStatus DecodeMEMrs9(MCInst &Inst, unsigned Insn, uint64_t Address,
160                                  const void *Dec) {
161   // We have the 9-bit immediate in the low bits, 6-bit register in high bits.
162   unsigned S9 = Insn & 0x1ff;
163   unsigned R = (Insn & (0x7fff & ~0x1ff)) >> 9;
164   DecodeGPR32RegisterClass(Inst, R, Address, Dec);
165   Inst.addOperand(MCOperand::createImm(SignExtend32<9>(S9)));
166   return MCDisassembler::Success;
167 }
168
169 static bool DecodeSymbolicOperand(MCInst &Inst, uint64_t Address,
170                                   uint64_t Value, const void *Decoder) {
171   static const uint64_t atLeast = 2;
172   // TODO: Try to force emitter to use MCDisassembler* instead of void*.
173   auto Disassembler = static_cast<const MCDisassembler *>(Decoder);
174   return (nullptr != Disassembler &&
175           Disassembler->tryAddingSymbolicOperand(Inst, Value, Address, true, 0,
176                                                  atLeast));
177 }
178
179 static void DecodeSymbolicOperandOff(MCInst &Inst, uint64_t Address,
180                                      uint64_t Offset, const void *Decoder) {
181   uint64_t nextAddress = Address + Offset;
182
183   if (!DecodeSymbolicOperand(Inst, Address, nextAddress, Decoder))
184     Inst.addOperand(MCOperand::createImm(Offset));
185 }
186
187 template <unsigned B>
188 static DecodeStatus DecodeBranchTargetS(MCInst &Inst, unsigned InsnS,
189                                         uint64_t Address, const void *Decoder) {
190
191   static_assert(B > 0, "field is empty");
192   DecodeSymbolicOperandOff(Inst, Address, SignExtend32<B>(InsnS), Decoder);
193   return MCDisassembler::Success;
194 }
195
196 template <unsigned B>
197 static DecodeStatus DecodeSignedOperand(MCInst &Inst, unsigned InsnS,
198                                         uint64_t /*Address*/,
199                                         const void * /*Decoder*/) {
200
201   static_assert(B > 0, "field is empty");
202   Inst.addOperand(MCOperand::createImm(
203       SignExtend32<B>(maskTrailingOnes<decltype(InsnS)>(B) & InsnS)));
204   return MCDisassembler::Success;
205 }
206
207 template <unsigned B>
208 static DecodeStatus DecodeFromCyclicRange(MCInst &Inst, unsigned InsnS,
209                                           uint64_t /*Address*/,
210                                           const void * /*Decoder*/) {
211
212   static_assert(B > 0, "field is empty");
213   const unsigned max = (1u << B) - 1;
214   Inst.addOperand(
215       MCOperand::createImm(InsnS < max ? static_cast<int>(InsnS) : -1));
216   return MCDisassembler::Success;
217 }
218
219 static DecodeStatus DecodeStLImmInstruction(MCInst &Inst, uint64_t Insn,
220                                             uint64_t Address,
221                                             const void *Decoder) {
222   unsigned SrcC, DstB, LImm;
223   DstB = decodeBField(Insn);
224   if (DstB != 62) {
225     LLVM_DEBUG(dbgs() << "Decoding StLImm found non-limm register.");
226     return MCDisassembler::Fail;
227   }
228   SrcC = decodeCField(Insn);
229   DecodeGPR32RegisterClass(Inst, SrcC, Address, Decoder);
230   LImm = (Insn >> 32);
231   Inst.addOperand(MCOperand::createImm(LImm));
232   Inst.addOperand(MCOperand::createImm(0));
233   return MCDisassembler::Success;
234 }
235
236 static DecodeStatus DecodeLdLImmInstruction(MCInst &Inst, uint64_t Insn,
237                                             uint64_t Address,
238                                             const void *Decoder) {
239   unsigned DstA, SrcB, LImm;
240   LLVM_DEBUG(dbgs() << "Decoding LdLImm:\n");
241   SrcB = decodeBField(Insn);
242   if (SrcB != 62) {
243     LLVM_DEBUG(dbgs() << "Decoding LdLImm found non-limm register.");
244     return MCDisassembler::Fail;
245   }
246   DstA = decodeAField(Insn);
247   DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder);
248   LImm = (Insn >> 32);
249   Inst.addOperand(MCOperand::createImm(LImm));
250   Inst.addOperand(MCOperand::createImm(0));
251   return MCDisassembler::Success;
252 }
253
254 static DecodeStatus DecodeLdRLImmInstruction(MCInst &Inst, uint64_t Insn,
255                                              uint64_t Address,
256                                              const void *Decoder) {
257   unsigned DstA, SrcB;
258   LLVM_DEBUG(dbgs() << "Decoding LdRLimm\n");
259   DstA = decodeAField(Insn);
260   DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder);
261   SrcB = decodeBField(Insn);
262   DecodeGPR32RegisterClass(Inst, SrcB, Address, Decoder);
263   if (decodeCField(Insn) != 62) {
264     LLVM_DEBUG(dbgs() << "Decoding LdRLimm found non-limm register.");
265     return MCDisassembler::Fail;
266   }
267   Inst.addOperand(MCOperand::createImm((uint32_t)(Insn >> 32)));
268   return MCDisassembler::Success;
269 }
270
271 static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t Insn,
272                                               uint64_t Address,
273                                               const void *Decoder) {
274   LLVM_DEBUG(dbgs() << "Decoding MOV_S h-register\n");
275   using Field = decltype(Insn);
276   Field h = fieldFromInstruction(Insn, 5, 3) |
277             (fieldFromInstruction(Insn, 0, 2) << 3);
278   Field g = fieldFromInstruction(Insn, 8, 3) |
279             (fieldFromInstruction(Insn, 3, 2) << 3);
280
281   auto DecodeRegisterOrImm = [&Inst, Address, Decoder](Field RegNum,
282                                                        Field Value) {
283     if (30 == RegNum) {
284       Inst.addOperand(MCOperand::createImm(Value));
285       return MCDisassembler::Success;
286     }
287
288     return DecodeGPR32RegisterClass(Inst, RegNum, Address, Decoder);
289   };
290
291   if (MCDisassembler::Success != DecodeRegisterOrImm(g, 0))
292     return MCDisassembler::Fail;
293
294   return DecodeRegisterOrImm(h, Insn >> 16u);
295 }
296
297 DecodeStatus ARCDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
298                                              ArrayRef<uint8_t> Bytes,
299                                              uint64_t Address,
300                                              raw_ostream &vStream,
301                                              raw_ostream &cStream) const {
302   MCDisassembler::DecodeStatus Result;
303   if (Bytes.size() < 2) {
304     Size = 0;
305     return Fail;
306   }
307   uint8_t DecodeByte = (Bytes[1] & 0xF7) >> 3;
308   // 0x00 -> 0x07 are 32-bit instructions.
309   // 0x08 -> 0x1F are 16-bit instructions.
310   if (DecodeByte < 0x08) {
311     // 32-bit instruction.
312     if (Bytes.size() < 4) {
313       // Did we decode garbage?
314       Size = 0;
315       return Fail;
316     }
317     if (Bytes.size() >= 8) {
318       // Attempt to decode 64-bit instruction.
319       uint64_t Insn64;
320       if (!readInstruction64(Bytes, Address, Size, Insn64))
321         return Fail;
322       Result =
323           decodeInstruction(DecoderTable64, Instr, Insn64, Address, this, STI);
324       if (Success == Result) {
325         LLVM_DEBUG(dbgs() << "Successfully decoded 64-bit instruction.");
326         return Result;
327       }
328       LLVM_DEBUG(dbgs() << "Not a 64-bit instruction, falling back to 32-bit.");
329     }
330     uint32_t Insn32;
331     if (!readInstruction32(Bytes, Address, Size, Insn32)) {
332       return Fail;
333     }
334     // Calling the auto-generated decoder function.
335     return decodeInstruction(DecoderTable32, Instr, Insn32, Address, this, STI);
336   } else {
337     if (Bytes.size() >= 6) {
338       // Attempt to treat as instr. with limm data.
339       uint64_t Insn48;
340       if (!readInstruction48(Bytes, Address, Size, Insn48))
341         return Fail;
342       Result =
343           decodeInstruction(DecoderTable48, Instr, Insn48, Address, this, STI);
344       if (Success == Result) {
345         LLVM_DEBUG(
346             dbgs() << "Successfully decoded 16-bit instruction with limm.");
347         return Result;
348       }
349       LLVM_DEBUG(
350           dbgs() << "Not a 16-bit instruction with limm, try without it.");
351     }
352
353     uint32_t Insn16;
354     if (!readInstruction16(Bytes, Address, Size, Insn16))
355       return Fail;
356
357     // Calling the auto-generated decoder function.
358     return decodeInstruction(DecoderTable16, Instr, Insn16, Address, this, STI);
359   }
360 }
361
362 static MCDisassembler *createARCDisassembler(const Target &T,
363                                              const MCSubtargetInfo &STI,
364                                              MCContext &Ctx) {
365   return new ARCDisassembler(STI, Ctx, T.createMCInstrInfo());
366 }
367
368 extern "C" void LLVMInitializeARCDisassembler() {
369   // Register the disassembler.
370   TargetRegistry::RegisterMCDisassembler(getTheARCTarget(),
371                                          createARCDisassembler);
372 }