ARMFastISel.cpp revision ce07b5458d87d5f5ad306a1d86785537e9a3ce0c
1//===-- ARMFastISel.cpp - ARM FastISel implementation ---------------------===//
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 defines the ARM-specific support for the FastISel class. Some
11// of the target-specific code is generated by tablegen in the file
12// ARMGenFastISel.inc, which is #included here.
13//
14//===----------------------------------------------------------------------===//
15
16#include "ARM.h"
17#include "ARMBaseInstrInfo.h"
18#include "ARMRegisterInfo.h"
19#include "ARMTargetMachine.h"
20#include "ARMSubtarget.h"
21#include "llvm/CallingConv.h"
22#include "llvm/DerivedTypes.h"
23#include "llvm/GlobalVariable.h"
24#include "llvm/Instructions.h"
25#include "llvm/IntrinsicInst.h"
26#include "llvm/CodeGen/Analysis.h"
27#include "llvm/CodeGen/FastISel.h"
28#include "llvm/CodeGen/FunctionLoweringInfo.h"
29#include "llvm/CodeGen/MachineInstrBuilder.h"
30#include "llvm/CodeGen/MachineModuleInfo.h"
31#include "llvm/CodeGen/MachineConstantPool.h"
32#include "llvm/CodeGen/MachineFrameInfo.h"
33#include "llvm/CodeGen/MachineRegisterInfo.h"
34#include "llvm/Support/CallSite.h"
35#include "llvm/Support/CommandLine.h"
36#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/GetElementPtrTypeIterator.h"
38#include "llvm/Target/TargetData.h"
39#include "llvm/Target/TargetInstrInfo.h"
40#include "llvm/Target/TargetLowering.h"
41#include "llvm/Target/TargetMachine.h"
42#include "llvm/Target/TargetOptions.h"
43using namespace llvm;
44
45static cl::opt<bool>
46EnableARMFastISel("arm-fast-isel",
47                  cl::desc("Turn on experimental ARM fast-isel support"),
48                  cl::init(false), cl::Hidden);
49
50namespace {
51
52class ARMFastISel : public FastISel {
53
54  /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
55  /// make the right decision when generating code for different targets.
56  const ARMSubtarget *Subtarget;
57  const TargetMachine &TM;
58  const TargetInstrInfo &TII;
59  const TargetLowering &TLI;
60  const ARMFunctionInfo *AFI;
61
62  // Convenience variable to avoid checking all the time.
63  bool isThumb;
64
65  public:
66    explicit ARMFastISel(FunctionLoweringInfo &funcInfo)
67    : FastISel(funcInfo),
68      TM(funcInfo.MF->getTarget()),
69      TII(*TM.getInstrInfo()),
70      TLI(*TM.getTargetLowering()) {
71      Subtarget = &TM.getSubtarget<ARMSubtarget>();
72      AFI = funcInfo.MF->getInfo<ARMFunctionInfo>();
73      isThumb = AFI->isThumbFunction();
74    }
75
76    // Code from FastISel.cpp.
77    virtual unsigned FastEmitInst_(unsigned MachineInstOpcode,
78                                   const TargetRegisterClass *RC);
79    virtual unsigned FastEmitInst_r(unsigned MachineInstOpcode,
80                                    const TargetRegisterClass *RC,
81                                    unsigned Op0, bool Op0IsKill);
82    virtual unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
83                                     const TargetRegisterClass *RC,
84                                     unsigned Op0, bool Op0IsKill,
85                                     unsigned Op1, bool Op1IsKill);
86    virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
87                                     const TargetRegisterClass *RC,
88                                     unsigned Op0, bool Op0IsKill,
89                                     uint64_t Imm);
90    virtual unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
91                                     const TargetRegisterClass *RC,
92                                     unsigned Op0, bool Op0IsKill,
93                                     const ConstantFP *FPImm);
94    virtual unsigned FastEmitInst_i(unsigned MachineInstOpcode,
95                                    const TargetRegisterClass *RC,
96                                    uint64_t Imm);
97    virtual unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
98                                      const TargetRegisterClass *RC,
99                                      unsigned Op0, bool Op0IsKill,
100                                      unsigned Op1, bool Op1IsKill,
101                                      uint64_t Imm);
102    virtual unsigned FastEmitInst_extractsubreg(MVT RetVT,
103                                                unsigned Op0, bool Op0IsKill,
104                                                uint32_t Idx);
105
106    // Backend specific FastISel code.
107    virtual bool TargetSelectInstruction(const Instruction *I);
108    virtual unsigned TargetMaterializeConstant(const Constant *C);
109
110  #include "ARMGenFastISel.inc"
111
112    // Instruction selection routines.
113    virtual bool ARMSelectLoad(const Instruction *I);
114    virtual bool ARMSelectStore(const Instruction *I);
115    virtual bool ARMSelectBranch(const Instruction *I);
116    virtual bool ARMSelectCmp(const Instruction *I);
117    virtual bool ARMSelectFPExt(const Instruction *I);
118    virtual bool ARMSelectFPTrunc(const Instruction *I);
119    virtual bool ARMSelectBinaryOp(const Instruction *I, unsigned ISDOpcode);
120    virtual bool ARMSelectSIToFP(const Instruction *I);
121    virtual bool ARMSelectFPToSI(const Instruction *I);
122
123    // Utility routines.
124  private:
125    bool isTypeLegal(const Type *Ty, EVT &VT);
126    bool isLoadTypeLegal(const Type *Ty, EVT &VT);
127    bool ARMEmitLoad(EVT VT, unsigned &ResultReg, unsigned Reg, int Offset);
128    bool ARMEmitStore(EVT VT, unsigned SrcReg, unsigned Reg, int Offset);
129    bool ARMLoadAlloca(const Instruction *I, EVT VT);
130    bool ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT);
131    bool ARMComputeRegOffset(const Value *Obj, unsigned &Reg, int &Offset);
132    unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT);
133    unsigned ARMMaterializeInt(const Constant *C);
134
135    bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR);
136    const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB);
137};
138
139} // end anonymous namespace
140
141// #include "ARMGenCallingConv.inc"
142
143// DefinesOptionalPredicate - This is different from DefinesPredicate in that
144// we don't care about implicit defs here, just places we'll need to add a
145// default CCReg argument. Sets CPSR if we're setting CPSR instead of CCR.
146bool ARMFastISel::DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR) {
147  const TargetInstrDesc &TID = MI->getDesc();
148  if (!TID.hasOptionalDef())
149    return false;
150
151  // Look to see if our OptionalDef is defining CPSR or CCR.
152  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
153    const MachineOperand &MO = MI->getOperand(i);
154    if (!MO.isReg() || !MO.isDef()) continue;
155    if (MO.getReg() == ARM::CPSR)
156      *CPSR = true;
157  }
158  return true;
159}
160
161// If the machine is predicable go ahead and add the predicate operands, if
162// it needs default CC operands add those.
163const MachineInstrBuilder &
164ARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) {
165  MachineInstr *MI = &*MIB;
166
167  // Do we use a predicate?
168  if (TII.isPredicable(MI))
169    AddDefaultPred(MIB);
170
171  // Do we optionally set a predicate?  Preds is size > 0 iff the predicate
172  // defines CPSR. All other OptionalDefines in ARM are the CCR register.
173  bool CPSR = false;
174  if (DefinesOptionalPredicate(MI, &CPSR)) {
175    if (CPSR)
176      AddDefaultT1CC(MIB);
177    else
178      AddDefaultCC(MIB);
179  }
180  return MIB;
181}
182
183unsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode,
184                                    const TargetRegisterClass* RC) {
185  unsigned ResultReg = createResultReg(RC);
186  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
187
188  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg));
189  return ResultReg;
190}
191
192unsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode,
193                                     const TargetRegisterClass *RC,
194                                     unsigned Op0, bool Op0IsKill) {
195  unsigned ResultReg = createResultReg(RC);
196  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
197
198  if (II.getNumDefs() >= 1)
199    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
200                   .addReg(Op0, Op0IsKill * RegState::Kill));
201  else {
202    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
203                   .addReg(Op0, Op0IsKill * RegState::Kill));
204    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
205                   TII.get(TargetOpcode::COPY), ResultReg)
206                   .addReg(II.ImplicitDefs[0]));
207  }
208  return ResultReg;
209}
210
211unsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
212                                      const TargetRegisterClass *RC,
213                                      unsigned Op0, bool Op0IsKill,
214                                      unsigned Op1, bool Op1IsKill) {
215  unsigned ResultReg = createResultReg(RC);
216  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
217
218  if (II.getNumDefs() >= 1)
219    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
220                   .addReg(Op0, Op0IsKill * RegState::Kill)
221                   .addReg(Op1, Op1IsKill * RegState::Kill));
222  else {
223    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
224                   .addReg(Op0, Op0IsKill * RegState::Kill)
225                   .addReg(Op1, Op1IsKill * RegState::Kill));
226    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
227                           TII.get(TargetOpcode::COPY), ResultReg)
228                   .addReg(II.ImplicitDefs[0]));
229  }
230  return ResultReg;
231}
232
233unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
234                                      const TargetRegisterClass *RC,
235                                      unsigned Op0, bool Op0IsKill,
236                                      uint64_t Imm) {
237  unsigned ResultReg = createResultReg(RC);
238  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
239
240  if (II.getNumDefs() >= 1)
241    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
242                   .addReg(Op0, Op0IsKill * RegState::Kill)
243                   .addImm(Imm));
244  else {
245    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
246                   .addReg(Op0, Op0IsKill * RegState::Kill)
247                   .addImm(Imm));
248    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
249                           TII.get(TargetOpcode::COPY), ResultReg)
250                   .addReg(II.ImplicitDefs[0]));
251  }
252  return ResultReg;
253}
254
255unsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode,
256                                      const TargetRegisterClass *RC,
257                                      unsigned Op0, bool Op0IsKill,
258                                      const ConstantFP *FPImm) {
259  unsigned ResultReg = createResultReg(RC);
260  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
261
262  if (II.getNumDefs() >= 1)
263    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
264                   .addReg(Op0, Op0IsKill * RegState::Kill)
265                   .addFPImm(FPImm));
266  else {
267    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
268                   .addReg(Op0, Op0IsKill * RegState::Kill)
269                   .addFPImm(FPImm));
270    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
271                           TII.get(TargetOpcode::COPY), ResultReg)
272                   .addReg(II.ImplicitDefs[0]));
273  }
274  return ResultReg;
275}
276
277unsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
278                                       const TargetRegisterClass *RC,
279                                       unsigned Op0, bool Op0IsKill,
280                                       unsigned Op1, bool Op1IsKill,
281                                       uint64_t Imm) {
282  unsigned ResultReg = createResultReg(RC);
283  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
284
285  if (II.getNumDefs() >= 1)
286    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
287                   .addReg(Op0, Op0IsKill * RegState::Kill)
288                   .addReg(Op1, Op1IsKill * RegState::Kill)
289                   .addImm(Imm));
290  else {
291    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
292                   .addReg(Op0, Op0IsKill * RegState::Kill)
293                   .addReg(Op1, Op1IsKill * RegState::Kill)
294                   .addImm(Imm));
295    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
296                           TII.get(TargetOpcode::COPY), ResultReg)
297                   .addReg(II.ImplicitDefs[0]));
298  }
299  return ResultReg;
300}
301
302unsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode,
303                                     const TargetRegisterClass *RC,
304                                     uint64_t Imm) {
305  unsigned ResultReg = createResultReg(RC);
306  const TargetInstrDesc &II = TII.get(MachineInstOpcode);
307
308  if (II.getNumDefs() >= 1)
309    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
310                   .addImm(Imm));
311  else {
312    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
313                   .addImm(Imm));
314    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
315                           TII.get(TargetOpcode::COPY), ResultReg)
316                   .addReg(II.ImplicitDefs[0]));
317  }
318  return ResultReg;
319}
320
321unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
322                                                 unsigned Op0, bool Op0IsKill,
323                                                 uint32_t Idx) {
324  unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
325  assert(TargetRegisterInfo::isVirtualRegister(Op0) &&
326         "Cannot yet extract from physregs");
327  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
328                         DL, TII.get(TargetOpcode::COPY), ResultReg)
329                 .addReg(Op0, getKillRegState(Op0IsKill), Idx));
330  return ResultReg;
331}
332
333// For double width floating point we need to materialize two constants
334// (the high and the low) into integer registers then use a move to get
335// the combined constant into an FP reg.
336unsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, EVT VT) {
337  const APFloat Val = CFP->getValueAPF();
338  bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64;
339
340  // This checks to see if we can use VFP3 instructions to materialize
341  // a constant, otherwise we have to go through the constant pool.
342  if (TLI.isFPImmLegal(Val, VT)) {
343    unsigned Opc = is64bit ? ARM::FCONSTD : ARM::FCONSTS;
344    unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
345    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
346                            DestReg)
347                    .addFPImm(CFP));
348    return DestReg;
349  }
350
351  // No 64-bit at the moment.
352  if (is64bit) return 0;
353
354  // Load this from the constant pool.
355  unsigned DestReg = ARMMaterializeInt(cast<Constant>(CFP));
356
357  // If we have a floating point constant we expect it in a floating point
358  // register.
359  unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
360  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
361                          TII.get(ARM::VMOVRS), MoveReg)
362                  .addReg(DestReg));
363  return MoveReg;
364}
365
366unsigned ARMFastISel::ARMMaterializeInt(const Constant *C) {
367  // MachineConstantPool wants an explicit alignment.
368  unsigned Align = TD.getPrefTypeAlignment(C->getType());
369  if (Align == 0) {
370    // TODO: Figure out if this is correct.
371    Align = TD.getTypeAllocSize(C->getType());
372  }
373  unsigned Idx = MCP.getConstantPoolIndex(C, Align);
374
375  unsigned DestReg = createResultReg(TLI.getRegClassFor(MVT::i32));
376  if (isThumb)
377    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
378                            TII.get(ARM::t2LDRpci))
379                    .addReg(DestReg).addConstantPoolIndex(Idx));
380  else
381    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
382                            TII.get(ARM::LDRcp))
383                            .addReg(DestReg).addConstantPoolIndex(Idx)
384                    .addReg(0).addImm(0));
385
386  return DestReg;
387}
388
389unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
390  EVT VT = TLI.getValueType(C->getType(), true);
391
392  // Only handle simple types.
393  if (!VT.isSimple()) return 0;
394
395  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
396    return ARMMaterializeFP(CFP, VT);
397  return ARMMaterializeInt(C);
398}
399
400bool ARMFastISel::isTypeLegal(const Type *Ty, EVT &VT) {
401  VT = TLI.getValueType(Ty, true);
402
403  // Only handle simple types.
404  if (VT == MVT::Other || !VT.isSimple()) return false;
405
406  // Handle all legal types, i.e. a register that will directly hold this
407  // value.
408  return TLI.isTypeLegal(VT);
409}
410
411bool ARMFastISel::isLoadTypeLegal(const Type *Ty, EVT &VT) {
412  if (isTypeLegal(Ty, VT)) return true;
413
414  // If this is a type than can be sign or zero-extended to a basic operation
415  // go ahead and accept it now.
416  if (VT == MVT::i8 || VT == MVT::i16)
417    return true;
418
419  return false;
420}
421
422// Computes the Reg+Offset to get to an object.
423bool ARMFastISel::ARMComputeRegOffset(const Value *Obj, unsigned &Reg,
424                                      int &Offset) {
425  // Some boilerplate from the X86 FastISel.
426  const User *U = NULL;
427  unsigned Opcode = Instruction::UserOp1;
428  if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
429    // Don't walk into other basic blocks; it's possible we haven't
430    // visited them yet, so the instructions may not yet be assigned
431    // virtual registers.
432    if (FuncInfo.MBBMap[I->getParent()] != FuncInfo.MBB)
433      return false;
434
435    Opcode = I->getOpcode();
436    U = I;
437  } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
438    Opcode = C->getOpcode();
439    U = C;
440  }
441
442  if (const PointerType *Ty = dyn_cast<PointerType>(Obj->getType()))
443    if (Ty->getAddressSpace() > 255)
444      // Fast instruction selection doesn't support the special
445      // address spaces.
446      return false;
447
448  switch (Opcode) {
449    default:
450    //errs() << "Failing Opcode is: " << *Op1 << "\n";
451    break;
452    case Instruction::Alloca: {
453      assert(false && "Alloca should have been handled earlier!");
454      return false;
455    }
456  }
457
458  if (const GlobalValue *GV = dyn_cast<GlobalValue>(Obj)) {
459    //errs() << "Failing GV is: " << GV << "\n";
460    (void)GV;
461    return false;
462  }
463
464  // Try to get this in a register if nothing else has worked.
465  Reg = getRegForValue(Obj);
466  if (Reg == 0) return false;
467
468  // Since the offset may be too large for the load instruction
469  // get the reg+offset into a register.
470  // TODO: Verify the additions work, otherwise we'll need to add the
471  // offset instead of 0 to the instructions and do all sorts of operand
472  // munging.
473  // TODO: Optimize this somewhat.
474  if (Offset != 0) {
475    ARMCC::CondCodes Pred = ARMCC::AL;
476    unsigned PredReg = 0;
477
478    if (!isThumb)
479      emitARMRegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
480                              Reg, Reg, Offset, Pred, PredReg,
481                              static_cast<const ARMBaseInstrInfo&>(TII));
482    else {
483      assert(AFI->isThumb2Function());
484      emitT2RegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
485                             Reg, Reg, Offset, Pred, PredReg,
486                             static_cast<const ARMBaseInstrInfo&>(TII));
487    }
488  }
489
490  return true;
491}
492
493bool ARMFastISel::ARMLoadAlloca(const Instruction *I, EVT VT) {
494  Value *Op0 = I->getOperand(0);
495
496  // Verify it's an alloca.
497  if (const AllocaInst *AI = dyn_cast<AllocaInst>(Op0)) {
498    DenseMap<const AllocaInst*, int>::iterator SI =
499      FuncInfo.StaticAllocaMap.find(AI);
500
501    if (SI != FuncInfo.StaticAllocaMap.end()) {
502      TargetRegisterClass* RC = TLI.getRegClassFor(VT);
503      unsigned ResultReg = createResultReg(RC);
504      TII.loadRegFromStackSlot(*FuncInfo.MBB, *FuncInfo.InsertPt,
505                               ResultReg, SI->second, RC,
506                               TM.getRegisterInfo());
507      UpdateValueMap(I, ResultReg);
508      return true;
509    }
510  }
511  return false;
512}
513
514bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg,
515                              unsigned Reg, int Offset) {
516
517  assert(VT.isSimple() && "Non-simple types are invalid here!");
518  unsigned Opc;
519
520  switch (VT.getSimpleVT().SimpleTy) {
521    default:
522      assert(false && "Trying to emit for an unhandled type!");
523      return false;
524    case MVT::i16:
525      Opc = isThumb ? ARM::tLDRH : ARM::LDRH;
526      VT = MVT::i32;
527      break;
528    case MVT::i8:
529      Opc = isThumb ? ARM::tLDRB : ARM::LDRB;
530      VT = MVT::i32;
531      break;
532    case MVT::i32:
533      Opc = isThumb ? ARM::tLDR : ARM::LDR;
534      break;
535  }
536
537  ResultReg = createResultReg(TLI.getRegClassFor(VT));
538
539  // TODO: Fix the Addressing modes so that these can share some code.
540  // Since this is a Thumb1 load this will work in Thumb1 or 2 mode.
541  if (isThumb)
542    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
543                            TII.get(Opc), ResultReg)
544                    .addReg(Reg).addImm(Offset).addReg(0));
545  else
546    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
547                            TII.get(Opc), ResultReg)
548                    .addReg(Reg).addReg(0).addImm(Offset));
549  return true;
550}
551
552bool ARMFastISel::ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT){
553  Value *Op1 = I->getOperand(1);
554
555  // Verify it's an alloca.
556  if (const AllocaInst *AI = dyn_cast<AllocaInst>(Op1)) {
557    DenseMap<const AllocaInst*, int>::iterator SI =
558      FuncInfo.StaticAllocaMap.find(AI);
559
560    if (SI != FuncInfo.StaticAllocaMap.end()) {
561      TargetRegisterClass* RC = TLI.getRegClassFor(VT);
562      assert(SrcReg != 0 && "Nothing to store!");
563      TII.storeRegToStackSlot(*FuncInfo.MBB, *FuncInfo.InsertPt,
564                              SrcReg, true /*isKill*/, SI->second, RC,
565                              TM.getRegisterInfo());
566      return true;
567    }
568  }
569  return false;
570}
571
572bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg,
573                               unsigned DstReg, int Offset) {
574  unsigned StrOpc;
575  switch (VT.getSimpleVT().SimpleTy) {
576    default: return false;
577    case MVT::i1:
578    case MVT::i8: StrOpc = isThumb ? ARM::tSTRB : ARM::STRB; break;
579    case MVT::i16: StrOpc = isThumb ? ARM::tSTRH : ARM::STRH; break;
580    case MVT::i32: StrOpc = isThumb ? ARM::tSTR : ARM::STR; break;
581    case MVT::f32:
582      if (!Subtarget->hasVFP2()) return false;
583      StrOpc = ARM::VSTRS;
584      break;
585    case MVT::f64:
586      if (!Subtarget->hasVFP2()) return false;
587      StrOpc = ARM::VSTRD;
588      break;
589  }
590
591  if (isThumb)
592    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
593                            TII.get(StrOpc), SrcReg)
594                    .addReg(DstReg).addImm(Offset).addReg(0));
595  else
596    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
597                            TII.get(StrOpc), SrcReg)
598                    .addReg(DstReg).addReg(0).addImm(Offset));
599
600  return true;
601}
602
603bool ARMFastISel::ARMSelectStore(const Instruction *I) {
604  Value *Op0 = I->getOperand(0);
605  unsigned SrcReg = 0;
606
607  // Yay type legalization
608  EVT VT;
609  if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
610    return false;
611
612  // Get the value to be stored into a register.
613  SrcReg = getRegForValue(Op0);
614  if (SrcReg == 0)
615    return false;
616
617  // If we're an alloca we know we have a frame index and can emit the store
618  // quickly.
619  if (ARMStoreAlloca(I, SrcReg, VT))
620    return true;
621
622  // Our register and offset with innocuous defaults.
623  unsigned Reg = 0;
624  int Offset = 0;
625
626  // See if we can handle this as Reg + Offset
627  if (!ARMComputeRegOffset(I->getOperand(1), Reg, Offset))
628    return false;
629
630  if (!ARMEmitStore(VT, SrcReg, Reg, Offset /* 0 */)) return false;
631
632  return false;
633}
634
635bool ARMFastISel::ARMSelectLoad(const Instruction *I) {
636  // Verify we have a legal type before going any further.
637  EVT VT;
638  if (!isLoadTypeLegal(I->getType(), VT))
639    return false;
640
641  // If we're an alloca we know we have a frame index and can emit the load
642  // directly in short order.
643  if (ARMLoadAlloca(I, VT))
644    return true;
645
646  // Our register and offset with innocuous defaults.
647  unsigned Reg = 0;
648  int Offset = 0;
649
650  // See if we can handle this as Reg + Offset
651  if (!ARMComputeRegOffset(I->getOperand(0), Reg, Offset))
652    return false;
653
654  unsigned ResultReg;
655  if (!ARMEmitLoad(VT, ResultReg, Reg, Offset /* 0 */)) return false;
656
657  UpdateValueMap(I, ResultReg);
658  return true;
659}
660
661bool ARMFastISel::ARMSelectBranch(const Instruction *I) {
662  const BranchInst *BI = cast<BranchInst>(I);
663  MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
664  MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
665
666  // Simple branch support.
667  unsigned CondReg = getRegForValue(BI->getCondition());
668  if (CondReg == 0) return false;
669
670  unsigned CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
671  unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc;
672  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
673                  .addReg(CondReg).addReg(CondReg));
674  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
675                  .addMBB(TBB).addImm(ARMCC::NE).addReg(ARM::CPSR);
676  FastEmitBranch(FBB, DL);
677  FuncInfo.MBB->addSuccessor(TBB);
678  return true;
679}
680
681bool ARMFastISel::ARMSelectCmp(const Instruction *I) {
682  const CmpInst *CI = cast<CmpInst>(I);
683
684  EVT VT;
685  const Type *Ty = CI->getOperand(0)->getType();
686  if (!isTypeLegal(Ty, VT))
687    return false;
688
689  bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
690  if (isFloat && !Subtarget->hasVFP2())
691    return false;
692
693  unsigned CmpOpc;
694  switch (VT.getSimpleVT().SimpleTy) {
695    default: return false;
696    // TODO: Verify compares.
697    case MVT::f32:
698      CmpOpc = ARM::VCMPES;
699      break;
700    case MVT::f64:
701      CmpOpc = ARM::VCMPED;
702      break;
703    case MVT::i32:
704      CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
705      break;
706  }
707
708  unsigned Arg1 = getRegForValue(CI->getOperand(0));
709  if (Arg1 == 0) return false;
710
711  unsigned Arg2 = getRegForValue(CI->getOperand(1));
712  if (Arg2 == 0) return false;
713
714  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
715                  .addReg(Arg1).addReg(Arg2));
716
717  // For floating point we need to move the result to a register we can
718  // actually do something with.
719  if (isFloat)
720    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
721                            TII.get(ARM::FMSTAT)));
722
723  // TODO: How to update the value map when there's no result reg?
724  return true;
725}
726
727bool ARMFastISel::ARMSelectFPExt(const Instruction *I) {
728  // Make sure we have VFP and that we're extending float to double.
729  if (!Subtarget->hasVFP2()) return false;
730
731  Value *V = I->getOperand(0);
732  if (!I->getType()->isDoubleTy() ||
733      !V->getType()->isFloatTy()) return false;
734
735  unsigned Op = getRegForValue(V);
736  if (Op == 0) return false;
737
738  unsigned Result = createResultReg(ARM::DPRRegisterClass);
739
740  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
741                          TII.get(ARM::VCVTSD), Result)
742                  .addReg(Op));
743  UpdateValueMap(I, Result);
744  return true;
745}
746
747bool ARMFastISel::ARMSelectFPTrunc(const Instruction *I) {
748  // Make sure we have VFP and that we're truncating double to float.
749  if (!Subtarget->hasVFP2()) return false;
750
751  Value *V = I->getOperand(0);
752  if (!I->getType()->isFloatTy() ||
753      !V->getType()->isDoubleTy()) return false;
754
755  unsigned Op = getRegForValue(V);
756  if (Op == 0) return false;
757
758  unsigned Result = createResultReg(ARM::SPRRegisterClass);
759
760  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
761                          TII.get(ARM::VCVTDS), Result)
762                  .addReg(Op));
763  UpdateValueMap(I, Result);
764  return true;
765}
766
767bool ARMFastISel::ARMSelectSIToFP(const Instruction *I) {
768  // Make sure we have VFP.
769  if (!Subtarget->hasVFP2()) return false;
770
771  EVT VT;
772  const Type *Ty = I->getType();
773  if (!isTypeLegal(Ty, VT))
774    return false;
775
776  unsigned Op = getRegForValue(I->getOperand(0));
777  if (Op == 0) return false;
778
779  unsigned Opc;
780  if (Ty->isFloatTy()) Opc = ARM::VSITOS;
781  else if (Ty->isDoubleTy()) Opc = ARM::VSITOD;
782  else return 0;
783
784  unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
785  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
786                          ResultReg)
787                  .addReg(Op));
788  UpdateValueMap(I, ResultReg);
789  return true;
790}
791
792bool ARMFastISel::ARMSelectFPToSI(const Instruction *I) {
793  // Make sure we have VFP.
794  if (!Subtarget->hasVFP2()) return false;
795
796  EVT VT;
797  const Type *RetTy = I->getType();
798  if (!isTypeLegal(RetTy, VT))
799    return false;
800
801  unsigned Op = getRegForValue(I->getOperand(0));
802  if (Op == 0) return false;
803
804  unsigned Opc;
805  const Type *OpTy = I->getOperand(0)->getType();
806  if (OpTy->isFloatTy()) Opc = ARM::VTOSIZS;
807  else if (OpTy->isDoubleTy()) Opc = ARM::VTOSIZD;
808  else return 0;
809
810  unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
811  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
812                          ResultReg)
813                  .addReg(Op));
814  UpdateValueMap(I, ResultReg);
815  return true;
816}
817
818bool ARMFastISel::ARMSelectBinaryOp(const Instruction *I, unsigned ISDOpcode) {
819  EVT VT  = TLI.getValueType(I->getType(), true);
820
821  // We can get here in the case when we want to use NEON for our fp
822  // operations, but can't figure out how to. Just use the vfp instructions
823  // if we have them.
824  // FIXME: It'd be nice to use NEON instructions.
825  const Type *Ty = I->getType();
826  bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
827  if (isFloat && !Subtarget->hasVFP2())
828    return false;
829
830  unsigned Op1 = getRegForValue(I->getOperand(0));
831  if (Op1 == 0) return false;
832
833  unsigned Op2 = getRegForValue(I->getOperand(1));
834  if (Op2 == 0) return false;
835
836  unsigned Opc;
837  bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64 ||
838                 VT.getSimpleVT().SimpleTy == MVT::i64;
839  switch (ISDOpcode) {
840    default: return false;
841    case ISD::FADD:
842      Opc = is64bit ? ARM::VADDD : ARM::VADDS;
843      break;
844    case ISD::FSUB:
845      Opc = is64bit ? ARM::VSUBD : ARM::VSUBS;
846      break;
847    case ISD::FMUL:
848      Opc = is64bit ? ARM::VMULD : ARM::VMULS;
849      break;
850  }
851  unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
852  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
853                          TII.get(Opc), ResultReg)
854                  .addReg(Op1).addReg(Op2));
855  UpdateValueMap(I, ResultReg);
856  return true;
857}
858
859// TODO: SoftFP support.
860bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
861  // No Thumb-1 for now.
862  if (isThumb && !AFI->isThumb2Function()) return false;
863
864  switch (I->getOpcode()) {
865    case Instruction::Load:
866      return ARMSelectLoad(I);
867    case Instruction::Store:
868      return ARMSelectStore(I);
869    case Instruction::Br:
870      return ARMSelectBranch(I);
871    case Instruction::ICmp:
872    case Instruction::FCmp:
873      return ARMSelectCmp(I);
874    case Instruction::FPExt:
875      return ARMSelectFPExt(I);
876    case Instruction::FPTrunc:
877      return ARMSelectFPTrunc(I);
878    case Instruction::SIToFP:
879      return ARMSelectSIToFP(I);
880    case Instruction::FPToSI:
881      return ARMSelectFPToSI(I);
882    case Instruction::FAdd:
883      return ARMSelectBinaryOp(I, ISD::FADD);
884    case Instruction::FSub:
885      return ARMSelectBinaryOp(I, ISD::FSUB);
886    case Instruction::FMul:
887      return ARMSelectBinaryOp(I, ISD::FMUL);
888    default: break;
889  }
890  return false;
891}
892
893namespace llvm {
894  llvm::FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo) {
895    if (EnableARMFastISel) return new ARMFastISel(funcInfo);
896    return 0;
897  }
898}
899