]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / lib / Target / Mips / MipsSERegisterInfo.cpp
1 //===-- MipsSERegisterInfo.cpp - MIPS32/64 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 MIPS32/64 implementation of the TargetRegisterInfo
11 // class.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "MipsSERegisterInfo.h"
16 #include "Mips.h"
17 #include "MipsAnalyzeImmediate.h"
18 #include "MipsMachineFunction.h"
19 #include "MipsSEInstrInfo.h"
20 #include "MipsSubtarget.h"
21 #include "llvm/ADT/BitVector.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/CodeGen/MachineFrameInfo.h"
24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/CodeGen/ValueTypes.h"
28 #include "llvm/DebugInfo.h"
29 #include "llvm/IR/Constants.h"
30 #include "llvm/IR/Function.h"
31 #include "llvm/IR/Type.h"
32 #include "llvm/Support/CommandLine.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include "llvm/Target/TargetFrameLowering.h"
37 #include "llvm/Target/TargetInstrInfo.h"
38 #include "llvm/Target/TargetMachine.h"
39 #include "llvm/Target/TargetOptions.h"
40
41 using namespace llvm;
42
43 MipsSERegisterInfo::MipsSERegisterInfo(const MipsSubtarget &ST)
44   : MipsRegisterInfo(ST) {}
45
46 bool MipsSERegisterInfo::
47 requiresRegisterScavenging(const MachineFunction &MF) const {
48   return true;
49 }
50
51 bool MipsSERegisterInfo::
52 requiresFrameIndexScavenging(const MachineFunction &MF) const {
53   return true;
54 }
55
56 const TargetRegisterClass *
57 MipsSERegisterInfo::intRegClass(unsigned Size) const {
58   if (Size == 4)
59     return &Mips::GPR32RegClass;
60
61   assert(Size == 8);
62   return &Mips::GPR64RegClass;
63 }
64
65 /// Determine whether a given opcode is an MSA load/store (supporting 10-bit
66 /// offsets) or a non-MSA load/store (supporting 16-bit offsets).
67 static inline bool isMSALoadOrStore(const unsigned Opcode) {
68   switch (Opcode) {
69   case Mips::LD_B:
70   case Mips::LD_H:
71   case Mips::LD_W:
72   case Mips::LD_D:
73   case Mips::ST_B:
74   case Mips::ST_H:
75   case Mips::ST_W:
76   case Mips::ST_D:
77     return true;
78   default:
79     return false;
80   }
81 }
82
83 void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
84                                      unsigned OpNo, int FrameIndex,
85                                      uint64_t StackSize,
86                                      int64_t SPOffset) const {
87   MachineInstr &MI = *II;
88   MachineFunction &MF = *MI.getParent()->getParent();
89   MachineFrameInfo *MFI = MF.getFrameInfo();
90   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
91
92   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
93   int MinCSFI = 0;
94   int MaxCSFI = -1;
95
96   if (CSI.size()) {
97     MinCSFI = CSI[0].getFrameIdx();
98     MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
99   }
100
101   bool EhDataRegFI = MipsFI->isEhDataRegFI(FrameIndex);
102
103   // The following stack frame objects are always referenced relative to $sp:
104   //  1. Outgoing arguments.
105   //  2. Pointer to dynamically allocated stack space.
106   //  3. Locations for callee-saved registers.
107   //  4. Locations for eh data registers.
108   // Everything else is referenced relative to whatever register
109   // getFrameRegister() returns.
110   unsigned FrameReg;
111
112   if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI)
113     FrameReg = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP;
114   else
115     FrameReg = getFrameRegister(MF);
116
117   // Calculate final offset.
118   // - There is no need to change the offset if the frame object is one of the
119   //   following: an outgoing argument, pointer to a dynamically allocated
120   //   stack space or a $gp restore location,
121   // - If the frame object is any of the following, its offset must be adjusted
122   //   by adding the size of the stack:
123   //   incoming argument, callee-saved register location or local variable.
124   bool IsKill = false;
125   int64_t Offset;
126
127   Offset = SPOffset + (int64_t)StackSize;
128   Offset += MI.getOperand(OpNo + 1).getImm();
129
130   DEBUG(errs() << "Offset     : " << Offset << "\n" << "<--------->\n");
131
132   if (!MI.isDebugValue()) {
133     // Make sure Offset fits within the field available.
134     // For MSA instructions, this is a 10-bit signed immediate, otherwise it is
135     // a 16-bit signed immediate.
136     unsigned OffsetBitSize = isMSALoadOrStore(MI.getOpcode()) ? 10 : 16;
137
138     if (OffsetBitSize == 10 && !isInt<10>(Offset) && isInt<16>(Offset)) {
139       // If we have an offset that needs to fit into a signed 10-bit immediate
140       // and doesn't, but does fit into 16-bits then use an ADDiu
141       MachineBasicBlock &MBB = *MI.getParent();
142       DebugLoc DL = II->getDebugLoc();
143       unsigned ADDiu = Subtarget.isABI_N64() ? Mips::DADDiu : Mips::ADDiu;
144       const TargetRegisterClass *RC =
145           Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
146       MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
147       unsigned Reg = RegInfo.createVirtualRegister(RC);
148       const MipsSEInstrInfo &TII =
149           *static_cast<const MipsSEInstrInfo *>(
150                MBB.getParent()->getTarget().getInstrInfo());
151       BuildMI(MBB, II, DL, TII.get(ADDiu), Reg).addReg(FrameReg).addImm(Offset);
152
153       FrameReg = Reg;
154       Offset = 0;
155       IsKill = true;
156     } else if (!isInt<16>(Offset)) {
157       // Otherwise split the offset into 16-bit pieces and add it in multiple
158       // instructions.
159       MachineBasicBlock &MBB = *MI.getParent();
160       DebugLoc DL = II->getDebugLoc();
161       unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu;
162       unsigned NewImm = 0;
163       const MipsSEInstrInfo &TII =
164           *static_cast<const MipsSEInstrInfo *>(
165                MBB.getParent()->getTarget().getInstrInfo());
166       unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL,
167                                        OffsetBitSize == 16 ? &NewImm : NULL);
168       BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(FrameReg)
169         .addReg(Reg, RegState::Kill);
170
171       FrameReg = Reg;
172       Offset = SignExtend64<16>(NewImm);
173       IsKill = true;
174     }
175   }
176
177   MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);
178   MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
179 }