blob: eba76667e2b874d42befe788d8d69c812c123368 [file] [log] [blame]
Tim Northover75f436c2013-02-14 16:17:01 +00001//===- AArch64Disassembler.cpp - Disassembler for AArch64 ISA -------------===//
Tim Northovere0e3aef2013-01-31 12:12:40 +00002//
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//===----------------------------------------------------------------------===//
Tim Northover75f436c2013-02-14 16:17:01 +00009//
10// This file contains the functions necessary to decode AArch64 instruction
11// bitpatterns into MCInsts (with the help of TableGenerated information from
12// the instruction definitions).
13//
14//===----------------------------------------------------------------------===//
Tim Northovere0e3aef2013-01-31 12:12:40 +000015
16#define DEBUG_TYPE "arm-disassembler"
17
18#include "AArch64.h"
19#include "AArch64RegisterInfo.h"
20#include "AArch64Subtarget.h"
Tim Northover969afbe2013-02-05 13:24:47 +000021#include "Utils/AArch64BaseInfo.h"
Tim Northovere0e3aef2013-01-31 12:12:40 +000022#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCInstrDesc.h"
24#include "llvm/MC/MCExpr.h"
25#include "llvm/MC/MCContext.h"
26#include "llvm/MC/MCDisassembler.h"
27#include "llvm/MC/MCFixedLenDisassembler.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/MemoryObject.h"
30#include "llvm/Support/ErrorHandling.h"
31#include "llvm/Support/TargetRegistry.h"
32#include "llvm/Support/raw_ostream.h"
33
34using namespace llvm;
35
36typedef MCDisassembler::DecodeStatus DecodeStatus;
37
38namespace {
39/// AArch64 disassembler for all AArch64 platforms.
40class AArch64Disassembler : public MCDisassembler {
41 const MCRegisterInfo *RegInfo;
42public:
43 /// Initializes the disassembler.
44 ///
45 AArch64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info)
46 : MCDisassembler(STI), RegInfo(Info) {
47 }
48
49 ~AArch64Disassembler() {
50 }
51
52 /// See MCDisassembler.
53 DecodeStatus getInstruction(MCInst &instr,
54 uint64_t &size,
55 const MemoryObject &region,
56 uint64_t address,
57 raw_ostream &vStream,
58 raw_ostream &cStream) const;
59
60 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
61};
62
63}
64
65// Forward-declarations used in the auto-generated files.
66static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
67 uint64_t Address, const void *Decoder);
68static DecodeStatus
69DecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
70 uint64_t Address, const void *Decoder);
71
72static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
73 uint64_t Address, const void *Decoder);
74static DecodeStatus
75DecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
76 uint64_t Address, const void *Decoder);
77
78static DecodeStatus DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
79 uint64_t Address, const void *Decoder);
80static DecodeStatus DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
81 uint64_t Address, const void *Decoder);
82static DecodeStatus DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
83 uint64_t Address, const void *Decoder);
84static DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
85 uint64_t Address, const void *Decoder);
Tim Northoverbcaca872013-02-05 13:24:56 +000086static DecodeStatus DecodeFPR128RegisterClass(llvm::MCInst &Inst,
87 unsigned RegNo, uint64_t Address,
88 const void *Decoder);
89static DecodeStatus DecodeVPR128RegisterClass(llvm::MCInst &Inst,
90 unsigned RegNo, uint64_t Address,
91 const void *Decoder);
Tim Northovere0e3aef2013-01-31 12:12:40 +000092
93static DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
94 unsigned OptionHiS,
95 uint64_t Address,
96 const void *Decoder);
97
98
99static DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
100 unsigned Imm6Bits,
101 uint64_t Address,
102 const void *Decoder);
103
104static DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
105 unsigned Imm6Bits,
106 uint64_t Address,
107 const void *Decoder);
108
109template<int RegWidth>
110static DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
111 unsigned FullImm,
112 uint64_t Address,
113 const void *Decoder);
114
115template<int RegWidth>
116static DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
117 unsigned Bits,
118 uint64_t Address,
119 const void *Decoder);
120
121static DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
122 unsigned ShiftAmount,
123 uint64_t Address,
124 const void *Decoder);
125
126static DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
127 unsigned ShiftAmount,
128 uint64_t Address,
129 const void *Decoder);
130static DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
131 uint64_t Address,
132 const void *Decoder);
133
134static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
135 uint64_t Address,
136 const void *Decoder);
137
138static DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
139 unsigned Insn,
140 uint64_t Address,
141 const void *Decoder);
142
143static DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
144 unsigned Val,
145 uint64_t Address,
146 const void *Decoder);
147
148template<typename SomeNamedImmMapper>
149static DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
150 unsigned Val,
151 uint64_t Address,
152 const void *Decoder);
153
Tim Northoverbcaca872013-02-05 13:24:56 +0000154static DecodeStatus
155DecodeSysRegOperand(const A64SysReg::SysRegMapper &InstMapper,
156 llvm::MCInst &Inst, unsigned Val,
157 uint64_t Address, const void *Decoder);
Tim Northovere0e3aef2013-01-31 12:12:40 +0000158
159static DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
160 unsigned Val,
161 uint64_t Address,
162 const void *Decoder);
163
164static DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
165 unsigned Val,
166 uint64_t Address,
167 const void *Decoder);
168
169
170static DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
171 unsigned Val,
172 uint64_t Address,
173 const void *Decoder);
174
175
176static bool Check(DecodeStatus &Out, DecodeStatus In);
177
178#include "AArch64GenDisassemblerTables.inc"
179#include "AArch64GenInstrInfo.inc"
180
181static bool Check(DecodeStatus &Out, DecodeStatus In) {
182 switch (In) {
183 case MCDisassembler::Success:
184 // Out stays the same.
185 return true;
186 case MCDisassembler::SoftFail:
187 Out = In;
188 return true;
189 case MCDisassembler::Fail:
190 Out = In;
191 return false;
192 }
193 llvm_unreachable("Invalid DecodeStatus!");
194}
195
196DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
197 const MemoryObject &Region,
198 uint64_t Address,
199 raw_ostream &os,
200 raw_ostream &cs) const {
201 CommentStream = &cs;
202
203 uint8_t bytes[4];
204
205 // We want to read exactly 4 bytes of data.
206 if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
207 Size = 0;
208 return MCDisassembler::Fail;
209 }
210
211 // Encoded as a small-endian 32-bit word in the stream.
212 uint32_t insn = (bytes[3] << 24) |
213 (bytes[2] << 16) |
214 (bytes[1] << 8) |
215 (bytes[0] << 0);
216
217 // Calling the auto-generated decoder function.
218 DecodeStatus result = decodeInstruction(DecoderTableA6432, MI, insn, Address,
219 this, STI);
220 if (result != MCDisassembler::Fail) {
221 Size = 4;
222 return result;
223 }
224
225 MI.clear();
226 Size = 0;
227 return MCDisassembler::Fail;
228}
229
230static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
231 const AArch64Disassembler *Dis = static_cast<const AArch64Disassembler*>(D);
232 return Dis->getRegInfo()->getRegClass(RC).getRegister(RegNo);
233}
234
235static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
236 uint64_t Address, const void *Decoder) {
237 if (RegNo > 31)
238 return MCDisassembler::Fail;
239
240 uint16_t Register = getReg(Decoder, AArch64::GPR64RegClassID, RegNo);
241 Inst.addOperand(MCOperand::CreateReg(Register));
242 return MCDisassembler::Success;
243}
244
245static DecodeStatus
246DecodeGPR64xspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
247 uint64_t Address, const void *Decoder) {
248 if (RegNo > 31)
249 return MCDisassembler::Fail;
250
251 uint16_t Register = getReg(Decoder, AArch64::GPR64xspRegClassID, RegNo);
252 Inst.addOperand(MCOperand::CreateReg(Register));
253 return MCDisassembler::Success;
254}
255
256static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Tim Northoverbcaca872013-02-05 13:24:56 +0000257 uint64_t Address,
258 const void *Decoder) {
Tim Northovere0e3aef2013-01-31 12:12:40 +0000259 if (RegNo > 31)
260 return MCDisassembler::Fail;
261
262 uint16_t Register = getReg(Decoder, AArch64::GPR32RegClassID, RegNo);
263 Inst.addOperand(MCOperand::CreateReg(Register));
264 return MCDisassembler::Success;
265}
266
267static DecodeStatus
268DecodeGPR32wspRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
269 uint64_t Address, const void *Decoder) {
270 if (RegNo > 31)
271 return MCDisassembler::Fail;
272
273 uint16_t Register = getReg(Decoder, AArch64::GPR32wspRegClassID, RegNo);
274 Inst.addOperand(MCOperand::CreateReg(Register));
275 return MCDisassembler::Success;
276}
277
278static DecodeStatus
279DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
280 uint64_t Address, const void *Decoder) {
281 if (RegNo > 31)
282 return MCDisassembler::Fail;
283
284 uint16_t Register = getReg(Decoder, AArch64::FPR8RegClassID, RegNo);
285 Inst.addOperand(MCOperand::CreateReg(Register));
286 return MCDisassembler::Success;
287}
288
289static DecodeStatus
290DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
291 uint64_t Address, const void *Decoder) {
292 if (RegNo > 31)
293 return MCDisassembler::Fail;
294
295 uint16_t Register = getReg(Decoder, AArch64::FPR16RegClassID, RegNo);
296 Inst.addOperand(MCOperand::CreateReg(Register));
297 return MCDisassembler::Success;
298}
299
300
301static DecodeStatus
302DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
303 uint64_t Address, const void *Decoder) {
304 if (RegNo > 31)
305 return MCDisassembler::Fail;
306
307 uint16_t Register = getReg(Decoder, AArch64::FPR32RegClassID, RegNo);
308 Inst.addOperand(MCOperand::CreateReg(Register));
309 return MCDisassembler::Success;
310}
311
312static DecodeStatus
313DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
314 uint64_t Address, const void *Decoder) {
315 if (RegNo > 31)
316 return MCDisassembler::Fail;
317
318 uint16_t Register = getReg(Decoder, AArch64::FPR64RegClassID, RegNo);
319 Inst.addOperand(MCOperand::CreateReg(Register));
320 return MCDisassembler::Success;
321}
322
323
324static DecodeStatus
325DecodeFPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
326 uint64_t Address, const void *Decoder) {
327 if (RegNo > 31)
328 return MCDisassembler::Fail;
329
330 uint16_t Register = getReg(Decoder, AArch64::FPR128RegClassID, RegNo);
331 Inst.addOperand(MCOperand::CreateReg(Register));
332 return MCDisassembler::Success;
333}
334
Tim Northovere0e3aef2013-01-31 12:12:40 +0000335static DecodeStatus
336DecodeVPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
337 uint64_t Address, const void *Decoder) {
338 if (RegNo > 31)
339 return MCDisassembler::Fail;
340
341 uint16_t Register = getReg(Decoder, AArch64::VPR128RegClassID, RegNo);
342 Inst.addOperand(MCOperand::CreateReg(Register));
343 return MCDisassembler::Success;
344}
345
346static DecodeStatus DecodeAddrRegExtendOperand(llvm::MCInst &Inst,
347 unsigned OptionHiS,
348 uint64_t Address,
349 const void *Decoder) {
350 // Option{1} must be 1. OptionHiS is made up of {Option{2}, Option{1},
351 // S}. Hence we want to check bit 1.
352 if (!(OptionHiS & 2))
353 return MCDisassembler::Fail;
354
355 Inst.addOperand(MCOperand::CreateImm(OptionHiS));
356 return MCDisassembler::Success;
357}
358
359static DecodeStatus DecodeBitfield32ImmOperand(llvm::MCInst &Inst,
360 unsigned Imm6Bits,
361 uint64_t Address,
362 const void *Decoder) {
363 // In the 32-bit variant, bit 6 must be zero. I.e. the immediate must be
364 // between 0 and 31.
365 if (Imm6Bits > 31)
366 return MCDisassembler::Fail;
367
368 Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
369 return MCDisassembler::Success;
370}
371
372static DecodeStatus DecodeCVT32FixedPosOperand(llvm::MCInst &Inst,
373 unsigned Imm6Bits,
374 uint64_t Address,
375 const void *Decoder) {
376 // 1 <= Imm <= 32. Encoded as 64 - Imm so: 63 >= Encoded >= 32.
377 if (Imm6Bits < 32)
378 return MCDisassembler::Fail;
379
380 Inst.addOperand(MCOperand::CreateImm(Imm6Bits));
381 return MCDisassembler::Success;
382}
383
384
385template<int RegWidth>
386static DecodeStatus DecodeMoveWideImmOperand(llvm::MCInst &Inst,
387 unsigned FullImm,
388 uint64_t Address,
389 const void *Decoder) {
390 unsigned Imm16 = FullImm & 0xffff;
391 unsigned Shift = FullImm >> 16;
392
393 if (RegWidth == 32 && Shift > 1) return MCDisassembler::Fail;
394
395 Inst.addOperand(MCOperand::CreateImm(Imm16));
396 Inst.addOperand(MCOperand::CreateImm(Shift));
397 return MCDisassembler::Success;
398}
399
400template<int RegWidth>
401static DecodeStatus DecodeLogicalImmOperand(llvm::MCInst &Inst,
402 unsigned Bits,
403 uint64_t Address,
404 const void *Decoder) {
405 uint64_t Imm;
406 if (!A64Imms::isLogicalImmBits(RegWidth, Bits, Imm))
407 return MCDisassembler::Fail;
408
409 Inst.addOperand(MCOperand::CreateImm(Bits));
410 return MCDisassembler::Success;
411}
412
413
414static DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
415 unsigned ShiftAmount,
416 uint64_t Address,
417 const void *Decoder) {
418 // Only values 0-4 are valid for this 3-bit field
419 if (ShiftAmount > 4)
420 return MCDisassembler::Fail;
421
422 Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
423 return MCDisassembler::Success;
424}
425
426static DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
427 unsigned ShiftAmount,
428 uint64_t Address,
429 const void *Decoder) {
430 // Only values below 32 are valid for a 32-bit register
431 if (ShiftAmount > 31)
432 return MCDisassembler::Fail;
433
434 Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
435 return MCDisassembler::Success;
436}
437
438static DecodeStatus DecodeBitfieldInstruction(llvm::MCInst &Inst, unsigned Insn,
439 uint64_t Address,
440 const void *Decoder) {
441 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
442 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
443 unsigned ImmS = fieldFromInstruction(Insn, 10, 6);
444 unsigned ImmR = fieldFromInstruction(Insn, 16, 6);
445 unsigned SF = fieldFromInstruction(Insn, 31, 1);
446
447 // Undef for 0b11 just in case it occurs. Don't want the compiler to optimise
448 // out assertions that it thinks should never be hit.
449 enum OpcTypes { SBFM = 0, BFM, UBFM, Undef } Opc;
450 Opc = (OpcTypes)fieldFromInstruction(Insn, 29, 2);
451
452 if (!SF) {
453 // ImmR and ImmS must be between 0 and 31 for 32-bit instructions.
454 if (ImmR > 31 || ImmS > 31)
455 return MCDisassembler::Fail;
456 }
457
458 if (SF) {
459 DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
460 // BFM MCInsts use Rd as a source too.
461 if (Opc == BFM) DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
462 DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
463 } else {
464 DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
465 // BFM MCInsts use Rd as a source too.
466 if (Opc == BFM) DecodeGPR32RegisterClass(Inst, Rd, Address, Decoder);
467 DecodeGPR32RegisterClass(Inst, Rn, Address, Decoder);
468 }
469
470 // ASR and LSR have more specific patterns so they won't get here:
Tim Northoverbcaca872013-02-05 13:24:56 +0000471 assert(!(ImmS == 31 && !SF && Opc != BFM)
472 && "shift should have used auto decode");
473 assert(!(ImmS == 63 && SF && Opc != BFM)
474 && "shift should have used auto decode");
Tim Northovere0e3aef2013-01-31 12:12:40 +0000475
476 // Extension instructions similarly:
477 if (Opc == SBFM && ImmR == 0) {
478 assert((ImmS != 7 && ImmS != 15) && "extension got here");
479 assert((ImmS != 31 || SF == 0) && "extension got here");
480 } else if (Opc == UBFM && ImmR == 0) {
481 assert((SF != 0 || (ImmS != 7 && ImmS != 15)) && "extension got here");
482 }
483
484 if (Opc == UBFM) {
485 // It might be a LSL instruction, which actually takes the shift amount
486 // itself as an MCInst operand.
487 if (SF && (ImmS + 1) % 64 == ImmR) {
488 Inst.setOpcode(AArch64::LSLxxi);
489 Inst.addOperand(MCOperand::CreateImm(63 - ImmS));
490 return MCDisassembler::Success;
491 } else if (!SF && (ImmS + 1) % 32 == ImmR) {
492 Inst.setOpcode(AArch64::LSLwwi);
493 Inst.addOperand(MCOperand::CreateImm(31 - ImmS));
494 return MCDisassembler::Success;
495 }
496 }
497
498 // Otherwise it's definitely either an extract or an insert depending on which
499 // of ImmR or ImmS is larger.
500 unsigned ExtractOp, InsertOp;
501 switch (Opc) {
502 default: llvm_unreachable("unexpected instruction trying to decode bitfield");
503 case SBFM:
504 ExtractOp = SF ? AArch64::SBFXxxii : AArch64::SBFXwwii;
505 InsertOp = SF ? AArch64::SBFIZxxii : AArch64::SBFIZwwii;
506 break;
507 case BFM:
508 ExtractOp = SF ? AArch64::BFXILxxii : AArch64::BFXILwwii;
509 InsertOp = SF ? AArch64::BFIxxii : AArch64::BFIwwii;
510 break;
511 case UBFM:
512 ExtractOp = SF ? AArch64::UBFXxxii : AArch64::UBFXwwii;
513 InsertOp = SF ? AArch64::UBFIZxxii : AArch64::UBFIZwwii;
514 break;
515 }
516
517 // Otherwise it's a boring insert or extract
518 Inst.addOperand(MCOperand::CreateImm(ImmR));
519 Inst.addOperand(MCOperand::CreateImm(ImmS));
520
521
522 if (ImmS < ImmR)
523 Inst.setOpcode(InsertOp);
524 else
525 Inst.setOpcode(ExtractOp);
526
527 return MCDisassembler::Success;
528}
529
530static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
531 uint64_t Address,
532 const void *Decoder) {
533 // This decoder exists to add the dummy Lane operand to the MCInst, which must
534 // be 1 in assembly but has no other real manifestation.
535 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
536 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
537 unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
538
539 if (IsToVec) {
540 DecodeVPR128RegisterClass(Inst, Rd, Address, Decoder);
541 DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
542 } else {
543 DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
544 DecodeVPR128RegisterClass(Inst, Rn, Address, Decoder);
545 }
546
547 // Add the lane
548 Inst.addOperand(MCOperand::CreateImm(1));
549
550 return MCDisassembler::Success;
551}
552
553
554static DecodeStatus DecodeLDSTPairInstruction(llvm::MCInst &Inst,
555 unsigned Insn,
556 uint64_t Address,
557 const void *Decoder) {
558 DecodeStatus Result = MCDisassembler::Success;
559 unsigned Rt = fieldFromInstruction(Insn, 0, 5);
560 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
561 unsigned Rt2 = fieldFromInstruction(Insn, 10, 5);
562 unsigned SImm7 = fieldFromInstruction(Insn, 15, 7);
563 unsigned L = fieldFromInstruction(Insn, 22, 1);
564 unsigned V = fieldFromInstruction(Insn, 26, 1);
565 unsigned Opc = fieldFromInstruction(Insn, 30, 2);
566
567 // Not an official name, but it turns out that bit 23 distinguishes indexed
568 // from non-indexed operations.
569 unsigned Indexed = fieldFromInstruction(Insn, 23, 1);
570
571 if (Indexed && L == 0) {
572 // The MCInst for an indexed store has an out operand and 4 ins:
573 // Rn_wb, Rt, Rt2, Rn, Imm
574 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
575 }
576
577 // You shouldn't load to the same register twice in an instruction...
578 if (L && Rt == Rt2)
579 Result = MCDisassembler::SoftFail;
580
581 // ... or do any operation that writes-back to a transfer register. But note
582 // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
583 if (Indexed && V == 0 && Rn != 31 && (Rt == Rn || Rt2 == Rn))
584 Result = MCDisassembler::SoftFail;
585
586 // Exactly how we decode the MCInst's registers depends on the Opc and V
587 // fields of the instruction. These also obviously determine the size of the
588 // operation so we can fill in that information while we're at it.
589 if (V) {
590 // The instruction operates on the FP/SIMD registers
591 switch (Opc) {
592 default: return MCDisassembler::Fail;
593 case 0:
594 DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
595 DecodeFPR32RegisterClass(Inst, Rt2, Address, Decoder);
596 break;
597 case 1:
598 DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
599 DecodeFPR64RegisterClass(Inst, Rt2, Address, Decoder);
600 break;
601 case 2:
602 DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
603 DecodeFPR128RegisterClass(Inst, Rt2, Address, Decoder);
604 break;
605 }
606 } else {
607 switch (Opc) {
608 default: return MCDisassembler::Fail;
609 case 0:
610 DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
611 DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder);
612 break;
613 case 1:
614 assert(L && "unexpected \"store signed\" attempt");
615 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
616 DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
617 break;
618 case 2:
619 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
620 DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder);
621 break;
622 }
623 }
624
625 if (Indexed && L == 1) {
626 // The MCInst for an indexed load has 3 out operands and an 3 ins:
627 // Rt, Rt2, Rn_wb, Rt2, Rn, Imm
628 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
629 }
630
631
632 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
633 Inst.addOperand(MCOperand::CreateImm(SImm7));
634
635 return Result;
636}
637
638static DecodeStatus DecodeLoadPairExclusiveInstruction(llvm::MCInst &Inst,
639 uint32_t Val,
640 uint64_t Address,
641 const void *Decoder) {
642 unsigned Rt = fieldFromInstruction(Val, 0, 5);
643 unsigned Rn = fieldFromInstruction(Val, 5, 5);
644 unsigned Rt2 = fieldFromInstruction(Val, 10, 5);
645 unsigned MemSize = fieldFromInstruction(Val, 30, 2);
646
647 DecodeStatus S = MCDisassembler::Success;
648 if (Rt == Rt2) S = MCDisassembler::SoftFail;
649
650 switch (MemSize) {
651 case 2:
652 if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder)))
653 return MCDisassembler::Fail;
654 if (!Check(S, DecodeGPR32RegisterClass(Inst, Rt2, Address, Decoder)))
655 return MCDisassembler::Fail;
656 break;
657 case 3:
658 if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder)))
659 return MCDisassembler::Fail;
660 if (!Check(S, DecodeGPR64RegisterClass(Inst, Rt2, Address, Decoder)))
661 return MCDisassembler::Fail;
662 break;
663 default:
664 llvm_unreachable("Invalid MemSize in DecodeLoadPairExclusiveInstruction");
665 }
666
667 if (!Check(S, DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder)))
668 return MCDisassembler::Fail;
669
670 return S;
671}
672
673template<typename SomeNamedImmMapper>
674static DecodeStatus DecodeNamedImmOperand(llvm::MCInst &Inst,
675 unsigned Val,
676 uint64_t Address,
677 const void *Decoder) {
678 SomeNamedImmMapper Mapper;
679 bool ValidNamed;
680 Mapper.toString(Val, ValidNamed);
681 if (ValidNamed || Mapper.validImm(Val)) {
682 Inst.addOperand(MCOperand::CreateImm(Val));
683 return MCDisassembler::Success;
684 }
685
686 return MCDisassembler::Fail;
687}
688
689static DecodeStatus DecodeSysRegOperand(const A64SysReg::SysRegMapper &Mapper,
690 llvm::MCInst &Inst,
691 unsigned Val,
692 uint64_t Address,
693 const void *Decoder) {
694 bool ValidNamed;
695 Mapper.toString(Val, ValidNamed);
696
697 Inst.addOperand(MCOperand::CreateImm(Val));
698
699 return ValidNamed ? MCDisassembler::Success : MCDisassembler::Fail;
700}
701
702static DecodeStatus DecodeMRSOperand(llvm::MCInst &Inst,
703 unsigned Val,
704 uint64_t Address,
705 const void *Decoder) {
706 return DecodeSysRegOperand(A64SysReg::MRSMapper(), Inst, Val, Address,
707 Decoder);
708}
709
710static DecodeStatus DecodeMSROperand(llvm::MCInst &Inst,
711 unsigned Val,
712 uint64_t Address,
713 const void *Decoder) {
714 return DecodeSysRegOperand(A64SysReg::MSRMapper(), Inst, Val, Address,
715 Decoder);
716}
717
718static DecodeStatus DecodeSingleIndexedInstruction(llvm::MCInst &Inst,
719 unsigned Insn,
720 uint64_t Address,
721 const void *Decoder) {
722 unsigned Rt = fieldFromInstruction(Insn, 0, 5);
723 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
724 unsigned Imm9 = fieldFromInstruction(Insn, 12, 9);
725
726 unsigned Opc = fieldFromInstruction(Insn, 22, 2);
727 unsigned V = fieldFromInstruction(Insn, 26, 1);
728 unsigned Size = fieldFromInstruction(Insn, 30, 2);
729
730 if (Opc == 0 || (V == 1 && Opc == 2)) {
731 // It's a store, the MCInst gets: Rn_wb, Rt, Rn, Imm
732 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
733 }
734
735 if (V == 0 && (Opc == 2 || Size == 3)) {
736 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
737 } else if (V == 0) {
738 DecodeGPR32RegisterClass(Inst, Rt, Address, Decoder);
739 } else if (V == 1 && (Opc & 2)) {
740 DecodeFPR128RegisterClass(Inst, Rt, Address, Decoder);
741 } else {
742 switch (Size) {
743 case 0:
744 DecodeFPR8RegisterClass(Inst, Rt, Address, Decoder);
745 break;
746 case 1:
747 DecodeFPR16RegisterClass(Inst, Rt, Address, Decoder);
748 break;
749 case 2:
750 DecodeFPR32RegisterClass(Inst, Rt, Address, Decoder);
751 break;
752 case 3:
753 DecodeFPR64RegisterClass(Inst, Rt, Address, Decoder);
754 break;
755 }
756 }
757
758 if (Opc != 0 && (V != 1 || Opc != 2)) {
759 // It's a load, the MCInst gets: Rt, Rn_wb, Rn, Imm
760 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
761 }
762
763 DecodeGPR64xspRegisterClass(Inst, Rn, Address, Decoder);
764
765 Inst.addOperand(MCOperand::CreateImm(Imm9));
766
767 // N.b. The official documentation says undpredictable if Rt == Rn, but this
768 // takes place at the architectural rather than encoding level:
769 //
770 // "STR xzr, [sp], #4" is perfectly valid.
771 if (V == 0 && Rt == Rn && Rn != 31)
772 return MCDisassembler::SoftFail;
773 else
774 return MCDisassembler::Success;
775}
776
777static MCDisassembler *createAArch64Disassembler(const Target &T,
778 const MCSubtargetInfo &STI) {
779 return new AArch64Disassembler(STI, T.createMCRegInfo(""));
780}
781
782extern "C" void LLVMInitializeAArch64Disassembler() {
783 TargetRegistry::RegisterMCDisassembler(TheAArch64Target,
784 createAArch64Disassembler);
785}
786
787