AArch64InstrInfo.cpp revision 263508
1//===- AArch64InstrInfo.cpp - AArch64 Instruction Information -------------===//
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 file contains the AArch64 implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AArch64.h"
15#include "AArch64InstrInfo.h"
16#include "AArch64MachineFunctionInfo.h"
17#include "AArch64TargetMachine.h"
18#include "MCTargetDesc/AArch64MCTargetDesc.h"
19#include "Utils/AArch64BaseInfo.h"
20#include "llvm/CodeGen/MachineConstantPool.h"
21#include "llvm/CodeGen/MachineDominators.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunctionPass.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
25#include "llvm/CodeGen/MachineRegisterInfo.h"
26#include "llvm/IR/Function.h"
27#include "llvm/Support/ErrorHandling.h"
28#include "llvm/Support/TargetRegistry.h"
29
30#include <algorithm>
31
32#define GET_INSTRINFO_CTOR_DTOR
33#include "AArch64GenInstrInfo.inc"
34
35using namespace llvm;
36
37AArch64InstrInfo::AArch64InstrInfo(const AArch64Subtarget &STI)
38  : AArch64GenInstrInfo(AArch64::ADJCALLSTACKDOWN, AArch64::ADJCALLSTACKUP),
39    Subtarget(STI) {}
40
41void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
42                                   MachineBasicBlock::iterator I, DebugLoc DL,
43                                   unsigned DestReg, unsigned SrcReg,
44                                   bool KillSrc) const {
45  unsigned Opc = 0;
46  unsigned ZeroReg = 0;
47  if (DestReg == AArch64::XSP || SrcReg == AArch64::XSP) {
48    // E.g. ADD xDst, xsp, #0 (, lsl #0)
49    BuildMI(MBB, I, DL, get(AArch64::ADDxxi_lsl0_s), DestReg)
50      .addReg(SrcReg)
51      .addImm(0);
52    return;
53  } else if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) {
54    // E.g. ADD wDST, wsp, #0 (, lsl #0)
55    BuildMI(MBB, I, DL, get(AArch64::ADDwwi_lsl0_s), DestReg)
56      .addReg(SrcReg)
57      .addImm(0);
58    return;
59  } else if (DestReg == AArch64::NZCV) {
60    assert(AArch64::GPR64RegClass.contains(SrcReg));
61    // E.g. MSR NZCV, xDST
62    BuildMI(MBB, I, DL, get(AArch64::MSRix))
63      .addImm(A64SysReg::NZCV)
64      .addReg(SrcReg);
65  } else if (SrcReg == AArch64::NZCV) {
66    assert(AArch64::GPR64RegClass.contains(DestReg));
67    // E.g. MRS xDST, NZCV
68    BuildMI(MBB, I, DL, get(AArch64::MRSxi), DestReg)
69      .addImm(A64SysReg::NZCV);
70  } else if (AArch64::GPR64RegClass.contains(DestReg)) {
71    if(AArch64::GPR64RegClass.contains(SrcReg)){
72      Opc = AArch64::ORRxxx_lsl;
73      ZeroReg = AArch64::XZR;
74    } else{
75      assert(AArch64::FPR64RegClass.contains(SrcReg));
76      BuildMI(MBB, I, DL, get(AArch64::FMOVxd), DestReg)
77        .addReg(SrcReg);
78      return;
79    }
80  } else if (AArch64::GPR32RegClass.contains(DestReg)) {
81    if(AArch64::GPR32RegClass.contains(SrcReg)){
82      Opc = AArch64::ORRwww_lsl;
83      ZeroReg = AArch64::WZR;
84    } else{
85      assert(AArch64::FPR32RegClass.contains(SrcReg));
86      BuildMI(MBB, I, DL, get(AArch64::FMOVws), DestReg)
87        .addReg(SrcReg);
88      return;
89    }
90  } else if (AArch64::FPR32RegClass.contains(DestReg)) {
91    if(AArch64::FPR32RegClass.contains(SrcReg)){
92      BuildMI(MBB, I, DL, get(AArch64::FMOVss), DestReg)
93        .addReg(SrcReg);
94      return;
95    }
96    else {
97      assert(AArch64::GPR32RegClass.contains(SrcReg));
98      BuildMI(MBB, I, DL, get(AArch64::FMOVsw), DestReg)
99        .addReg(SrcReg);
100      return;
101    }
102  } else if (AArch64::FPR64RegClass.contains(DestReg)) {
103    if(AArch64::FPR64RegClass.contains(SrcReg)){
104      BuildMI(MBB, I, DL, get(AArch64::FMOVdd), DestReg)
105        .addReg(SrcReg);
106      return;
107    }
108    else {
109      assert(AArch64::GPR64RegClass.contains(SrcReg));
110      BuildMI(MBB, I, DL, get(AArch64::FMOVdx), DestReg)
111        .addReg(SrcReg);
112      return;
113    }
114  } else if (AArch64::FPR128RegClass.contains(DestReg)) {
115    assert(AArch64::FPR128RegClass.contains(SrcReg));
116
117    // If NEON is enable, we use ORR to implement this copy.
118    // If NEON isn't available, emit STR and LDR to handle this.
119    if(getSubTarget().hasNEON()) {
120      BuildMI(MBB, I, DL, get(AArch64::ORRvvv_16B), DestReg)
121        .addReg(SrcReg)
122        .addReg(SrcReg);
123      return;
124    } else {
125      BuildMI(MBB, I, DL, get(AArch64::LSFP128_PreInd_STR), AArch64::XSP)
126        .addReg(SrcReg)
127        .addReg(AArch64::XSP)
128        .addImm(0x1ff & -16);
129
130      BuildMI(MBB, I, DL, get(AArch64::LSFP128_PostInd_LDR), DestReg)
131        .addReg(AArch64::XSP, RegState::Define)
132        .addReg(AArch64::XSP)
133        .addImm(16);
134      return;
135    }
136  } else {
137    llvm_unreachable("Unknown register class in copyPhysReg");
138  }
139
140  // E.g. ORR xDst, xzr, xSrc, lsl #0
141  BuildMI(MBB, I, DL, get(Opc), DestReg)
142    .addReg(ZeroReg)
143    .addReg(SrcReg)
144    .addImm(0);
145}
146
147/// Does the Opcode represent a conditional branch that we can remove and re-add
148/// at the end of a basic block?
149static bool isCondBranch(unsigned Opc) {
150  return Opc == AArch64::Bcc || Opc == AArch64::CBZw || Opc == AArch64::CBZx ||
151         Opc == AArch64::CBNZw || Opc == AArch64::CBNZx ||
152         Opc == AArch64::TBZwii || Opc == AArch64::TBZxii ||
153         Opc == AArch64::TBNZwii || Opc == AArch64::TBNZxii;
154}
155
156/// Takes apart a given conditional branch MachineInstr (see isCondBranch),
157/// setting TBB to the destination basic block and populating the Cond vector
158/// with data necessary to recreate the conditional branch at a later
159/// date. First element will be the opcode, and subsequent ones define the
160/// conditions being branched on in an instruction-specific manner.
161static void classifyCondBranch(MachineInstr *I, MachineBasicBlock *&TBB,
162                               SmallVectorImpl<MachineOperand> &Cond) {
163  switch(I->getOpcode()) {
164  case AArch64::Bcc:
165  case AArch64::CBZw:
166  case AArch64::CBZx:
167  case AArch64::CBNZw:
168  case AArch64::CBNZx:
169    // These instructions just have one predicate operand in position 0 (either
170    // a condition code or a register being compared).
171    Cond.push_back(MachineOperand::CreateImm(I->getOpcode()));
172    Cond.push_back(I->getOperand(0));
173    TBB = I->getOperand(1).getMBB();
174    return;
175  case AArch64::TBZwii:
176  case AArch64::TBZxii:
177  case AArch64::TBNZwii:
178  case AArch64::TBNZxii:
179    // These have two predicate operands: a register and a bit position.
180    Cond.push_back(MachineOperand::CreateImm(I->getOpcode()));
181    Cond.push_back(I->getOperand(0));
182    Cond.push_back(I->getOperand(1));
183    TBB = I->getOperand(2).getMBB();
184    return;
185  default:
186    llvm_unreachable("Unknown conditional branch to classify");
187  }
188}
189
190
191bool
192AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
193                                MachineBasicBlock *&FBB,
194                                SmallVectorImpl<MachineOperand> &Cond,
195                                bool AllowModify) const {
196  // If the block has no terminators, it just falls into the block after it.
197  MachineBasicBlock::iterator I = MBB.end();
198  if (I == MBB.begin())
199    return false;
200  --I;
201  while (I->isDebugValue()) {
202    if (I == MBB.begin())
203      return false;
204    --I;
205  }
206  if (!isUnpredicatedTerminator(I))
207    return false;
208
209  // Get the last instruction in the block.
210  MachineInstr *LastInst = I;
211
212  // If there is only one terminator instruction, process it.
213  unsigned LastOpc = LastInst->getOpcode();
214  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
215    if (LastOpc == AArch64::Bimm) {
216      TBB = LastInst->getOperand(0).getMBB();
217      return false;
218    }
219    if (isCondBranch(LastOpc)) {
220      classifyCondBranch(LastInst, TBB, Cond);
221      return false;
222    }
223    return true;  // Can't handle indirect branch.
224  }
225
226  // Get the instruction before it if it is a terminator.
227  MachineInstr *SecondLastInst = I;
228  unsigned SecondLastOpc = SecondLastInst->getOpcode();
229
230  // If AllowModify is true and the block ends with two or more unconditional
231  // branches, delete all but the first unconditional branch.
232  if (AllowModify && LastOpc == AArch64::Bimm) {
233    while (SecondLastOpc == AArch64::Bimm) {
234      LastInst->eraseFromParent();
235      LastInst = SecondLastInst;
236      LastOpc = LastInst->getOpcode();
237      if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
238        // Return now the only terminator is an unconditional branch.
239        TBB = LastInst->getOperand(0).getMBB();
240        return false;
241      } else {
242        SecondLastInst = I;
243        SecondLastOpc = SecondLastInst->getOpcode();
244      }
245    }
246  }
247
248  // If there are three terminators, we don't know what sort of block this is.
249  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
250    return true;
251
252  // If the block ends with a B and a Bcc, handle it.
253  if (LastOpc == AArch64::Bimm) {
254    if (SecondLastOpc == AArch64::Bcc) {
255      TBB =  SecondLastInst->getOperand(1).getMBB();
256      Cond.push_back(MachineOperand::CreateImm(AArch64::Bcc));
257      Cond.push_back(SecondLastInst->getOperand(0));
258      FBB = LastInst->getOperand(0).getMBB();
259      return false;
260    } else if (isCondBranch(SecondLastOpc)) {
261      classifyCondBranch(SecondLastInst, TBB, Cond);
262      FBB = LastInst->getOperand(0).getMBB();
263      return false;
264    }
265  }
266
267  // If the block ends with two unconditional branches, handle it.  The second
268  // one is not executed, so remove it.
269  if (SecondLastOpc == AArch64::Bimm && LastOpc == AArch64::Bimm) {
270    TBB = SecondLastInst->getOperand(0).getMBB();
271    I = LastInst;
272    if (AllowModify)
273      I->eraseFromParent();
274    return false;
275  }
276
277  // Otherwise, can't handle this.
278  return true;
279}
280
281bool AArch64InstrInfo::ReverseBranchCondition(
282                                  SmallVectorImpl<MachineOperand> &Cond) const {
283  switch (Cond[0].getImm()) {
284  case AArch64::Bcc: {
285    A64CC::CondCodes CC = static_cast<A64CC::CondCodes>(Cond[1].getImm());
286    CC = A64InvertCondCode(CC);
287    Cond[1].setImm(CC);
288    return false;
289  }
290  case AArch64::CBZw:
291    Cond[0].setImm(AArch64::CBNZw);
292    return false;
293  case AArch64::CBZx:
294    Cond[0].setImm(AArch64::CBNZx);
295    return false;
296  case AArch64::CBNZw:
297    Cond[0].setImm(AArch64::CBZw);
298    return false;
299  case AArch64::CBNZx:
300    Cond[0].setImm(AArch64::CBZx);
301    return false;
302  case AArch64::TBZwii:
303    Cond[0].setImm(AArch64::TBNZwii);
304    return false;
305  case AArch64::TBZxii:
306    Cond[0].setImm(AArch64::TBNZxii);
307    return false;
308  case AArch64::TBNZwii:
309    Cond[0].setImm(AArch64::TBZwii);
310    return false;
311  case AArch64::TBNZxii:
312    Cond[0].setImm(AArch64::TBZxii);
313    return false;
314  default:
315    llvm_unreachable("Unknown branch type");
316  }
317}
318
319
320unsigned
321AArch64InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
322                               MachineBasicBlock *FBB,
323                               const SmallVectorImpl<MachineOperand> &Cond,
324                               DebugLoc DL) const {
325  if (FBB == 0 && Cond.empty()) {
326    BuildMI(&MBB, DL, get(AArch64::Bimm)).addMBB(TBB);
327    return 1;
328  } else if (FBB == 0) {
329    MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
330    for (int i = 1, e = Cond.size(); i != e; ++i)
331      MIB.addOperand(Cond[i]);
332    MIB.addMBB(TBB);
333    return 1;
334  }
335
336  MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
337  for (int i = 1, e = Cond.size(); i != e; ++i)
338    MIB.addOperand(Cond[i]);
339  MIB.addMBB(TBB);
340
341  BuildMI(&MBB, DL, get(AArch64::Bimm)).addMBB(FBB);
342  return 2;
343}
344
345unsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
346  MachineBasicBlock::iterator I = MBB.end();
347  if (I == MBB.begin()) return 0;
348  --I;
349  while (I->isDebugValue()) {
350    if (I == MBB.begin())
351      return 0;
352    --I;
353  }
354  if (I->getOpcode() != AArch64::Bimm && !isCondBranch(I->getOpcode()))
355    return 0;
356
357  // Remove the branch.
358  I->eraseFromParent();
359
360  I = MBB.end();
361
362  if (I == MBB.begin()) return 1;
363  --I;
364  if (!isCondBranch(I->getOpcode()))
365    return 1;
366
367  // Remove the branch.
368  I->eraseFromParent();
369  return 2;
370}
371
372bool
373AArch64InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const {
374  MachineInstr &MI = *MBBI;
375  MachineBasicBlock &MBB = *MI.getParent();
376
377  unsigned Opcode = MI.getOpcode();
378  switch (Opcode) {
379  case AArch64::TLSDESC_BLRx: {
380    MachineInstr *NewMI =
381      BuildMI(MBB, MBBI, MI.getDebugLoc(), get(AArch64::TLSDESCCALL))
382        .addOperand(MI.getOperand(1));
383    MI.setDesc(get(AArch64::BLRx));
384
385    llvm::finalizeBundle(MBB, NewMI, *++MBBI);
386    return true;
387    }
388  default:
389    return false;
390  }
391
392  return false;
393}
394
395void
396AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
397                                      MachineBasicBlock::iterator MBBI,
398                                      unsigned SrcReg, bool isKill,
399                                      int FrameIdx,
400                                      const TargetRegisterClass *RC,
401                                      const TargetRegisterInfo *TRI) const {
402  DebugLoc DL = MBB.findDebugLoc(MBBI);
403  MachineFunction &MF = *MBB.getParent();
404  MachineFrameInfo &MFI = *MF.getFrameInfo();
405  unsigned Align = MFI.getObjectAlignment(FrameIdx);
406
407  MachineMemOperand *MMO
408    = MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
409                              MachineMemOperand::MOStore,
410                              MFI.getObjectSize(FrameIdx),
411                              Align);
412
413  unsigned StoreOp = 0;
414  if (RC->hasType(MVT::i64) || RC->hasType(MVT::i32)) {
415    switch(RC->getSize()) {
416    case 4: StoreOp = AArch64::LS32_STR; break;
417    case 8: StoreOp = AArch64::LS64_STR; break;
418    default:
419      llvm_unreachable("Unknown size for regclass");
420    }
421  } else {
422    assert((RC->hasType(MVT::f32) || RC->hasType(MVT::f64) ||
423            RC->hasType(MVT::f128))
424           && "Expected integer or floating type for store");
425    switch (RC->getSize()) {
426    case 4: StoreOp = AArch64::LSFP32_STR; break;
427    case 8: StoreOp = AArch64::LSFP64_STR; break;
428    case 16: StoreOp = AArch64::LSFP128_STR; break;
429    default:
430      llvm_unreachable("Unknown size for regclass");
431    }
432  }
433
434  MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(StoreOp));
435  NewMI.addReg(SrcReg, getKillRegState(isKill))
436    .addFrameIndex(FrameIdx)
437    .addImm(0)
438    .addMemOperand(MMO);
439
440}
441
442void
443AArch64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
444                                       MachineBasicBlock::iterator MBBI,
445                                       unsigned DestReg, int FrameIdx,
446                                       const TargetRegisterClass *RC,
447                                       const TargetRegisterInfo *TRI) const {
448  DebugLoc DL = MBB.findDebugLoc(MBBI);
449  MachineFunction &MF = *MBB.getParent();
450  MachineFrameInfo &MFI = *MF.getFrameInfo();
451  unsigned Align = MFI.getObjectAlignment(FrameIdx);
452
453  MachineMemOperand *MMO
454    = MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
455                              MachineMemOperand::MOLoad,
456                              MFI.getObjectSize(FrameIdx),
457                              Align);
458
459  unsigned LoadOp = 0;
460  if (RC->hasType(MVT::i64) || RC->hasType(MVT::i32)) {
461    switch(RC->getSize()) {
462    case 4: LoadOp = AArch64::LS32_LDR; break;
463    case 8: LoadOp = AArch64::LS64_LDR; break;
464    default:
465      llvm_unreachable("Unknown size for regclass");
466    }
467  } else {
468    assert((RC->hasType(MVT::f32) || RC->hasType(MVT::f64)
469            || RC->hasType(MVT::f128))
470           && "Expected integer or floating type for store");
471    switch (RC->getSize()) {
472    case 4: LoadOp = AArch64::LSFP32_LDR; break;
473    case 8: LoadOp = AArch64::LSFP64_LDR; break;
474    case 16: LoadOp = AArch64::LSFP128_LDR; break;
475    default:
476      llvm_unreachable("Unknown size for regclass");
477    }
478  }
479
480  MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(LoadOp), DestReg);
481  NewMI.addFrameIndex(FrameIdx)
482       .addImm(0)
483       .addMemOperand(MMO);
484}
485
486unsigned AArch64InstrInfo::estimateRSStackLimit(MachineFunction &MF) const {
487  unsigned Limit = (1 << 16) - 1;
488  for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
489    for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
490         I != E; ++I) {
491      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
492        if (!I->getOperand(i).isFI()) continue;
493
494        // When using ADDxxi_lsl0_s to get the address of a stack object, 0xfff
495        // is the largest offset guaranteed to fit in the immediate offset.
496        if (I->getOpcode() == AArch64::ADDxxi_lsl0_s) {
497          Limit = std::min(Limit, 0xfffu);
498          break;
499        }
500
501        int AccessScale, MinOffset, MaxOffset;
502        getAddressConstraints(*I, AccessScale, MinOffset, MaxOffset);
503        Limit = std::min(Limit, static_cast<unsigned>(MaxOffset));
504
505        break; // At most one FI per instruction
506      }
507    }
508  }
509
510  return Limit;
511}
512void AArch64InstrInfo::getAddressConstraints(const MachineInstr &MI,
513                                             int &AccessScale, int &MinOffset,
514                                             int &MaxOffset) const {
515  switch (MI.getOpcode()) {
516  default: llvm_unreachable("Unkown load/store kind");
517  case TargetOpcode::DBG_VALUE:
518    AccessScale = 1;
519    MinOffset = INT_MIN;
520    MaxOffset = INT_MAX;
521    return;
522  case AArch64::LS8_LDR: case AArch64::LS8_STR:
523  case AArch64::LSFP8_LDR: case AArch64::LSFP8_STR:
524  case AArch64::LDRSBw:
525  case AArch64::LDRSBx:
526    AccessScale = 1;
527    MinOffset = 0;
528    MaxOffset = 0xfff;
529    return;
530  case AArch64::LS16_LDR: case AArch64::LS16_STR:
531  case AArch64::LSFP16_LDR: case AArch64::LSFP16_STR:
532  case AArch64::LDRSHw:
533  case AArch64::LDRSHx:
534    AccessScale = 2;
535    MinOffset = 0;
536    MaxOffset = 0xfff * AccessScale;
537    return;
538  case AArch64::LS32_LDR:  case AArch64::LS32_STR:
539  case AArch64::LSFP32_LDR: case AArch64::LSFP32_STR:
540  case AArch64::LDRSWx:
541  case AArch64::LDPSWx:
542    AccessScale = 4;
543    MinOffset = 0;
544    MaxOffset = 0xfff * AccessScale;
545    return;
546  case AArch64::LS64_LDR: case AArch64::LS64_STR:
547  case AArch64::LSFP64_LDR: case AArch64::LSFP64_STR:
548  case AArch64::PRFM:
549    AccessScale = 8;
550    MinOffset = 0;
551    MaxOffset = 0xfff * AccessScale;
552    return;
553  case AArch64::LSFP128_LDR: case AArch64::LSFP128_STR:
554    AccessScale = 16;
555    MinOffset = 0;
556    MaxOffset = 0xfff * AccessScale;
557    return;
558  case AArch64::LSPair32_LDR: case AArch64::LSPair32_STR:
559  case AArch64::LSFPPair32_LDR: case AArch64::LSFPPair32_STR:
560    AccessScale = 4;
561    MinOffset = -0x40 * AccessScale;
562    MaxOffset = 0x3f * AccessScale;
563    return;
564  case AArch64::LSPair64_LDR: case AArch64::LSPair64_STR:
565  case AArch64::LSFPPair64_LDR: case AArch64::LSFPPair64_STR:
566    AccessScale = 8;
567    MinOffset = -0x40 * AccessScale;
568    MaxOffset = 0x3f * AccessScale;
569    return;
570  case AArch64::LSFPPair128_LDR: case AArch64::LSFPPair128_STR:
571    AccessScale = 16;
572    MinOffset = -0x40 * AccessScale;
573    MaxOffset = 0x3f * AccessScale;
574    return;
575  }
576}
577
578unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
579  const MCInstrDesc &MCID = MI.getDesc();
580  const MachineBasicBlock &MBB = *MI.getParent();
581  const MachineFunction &MF = *MBB.getParent();
582  const MCAsmInfo &MAI = *MF.getTarget().getMCAsmInfo();
583
584  if (MCID.getSize())
585    return MCID.getSize();
586
587  if (MI.getOpcode() == AArch64::INLINEASM)
588    return getInlineAsmLength(MI.getOperand(0).getSymbolName(), MAI);
589
590  if (MI.isLabel())
591    return 0;
592
593  switch (MI.getOpcode()) {
594  case TargetOpcode::BUNDLE:
595    return getInstBundleLength(MI);
596  case TargetOpcode::IMPLICIT_DEF:
597  case TargetOpcode::KILL:
598  case TargetOpcode::PROLOG_LABEL:
599  case TargetOpcode::EH_LABEL:
600  case TargetOpcode::DBG_VALUE:
601    return 0;
602  case AArch64::TLSDESCCALL:
603    return 0;
604  default:
605    llvm_unreachable("Unknown instruction class");
606  }
607}
608
609unsigned AArch64InstrInfo::getInstBundleLength(const MachineInstr &MI) const {
610  unsigned Size = 0;
611  MachineBasicBlock::const_instr_iterator I = MI;
612  MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
613  while (++I != E && I->isInsideBundle()) {
614    assert(!I->isBundle() && "No nested bundle!");
615    Size += getInstSizeInBytes(*I);
616  }
617  return Size;
618}
619
620bool llvm::rewriteA64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
621                                unsigned FrameReg, int &Offset,
622                                const AArch64InstrInfo &TII) {
623  MachineBasicBlock &MBB = *MI.getParent();
624  MachineFunction &MF = *MBB.getParent();
625  MachineFrameInfo &MFI = *MF.getFrameInfo();
626
627  MFI.getObjectOffset(FrameRegIdx);
628  llvm_unreachable("Unimplemented rewriteFrameIndex");
629}
630
631void llvm::emitRegUpdate(MachineBasicBlock &MBB,
632                         MachineBasicBlock::iterator MBBI,
633                         DebugLoc dl, const TargetInstrInfo &TII,
634                         unsigned DstReg, unsigned SrcReg, unsigned ScratchReg,
635                         int64_t NumBytes, MachineInstr::MIFlag MIFlags) {
636  if (NumBytes == 0 && DstReg == SrcReg)
637    return;
638  else if (abs64(NumBytes) & ~0xffffff) {
639    // Generically, we have to materialize the offset into a temporary register
640    // and subtract it. There are a couple of ways this could be done, for now
641    // we'll use a movz/movk or movn/movk sequence.
642    uint64_t Bits = static_cast<uint64_t>(abs64(NumBytes));
643    BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVZxii), ScratchReg)
644      .addImm(0xffff & Bits).addImm(0)
645      .setMIFlags(MIFlags);
646
647    Bits >>= 16;
648    if (Bits & 0xffff) {
649      BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
650        .addReg(ScratchReg)
651        .addImm(0xffff & Bits).addImm(1)
652        .setMIFlags(MIFlags);
653    }
654
655    Bits >>= 16;
656    if (Bits & 0xffff) {
657      BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
658        .addReg(ScratchReg)
659        .addImm(0xffff & Bits).addImm(2)
660        .setMIFlags(MIFlags);
661    }
662
663    Bits >>= 16;
664    if (Bits & 0xffff) {
665      BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
666        .addReg(ScratchReg)
667        .addImm(0xffff & Bits).addImm(3)
668        .setMIFlags(MIFlags);
669    }
670
671    // ADD DST, SRC, xTMP (, lsl #0)
672    unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx;
673    BuildMI(MBB, MBBI, dl, TII.get(AddOp), DstReg)
674      .addReg(SrcReg, RegState::Kill)
675      .addReg(ScratchReg, RegState::Kill)
676      .addImm(0)
677      .setMIFlag(MIFlags);
678    return;
679  }
680
681  // Now we know that the adjustment can be done in at most two add/sub
682  // (immediate) instructions, which is always more efficient than a
683  // literal-pool load, or even a hypothetical movz/movk/add sequence
684
685  // Decide whether we're doing addition or subtraction
686  unsigned LowOp, HighOp;
687  if (NumBytes >= 0) {
688    LowOp = AArch64::ADDxxi_lsl0_s;
689    HighOp = AArch64::ADDxxi_lsl12_s;
690  } else {
691    LowOp = AArch64::SUBxxi_lsl0_s;
692    HighOp = AArch64::SUBxxi_lsl12_s;
693    NumBytes = abs64(NumBytes);
694  }
695
696  // If we're here, at the very least a move needs to be produced, which just
697  // happens to be materializable by an ADD.
698  if ((NumBytes & 0xfff) || NumBytes == 0) {
699    BuildMI(MBB, MBBI, dl, TII.get(LowOp), DstReg)
700      .addReg(SrcReg, RegState::Kill)
701      .addImm(NumBytes & 0xfff)
702      .setMIFlag(MIFlags);
703
704    // Next update should use the register we've just defined.
705    SrcReg = DstReg;
706  }
707
708  if (NumBytes & 0xfff000) {
709    BuildMI(MBB, MBBI, dl, TII.get(HighOp), DstReg)
710      .addReg(SrcReg, RegState::Kill)
711      .addImm(NumBytes >> 12)
712      .setMIFlag(MIFlags);
713  }
714}
715
716void llvm::emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
717                        DebugLoc dl, const TargetInstrInfo &TII,
718                        unsigned ScratchReg, int64_t NumBytes,
719                        MachineInstr::MIFlag MIFlags) {
720  emitRegUpdate(MBB, MI, dl, TII, AArch64::XSP, AArch64::XSP, AArch64::X16,
721                NumBytes, MIFlags);
722}
723
724
725namespace {
726  struct LDTLSCleanup : public MachineFunctionPass {
727    static char ID;
728    LDTLSCleanup() : MachineFunctionPass(ID) {}
729
730    virtual bool runOnMachineFunction(MachineFunction &MF) {
731      AArch64MachineFunctionInfo* MFI
732        = MF.getInfo<AArch64MachineFunctionInfo>();
733      if (MFI->getNumLocalDynamicTLSAccesses() < 2) {
734        // No point folding accesses if there isn't at least two.
735        return false;
736      }
737
738      MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
739      return VisitNode(DT->getRootNode(), 0);
740    }
741
742    // Visit the dominator subtree rooted at Node in pre-order.
743    // If TLSBaseAddrReg is non-null, then use that to replace any
744    // TLS_base_addr instructions. Otherwise, create the register
745    // when the first such instruction is seen, and then use it
746    // as we encounter more instructions.
747    bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg) {
748      MachineBasicBlock *BB = Node->getBlock();
749      bool Changed = false;
750
751      // Traverse the current block.
752      for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;
753           ++I) {
754        switch (I->getOpcode()) {
755        case AArch64::TLSDESC_BLRx:
756          // Make sure it's a local dynamic access.
757          if (!I->getOperand(1).isSymbol() ||
758              strcmp(I->getOperand(1).getSymbolName(), "_TLS_MODULE_BASE_"))
759            break;
760
761          if (TLSBaseAddrReg)
762            I = ReplaceTLSBaseAddrCall(I, TLSBaseAddrReg);
763          else
764            I = SetRegister(I, &TLSBaseAddrReg);
765          Changed = true;
766          break;
767        default:
768          break;
769        }
770      }
771
772      // Visit the children of this block in the dominator tree.
773      for (MachineDomTreeNode::iterator I = Node->begin(), E = Node->end();
774           I != E; ++I) {
775        Changed |= VisitNode(*I, TLSBaseAddrReg);
776      }
777
778      return Changed;
779    }
780
781    // Replace the TLS_base_addr instruction I with a copy from
782    // TLSBaseAddrReg, returning the new instruction.
783    MachineInstr *ReplaceTLSBaseAddrCall(MachineInstr *I,
784                                         unsigned TLSBaseAddrReg) {
785      MachineFunction *MF = I->getParent()->getParent();
786      const AArch64TargetMachine *TM =
787          static_cast<const AArch64TargetMachine *>(&MF->getTarget());
788      const AArch64InstrInfo *TII = TM->getInstrInfo();
789
790      // Insert a Copy from TLSBaseAddrReg to x0, which is where the rest of the
791      // code sequence assumes the address will be.
792      MachineInstr *Copy = BuildMI(*I->getParent(), I, I->getDebugLoc(),
793                                   TII->get(TargetOpcode::COPY),
794                                   AArch64::X0)
795        .addReg(TLSBaseAddrReg);
796
797      // Erase the TLS_base_addr instruction.
798      I->eraseFromParent();
799
800      return Copy;
801    }
802
803    // Create a virtal register in *TLSBaseAddrReg, and populate it by
804    // inserting a copy instruction after I. Returns the new instruction.
805    MachineInstr *SetRegister(MachineInstr *I, unsigned *TLSBaseAddrReg) {
806      MachineFunction *MF = I->getParent()->getParent();
807      const AArch64TargetMachine *TM =
808          static_cast<const AArch64TargetMachine *>(&MF->getTarget());
809      const AArch64InstrInfo *TII = TM->getInstrInfo();
810
811      // Create a virtual register for the TLS base address.
812      MachineRegisterInfo &RegInfo = MF->getRegInfo();
813      *TLSBaseAddrReg = RegInfo.createVirtualRegister(&AArch64::GPR64RegClass);
814
815      // Insert a copy from X0 to TLSBaseAddrReg for later.
816      MachineInstr *Next = I->getNextNode();
817      MachineInstr *Copy = BuildMI(*I->getParent(), Next, I->getDebugLoc(),
818                                   TII->get(TargetOpcode::COPY),
819                                   *TLSBaseAddrReg)
820        .addReg(AArch64::X0);
821
822      return Copy;
823    }
824
825    virtual const char *getPassName() const {
826      return "Local Dynamic TLS Access Clean-up";
827    }
828
829    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
830      AU.setPreservesCFG();
831      AU.addRequired<MachineDominatorTree>();
832      MachineFunctionPass::getAnalysisUsage(AU);
833    }
834  };
835}
836
837char LDTLSCleanup::ID = 0;
838FunctionPass*
839llvm::createAArch64CleanupLocalDynamicTLSPass() { return new LDTLSCleanup(); }
840