ce665048c371932d99cc73965e5f8cc60e9fb8bc
[oota-llvm.git] / lib / Target / AArch64 / AArch64RegisterInfo.cpp
1 //===- AArch64RegisterInfo.cpp - AArch64 Register 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 TargetRegisterInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14
15 #include "AArch64RegisterInfo.h"
16 #include "AArch64FrameLowering.h"
17 #include "AArch64MachineFunctionInfo.h"
18 #include "AArch64TargetMachine.h"
19 #include "MCTargetDesc/AArch64MCTargetDesc.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/CodeGen/RegisterScavenging.h"
24 #include "llvm/ADT/BitVector.h"
25
26 #define GET_REGINFO_TARGET_DESC
27 #include "AArch64GenRegisterInfo.inc"
28
29 using namespace llvm;
30
31 AArch64RegisterInfo::AArch64RegisterInfo(const AArch64InstrInfo &tii,
32                                          const AArch64Subtarget &sti)
33   : AArch64GenRegisterInfo(AArch64::X30), TII(tii) {
34 }
35
36 const uint16_t *
37 AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
38   return CSR_PCS_SaveList;
39 }
40
41 const uint32_t*
42 AArch64RegisterInfo::getCallPreservedMask(CallingConv::ID) const {
43   return CSR_PCS_RegMask;
44 }
45
46 const uint32_t *AArch64RegisterInfo::getTLSDescCallPreservedMask() const {
47   return TLSDesc_RegMask;
48 }
49
50 const TargetRegisterClass *
51 AArch64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
52   if (RC == &AArch64::FlagClassRegClass)
53     return &AArch64::GPR64RegClass;
54
55   return RC;
56 }
57
58
59
60 BitVector
61 AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
62   BitVector Reserved(getNumRegs());
63   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
64
65   Reserved.set(AArch64::XSP);
66   Reserved.set(AArch64::WSP);
67
68   Reserved.set(AArch64::XZR);
69   Reserved.set(AArch64::WZR);
70
71   if (TFI->hasFP(MF)) {
72     Reserved.set(AArch64::X29);
73     Reserved.set(AArch64::W29);
74   }
75
76   return Reserved;
77 }
78
79 void
80 AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBI,
81                                          int SPAdj, RegScavenger *RS) const {
82   assert(SPAdj == 0 && "Cannot deal with nonzero SPAdj yet");
83   MachineInstr &MI = *MBBI;
84   MachineBasicBlock &MBB = *MI.getParent();
85   MachineFunction &MF = *MBB.getParent();
86   MachineFrameInfo *MFI = MF.getFrameInfo();
87   const AArch64FrameLowering *TFI =
88     static_cast<const AArch64FrameLowering *>(MF.getTarget().getFrameLowering());
89
90   unsigned i = 0;
91   while (!MI.getOperand(i).isFI()) {
92     ++i;
93     assert(i < MI.getNumOperands() && "Instr doesn't have a FrameIndex Operand");
94   }
95
96   // In order to work out the base and offset for addressing, the FrameLowering
97   // code needs to know (sometimes) whether the instruction is storing/loading a
98   // callee-saved register, or whether it's a more generic
99   // operation. Fortunately the frame indices are used *only* for that purpose
100   // and are contiguous, so we can check here.
101   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
102   int MinCSFI = 0;
103   int MaxCSFI = -1;
104
105   if (CSI.size()) {
106     MinCSFI = CSI[0].getFrameIdx();
107     MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
108   }
109
110   int FrameIndex = MI.getOperand(i).getIndex();
111   bool IsCalleeSaveOp = FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI;
112
113   unsigned FrameReg;
114   int64_t Offset;
115   Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj,
116                                            IsCalleeSaveOp);
117
118   Offset += MI.getOperand(i+1).getImm();
119
120   // DBG_VALUE instructions have no real restrictions so they can be handled
121   // easily.
122   if (MI.isDebugValue()) {
123     MI.getOperand(i).ChangeToRegister(FrameReg, /*isDef=*/ false);
124     MI.getOperand(i+1).ChangeToImmediate(Offset);
125     return;
126   }
127
128   int MinOffset, MaxOffset, OffsetScale;
129   if (MI.getOpcode() == AArch64::ADDxxi_lsl0_s) {
130     MinOffset = 0;
131     MaxOffset = 0xfff;
132     OffsetScale = 1;
133   } else {
134     // Load/store of a stack object
135     TII.getAddressConstraints(MI, OffsetScale, MinOffset, MaxOffset);
136   }
137
138   // The frame lowering has told us a base and offset it thinks we should use to
139   // access this variable, but it's still up to us to make sure the values are
140   // legal for the instruction in question.
141   if (Offset % OffsetScale != 0 || Offset < MinOffset || Offset > MaxOffset) {
142     unsigned BaseReg =
143       MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
144     emitRegUpdate(MBB, MBBI, MBBI->getDebugLoc(), TII,
145                   BaseReg, FrameReg, BaseReg, Offset);
146     FrameReg = BaseReg;
147     Offset = 0;
148   }
149
150   // Negative offsets are expected if we address from FP, but for
151   // now this checks nothing has gone horribly wrong.
152   assert(Offset >= 0 && "Unexpected negative offset from SP");
153
154   MI.getOperand(i).ChangeToRegister(FrameReg, false, false, true);
155   MI.getOperand(i+1).ChangeToImmediate(Offset / OffsetScale);
156 }
157
158 void
159 AArch64RegisterInfo::eliminateCallFramePseudoInstr(MachineFunction &MF,
160                                          MachineBasicBlock &MBB,
161                                          MachineBasicBlock::iterator MI) const {
162   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
163   DebugLoc dl = MI->getDebugLoc();
164   int Opcode = MI->getOpcode();
165   bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode();
166   uint64_t CalleePopAmount = IsDestroy ? MI->getOperand(1).getImm() : 0;
167
168   if (!TFI->hasReservedCallFrame(MF)) {
169     unsigned Align = TFI->getStackAlignment();
170
171     uint64_t Amount = MI->getOperand(0).getImm();
172     Amount = (Amount + Align - 1)/Align * Align;
173     if (!IsDestroy) Amount = -Amount;
174
175     // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it
176     // doesn't have to pop anything), then the first operand will be zero too so
177     // this adjustment is a no-op.
178     if (CalleePopAmount == 0) {
179       // FIXME: in-function stack adjustment for calls is limited to 12-bits
180       // because there's no guaranteed temporary register available. Mostly call
181       // frames will be allocated at the start of a function so this is OK, but
182       // it is a limitation that needs dealing with.
183       assert(abs(Amount) < 0xfff && "call frame too large");
184       emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, Amount);
185     }
186   } else if (CalleePopAmount != 0) {
187     // If the calling convention demands that the callee pops arguments from the
188     // stack, we want to add it back if we have a reserved call frame.
189     assert(CalleePopAmount < 0xfff && "call frame too large");
190     emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, -CalleePopAmount);
191   }
192
193   MBB.erase(MI);
194 }
195
196 unsigned
197 AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
198   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
199
200   if (TFI->hasFP(MF))
201     return AArch64::X29;
202   else
203     return AArch64::XSP;
204 }
205
206 bool
207 AArch64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
208   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
209   const AArch64FrameLowering *AFI = static_cast<const AArch64FrameLowering*>(TFI);
210   return AFI->useFPForAddressing(MF);
211 }