Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
35293 views
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.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "AVR.h"
14
#include "AVRRegisterInfo.h"
15
#include "AVRSubtarget.h"
16
#include "MCTargetDesc/AVRMCTargetDesc.h"
17
#include "TargetInfo/AVRTargetInfo.h"
18
19
#include "llvm/ADT/DenseMap.h"
20
#include "llvm/ADT/STLExtras.h"
21
22
#include "llvm/MC/MCAsmInfo.h"
23
#include "llvm/MC/MCContext.h"
24
#include "llvm/MC/MCDecoderOps.h"
25
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
26
#include "llvm/MC/MCInst.h"
27
#include "llvm/MC/TargetRegistry.h"
28
29
using namespace llvm;
30
31
#define DEBUG_TYPE "avr-disassembler"
32
33
typedef MCDisassembler::DecodeStatus DecodeStatus;
34
35
namespace {
36
37
/// A disassembler class for AVR.
38
class AVRDisassembler : public MCDisassembler {
39
public:
40
AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
41
: MCDisassembler(STI, Ctx) {}
42
virtual ~AVRDisassembler() = default;
43
44
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
45
ArrayRef<uint8_t> Bytes, uint64_t Address,
46
raw_ostream &CStream) const override;
47
};
48
} // namespace
49
50
static MCDisassembler *createAVRDisassembler(const Target &T,
51
const MCSubtargetInfo &STI,
52
MCContext &Ctx) {
53
return new AVRDisassembler(STI, Ctx);
54
}
55
56
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() {
57
// Register the disassembler.
58
TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(),
59
createAVRDisassembler);
60
}
61
62
static const uint16_t GPRDecoderTable[] = {
63
AVR::R0, AVR::R1, AVR::R2, AVR::R3, AVR::R4, AVR::R5, AVR::R6,
64
AVR::R7, AVR::R8, AVR::R9, AVR::R10, AVR::R11, AVR::R12, AVR::R13,
65
AVR::R14, AVR::R15, AVR::R16, AVR::R17, AVR::R18, AVR::R19, AVR::R20,
66
AVR::R21, AVR::R22, AVR::R23, AVR::R24, AVR::R25, AVR::R26, AVR::R27,
67
AVR::R28, AVR::R29, AVR::R30, AVR::R31,
68
};
69
70
static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo,
71
uint64_t Address,
72
const MCDisassembler *Decoder) {
73
if (RegNo > 31)
74
return MCDisassembler::Fail;
75
76
unsigned Register = GPRDecoderTable[RegNo];
77
Inst.addOperand(MCOperand::createReg(Register));
78
return MCDisassembler::Success;
79
}
80
81
static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo,
82
uint64_t Address,
83
const MCDisassembler *Decoder) {
84
if (RegNo > 15)
85
return MCDisassembler::Fail;
86
87
unsigned Register = GPRDecoderTable[RegNo + 16];
88
Inst.addOperand(MCOperand::createReg(Register));
89
return MCDisassembler::Success;
90
}
91
92
static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address,
93
const MCDisassembler *Decoder);
94
95
static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address,
96
const MCDisassembler *Decoder);
97
98
static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address,
99
const MCDisassembler *Decoder);
100
101
static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn,
102
uint64_t Address,
103
const MCDisassembler *Decoder);
104
105
static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address,
106
const MCDisassembler *Decoder);
107
108
static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address,
109
const MCDisassembler *Decoder);
110
111
static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
112
uint64_t Address,
113
const MCDisassembler *Decoder);
114
115
static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
116
uint64_t Address,
117
const MCDisassembler *Decoder);
118
119
static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address,
120
const MCDisassembler *Decoder);
121
122
static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
123
uint64_t Address,
124
const MCDisassembler *Decoder);
125
126
static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
127
const MCDisassembler *Decoder);
128
129
static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address,
130
const MCDisassembler *Decoder);
131
132
static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn,
133
uint64_t Address,
134
const MCDisassembler *Decoder);
135
136
static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
137
uint64_t Address,
138
const MCDisassembler *Decoder);
139
140
#include "AVRGenDisassemblerTables.inc"
141
142
static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address,
143
const MCDisassembler *Decoder) {
144
unsigned addr = 0;
145
addr |= fieldFromInstruction(Insn, 0, 4);
146
addr |= fieldFromInstruction(Insn, 9, 2) << 4;
147
unsigned reg = fieldFromInstruction(Insn, 4, 5);
148
Inst.addOperand(MCOperand::createImm(addr));
149
if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) ==
150
MCDisassembler::Fail)
151
return MCDisassembler::Fail;
152
return MCDisassembler::Success;
153
}
154
155
static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address,
156
const MCDisassembler *Decoder) {
157
unsigned addr = 0;
158
addr |= fieldFromInstruction(Insn, 0, 4);
159
addr |= fieldFromInstruction(Insn, 9, 2) << 4;
160
unsigned reg = fieldFromInstruction(Insn, 4, 5);
161
if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) ==
162
MCDisassembler::Fail)
163
return MCDisassembler::Fail;
164
Inst.addOperand(MCOperand::createImm(addr));
165
return MCDisassembler::Success;
166
}
167
168
static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address,
169
const MCDisassembler *Decoder) {
170
unsigned addr = fieldFromInstruction(Insn, 3, 5);
171
unsigned b = fieldFromInstruction(Insn, 0, 3);
172
Inst.addOperand(MCOperand::createImm(addr));
173
Inst.addOperand(MCOperand::createImm(b));
174
return MCDisassembler::Success;
175
}
176
177
static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field,
178
uint64_t Address,
179
const MCDisassembler *Decoder) {
180
// Call targets need to be shifted left by one so this needs a custom
181
// decoder.
182
Inst.addOperand(MCOperand::createImm(Field << 1));
183
return MCDisassembler::Success;
184
}
185
186
static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address,
187
const MCDisassembler *Decoder) {
188
unsigned d = fieldFromInstruction(Insn, 4, 5);
189
if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
190
MCDisassembler::Fail)
191
return MCDisassembler::Fail;
192
return MCDisassembler::Success;
193
}
194
195
static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address,
196
const MCDisassembler *Decoder) {
197
if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail)
198
return MCDisassembler::Fail;
199
Inst.addOperand(MCOperand::createReg(AVR::R31R30));
200
return MCDisassembler::Success;
201
}
202
203
static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
204
uint64_t Address,
205
const MCDisassembler *Decoder) {
206
unsigned d = fieldFromInstruction(Insn, 4, 3) + 16;
207
unsigned r = fieldFromInstruction(Insn, 0, 3) + 16;
208
if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
209
MCDisassembler::Fail)
210
return MCDisassembler::Fail;
211
if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
212
MCDisassembler::Fail)
213
return MCDisassembler::Fail;
214
return MCDisassembler::Success;
215
}
216
217
static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
218
uint64_t Address,
219
const MCDisassembler *Decoder) {
220
unsigned r = fieldFromInstruction(Insn, 4, 4) * 2;
221
unsigned d = fieldFromInstruction(Insn, 0, 4) * 2;
222
if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
223
MCDisassembler::Fail)
224
return MCDisassembler::Fail;
225
if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
226
MCDisassembler::Fail)
227
return MCDisassembler::Fail;
228
return MCDisassembler::Success;
229
}
230
231
static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address,
232
const MCDisassembler *Decoder) {
233
unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25
234
unsigned k = 0;
235
k |= fieldFromInstruction(Insn, 0, 4);
236
k |= fieldFromInstruction(Insn, 6, 2) << 4;
237
if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
238
MCDisassembler::Fail)
239
return MCDisassembler::Fail;
240
if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
241
MCDisassembler::Fail)
242
return MCDisassembler::Fail;
243
Inst.addOperand(MCOperand::createImm(k));
244
return MCDisassembler::Success;
245
}
246
247
static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
248
uint64_t Address,
249
const MCDisassembler *Decoder) {
250
unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16;
251
unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16;
252
if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) ==
253
MCDisassembler::Fail)
254
return MCDisassembler::Fail;
255
if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) ==
256
MCDisassembler::Fail)
257
return MCDisassembler::Fail;
258
return MCDisassembler::Success;
259
}
260
261
static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
262
const MCDisassembler *Decoder) {
263
// As in the EncoderMethod `AVRMCCodeEmitter::encodeMemri`, the memory
264
// address is encoded into 7-bit, in which bits 0-5 are the immediate offset,
265
// and the bit-6 is the pointer register bit (Z=0, Y=1).
266
if (Insn > 127)
267
return MCDisassembler::Fail;
268
269
// Append the base register operand.
270
Inst.addOperand(
271
MCOperand::createReg((Insn & 0x40) ? AVR::R29R28 : AVR::R31R30));
272
// Append the immediate offset operand.
273
Inst.addOperand(MCOperand::createImm(Insn & 0x3f));
274
275
return MCDisassembler::Success;
276
}
277
278
static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address,
279
const MCDisassembler *Decoder) {
280
// Decode the opcode.
281
switch (Insn & 0xf000) {
282
case 0xc000:
283
Inst.setOpcode(AVR::RJMPk);
284
break;
285
case 0xd000:
286
Inst.setOpcode(AVR::RCALLk);
287
break;
288
default: // Unknown relative branch instruction.
289
return MCDisassembler::Fail;
290
}
291
// Decode the relative offset.
292
int16_t Offset = ((int16_t)((Insn & 0xfff) << 4)) >> 3;
293
Inst.addOperand(MCOperand::createImm(Offset));
294
return MCDisassembler::Success;
295
}
296
297
static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn,
298
uint64_t Address,
299
const MCDisassembler *Decoder) {
300
// These 8 instructions are not defined as aliases of BRBS/BRBC.
301
DenseMap<unsigned, unsigned> brInsts = {
302
{0x000, AVR::BRLOk}, {0x400, AVR::BRSHk}, {0x001, AVR::BREQk},
303
{0x401, AVR::BRNEk}, {0x002, AVR::BRMIk}, {0x402, AVR::BRPLk},
304
{0x004, AVR::BRLTk}, {0x404, AVR::BRGEk}};
305
306
// Get the relative offset.
307
int16_t Offset = ((int16_t)((Insn & 0x3f8) << 6)) >> 8;
308
309
// Search the instruction pattern.
310
auto NotAlias = [&Insn](const std::pair<unsigned, unsigned> &I) {
311
return (Insn & 0x407) != I.first;
312
};
313
llvm::partition(brInsts, NotAlias);
314
auto It = llvm::partition_point(brInsts, NotAlias);
315
316
// Decode the instruction.
317
if (It != brInsts.end()) {
318
// This instruction is not an alias of BRBC/BRBS.
319
Inst.setOpcode(It->second);
320
Inst.addOperand(MCOperand::createImm(Offset));
321
} else {
322
// Fall back to an ordinary BRBS/BRBC.
323
Inst.setOpcode(Insn & 0x400 ? AVR::BRBCsk : AVR::BRBSsk);
324
Inst.addOperand(MCOperand::createImm(Insn & 7));
325
Inst.addOperand(MCOperand::createImm(Offset));
326
}
327
328
return MCDisassembler::Success;
329
}
330
331
static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
332
uint64_t Address,
333
const MCDisassembler *Decoder) {
334
// Get the register will be loaded or stored.
335
unsigned RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f];
336
337
// Decode LDD/STD with offset less than 8.
338
if ((Insn & 0xf000) == 0x8000) {
339
unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30;
340
unsigned Offset = Insn & 7; // We need not consider offset > 7.
341
if ((Insn & 0x200) == 0) { // Decode LDD.
342
Inst.setOpcode(AVR::LDDRdPtrQ);
343
Inst.addOperand(MCOperand::createReg(RegVal));
344
Inst.addOperand(MCOperand::createReg(RegBase));
345
Inst.addOperand(MCOperand::createImm(Offset));
346
} else { // Decode STD.
347
Inst.setOpcode(AVR::STDPtrQRr);
348
Inst.addOperand(MCOperand::createReg(RegBase));
349
Inst.addOperand(MCOperand::createImm(Offset));
350
Inst.addOperand(MCOperand::createReg(RegVal));
351
}
352
return MCDisassembler::Success;
353
}
354
355
// Decode the following 14 instructions. Bit 9 indicates load(0) or store(1),
356
// bits 8~4 indicate the value register, bits 3-2 indicate the base address
357
// register (11-X, 10-Y, 00-Z), bits 1~0 indicate the mode (00-basic,
358
// 01-postinc, 10-predec).
359
// ST X, Rr : 1001 001r rrrr 1100
360
// ST X+, Rr : 1001 001r rrrr 1101
361
// ST -X, Rr : 1001 001r rrrr 1110
362
// ST Y+, Rr : 1001 001r rrrr 1001
363
// ST -Y, Rr : 1001 001r rrrr 1010
364
// ST Z+, Rr : 1001 001r rrrr 0001
365
// ST -Z, Rr : 1001 001r rrrr 0010
366
// LD Rd, X : 1001 000d dddd 1100
367
// LD Rd, X+ : 1001 000d dddd 1101
368
// LD Rd, -X : 1001 000d dddd 1110
369
// LD Rd, Y+ : 1001 000d dddd 1001
370
// LD Rd, -Y : 1001 000d dddd 1010
371
// LD Rd, Z+ : 1001 000d dddd 0001
372
// LD Rd, -Z : 1001 000d dddd 0010
373
if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0)
374
return MCDisassembler::Fail;
375
376
// Get the base address register.
377
unsigned RegBase;
378
switch (Insn & 0xc) {
379
case 0xc:
380
RegBase = AVR::R27R26;
381
break;
382
case 0x8:
383
RegBase = AVR::R29R28;
384
break;
385
case 0x0:
386
RegBase = AVR::R31R30;
387
break;
388
default:
389
return MCDisassembler::Fail;
390
}
391
392
// Set the opcode.
393
switch (Insn & 0x203) {
394
case 0x200:
395
Inst.setOpcode(AVR::STPtrRr);
396
Inst.addOperand(MCOperand::createReg(RegBase));
397
Inst.addOperand(MCOperand::createReg(RegVal));
398
return MCDisassembler::Success;
399
case 0x201:
400
Inst.setOpcode(AVR::STPtrPiRr);
401
break;
402
case 0x202:
403
Inst.setOpcode(AVR::STPtrPdRr);
404
break;
405
case 0:
406
Inst.setOpcode(AVR::LDRdPtr);
407
Inst.addOperand(MCOperand::createReg(RegVal));
408
Inst.addOperand(MCOperand::createReg(RegBase));
409
return MCDisassembler::Success;
410
case 1:
411
Inst.setOpcode(AVR::LDRdPtrPi);
412
break;
413
case 2:
414
Inst.setOpcode(AVR::LDRdPtrPd);
415
break;
416
default:
417
return MCDisassembler::Fail;
418
}
419
420
// Build postinc/predec machine instructions.
421
if ((Insn & 0x200) == 0) { // This is a load instruction.
422
Inst.addOperand(MCOperand::createReg(RegVal));
423
Inst.addOperand(MCOperand::createReg(RegBase));
424
Inst.addOperand(MCOperand::createReg(RegBase));
425
} else { // This is a store instruction.
426
Inst.addOperand(MCOperand::createReg(RegBase));
427
Inst.addOperand(MCOperand::createReg(RegBase));
428
Inst.addOperand(MCOperand::createReg(RegVal));
429
// STPtrPiRr and STPtrPdRr have an extra immediate operand.
430
Inst.addOperand(MCOperand::createImm(1));
431
}
432
433
return MCDisassembler::Success;
434
}
435
436
static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
437
uint64_t &Size, uint32_t &Insn) {
438
if (Bytes.size() < 2) {
439
Size = 0;
440
return MCDisassembler::Fail;
441
}
442
443
Size = 2;
444
Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
445
446
return MCDisassembler::Success;
447
}
448
449
static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
450
uint64_t &Size, uint32_t &Insn) {
451
452
if (Bytes.size() < 4) {
453
Size = 0;
454
return MCDisassembler::Fail;
455
}
456
457
Size = 4;
458
Insn =
459
(Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
460
461
return MCDisassembler::Success;
462
}
463
464
static const uint8_t *getDecoderTable(uint64_t Size) {
465
466
switch (Size) {
467
case 2:
468
return DecoderTable16;
469
case 4:
470
return DecoderTable32;
471
default:
472
llvm_unreachable("instructions must be 16 or 32-bits");
473
}
474
}
475
476
DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
477
ArrayRef<uint8_t> Bytes,
478
uint64_t Address,
479
raw_ostream &CStream) const {
480
uint32_t Insn;
481
482
DecodeStatus Result;
483
484
// Try decode a 16-bit instruction.
485
{
486
Result = readInstruction16(Bytes, Address, Size, Insn);
487
488
if (Result == MCDisassembler::Fail)
489
return MCDisassembler::Fail;
490
491
// Try to decode AVRTiny instructions.
492
if (STI.hasFeature(AVR::FeatureTinyEncoding)) {
493
Result = decodeInstruction(DecoderTableAVRTiny16, Instr, Insn, Address,
494
this, STI);
495
if (Result != MCDisassembler::Fail)
496
return Result;
497
}
498
499
// Try to auto-decode a 16-bit instruction.
500
Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
501
this, STI);
502
if (Result != MCDisassembler::Fail)
503
return Result;
504
505
// Try to decode to a load/store instruction. ST/LD need a specified
506
// DecoderMethod, as they already have a specified PostEncoderMethod.
507
Result = decodeLoadStore(Instr, Insn, Address, this);
508
if (Result != MCDisassembler::Fail)
509
return Result;
510
}
511
512
// Try decode a 32-bit instruction.
513
{
514
Result = readInstruction32(Bytes, Address, Size, Insn);
515
516
if (Result == MCDisassembler::Fail)
517
return MCDisassembler::Fail;
518
519
Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
520
this, STI);
521
522
if (Result != MCDisassembler::Fail) {
523
return Result;
524
}
525
526
return MCDisassembler::Fail;
527
}
528
}
529
530
typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
531
const MCDisassembler *Decoder);
532
533