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