]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
Merge llvm, clang, lld and lldb trunk r300890, and update build glue.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARM / ARMInstructionSelector.cpp
1 //===- ARMInstructionSelector.cpp ----------------------------*- C++ -*-==//
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 /// \file
10 /// This file implements the targeting of the InstructionSelector class for ARM.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13
14 #include "ARMInstructionSelector.h"
15 #include "ARMRegisterBankInfo.h"
16 #include "ARMSubtarget.h"
17 #include "ARMTargetMachine.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/Support/Debug.h"
20
21 #define DEBUG_TYPE "arm-isel"
22
23 using namespace llvm;
24
25 #ifndef LLVM_BUILD_GLOBAL_ISEL
26 #error "You shouldn't build this"
27 #endif
28
29 ARMInstructionSelector::ARMInstructionSelector(const ARMSubtarget &STI,
30                                                const ARMRegisterBankInfo &RBI)
31     : InstructionSelector(), TII(*STI.getInstrInfo()),
32       TRI(*STI.getRegisterInfo()), RBI(RBI) {}
33
34 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
35                        MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
36                        const RegisterBankInfo &RBI) {
37   unsigned DstReg = I.getOperand(0).getReg();
38   if (TargetRegisterInfo::isPhysicalRegister(DstReg))
39     return true;
40
41   const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
42   (void)RegBank;
43   assert(RegBank && "Can't get reg bank for virtual register");
44
45   const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
46   (void)DstSize;
47   unsigned SrcReg = I.getOperand(1).getReg();
48   const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
49   (void)SrcSize;
50   assert((DstSize == SrcSize ||
51           // Copies are a means to setup initial types, the number of
52           // bits may not exactly match.
53           (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
54            DstSize <= SrcSize)) &&
55          "Copy with different width?!");
56
57   assert((RegBank->getID() == ARM::GPRRegBankID ||
58           RegBank->getID() == ARM::FPRRegBankID) &&
59          "Unsupported reg bank");
60
61   const TargetRegisterClass *RC = &ARM::GPRRegClass;
62
63   if (RegBank->getID() == ARM::FPRRegBankID) {
64     if (DstSize == 32)
65       RC = &ARM::SPRRegClass;
66     else if (DstSize == 64)
67       RC = &ARM::DPRRegClass;
68     else
69       llvm_unreachable("Unsupported destination size");
70   }
71
72   // No need to constrain SrcReg. It will get constrained when
73   // we hit another of its uses or its defs.
74   // Copies do not have constraints.
75   if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
76     DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
77                  << " operand\n");
78     return false;
79   }
80   return true;
81 }
82
83 static bool selectFAdd(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
84                        MachineRegisterInfo &MRI) {
85   assert(TII.getSubtarget().hasVFP2() && "Can't select fp add without vfp");
86
87   LLT Ty = MRI.getType(MIB->getOperand(0).getReg());
88   unsigned ValSize = Ty.getSizeInBits();
89
90   if (ValSize == 32) {
91     if (TII.getSubtarget().useNEONForSinglePrecisionFP())
92       return false;
93     MIB->setDesc(TII.get(ARM::VADDS));
94   } else {
95     assert(ValSize == 64 && "Unsupported size for floating point value");
96     if (TII.getSubtarget().isFPOnlySP())
97       return false;
98     MIB->setDesc(TII.get(ARM::VADDD));
99   }
100   MIB.add(predOps(ARMCC::AL));
101
102   return true;
103 }
104
105 static bool selectSequence(MachineInstrBuilder &MIB,
106                            const ARMBaseInstrInfo &TII,
107                            MachineRegisterInfo &MRI,
108                            const TargetRegisterInfo &TRI,
109                            const RegisterBankInfo &RBI) {
110   assert(TII.getSubtarget().hasVFP2() && "Can't select sequence without VFP");
111
112   // We only support G_SEQUENCE as a way to stick together two scalar GPRs
113   // into one DPR.
114   unsigned VReg0 = MIB->getOperand(0).getReg();
115   (void)VReg0;
116   assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
117          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
118          "Unsupported operand for G_SEQUENCE");
119   unsigned VReg1 = MIB->getOperand(1).getReg();
120   (void)VReg1;
121   assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
122          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
123          "Unsupported operand for G_SEQUENCE");
124   unsigned VReg2 = MIB->getOperand(3).getReg();
125   (void)VReg2;
126   assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
127          RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
128          "Unsupported operand for G_SEQUENCE");
129
130   // Remove the operands corresponding to the offsets.
131   MIB->RemoveOperand(4);
132   MIB->RemoveOperand(2);
133
134   MIB->setDesc(TII.get(ARM::VMOVDRR));
135   MIB.add(predOps(ARMCC::AL));
136
137   return true;
138 }
139
140 static bool selectExtract(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
141                           MachineRegisterInfo &MRI,
142                           const TargetRegisterInfo &TRI,
143                           const RegisterBankInfo &RBI) {
144   assert(TII.getSubtarget().hasVFP2() && "Can't select extract without VFP");
145
146   // We only support G_EXTRACT as a way to break up one DPR into two GPRs.
147   unsigned VReg0 = MIB->getOperand(0).getReg();
148   (void)VReg0;
149   assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
150          RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
151          "Unsupported operand for G_EXTRACT");
152   unsigned VReg1 = MIB->getOperand(1).getReg();
153   (void)VReg1;
154   assert(MRI.getType(VReg1).getSizeInBits() == 64 &&
155          RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::FPRRegBankID &&
156          "Unsupported operand for G_EXTRACT");
157   assert(MIB->getOperand(2).getImm() % 32 == 0 &&
158          "Unsupported operand for G_EXTRACT");
159
160   // Remove the operands corresponding to the offsets.
161   MIB->getOperand(2).setImm(MIB->getOperand(2).getImm() / 32);
162
163   MIB->setDesc(TII.get(ARM::VGETLNi32));
164   MIB.add(predOps(ARMCC::AL));
165
166   return true;
167 }
168
169 /// Select the opcode for simple extensions (that translate to a single SXT/UXT
170 /// instruction). Extension operations more complicated than that should not
171 /// invoke this. Returns the original opcode if it doesn't know how to select a
172 /// better one.
173 static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) {
174   using namespace TargetOpcode;
175
176   if (Size != 8 && Size != 16)
177     return Opc;
178
179   if (Opc == G_SEXT)
180     return Size == 8 ? ARM::SXTB : ARM::SXTH;
181
182   if (Opc == G_ZEXT)
183     return Size == 8 ? ARM::UXTB : ARM::UXTH;
184
185   return Opc;
186 }
187
188 /// Select the opcode for simple loads and stores. For types smaller than 32
189 /// bits, the value will be zero extended. Returns the original opcode if it
190 /// doesn't know how to select a better one.
191 static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
192                                       unsigned Size) {
193   bool isStore = Opc == TargetOpcode::G_STORE;
194
195   if (RegBank == ARM::GPRRegBankID) {
196     switch (Size) {
197     case 1:
198     case 8:
199       return isStore ? ARM::STRBi12 : ARM::LDRBi12;
200     case 16:
201       return isStore ? ARM::STRH : ARM::LDRH;
202     case 32:
203       return isStore ? ARM::STRi12 : ARM::LDRi12;
204     default:
205       return Opc;
206     }
207   }
208
209   if (RegBank == ARM::FPRRegBankID) {
210     switch (Size) {
211     case 32:
212       return isStore ? ARM::VSTRS : ARM::VLDRS;
213     case 64:
214       return isStore ? ARM::VSTRD : ARM::VLDRD;
215     default:
216       return Opc;
217     }
218   }
219
220   return Opc;
221 }
222
223 bool ARMInstructionSelector::select(MachineInstr &I) const {
224   assert(I.getParent() && "Instruction should be in a basic block!");
225   assert(I.getParent()->getParent() && "Instruction should be in a function!");
226
227   auto &MBB = *I.getParent();
228   auto &MF = *MBB.getParent();
229   auto &MRI = MF.getRegInfo();
230
231   if (!isPreISelGenericOpcode(I.getOpcode())) {
232     if (I.isCopy())
233       return selectCopy(I, TII, MRI, TRI, RBI);
234
235     return true;
236   }
237
238   MachineInstrBuilder MIB{MF, I};
239   bool isSExt = false;
240
241   using namespace TargetOpcode;
242   switch (I.getOpcode()) {
243   case G_SEXT:
244     isSExt = true;
245     LLVM_FALLTHROUGH;
246   case G_ZEXT: {
247     LLT DstTy = MRI.getType(I.getOperand(0).getReg());
248     // FIXME: Smaller destination sizes coming soon!
249     if (DstTy.getSizeInBits() != 32) {
250       DEBUG(dbgs() << "Unsupported destination size for extension");
251       return false;
252     }
253
254     LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
255     unsigned SrcSize = SrcTy.getSizeInBits();
256     switch (SrcSize) {
257     case 1: {
258       // ZExt boils down to & 0x1; for SExt we also subtract that from 0
259       I.setDesc(TII.get(ARM::ANDri));
260       MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp());
261
262       if (isSExt) {
263         unsigned SExtResult = I.getOperand(0).getReg();
264
265         // Use a new virtual register for the result of the AND
266         unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
267         I.getOperand(0).setReg(AndResult);
268
269         auto InsertBefore = std::next(I.getIterator());
270         auto SubI =
271             BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri))
272                 .addDef(SExtResult)
273                 .addUse(AndResult)
274                 .addImm(0)
275                 .add(predOps(ARMCC::AL))
276                 .add(condCodeOp());
277         if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
278           return false;
279       }
280       break;
281     }
282     case 8:
283     case 16: {
284       unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
285       if (NewOpc == I.getOpcode())
286         return false;
287       I.setDesc(TII.get(NewOpc));
288       MIB.addImm(0).add(predOps(ARMCC::AL));
289       break;
290     }
291     default:
292       DEBUG(dbgs() << "Unsupported source size for extension");
293       return false;
294     }
295     break;
296   }
297   case G_ADD:
298   case G_GEP:
299     I.setDesc(TII.get(ARM::ADDrr));
300     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
301     break;
302   case G_SUB:
303     I.setDesc(TII.get(ARM::SUBrr));
304     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
305     break;
306   case G_MUL:
307     if (TII.getSubtarget().hasV6Ops()) {
308       I.setDesc(TII.get(ARM::MUL));
309     } else {
310       assert(TII.getSubtarget().useMulOps() && "Unsupported target");
311       I.setDesc(TII.get(ARM::MULv5));
312       MIB->getOperand(0).setIsEarlyClobber(true);
313     }
314     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
315     break;
316   case G_FADD:
317     if (!selectFAdd(MIB, TII, MRI))
318       return false;
319     break;
320   case G_FRAME_INDEX:
321     // Add 0 to the given frame index and hope it will eventually be folded into
322     // the user(s).
323     I.setDesc(TII.get(ARM::ADDri));
324     MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
325     break;
326   case G_CONSTANT: {
327     unsigned Reg = I.getOperand(0).getReg();
328     if (MRI.getType(Reg).getSizeInBits() != 32)
329       return false;
330
331     assert(RBI.getRegBank(Reg, MRI, TRI)->getID() == ARM::GPRRegBankID &&
332            "Expected constant to live in a GPR");
333     I.setDesc(TII.get(ARM::MOVi));
334     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
335     break;
336   }
337   case G_STORE:
338   case G_LOAD: {
339     const auto &MemOp = **I.memoperands_begin();
340     if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
341       DEBUG(dbgs() << "Atomic load/store not supported yet\n");
342       return false;
343     }
344
345     unsigned Reg = I.getOperand(0).getReg();
346     unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
347
348     LLT ValTy = MRI.getType(Reg);
349     const auto ValSize = ValTy.getSizeInBits();
350
351     assert((ValSize != 64 || TII.getSubtarget().hasVFP2()) &&
352            "Don't know how to load/store 64-bit value without VFP");
353
354     const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
355     if (NewOpc == G_LOAD || NewOpc == G_STORE)
356       return false;
357
358     I.setDesc(TII.get(NewOpc));
359
360     if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
361       // LDRH has a funny addressing mode (there's already a FIXME for it).
362       MIB.addReg(0);
363     MIB.addImm(0).add(predOps(ARMCC::AL));
364     break;
365   }
366   case G_SEQUENCE: {
367     if (!selectSequence(MIB, TII, MRI, TRI, RBI))
368       return false;
369     break;
370   }
371   case G_EXTRACT: {
372     if (!selectExtract(MIB, TII, MRI, TRI, RBI))
373       return false;
374     break;
375   }
376   default:
377     return false;
378   }
379
380   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
381 }