llvm/test/Object/ar-error.test: Don't check the message "No such file or directory".
[oota-llvm.git] / lib / Target / AArch64 / InstPrinter / AArch64InstPrinter.cpp
1 //==-- AArch64InstPrinter.cpp - Convert AArch64 MCInst to assembly syntax --==//
2 //
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 //===----------------------------------------------------------------------===//
9 //
10 // This class prints an AArch64 MCInst to a .s file.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "AArch64InstPrinter.h"
15 #include "MCTargetDesc/AArch64MCTargetDesc.h"
16 #include "Utils/AArch64BaseInfo.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/raw_ostream.h"
23
24 using namespace llvm;
25
26 #define DEBUG_TYPE "asm-printer"
27
28 #define GET_INSTRUCTION_NAME
29 #define PRINT_ALIAS_INSTR
30 #include "AArch64GenAsmWriter.inc"
31
32 static int64_t unpackSignedImm(int BitWidth, uint64_t Value) {
33   assert(!(Value & ~((1ULL << BitWidth)-1)) && "immediate not n-bit");
34   if (Value & (1ULL <<  (BitWidth - 1)))
35     return static_cast<int64_t>(Value) - (1LL << BitWidth);
36   else
37     return Value;
38 }
39
40 AArch64InstPrinter::AArch64InstPrinter(const MCAsmInfo &MAI,
41                                        const MCInstrInfo &MII,
42                                        const MCRegisterInfo &MRI,
43                                        const MCSubtargetInfo &STI) :
44   MCInstPrinter(MAI, MII, MRI) {
45   // Initialize the set of available features.
46   setAvailableFeatures(STI.getFeatureBits());
47 }
48
49 void AArch64InstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
50   OS << getRegisterName(RegNo);
51 }
52
53 void
54 AArch64InstPrinter::printOffsetSImm9Operand(const MCInst *MI,
55                                               unsigned OpNum, raw_ostream &O) {
56   const MCOperand &MOImm = MI->getOperand(OpNum);
57   int32_t Imm = unpackSignedImm(9, MOImm.getImm());
58
59   O << '#' << Imm;
60 }
61
62 void
63 AArch64InstPrinter::printAddrRegExtendOperand(const MCInst *MI, unsigned OpNum,
64                                           raw_ostream &O, unsigned MemSize,
65                                           unsigned RmSize) {
66   unsigned ExtImm = MI->getOperand(OpNum).getImm();
67   unsigned OptionHi = ExtImm >> 1;
68   unsigned S = ExtImm & 1;
69   bool IsLSL = OptionHi == 1 && RmSize == 64;
70
71   const char *Ext;
72   switch (OptionHi) {
73   case 1:
74     Ext = (RmSize == 32) ? "uxtw" : "lsl";
75     break;
76   case 3:
77     Ext = (RmSize == 32) ? "sxtw" : "sxtx";
78     break;
79   default:
80     llvm_unreachable("Incorrect Option on load/store (reg offset)");
81   }
82   O << Ext;
83
84   if (S) {
85     unsigned ShiftAmt = Log2_32(MemSize);
86     O << " #" << ShiftAmt;
87   } else if (IsLSL) {
88     O << " #0";
89   }
90 }
91
92 void
93 AArch64InstPrinter::printAddSubImmLSL0Operand(const MCInst *MI,
94                                               unsigned OpNum, raw_ostream &O) {
95   const MCOperand &Imm12Op = MI->getOperand(OpNum);
96
97   if (Imm12Op.isImm()) {
98     int64_t Imm12 = Imm12Op.getImm();
99     assert(Imm12 >= 0 && "Invalid immediate for add/sub imm");
100     O << "#" << Imm12;
101   } else {
102     assert(Imm12Op.isExpr() && "Unexpected shift operand type");
103     O << "#" << *Imm12Op.getExpr();
104   }
105 }
106
107 void
108 AArch64InstPrinter::printAddSubImmLSL12Operand(const MCInst *MI, unsigned OpNum,
109                                                raw_ostream &O) {
110
111   printAddSubImmLSL0Operand(MI, OpNum, O);
112
113   O << ", lsl #12";
114 }
115
116 void
117 AArch64InstPrinter::printBareImmOperand(const MCInst *MI, unsigned OpNum,
118                                         raw_ostream &O) {
119   const MCOperand &MO = MI->getOperand(OpNum);
120   O << MO.getImm();
121 }
122
123 template<unsigned RegWidth> void
124 AArch64InstPrinter::printBFILSBOperand(const MCInst *MI, unsigned OpNum,
125                                        raw_ostream &O) {
126   const MCOperand &ImmROp = MI->getOperand(OpNum);
127   unsigned LSB = ImmROp.getImm() == 0 ? 0 : RegWidth - ImmROp.getImm();
128
129   O << '#' << LSB;
130 }
131
132 void AArch64InstPrinter::printBFIWidthOperand(const MCInst *MI, unsigned OpNum,
133                                               raw_ostream &O) {
134   const MCOperand &ImmSOp = MI->getOperand(OpNum);
135   unsigned Width = ImmSOp.getImm() + 1;
136
137   O << '#' << Width;
138 }
139
140 void
141 AArch64InstPrinter::printBFXWidthOperand(const MCInst *MI, unsigned OpNum,
142                                          raw_ostream &O) {
143   const MCOperand &ImmSOp = MI->getOperand(OpNum);
144   const MCOperand &ImmROp = MI->getOperand(OpNum - 1);
145
146   unsigned ImmR = ImmROp.getImm();
147   unsigned ImmS = ImmSOp.getImm();
148
149   assert(ImmS >= ImmR && "Invalid ImmR, ImmS combination for bitfield extract");
150
151   O << '#' << (ImmS - ImmR + 1);
152 }
153
154 void
155 AArch64InstPrinter::printCRxOperand(const MCInst *MI, unsigned OpNum,
156                                     raw_ostream &O) {
157     const MCOperand &CRx = MI->getOperand(OpNum);
158
159     O << 'c' << CRx.getImm();
160 }
161
162
163 void
164 AArch64InstPrinter::printCVTFixedPosOperand(const MCInst *MI, unsigned OpNum,
165                                             raw_ostream &O) {
166     const MCOperand &ScaleOp = MI->getOperand(OpNum);
167
168     O << '#' << (64 - ScaleOp.getImm());
169 }
170
171
172 void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
173                                            raw_ostream &o) {
174   const MCOperand &MOImm8 = MI->getOperand(OpNum);
175
176   assert(MOImm8.isImm()
177          && "Immediate operand required for floating-point immediate inst");
178
179   uint32_t Imm8 = MOImm8.getImm();
180   uint32_t Fraction = Imm8 & 0xf;
181   uint32_t Exponent = (Imm8 >> 4) & 0x7;
182   uint32_t Negative = (Imm8 >> 7) & 0x1;
183
184   float Val = 1.0f + Fraction / 16.0f;
185
186   // That is:
187   // 000 -> 2^1,  001 -> 2^2,  010 -> 2^3,  011 -> 2^4,
188   // 100 -> 2^-3, 101 -> 2^-2, 110 -> 2^-1, 111 -> 2^0
189   if (Exponent & 0x4) {
190     Val /= 1 << (7 - Exponent);
191   } else {
192     Val *= 1 << (Exponent + 1);
193   }
194
195   Val = Negative ? -Val : Val;
196
197   o << '#' << format("%.8f", Val);
198 }
199
200 void AArch64InstPrinter::printFPZeroOperand(const MCInst *MI, unsigned OpNum,
201                                             raw_ostream &o) {
202   o << "#0.0";
203 }
204
205 void
206 AArch64InstPrinter::printCondCodeOperand(const MCInst *MI, unsigned OpNum,
207                                          raw_ostream &O) {
208   const MCOperand &MO = MI->getOperand(OpNum);
209
210   O << A64CondCodeToString(static_cast<A64CC::CondCodes>(MO.getImm()));
211 }
212
213 void
214 AArch64InstPrinter::printInverseCondCodeOperand(const MCInst *MI,
215                                                 unsigned OpNum,
216                                                 raw_ostream &O) {
217   A64CC::CondCodes CC =
218       static_cast<A64CC::CondCodes>(MI->getOperand(OpNum).getImm());
219   O << A64CondCodeToString(A64InvertCondCode(CC));
220 }
221
222 template <unsigned field_width, unsigned scale> void
223 AArch64InstPrinter::printLabelOperand(const MCInst *MI, unsigned OpNum,
224                                             raw_ostream &O) {
225   const MCOperand &MO = MI->getOperand(OpNum);
226
227   if (!MO.isImm()) {
228     printOperand(MI, OpNum, O);
229     return;
230   }
231
232   // The immediate of LDR (lit) instructions is a signed 19-bit immediate, which
233   // is multiplied by 4 (because all A64 instructions are 32-bits wide).
234   uint64_t UImm = MO.getImm();
235   uint64_t Sign = UImm & (1LL << (field_width - 1));
236   int64_t SImm = scale * ((UImm & ~Sign) - Sign);
237
238   O << "#" << SImm;
239 }
240
241 template<unsigned RegWidth> void
242 AArch64InstPrinter::printLogicalImmOperand(const MCInst *MI, unsigned OpNum,
243                                            raw_ostream &O) {
244   const MCOperand &MO = MI->getOperand(OpNum);
245   uint64_t Val;
246   A64Imms::isLogicalImmBits(RegWidth, MO.getImm(), Val);
247   O << "#0x";
248   O.write_hex(Val);
249 }
250
251 void
252 AArch64InstPrinter::printOffsetUImm12Operand(const MCInst *MI, unsigned OpNum,
253                                                raw_ostream &O, int MemSize) {
254   const MCOperand &MOImm = MI->getOperand(OpNum);
255
256   if (MOImm.isImm()) {
257     uint32_t Imm = MOImm.getImm() * MemSize;
258
259     O << "#" << Imm;
260   } else {
261     O << "#" << *MOImm.getExpr();
262   }
263 }
264
265 void
266 AArch64InstPrinter::printShiftOperand(const MCInst *MI,  unsigned OpNum,
267                                       raw_ostream &O,
268                                       A64SE::ShiftExtSpecifiers Shift) {
269     const MCOperand &MO = MI->getOperand(OpNum);
270
271     // LSL #0 is not printed
272     if (Shift == A64SE::LSL && MO.isImm() && MO.getImm() == 0)
273         return;
274
275     switch (Shift) {
276     case A64SE::LSL: O << "lsl"; break;
277     case A64SE::LSR: O << "lsr"; break;
278     case A64SE::ASR: O << "asr"; break;
279     case A64SE::ROR: O << "ror"; break;
280     default: llvm_unreachable("Invalid shift specifier in logical instruction");
281     }
282
283   O << " #" << MO.getImm();
284 }
285
286 void
287 AArch64InstPrinter::printMoveWideImmOperand(const MCInst *MI,  unsigned OpNum,
288                                             raw_ostream &O) {
289   const MCOperand &UImm16MO = MI->getOperand(OpNum);
290   const MCOperand &ShiftMO = MI->getOperand(OpNum + 1);
291
292   if (UImm16MO.isImm()) {
293     O << '#' << UImm16MO.getImm();
294
295     if (ShiftMO.getImm() != 0)
296       O << ", lsl #" << (ShiftMO.getImm() * 16);
297
298     return;
299   }
300
301   O << "#" << *UImm16MO.getExpr();
302 }
303
304 void AArch64InstPrinter::printNamedImmOperand(const NamedImmMapper &Mapper,
305                                               const MCInst *MI, unsigned OpNum,
306                                               raw_ostream &O) {
307   bool ValidName;
308   const MCOperand &MO = MI->getOperand(OpNum);
309   StringRef Name = Mapper.toString(MO.getImm(), ValidName);
310
311   if (ValidName)
312     O << Name;
313   else
314     O << '#' << MO.getImm();
315 }
316
317 void
318 AArch64InstPrinter::printSysRegOperand(const A64SysReg::SysRegMapper &Mapper,
319                                        const MCInst *MI, unsigned OpNum,
320                                        raw_ostream &O) {
321   const MCOperand &MO = MI->getOperand(OpNum);
322
323   bool ValidName;
324   std::string Name = Mapper.toString(MO.getImm(), ValidName);
325   if (ValidName) {
326     O << Name;
327     return;
328   }
329 }
330
331
332 void AArch64InstPrinter::printRegExtendOperand(const MCInst *MI,
333                                                unsigned OpNum,
334                                                raw_ostream &O,
335                                                A64SE::ShiftExtSpecifiers Ext) {
336   // FIXME: In principle TableGen should be able to detect this itself far more
337   // easily. We will only accumulate more of these hacks.
338   unsigned Reg0 = MI->getOperand(0).getReg();
339   unsigned Reg1 = MI->getOperand(1).getReg();
340
341   if (isStackReg(Reg0) || isStackReg(Reg1)) {
342     A64SE::ShiftExtSpecifiers LSLEquiv;
343
344     if (Reg0 == AArch64::XSP || Reg1 == AArch64::XSP)
345       LSLEquiv = A64SE::UXTX;
346     else
347       LSLEquiv = A64SE::UXTW;
348
349     if (Ext == LSLEquiv) {
350       O << "lsl #" << MI->getOperand(OpNum).getImm();
351       return;
352     }
353   }
354
355   switch (Ext) {
356   case A64SE::UXTB: O << "uxtb"; break;
357   case A64SE::UXTH: O << "uxth"; break;
358   case A64SE::UXTW: O << "uxtw"; break;
359   case A64SE::UXTX: O << "uxtx"; break;
360   case A64SE::SXTB: O << "sxtb"; break;
361   case A64SE::SXTH: O << "sxth"; break;
362   case A64SE::SXTW: O << "sxtw"; break;
363   case A64SE::SXTX: O << "sxtx"; break;
364   default: llvm_unreachable("Unexpected shift type for printing");
365   }
366
367   const MCOperand &MO = MI->getOperand(OpNum);
368   if (MO.getImm() != 0)
369     O << " #" << MO.getImm();
370 }
371
372 template<int MemScale> void
373 AArch64InstPrinter::printSImm7ScaledOperand(const MCInst *MI, unsigned OpNum,
374                                       raw_ostream &O) {
375   const MCOperand &MOImm = MI->getOperand(OpNum);
376   int32_t Imm = unpackSignedImm(7, MOImm.getImm());
377
378   O << "#" << (Imm * MemScale);
379 }
380
381 void AArch64InstPrinter::printVPRRegister(const MCInst *MI, unsigned OpNo,
382                                           raw_ostream &O) {
383   unsigned Reg = MI->getOperand(OpNo).getReg();
384   std::string Name = getRegisterName(Reg);
385   Name[0] = 'v';
386   O << Name;
387 }
388
389 void AArch64InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
390                                       raw_ostream &O) {
391   const MCOperand &Op = MI->getOperand(OpNo);
392   if (Op.isReg()) {
393     unsigned Reg = Op.getReg();
394     O << getRegisterName(Reg);
395   } else if (Op.isImm()) {
396     O << '#' << Op.getImm();
397   } else {
398     assert(Op.isExpr() && "unknown operand kind in printOperand");
399     // If a symbolic branch target was added as a constant expression then print
400     // that address in hex.
401     const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
402     int64_t Address;
403     if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
404       O << "0x";
405       O.write_hex(Address);
406     }
407     else {
408       // Otherwise, just print the expression.
409       O << *Op.getExpr();
410     }
411   }
412 }
413
414
415 void AArch64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
416                                    StringRef Annot) {
417   if (MI->getOpcode() == AArch64::TLSDESCCALL) {
418     // This is a special assembler directive which applies an
419     // R_AARCH64_TLSDESC_CALL to the following (BLR) instruction. It has a fixed
420     // form outside the normal TableGenerated scheme.
421     O << "\t.tlsdesccall " << *MI->getOperand(0).getExpr();
422   } else if (!printAliasInstr(MI, O))
423     printInstruction(MI, O);
424
425   printAnnotation(O, Annot);
426 }
427
428 template <A64SE::ShiftExtSpecifiers Ext, bool isHalf>
429 void AArch64InstPrinter::printNeonMovImmShiftOperand(const MCInst *MI,
430                                                      unsigned OpNum,
431                                                      raw_ostream &O) {
432   const MCOperand &MO = MI->getOperand(OpNum);
433
434   assert(MO.isImm() &&
435          "Immediate operand required for Neon vector immediate inst.");
436
437   bool IsLSL = false;
438   if (Ext == A64SE::LSL)
439     IsLSL = true;
440   else if (Ext != A64SE::MSL)
441     llvm_unreachable("Invalid shift specifier in movi instruction");
442
443   int64_t Imm = MO.getImm();
444
445   // MSL and LSLH accepts encoded shift amount 0 or 1.
446   if ((!IsLSL || (IsLSL && isHalf)) && Imm != 0 && Imm != 1)
447     llvm_unreachable("Invalid shift amount in movi instruction");
448
449   // LSH accepts encoded shift amount 0, 1, 2 or 3.
450   if (IsLSL && (Imm < 0 || Imm > 3))
451     llvm_unreachable("Invalid shift amount in movi instruction");
452
453   // Print shift amount as multiple of 8 with MSL encoded shift amount
454   // 0 and 1 printed as 8 and 16.
455   if (!IsLSL)
456     Imm++;
457   Imm *= 8;
458
459   // LSL #0 is not printed
460   if (IsLSL) {
461     if (Imm == 0)
462       return;
463     O << ", lsl";
464   } else
465     O << ", msl";
466
467   O << " #" << Imm;
468 }
469
470 void AArch64InstPrinter::printNeonUImm0Operand(const MCInst *MI, unsigned OpNum,
471                                                raw_ostream &o) {
472   o << "#0x0";
473 }
474
475 void AArch64InstPrinter::printUImmHexOperand(const MCInst *MI, unsigned OpNum,
476                                              raw_ostream &O) {
477   const MCOperand &MOUImm = MI->getOperand(OpNum);
478
479   assert(MOUImm.isImm() &&
480          "Immediate operand required for Neon vector immediate inst.");
481
482   unsigned Imm = MOUImm.getImm();
483
484   O << "#0x";
485   O.write_hex(Imm);
486 }
487
488 void AArch64InstPrinter::printUImmBareOperand(const MCInst *MI,
489                                               unsigned OpNum,
490                                               raw_ostream &O) {
491   const MCOperand &MOUImm = MI->getOperand(OpNum);
492
493   assert(MOUImm.isImm()
494          && "Immediate operand required for Neon vector immediate inst.");
495
496   unsigned Imm = MOUImm.getImm();
497   O << Imm;
498 }
499
500 void AArch64InstPrinter::printNeonUImm64MaskOperand(const MCInst *MI,
501                                                     unsigned OpNum,
502                                                     raw_ostream &O) {
503   const MCOperand &MOUImm8 = MI->getOperand(OpNum);
504
505   assert(MOUImm8.isImm() &&
506          "Immediate operand required for Neon vector immediate bytemask inst.");
507
508   uint32_t UImm8 = MOUImm8.getImm();
509   uint64_t Mask = 0;
510
511   // Replicates 0x00 or 0xff byte in a 64-bit vector
512   for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
513     if ((UImm8 >> ByteNum) & 1)
514       Mask |= (uint64_t)0xff << (8 * ByteNum);
515   }
516
517   O << "#0x";
518   O.write_hex(Mask);
519 }
520
521 // If Count > 1, there are two valid kinds of vector list:
522 //   (1) {Vn.layout, Vn+1.layout, ... , Vm.layout}
523 //   (2) {Vn.layout - Vm.layout}
524 // We choose the first kind as output.
525 template <A64Layout::VectorLayout Layout, unsigned Count>
526 void AArch64InstPrinter::printVectorList(const MCInst *MI, unsigned OpNum,
527                                          raw_ostream &O) {
528   assert(Count >= 1 && Count <= 4 && "Invalid Number of Vectors");
529
530   unsigned Reg = MI->getOperand(OpNum).getReg();
531   std::string LayoutStr = A64VectorLayoutToString(Layout);
532   O << "{ ";
533   if (Count > 1) { // Print sub registers separately
534     bool IsVec64 = (Layout < A64Layout::VL_16B);
535     unsigned SubRegIdx = IsVec64 ? AArch64::dsub_0 : AArch64::qsub_0;
536     for (unsigned I = 0; I < Count; I++) {
537       std::string Name = getRegisterName(MRI.getSubReg(Reg, SubRegIdx++));
538       Name[0] = 'v';
539       O << Name << LayoutStr;
540       if (I != Count - 1)
541         O << ", ";
542     }
543   } else { // Print the register directly when NumVecs is 1.
544     std::string Name = getRegisterName(Reg);
545     Name[0] = 'v';
546     O << Name << LayoutStr;
547   }
548   O << " }";
549 }