[AVR] Support 16-bit LDS/STS on AVRTiny.
[llvm-project.git] / llvm / lib / Target / AVR / Disassembler / AVRDisassembler.cpp
blobd8734596148d5953b4a7c3e393e53a40481c9318
1 //===- AVRDisassembler.cpp - Disassembler for AVR ---------------*- 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 AVR Disassembler.
11 //===----------------------------------------------------------------------===//
13 #include "AVR.h"
14 #include "AVRRegisterInfo.h"
15 #include "AVRSubtarget.h"
16 #include "MCTargetDesc/AVRMCTargetDesc.h"
17 #include "TargetInfo/AVRTargetInfo.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCDecoderOps.h"
22 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/TargetRegistry.h"
26 using namespace llvm;
28 #define DEBUG_TYPE "avr-disassembler"
30 typedef MCDisassembler::DecodeStatus DecodeStatus;
32 namespace {
34 /// A disassembler class for AVR.
35 class AVRDisassembler : public MCDisassembler {
36 public:
37 AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
38 : MCDisassembler(STI, Ctx) {}
39 virtual ~AVRDisassembler() = default;
41 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
42 ArrayRef<uint8_t> Bytes, uint64_t Address,
43 raw_ostream &CStream) const override;
45 } // namespace
47 static MCDisassembler *createAVRDisassembler(const Target &T,
48 const MCSubtargetInfo &STI,
49 MCContext &Ctx) {
50 return new AVRDisassembler(STI, Ctx);
53 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() {
54 // Register the disassembler.
55 TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(),
56 createAVRDisassembler);
59 static const uint16_t GPRDecoderTable[] = {
60 AVR::R0, AVR::R1, AVR::R2, AVR::R3, AVR::R4, AVR::R5, AVR::R6,
61 AVR::R7, AVR::R8, AVR::R9, AVR::R10, AVR::R11, AVR::R12, AVR::R13,
62 AVR::R14, AVR::R15, AVR::R16, AVR::R17, AVR::R18, AVR::R19, AVR::R20,
63 AVR::R21, AVR::R22, AVR::R23, AVR::R24, AVR::R25, AVR::R26, AVR::R27,
64 AVR::R28, AVR::R29, AVR::R30, AVR::R31,
67 static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo,
68 uint64_t Address,
69 const MCDisassembler *Decoder) {
70 if (RegNo > 31)
71 return MCDisassembler::Fail;
73 unsigned Register = GPRDecoderTable[RegNo];
74 Inst.addOperand(MCOperand::createReg(Register));
75 return MCDisassembler::Success;
78 static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo,
79 uint64_t Address,
80 const MCDisassembler *Decoder) {
81 if (RegNo > 15)
82 return MCDisassembler::Fail;
84 unsigned Register = GPRDecoderTable[RegNo + 16];
85 Inst.addOperand(MCOperand::createReg(Register));
86 return MCDisassembler::Success;
89 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address,
90 const MCDisassembler *Decoder);
92 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address,
93 const MCDisassembler *Decoder);
95 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address,
96 const MCDisassembler *Decoder);
98 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn,
99 uint64_t Address,
100 const MCDisassembler *Decoder);
102 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address,
103 const MCDisassembler *Decoder);
105 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address,
106 const MCDisassembler *Decoder);
108 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
109 uint64_t Address,
110 const MCDisassembler *Decoder);
112 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
113 uint64_t Address,
114 const MCDisassembler *Decoder);
116 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address,
117 const MCDisassembler *Decoder);
119 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
120 uint64_t Address,
121 const MCDisassembler *Decoder);
123 static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
124 const MCDisassembler *Decoder);
126 static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
127 uint64_t Address,
128 const MCDisassembler *Decoder);
130 #include "AVRGenDisassemblerTables.inc"
132 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address,
133 const MCDisassembler *Decoder) {
134 unsigned addr = 0;
135 addr |= fieldFromInstruction(Insn, 0, 4);
136 addr |= fieldFromInstruction(Insn, 9, 2) << 4;
137 unsigned reg = fieldFromInstruction(Insn, 4, 5);
138 Inst.addOperand(MCOperand::createImm(addr));
139 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) ==
140 MCDisassembler::Fail)
141 return MCDisassembler::Fail;
142 return MCDisassembler::Success;
145 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address,
146 const MCDisassembler *Decoder) {
147 unsigned addr = 0;
148 addr |= fieldFromInstruction(Insn, 0, 4);
149 addr |= fieldFromInstruction(Insn, 9, 2) << 4;
150 unsigned reg = fieldFromInstruction(Insn, 4, 5);
151 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) ==
152 MCDisassembler::Fail)
153 return MCDisassembler::Fail;
154 Inst.addOperand(MCOperand::createImm(addr));
155 return MCDisassembler::Success;
158 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address,
159 const MCDisassembler *Decoder) {
160 unsigned addr = fieldFromInstruction(Insn, 3, 5);
161 unsigned b = fieldFromInstruction(Insn, 0, 3);
162 Inst.addOperand(MCOperand::createImm(addr));
163 Inst.addOperand(MCOperand::createImm(b));
164 return MCDisassembler::Success;
167 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field,
168 uint64_t Address,
169 const MCDisassembler *Decoder) {
170 // Call targets need to be shifted left by one so this needs a custom
171 // decoder.
172 Inst.addOperand(MCOperand::createImm(Field << 1));
173 return MCDisassembler::Success;
176 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address,
177 const MCDisassembler *Decoder) {
178 unsigned d = fieldFromInstruction(Insn, 4, 5);
179 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
180 MCDisassembler::Fail)
181 return MCDisassembler::Fail;
182 return MCDisassembler::Success;
185 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address,
186 const MCDisassembler *Decoder) {
187 if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail)
188 return MCDisassembler::Fail;
189 Inst.addOperand(MCOperand::createReg(AVR::R31R30));
190 return MCDisassembler::Success;
193 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
194 uint64_t Address,
195 const MCDisassembler *Decoder) {
196 unsigned d = fieldFromInstruction(Insn, 4, 3) + 16;
197 unsigned r = fieldFromInstruction(Insn, 0, 3) + 16;
198 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
199 MCDisassembler::Fail)
200 return MCDisassembler::Fail;
201 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
202 MCDisassembler::Fail)
203 return MCDisassembler::Fail;
204 return MCDisassembler::Success;
207 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
208 uint64_t Address,
209 const MCDisassembler *Decoder) {
210 unsigned r = fieldFromInstruction(Insn, 4, 4) * 2;
211 unsigned d = fieldFromInstruction(Insn, 0, 4) * 2;
212 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
213 MCDisassembler::Fail)
214 return MCDisassembler::Fail;
215 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
216 MCDisassembler::Fail)
217 return MCDisassembler::Fail;
218 return MCDisassembler::Success;
221 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address,
222 const MCDisassembler *Decoder) {
223 unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25
224 unsigned k = 0;
225 k |= fieldFromInstruction(Insn, 0, 4);
226 k |= fieldFromInstruction(Insn, 6, 2) << 4;
227 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
228 MCDisassembler::Fail)
229 return MCDisassembler::Fail;
230 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
231 MCDisassembler::Fail)
232 return MCDisassembler::Fail;
233 Inst.addOperand(MCOperand::createImm(k));
234 return MCDisassembler::Success;
237 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
238 uint64_t Address,
239 const MCDisassembler *Decoder) {
240 unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16;
241 unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16;
242 if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) ==
243 MCDisassembler::Fail)
244 return MCDisassembler::Fail;
245 if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) ==
246 MCDisassembler::Fail)
247 return MCDisassembler::Fail;
248 return MCDisassembler::Success;
251 static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
252 const MCDisassembler *Decoder) {
253 // As in the EncoderMethod `AVRMCCodeEmitter::encodeMemri`, the memory
254 // address is encoded into 7-bit, in which bits 0-5 are the immediate offset,
255 // and the bit-6 is the pointer register bit (Z=0, Y=1).
256 if (Insn > 127)
257 return MCDisassembler::Fail;
259 // Append the base register operand.
260 Inst.addOperand(
261 MCOperand::createReg((Insn & 0x40) ? AVR::R29R28 : AVR::R31R30));
262 // Append the immediate offset operand.
263 Inst.addOperand(MCOperand::createImm(Insn & 0x3f));
265 return MCDisassembler::Success;
268 static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
269 uint64_t Address,
270 const MCDisassembler *Decoder) {
271 // Get the register will be loaded or stored.
272 unsigned RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f];
274 // Decode LDD/STD with offset less than 8.
275 if ((Insn & 0xf000) == 0x8000) {
276 unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30;
277 unsigned Offset = Insn & 7; // We need not consider offset > 7.
278 if ((Insn & 0x200) == 0) { // Decode LDD.
279 Inst.setOpcode(AVR::LDDRdPtrQ);
280 Inst.addOperand(MCOperand::createReg(RegVal));
281 Inst.addOperand(MCOperand::createReg(RegBase));
282 Inst.addOperand(MCOperand::createImm(Offset));
283 } else { // Decode STD.
284 Inst.setOpcode(AVR::STDPtrQRr);
285 Inst.addOperand(MCOperand::createReg(RegBase));
286 Inst.addOperand(MCOperand::createImm(Offset));
287 Inst.addOperand(MCOperand::createReg(RegVal));
289 return MCDisassembler::Success;
292 // Decode the following 14 instructions. Bit 9 indicates load(0) or store(1),
293 // bits 8~4 indicate the value register, bits 3-2 indicate the base address
294 // register (11-X, 10-Y, 00-Z), bits 1~0 indicate the mode (00-basic,
295 // 01-postinc, 10-predec).
296 // ST X, Rr : 1001 001r rrrr 1100
297 // ST X+, Rr : 1001 001r rrrr 1101
298 // ST -X, Rr : 1001 001r rrrr 1110
299 // ST Y+, Rr : 1001 001r rrrr 1001
300 // ST -Y, Rr : 1001 001r rrrr 1010
301 // ST Z+, Rr : 1001 001r rrrr 0001
302 // ST -Z, Rr : 1001 001r rrrr 0010
303 // LD Rd, X : 1001 000d dddd 1100
304 // LD Rd, X+ : 1001 000d dddd 1101
305 // LD Rd, -X : 1001 000d dddd 1110
306 // LD Rd, Y+ : 1001 000d dddd 1001
307 // LD Rd, -Y : 1001 000d dddd 1010
308 // LD Rd, Z+ : 1001 000d dddd 0001
309 // LD Rd, -Z : 1001 000d dddd 0010
310 if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0)
311 return MCDisassembler::Fail;
313 // Get the base address register.
314 unsigned RegBase;
315 switch (Insn & 0xc) {
316 case 0xc:
317 RegBase = AVR::R27R26;
318 break;
319 case 0x8:
320 RegBase = AVR::R29R28;
321 break;
322 case 0x0:
323 RegBase = AVR::R31R30;
324 break;
325 default:
326 return MCDisassembler::Fail;
329 // Set the opcode.
330 switch (Insn & 0x203) {
331 case 0x200:
332 Inst.setOpcode(AVR::STPtrRr);
333 Inst.addOperand(MCOperand::createReg(RegBase));
334 Inst.addOperand(MCOperand::createReg(RegVal));
335 return MCDisassembler::Success;
336 case 0x201:
337 Inst.setOpcode(AVR::STPtrPiRr);
338 break;
339 case 0x202:
340 Inst.setOpcode(AVR::STPtrPdRr);
341 break;
342 case 0:
343 Inst.setOpcode(AVR::LDRdPtr);
344 Inst.addOperand(MCOperand::createReg(RegVal));
345 Inst.addOperand(MCOperand::createReg(RegBase));
346 return MCDisassembler::Success;
347 case 1:
348 Inst.setOpcode(AVR::LDRdPtrPi);
349 break;
350 case 2:
351 Inst.setOpcode(AVR::LDRdPtrPd);
352 break;
353 default:
354 return MCDisassembler::Fail;
357 // Build postinc/predec machine instructions.
358 if ((Insn & 0x200) == 0) { // This is a load instruction.
359 Inst.addOperand(MCOperand::createReg(RegVal));
360 Inst.addOperand(MCOperand::createReg(RegBase));
361 Inst.addOperand(MCOperand::createReg(RegBase));
362 } else { // This is a store instruction.
363 Inst.addOperand(MCOperand::createReg(RegBase));
364 Inst.addOperand(MCOperand::createReg(RegBase));
365 Inst.addOperand(MCOperand::createReg(RegVal));
366 // STPtrPiRr and STPtrPdRr have an extra immediate operand.
367 Inst.addOperand(MCOperand::createImm(1));
370 return MCDisassembler::Success;
373 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
374 uint64_t &Size, uint32_t &Insn) {
375 if (Bytes.size() < 2) {
376 Size = 0;
377 return MCDisassembler::Fail;
380 Size = 2;
381 Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
383 return MCDisassembler::Success;
386 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
387 uint64_t &Size, uint32_t &Insn) {
389 if (Bytes.size() < 4) {
390 Size = 0;
391 return MCDisassembler::Fail;
394 Size = 4;
395 Insn =
396 (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
398 return MCDisassembler::Success;
401 static const uint8_t *getDecoderTable(uint64_t Size) {
403 switch (Size) {
404 case 2:
405 return DecoderTable16;
406 case 4:
407 return DecoderTable32;
408 default:
409 llvm_unreachable("instructions must be 16 or 32-bits");
413 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
414 ArrayRef<uint8_t> Bytes,
415 uint64_t Address,
416 raw_ostream &CStream) const {
417 uint32_t Insn;
419 DecodeStatus Result;
421 // Try decode a 16-bit instruction.
423 Result = readInstruction16(Bytes, Address, Size, Insn);
425 if (Result == MCDisassembler::Fail)
426 return MCDisassembler::Fail;
428 // Try to decode AVRTiny instructions.
429 if (STI.getFeatureBits()[AVR::FeatureTinyEncoding]) {
430 Result = decodeInstruction(DecoderTableAVRTiny16, Instr, Insn, Address,
431 this, STI);
432 if (Result != MCDisassembler::Fail)
433 return Result;
436 // Try to auto-decode a 16-bit instruction.
437 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
438 this, STI);
439 if (Result != MCDisassembler::Fail)
440 return Result;
442 // Try to decode to a load/store instruction. ST/LD need a specified
443 // DecoderMethod, as they already have a specified PostEncoderMethod.
444 Result = decodeLoadStore(Instr, Insn, Address, this);
445 if (Result != MCDisassembler::Fail)
446 return Result;
449 // Try decode a 32-bit instruction.
451 Result = readInstruction32(Bytes, Address, Size, Insn);
453 if (Result == MCDisassembler::Fail)
454 return MCDisassembler::Fail;
456 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
457 this, STI);
459 if (Result != MCDisassembler::Fail) {
460 return Result;
463 return MCDisassembler::Fail;
467 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
468 const MCDisassembler *Decoder);