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