| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 1 | ///===-- FastISel.cpp - Implementation of the FastISel class --------------===// | 
 | 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 implementation of the FastISel class. | 
 | 11 | // | 
| Dan Gohman | 5ec9efd | 2008-09-30 20:48:29 +0000 | [diff] [blame] | 12 | // "Fast" instruction selection is designed to emit very poor code quickly. | 
 | 13 | // Also, it is not designed to be able to do much lowering, so most illegal | 
| Chris Lattner | 44d2a98 | 2008-10-13 01:59:13 +0000 | [diff] [blame] | 14 | // types (e.g. i64 on 32-bit targets) and operations are not supported.  It is | 
 | 15 | // also not intended to be able to do much optimization, except in a few cases | 
 | 16 | // where doing optimizations reduces overall compile time.  For example, folding | 
 | 17 | // constants into immediate fields is often done, because it's cheap and it | 
 | 18 | // reduces the number of instructions later phases have to examine. | 
| Dan Gohman | 5ec9efd | 2008-09-30 20:48:29 +0000 | [diff] [blame] | 19 | // | 
 | 20 | // "Fast" instruction selection is able to fail gracefully and transfer | 
 | 21 | // control to the SelectionDAG selector for operations that it doesn't | 
| Chris Lattner | 44d2a98 | 2008-10-13 01:59:13 +0000 | [diff] [blame] | 22 | // support.  In many cases, this allows us to avoid duplicating a lot of | 
| Dan Gohman | 5ec9efd | 2008-09-30 20:48:29 +0000 | [diff] [blame] | 23 | // the complicated lowering logic that SelectionDAG currently has. | 
 | 24 | // | 
 | 25 | // The intended use for "fast" instruction selection is "-O0" mode | 
 | 26 | // compilation, where the quality of the generated code is irrelevant when | 
| Chris Lattner | 44d2a98 | 2008-10-13 01:59:13 +0000 | [diff] [blame] | 27 | // weighed against the speed at which the code can be generated.  Also, | 
| Dan Gohman | 5ec9efd | 2008-09-30 20:48:29 +0000 | [diff] [blame] | 28 | // at -O0, the LLVM optimizers are not running, and this makes the | 
 | 29 | // compile time of codegen a much higher portion of the overall compile | 
| Chris Lattner | 44d2a98 | 2008-10-13 01:59:13 +0000 | [diff] [blame] | 30 | // time.  Despite its limitations, "fast" instruction selection is able to | 
| Dan Gohman | 5ec9efd | 2008-09-30 20:48:29 +0000 | [diff] [blame] | 31 | // handle enough code on its own to provide noticeable overall speedups | 
 | 32 | // in -O0 compiles. | 
 | 33 | // | 
 | 34 | // Basic operations are supported in a target-independent way, by reading | 
 | 35 | // the same instruction descriptions that the SelectionDAG selector reads, | 
 | 36 | // and identifying simple arithmetic operations that can be directly selected | 
| Chris Lattner | 44d2a98 | 2008-10-13 01:59:13 +0000 | [diff] [blame] | 37 | // from simple operators.  More complicated operations currently require | 
| Dan Gohman | 5ec9efd | 2008-09-30 20:48:29 +0000 | [diff] [blame] | 38 | // target-specific code. | 
 | 39 | // | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 40 | //===----------------------------------------------------------------------===// | 
 | 41 |  | 
| Dan Gohman | 33134c4 | 2008-09-25 17:05:24 +0000 | [diff] [blame] | 42 | #include "llvm/Function.h" | 
 | 43 | #include "llvm/GlobalVariable.h" | 
| Dan Gohman | 6f2766d | 2008-08-19 22:31:46 +0000 | [diff] [blame] | 44 | #include "llvm/Instructions.h" | 
| Dan Gohman | 33134c4 | 2008-09-25 17:05:24 +0000 | [diff] [blame] | 45 | #include "llvm/IntrinsicInst.h" | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 46 | #include "llvm/CodeGen/FastISel.h" | 
 | 47 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
| Dan Gohman | 33134c4 | 2008-09-25 17:05:24 +0000 | [diff] [blame] | 48 | #include "llvm/CodeGen/MachineModuleInfo.h" | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 49 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
| Devang Patel | 83489bb | 2009-01-13 00:35:13 +0000 | [diff] [blame] | 50 | #include "llvm/CodeGen/DwarfWriter.h" | 
 | 51 | #include "llvm/Analysis/DebugInfo.h" | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 52 | #include "llvm/Target/TargetData.h" | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 53 | #include "llvm/Target/TargetInstrInfo.h" | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 54 | #include "llvm/Target/TargetLowering.h" | 
| Dan Gohman | bb46633 | 2008-08-20 21:05:57 +0000 | [diff] [blame] | 55 | #include "llvm/Target/TargetMachine.h" | 
| Dan Gohman | 66336ed | 2009-11-23 17:42:46 +0000 | [diff] [blame] | 56 | #include "FunctionLoweringInfo.h" | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 57 | using namespace llvm; | 
 | 58 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 59 | unsigned FastISel::getRegForValue(Value *V) { | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 60 |   EVT RealVT = TLI.getValueType(V->getType(), /*AllowUnknown=*/true); | 
| Dan Gohman | 4fd5528 | 2009-04-07 20:40:11 +0000 | [diff] [blame] | 61 |   // Don't handle non-simple values in FastISel. | 
 | 62 |   if (!RealVT.isSimple()) | 
 | 63 |     return 0; | 
| Dan Gohman | c8a1a3c | 2008-12-08 07:57:47 +0000 | [diff] [blame] | 64 |  | 
 | 65 |   // Ignore illegal types. We must do this before looking up the value | 
 | 66 |   // in ValueMap because Arguments are given virtual registers regardless | 
 | 67 |   // of whether FastISel can handle them. | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 68 |   MVT VT = RealVT.getSimpleVT(); | 
| Dan Gohman | c8a1a3c | 2008-12-08 07:57:47 +0000 | [diff] [blame] | 69 |   if (!TLI.isTypeLegal(VT)) { | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 70 |     // Promote MVT::i1 to a legal type though, because it's common and easy. | 
 | 71 |     if (VT == MVT::i1) | 
| Owen Anderson | 23b9b19 | 2009-08-12 00:36:31 +0000 | [diff] [blame] | 72 |       VT = TLI.getTypeToTransformTo(V->getContext(), VT).getSimpleVT(); | 
| Dan Gohman | c8a1a3c | 2008-12-08 07:57:47 +0000 | [diff] [blame] | 73 |     else | 
 | 74 |       return 0; | 
 | 75 |   } | 
 | 76 |  | 
| Dan Gohman | 104e4ce | 2008-09-03 23:32:19 +0000 | [diff] [blame] | 77 |   // Look up the value to see if we already have a register for it. We | 
 | 78 |   // cache values defined by Instructions across blocks, and other values | 
 | 79 |   // only locally. This is because Instructions already have the SSA | 
| Dan Gohman | 5c9cf19 | 2010-01-12 04:30:26 +0000 | [diff] [blame] | 80 |   // def-dominates-use requirement enforced. | 
| Owen Anderson | 99aaf10 | 2008-09-03 17:37:03 +0000 | [diff] [blame] | 81 |   if (ValueMap.count(V)) | 
 | 82 |     return ValueMap[V]; | 
| Dan Gohman | 104e4ce | 2008-09-03 23:32:19 +0000 | [diff] [blame] | 83 |   unsigned Reg = LocalValueMap[V]; | 
 | 84 |   if (Reg != 0) | 
 | 85 |     return Reg; | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 86 |  | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 87 |   if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { | 
| Dan Gohman | 2ff7fd1 | 2008-09-19 22:16:54 +0000 | [diff] [blame] | 88 |     if (CI->getValue().getActiveBits() <= 64) | 
 | 89 |       Reg = FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue()); | 
| Dan Gohman | 0586d91 | 2008-09-10 20:11:02 +0000 | [diff] [blame] | 90 |   } else if (isa<AllocaInst>(V)) { | 
| Dan Gohman | 2ff7fd1 | 2008-09-19 22:16:54 +0000 | [diff] [blame] | 91 |     Reg = TargetMaterializeAlloca(cast<AllocaInst>(V)); | 
| Dan Gohman | 205d925 | 2008-08-28 21:19:07 +0000 | [diff] [blame] | 92 |   } else if (isa<ConstantPointerNull>(V)) { | 
| Dan Gohman | 1e9e8c3 | 2008-10-07 22:03:27 +0000 | [diff] [blame] | 93 |     // Translate this as an integer zero so that it can be | 
 | 94 |     // local-CSE'd with actual integer zeros. | 
| Owen Anderson | 1d0be15 | 2009-08-13 21:58:54 +0000 | [diff] [blame] | 95 |     Reg = | 
 | 96 |       getRegForValue(Constant::getNullValue(TD.getIntPtrType(V->getContext()))); | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 97 |   } else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) { | 
| Dan Gohman | 104e4ce | 2008-09-03 23:32:19 +0000 | [diff] [blame] | 98 |     Reg = FastEmit_f(VT, VT, ISD::ConstantFP, CF); | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 99 |  | 
 | 100 |     if (!Reg) { | 
 | 101 |       const APFloat &Flt = CF->getValueAPF(); | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 102 |       EVT IntVT = TLI.getPointerTy(); | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 103 |  | 
 | 104 |       uint64_t x[2]; | 
 | 105 |       uint32_t IntBitWidth = IntVT.getSizeInBits(); | 
| Dale Johannesen | 23a9855 | 2008-10-09 23:00:39 +0000 | [diff] [blame] | 106 |       bool isExact; | 
 | 107 |       (void) Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true, | 
 | 108 |                                 APFloat::rmTowardZero, &isExact); | 
 | 109 |       if (isExact) { | 
| Dan Gohman | 2ff7fd1 | 2008-09-19 22:16:54 +0000 | [diff] [blame] | 110 |         APInt IntVal(IntBitWidth, 2, x); | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 111 |  | 
| Owen Anderson | e922c02 | 2009-07-22 00:24:57 +0000 | [diff] [blame] | 112 |         unsigned IntegerReg = | 
| Owen Anderson | eed707b | 2009-07-24 23:12:02 +0000 | [diff] [blame] | 113 |           getRegForValue(ConstantInt::get(V->getContext(), IntVal)); | 
| Dan Gohman | 2ff7fd1 | 2008-09-19 22:16:54 +0000 | [diff] [blame] | 114 |         if (IntegerReg != 0) | 
 | 115 |           Reg = FastEmit_r(IntVT.getSimpleVT(), VT, ISD::SINT_TO_FP, IntegerReg); | 
 | 116 |       } | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 117 |     } | 
| Dan Gohman | 40b189e | 2008-09-05 18:18:20 +0000 | [diff] [blame] | 118 |   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { | 
 | 119 |     if (!SelectOperator(CE, CE->getOpcode())) return 0; | 
 | 120 |     Reg = LocalValueMap[CE]; | 
| Dan Gohman | 205d925 | 2008-08-28 21:19:07 +0000 | [diff] [blame] | 121 |   } else if (isa<UndefValue>(V)) { | 
| Dan Gohman | 104e4ce | 2008-09-03 23:32:19 +0000 | [diff] [blame] | 122 |     Reg = createResultReg(TLI.getRegClassFor(VT)); | 
| Chris Lattner | 518bb53 | 2010-02-09 19:54:29 +0000 | [diff] [blame] | 123 |     BuildMI(MBB, DL, TII.get(TargetOpcode::IMPLICIT_DEF), Reg); | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 124 |   } | 
| Owen Anderson | d5d81a4 | 2008-09-03 17:51:57 +0000 | [diff] [blame] | 125 |    | 
| Dan Gohman | dceffe6 | 2008-09-25 01:28:51 +0000 | [diff] [blame] | 126 |   // If target-independent code couldn't handle the value, give target-specific | 
 | 127 |   // code a try. | 
| Owen Anderson | 6e60745 | 2008-09-05 23:36:01 +0000 | [diff] [blame] | 128 |   if (!Reg && isa<Constant>(V)) | 
| Dan Gohman | 2ff7fd1 | 2008-09-19 22:16:54 +0000 | [diff] [blame] | 129 |     Reg = TargetMaterializeConstant(cast<Constant>(V)); | 
| Owen Anderson | 6e60745 | 2008-09-05 23:36:01 +0000 | [diff] [blame] | 130 |    | 
| Dan Gohman | 2ff7fd1 | 2008-09-19 22:16:54 +0000 | [diff] [blame] | 131 |   // Don't cache constant materializations in the general ValueMap. | 
 | 132 |   // To do so would require tracking what uses they dominate. | 
| Dan Gohman | dceffe6 | 2008-09-25 01:28:51 +0000 | [diff] [blame] | 133 |   if (Reg != 0) | 
 | 134 |     LocalValueMap[V] = Reg; | 
| Dan Gohman | 104e4ce | 2008-09-03 23:32:19 +0000 | [diff] [blame] | 135 |   return Reg; | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 136 | } | 
 | 137 |  | 
| Evan Cheng | 59fbc80 | 2008-09-09 01:26:59 +0000 | [diff] [blame] | 138 | unsigned FastISel::lookUpRegForValue(Value *V) { | 
 | 139 |   // Look up the value to see if we already have a register for it. We | 
 | 140 |   // cache values defined by Instructions across blocks, and other values | 
 | 141 |   // only locally. This is because Instructions already have the SSA | 
 | 142 |   // def-dominatess-use requirement enforced. | 
 | 143 |   if (ValueMap.count(V)) | 
 | 144 |     return ValueMap[V]; | 
 | 145 |   return LocalValueMap[V]; | 
 | 146 | } | 
 | 147 |  | 
| Owen Anderson | cc54e76 | 2008-08-30 00:38:46 +0000 | [diff] [blame] | 148 | /// UpdateValueMap - Update the value map to include the new mapping for this | 
 | 149 | /// instruction, or insert an extra copy to get the result in a previous | 
 | 150 | /// determined register. | 
 | 151 | /// NOTE: This is only necessary because we might select a block that uses | 
 | 152 | /// a value before we select the block that defines the value.  It might be | 
 | 153 | /// possible to fix this by selecting blocks in reverse postorder. | 
| Chris Lattner | c5040ab | 2009-04-12 07:45:01 +0000 | [diff] [blame] | 154 | unsigned FastISel::UpdateValueMap(Value* I, unsigned Reg) { | 
| Dan Gohman | 40b189e | 2008-09-05 18:18:20 +0000 | [diff] [blame] | 155 |   if (!isa<Instruction>(I)) { | 
 | 156 |     LocalValueMap[I] = Reg; | 
| Chris Lattner | c5040ab | 2009-04-12 07:45:01 +0000 | [diff] [blame] | 157 |     return Reg; | 
| Dan Gohman | 40b189e | 2008-09-05 18:18:20 +0000 | [diff] [blame] | 158 |   } | 
| Chris Lattner | c5040ab | 2009-04-12 07:45:01 +0000 | [diff] [blame] | 159 |    | 
 | 160 |   unsigned &AssignedReg = ValueMap[I]; | 
 | 161 |   if (AssignedReg == 0) | 
 | 162 |     AssignedReg = Reg; | 
| Chris Lattner | 36e3946 | 2009-04-12 07:46:30 +0000 | [diff] [blame] | 163 |   else if (Reg != AssignedReg) { | 
| Chris Lattner | c5040ab | 2009-04-12 07:45:01 +0000 | [diff] [blame] | 164 |     const TargetRegisterClass *RegClass = MRI.getRegClass(Reg); | 
 | 165 |     TII.copyRegToReg(*MBB, MBB->end(), AssignedReg, | 
 | 166 |                      Reg, RegClass, RegClass); | 
 | 167 |   } | 
 | 168 |   return AssignedReg; | 
| Owen Anderson | cc54e76 | 2008-08-30 00:38:46 +0000 | [diff] [blame] | 169 | } | 
 | 170 |  | 
| Dan Gohman | c8a1a3c | 2008-12-08 07:57:47 +0000 | [diff] [blame] | 171 | unsigned FastISel::getRegForGEPIndex(Value *Idx) { | 
 | 172 |   unsigned IdxN = getRegForValue(Idx); | 
 | 173 |   if (IdxN == 0) | 
 | 174 |     // Unhandled operand. Halt "fast" selection and bail. | 
 | 175 |     return 0; | 
 | 176 |  | 
 | 177 |   // If the index is smaller or larger than intptr_t, truncate or extend it. | 
| Owen Anderson | 766b5ef | 2009-08-11 21:59:30 +0000 | [diff] [blame] | 178 |   MVT PtrVT = TLI.getPointerTy(); | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 179 |   EVT IdxVT = EVT::getEVT(Idx->getType(), /*HandleUnknown=*/false); | 
| Dan Gohman | c8a1a3c | 2008-12-08 07:57:47 +0000 | [diff] [blame] | 180 |   if (IdxVT.bitsLT(PtrVT)) | 
| Owen Anderson | 766b5ef | 2009-08-11 21:59:30 +0000 | [diff] [blame] | 181 |     IdxN = FastEmit_r(IdxVT.getSimpleVT(), PtrVT, ISD::SIGN_EXTEND, IdxN); | 
| Dan Gohman | c8a1a3c | 2008-12-08 07:57:47 +0000 | [diff] [blame] | 182 |   else if (IdxVT.bitsGT(PtrVT)) | 
| Owen Anderson | 766b5ef | 2009-08-11 21:59:30 +0000 | [diff] [blame] | 183 |     IdxN = FastEmit_r(IdxVT.getSimpleVT(), PtrVT, ISD::TRUNCATE, IdxN); | 
| Dan Gohman | c8a1a3c | 2008-12-08 07:57:47 +0000 | [diff] [blame] | 184 |   return IdxN; | 
 | 185 | } | 
 | 186 |  | 
| Dan Gohman | bdedd44 | 2008-08-20 00:11:48 +0000 | [diff] [blame] | 187 | /// SelectBinaryOp - Select and emit code for a binary operator instruction, | 
 | 188 | /// which has an opcode which directly corresponds to the given ISD opcode. | 
 | 189 | /// | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 190 | bool FastISel::SelectBinaryOp(User *I, unsigned ISDOpcode) { | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 191 |   EVT VT = EVT::getEVT(I->getType(), /*HandleUnknown=*/true); | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 192 |   if (VT == MVT::Other || !VT.isSimple()) | 
| Dan Gohman | bdedd44 | 2008-08-20 00:11:48 +0000 | [diff] [blame] | 193 |     // Unhandled type. Halt "fast" selection and bail. | 
 | 194 |     return false; | 
| Dan Gohman | 638c683 | 2008-09-05 18:44:22 +0000 | [diff] [blame] | 195 |  | 
| Dan Gohman | b71fea2 | 2008-08-26 20:52:40 +0000 | [diff] [blame] | 196 |   // We only handle legal types. For example, on x86-32 the instruction | 
 | 197 |   // selector contains all of the 64-bit instructions from x86-64, | 
 | 198 |   // under the assumption that i64 won't be used if the target doesn't | 
 | 199 |   // support it. | 
| Dan Gohman | 638c683 | 2008-09-05 18:44:22 +0000 | [diff] [blame] | 200 |   if (!TLI.isTypeLegal(VT)) { | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 201 |     // MVT::i1 is special. Allow AND, OR, or XOR because they | 
| Dan Gohman | 638c683 | 2008-09-05 18:44:22 +0000 | [diff] [blame] | 202 |     // don't require additional zeroing, which makes them easy. | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 203 |     if (VT == MVT::i1 && | 
| Dan Gohman | 5dd9c2e | 2008-09-25 17:22:52 +0000 | [diff] [blame] | 204 |         (ISDOpcode == ISD::AND || ISDOpcode == ISD::OR || | 
 | 205 |          ISDOpcode == ISD::XOR)) | 
| Owen Anderson | 23b9b19 | 2009-08-12 00:36:31 +0000 | [diff] [blame] | 206 |       VT = TLI.getTypeToTransformTo(I->getContext(), VT); | 
| Dan Gohman | 638c683 | 2008-09-05 18:44:22 +0000 | [diff] [blame] | 207 |     else | 
 | 208 |       return false; | 
 | 209 |   } | 
| Dan Gohman | bdedd44 | 2008-08-20 00:11:48 +0000 | [diff] [blame] | 210 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 211 |   unsigned Op0 = getRegForValue(I->getOperand(0)); | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 212 |   if (Op0 == 0) | 
 | 213 |     // Unhandled operand. Halt "fast" selection and bail. | 
 | 214 |     return false; | 
 | 215 |  | 
 | 216 |   // Check if the second operand is a constant and handle it appropriately. | 
 | 217 |   if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) { | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 218 |     unsigned ResultReg = FastEmit_ri(VT.getSimpleVT(), VT.getSimpleVT(), | 
 | 219 |                                      ISDOpcode, Op0, CI->getZExtValue()); | 
 | 220 |     if (ResultReg != 0) { | 
 | 221 |       // We successfully emitted code for the given LLVM Instruction. | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 222 |       UpdateValueMap(I, ResultReg); | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 223 |       return true; | 
 | 224 |     } | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 225 |   } | 
 | 226 |  | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 227 |   // Check if the second operand is a constant float. | 
 | 228 |   if (ConstantFP *CF = dyn_cast<ConstantFP>(I->getOperand(1))) { | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 229 |     unsigned ResultReg = FastEmit_rf(VT.getSimpleVT(), VT.getSimpleVT(), | 
 | 230 |                                      ISDOpcode, Op0, CF); | 
 | 231 |     if (ResultReg != 0) { | 
 | 232 |       // We successfully emitted code for the given LLVM Instruction. | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 233 |       UpdateValueMap(I, ResultReg); | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 234 |       return true; | 
 | 235 |     } | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 236 |   } | 
 | 237 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 238 |   unsigned Op1 = getRegForValue(I->getOperand(1)); | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 239 |   if (Op1 == 0) | 
 | 240 |     // Unhandled operand. Halt "fast" selection and bail. | 
 | 241 |     return false; | 
 | 242 |  | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 243 |   // Now we have both operands in registers. Emit the instruction. | 
| Owen Anderson | 0f84e4e | 2008-08-25 23:58:18 +0000 | [diff] [blame] | 244 |   unsigned ResultReg = FastEmit_rr(VT.getSimpleVT(), VT.getSimpleVT(), | 
 | 245 |                                    ISDOpcode, Op0, Op1); | 
| Dan Gohman | bdedd44 | 2008-08-20 00:11:48 +0000 | [diff] [blame] | 246 |   if (ResultReg == 0) | 
 | 247 |     // Target-specific code wasn't able to find a machine opcode for | 
 | 248 |     // the given ISD opcode and type. Halt "fast" selection and bail. | 
 | 249 |     return false; | 
 | 250 |  | 
| Dan Gohman | 8014e86 | 2008-08-20 00:23:20 +0000 | [diff] [blame] | 251 |   // We successfully emitted code for the given LLVM Instruction. | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 252 |   UpdateValueMap(I, ResultReg); | 
| Dan Gohman | bdedd44 | 2008-08-20 00:11:48 +0000 | [diff] [blame] | 253 |   return true; | 
 | 254 | } | 
 | 255 |  | 
| Dan Gohman | 40b189e | 2008-09-05 18:18:20 +0000 | [diff] [blame] | 256 | bool FastISel::SelectGetElementPtr(User *I) { | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 257 |   unsigned N = getRegForValue(I->getOperand(0)); | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 258 |   if (N == 0) | 
 | 259 |     // Unhandled operand. Halt "fast" selection and bail. | 
 | 260 |     return false; | 
 | 261 |  | 
 | 262 |   const Type *Ty = I->getOperand(0)->getType(); | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 263 |   MVT VT = TLI.getPointerTy(); | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 264 |   for (GetElementPtrInst::op_iterator OI = I->op_begin()+1, E = I->op_end(); | 
 | 265 |        OI != E; ++OI) { | 
 | 266 |     Value *Idx = *OI; | 
 | 267 |     if (const StructType *StTy = dyn_cast<StructType>(Ty)) { | 
 | 268 |       unsigned Field = cast<ConstantInt>(Idx)->getZExtValue(); | 
 | 269 |       if (Field) { | 
 | 270 |         // N = N + Offset | 
 | 271 |         uint64_t Offs = TD.getStructLayout(StTy)->getElementOffset(Field); | 
 | 272 |         // FIXME: This can be optimized by combining the add with a | 
 | 273 |         // subsequent one. | 
| Dan Gohman | 7a0e659 | 2008-08-21 17:25:26 +0000 | [diff] [blame] | 274 |         N = FastEmit_ri_(VT, ISD::ADD, N, Offs, VT); | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 275 |         if (N == 0) | 
 | 276 |           // Unhandled operand. Halt "fast" selection and bail. | 
 | 277 |           return false; | 
 | 278 |       } | 
 | 279 |       Ty = StTy->getElementType(Field); | 
 | 280 |     } else { | 
 | 281 |       Ty = cast<SequentialType>(Ty)->getElementType(); | 
 | 282 |  | 
 | 283 |       // If this is a constant subscript, handle it quickly. | 
 | 284 |       if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx)) { | 
 | 285 |         if (CI->getZExtValue() == 0) continue; | 
 | 286 |         uint64_t Offs =  | 
| Duncan Sands | 777d230 | 2009-05-09 07:06:46 +0000 | [diff] [blame] | 287 |           TD.getTypeAllocSize(Ty)*cast<ConstantInt>(CI)->getSExtValue(); | 
| Dan Gohman | 7a0e659 | 2008-08-21 17:25:26 +0000 | [diff] [blame] | 288 |         N = FastEmit_ri_(VT, ISD::ADD, N, Offs, VT); | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 289 |         if (N == 0) | 
 | 290 |           // Unhandled operand. Halt "fast" selection and bail. | 
 | 291 |           return false; | 
 | 292 |         continue; | 
 | 293 |       } | 
 | 294 |        | 
 | 295 |       // N = N + Idx * ElementSize; | 
| Duncan Sands | 777d230 | 2009-05-09 07:06:46 +0000 | [diff] [blame] | 296 |       uint64_t ElementSize = TD.getTypeAllocSize(Ty); | 
| Dan Gohman | c8a1a3c | 2008-12-08 07:57:47 +0000 | [diff] [blame] | 297 |       unsigned IdxN = getRegForGEPIndex(Idx); | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 298 |       if (IdxN == 0) | 
 | 299 |         // Unhandled operand. Halt "fast" selection and bail. | 
 | 300 |         return false; | 
 | 301 |  | 
| Dan Gohman | 80bc6e2 | 2008-08-26 20:57:08 +0000 | [diff] [blame] | 302 |       if (ElementSize != 1) { | 
| Dan Gohman | f93cf79 | 2008-08-21 17:37:05 +0000 | [diff] [blame] | 303 |         IdxN = FastEmit_ri_(VT, ISD::MUL, IdxN, ElementSize, VT); | 
| Dan Gohman | 80bc6e2 | 2008-08-26 20:57:08 +0000 | [diff] [blame] | 304 |         if (IdxN == 0) | 
 | 305 |           // Unhandled operand. Halt "fast" selection and bail. | 
 | 306 |           return false; | 
 | 307 |       } | 
| Owen Anderson | 0f84e4e | 2008-08-25 23:58:18 +0000 | [diff] [blame] | 308 |       N = FastEmit_rr(VT, VT, ISD::ADD, N, IdxN); | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 309 |       if (N == 0) | 
 | 310 |         // Unhandled operand. Halt "fast" selection and bail. | 
 | 311 |         return false; | 
 | 312 |     } | 
 | 313 |   } | 
 | 314 |  | 
 | 315 |   // We successfully emitted code for the given LLVM Instruction. | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 316 |   UpdateValueMap(I, N); | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 317 |   return true; | 
| Dan Gohman | bdedd44 | 2008-08-20 00:11:48 +0000 | [diff] [blame] | 318 | } | 
 | 319 |  | 
| Dan Gohman | 33134c4 | 2008-09-25 17:05:24 +0000 | [diff] [blame] | 320 | bool FastISel::SelectCall(User *I) { | 
 | 321 |   Function *F = cast<CallInst>(I)->getCalledFunction(); | 
 | 322 |   if (!F) return false; | 
 | 323 |  | 
 | 324 |   unsigned IID = F->getIntrinsicID(); | 
 | 325 |   switch (IID) { | 
 | 326 |   default: break; | 
| Bill Wendling | 92c1e12 | 2009-02-13 02:16:35 +0000 | [diff] [blame] | 327 |   case Intrinsic::dbg_declare: { | 
 | 328 |     DbgDeclareInst *DI = cast<DbgDeclareInst>(I); | 
| Chris Lattner | bf0ca2b | 2009-12-29 09:32:19 +0000 | [diff] [blame] | 329 |     if (!DIDescriptor::ValidDebugInfo(DI->getVariable(), CodeGenOpt::None)||!DW | 
| Devang Patel | 7e1e31f | 2009-07-02 22:43:26 +0000 | [diff] [blame] | 330 |         || !DW->ShouldEmitDwarfDebug()) | 
 | 331 |       return true; | 
 | 332 |  | 
| Devang Patel | 7e1e31f | 2009-07-02 22:43:26 +0000 | [diff] [blame] | 333 |     Value *Address = DI->getAddress(); | 
| Dale Johannesen | dc91856 | 2010-02-06 02:26:02 +0000 | [diff] [blame] | 334 |     if (!Address) | 
 | 335 |       return true; | 
| Devang Patel | 7e1e31f | 2009-07-02 22:43:26 +0000 | [diff] [blame] | 336 |     AllocaInst *AI = dyn_cast<AllocaInst>(Address); | 
 | 337 |     // Don't handle byval struct arguments or VLAs, for example. | 
 | 338 |     if (!AI) break; | 
 | 339 |     DenseMap<const AllocaInst*, int>::iterator SI = | 
 | 340 |       StaticAllocaMap.find(AI); | 
 | 341 |     if (SI == StaticAllocaMap.end()) break; // VLAs. | 
 | 342 |     int FI = SI->second; | 
| Chris Lattner | de4845c | 2010-04-02 19:42:39 +0000 | [diff] [blame^] | 343 |     if (!DI->getDebugLoc().isUnknown()) | 
 | 344 |       MMI->setVariableDbgInfo(DI->getVariable(), FI, DI->getDebugLoc()); | 
| Chris Lattner | 870cfcf | 2010-03-31 03:34:40 +0000 | [diff] [blame] | 345 |      | 
| Dale Johannesen | 10fedd2 | 2010-02-10 00:11:11 +0000 | [diff] [blame] | 346 |     // Building the map above is target independent.  Generating DBG_VALUE | 
| Dale Johannesen | 5ed17ae | 2010-01-26 00:09:58 +0000 | [diff] [blame] | 347 |     // inline is target dependent; do this now. | 
 | 348 |     (void)TargetSelectInstruction(cast<Instruction>(I)); | 
| Dan Gohman | 33134c4 | 2008-09-25 17:05:24 +0000 | [diff] [blame] | 349 |     return true; | 
| Bill Wendling | 92c1e12 | 2009-02-13 02:16:35 +0000 | [diff] [blame] | 350 |   } | 
| Dale Johannesen | 45df761 | 2010-02-26 20:01:55 +0000 | [diff] [blame] | 351 |   case Intrinsic::dbg_value: { | 
 | 352 |     // This requires target support, but right now X86 is the only Fast target. | 
 | 353 |     DbgValueInst *DI = cast<DbgValueInst>(I); | 
 | 354 |     const TargetInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE); | 
 | 355 |     Value *V = DI->getValue(); | 
 | 356 |     if (!V) { | 
 | 357 |       // Currently the optimizer can produce this; insert an undef to | 
 | 358 |       // help debugging.  Probably the optimizer should not do this. | 
 | 359 |       BuildMI(MBB, DL, II).addReg(0U).addImm(DI->getOffset()). | 
 | 360 |                                      addMetadata(DI->getVariable()); | 
 | 361 |     } else if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { | 
 | 362 |       BuildMI(MBB, DL, II).addImm(CI->getZExtValue()).addImm(DI->getOffset()). | 
 | 363 |                                      addMetadata(DI->getVariable()); | 
 | 364 |     } else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) { | 
 | 365 |       BuildMI(MBB, DL, II).addFPImm(CF).addImm(DI->getOffset()). | 
 | 366 |                                      addMetadata(DI->getVariable()); | 
 | 367 |     } else if (unsigned Reg = lookUpRegForValue(V)) { | 
 | 368 |       BuildMI(MBB, DL, II).addReg(Reg, RegState::Debug).addImm(DI->getOffset()). | 
 | 369 |                                      addMetadata(DI->getVariable()); | 
 | 370 |     } else { | 
 | 371 |       // We can't yet handle anything else here because it would require | 
 | 372 |       // generating code, thus altering codegen because of debug info. | 
 | 373 |       // Insert an undef so we can see what we dropped. | 
 | 374 |       BuildMI(MBB, DL, II).addReg(0U).addImm(DI->getOffset()). | 
 | 375 |                                      addMetadata(DI->getVariable()); | 
 | 376 |     }      | 
 | 377 |     return true; | 
 | 378 |   } | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 379 |   case Intrinsic::eh_exception: { | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 380 |     EVT VT = TLI.getValueType(I->getType()); | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 381 |     switch (TLI.getOperationAction(ISD::EXCEPTIONADDR, VT)) { | 
 | 382 |     default: break; | 
 | 383 |     case TargetLowering::Expand: { | 
| Duncan Sands | b0f1e17 | 2009-05-22 20:36:31 +0000 | [diff] [blame] | 384 |       assert(MBB->isLandingPad() && "Call to eh.exception not in landing pad!"); | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 385 |       unsigned Reg = TLI.getExceptionAddressRegister(); | 
 | 386 |       const TargetRegisterClass *RC = TLI.getRegClassFor(VT); | 
 | 387 |       unsigned ResultReg = createResultReg(RC); | 
 | 388 |       bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, | 
 | 389 |                                            Reg, RC, RC); | 
 | 390 |       assert(InsertedCopy && "Can't copy address registers!"); | 
| Evan Cheng | 24ac408 | 2008-11-24 07:09:49 +0000 | [diff] [blame] | 391 |       InsertedCopy = InsertedCopy; | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 392 |       UpdateValueMap(I, ResultReg); | 
 | 393 |       return true; | 
 | 394 |     } | 
 | 395 |     } | 
 | 396 |     break; | 
 | 397 |   } | 
| Duncan Sands | b01bbdc | 2009-10-14 16:11:37 +0000 | [diff] [blame] | 398 |   case Intrinsic::eh_selector: { | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 399 |     EVT VT = TLI.getValueType(I->getType()); | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 400 |     switch (TLI.getOperationAction(ISD::EHSELECTION, VT)) { | 
 | 401 |     default: break; | 
 | 402 |     case TargetLowering::Expand: { | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 403 |       if (MMI) { | 
 | 404 |         if (MBB->isLandingPad()) | 
 | 405 |           AddCatchInfo(*cast<CallInst>(I), MMI, MBB); | 
 | 406 |         else { | 
 | 407 | #ifndef NDEBUG | 
 | 408 |           CatchInfoLost.insert(cast<CallInst>(I)); | 
 | 409 | #endif | 
 | 410 |           // FIXME: Mark exception selector register as live in.  Hack for PR1508. | 
 | 411 |           unsigned Reg = TLI.getExceptionSelectorRegister(); | 
 | 412 |           if (Reg) MBB->addLiveIn(Reg); | 
 | 413 |         } | 
 | 414 |  | 
 | 415 |         unsigned Reg = TLI.getExceptionSelectorRegister(); | 
| Duncan Sands | b01bbdc | 2009-10-14 16:11:37 +0000 | [diff] [blame] | 416 |         EVT SrcVT = TLI.getPointerTy(); | 
 | 417 |         const TargetRegisterClass *RC = TLI.getRegClassFor(SrcVT); | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 418 |         unsigned ResultReg = createResultReg(RC); | 
| Duncan Sands | b01bbdc | 2009-10-14 16:11:37 +0000 | [diff] [blame] | 419 |         bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, Reg, | 
 | 420 |                                              RC, RC); | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 421 |         assert(InsertedCopy && "Can't copy address registers!"); | 
| Evan Cheng | 24ac408 | 2008-11-24 07:09:49 +0000 | [diff] [blame] | 422 |         InsertedCopy = InsertedCopy; | 
| Duncan Sands | b01bbdc | 2009-10-14 16:11:37 +0000 | [diff] [blame] | 423 |  | 
 | 424 |         // Cast the register to the type of the selector. | 
 | 425 |         if (SrcVT.bitsGT(MVT::i32)) | 
 | 426 |           ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32, ISD::TRUNCATE, | 
 | 427 |                                  ResultReg); | 
 | 428 |         else if (SrcVT.bitsLT(MVT::i32)) | 
 | 429 |           ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32, | 
 | 430 |                                  ISD::SIGN_EXTEND, ResultReg); | 
 | 431 |         if (ResultReg == 0) | 
 | 432 |           // Unhandled operand. Halt "fast" selection and bail. | 
 | 433 |           return false; | 
 | 434 |  | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 435 |         UpdateValueMap(I, ResultReg); | 
 | 436 |       } else { | 
 | 437 |         unsigned ResultReg = | 
| Owen Anderson | a7235ea | 2009-07-31 20:28:14 +0000 | [diff] [blame] | 438 |           getRegForValue(Constant::getNullValue(I->getType())); | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 439 |         UpdateValueMap(I, ResultReg); | 
 | 440 |       } | 
 | 441 |       return true; | 
 | 442 |     } | 
 | 443 |     } | 
 | 444 |     break; | 
 | 445 |   } | 
| Dan Gohman | 33134c4 | 2008-09-25 17:05:24 +0000 | [diff] [blame] | 446 |   } | 
 | 447 |   return false; | 
 | 448 | } | 
 | 449 |  | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 450 | bool FastISel::SelectCast(User *I, unsigned Opcode) { | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 451 |   EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType()); | 
 | 452 |   EVT DstVT = TLI.getValueType(I->getType()); | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 453 |      | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 454 |   if (SrcVT == MVT::Other || !SrcVT.isSimple() || | 
 | 455 |       DstVT == MVT::Other || !DstVT.isSimple()) | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 456 |     // Unhandled type. Halt "fast" selection and bail. | 
 | 457 |     return false; | 
 | 458 |      | 
| Dan Gohman | 474d3b3 | 2009-03-13 23:53:06 +0000 | [diff] [blame] | 459 |   // Check if the destination type is legal. Or as a special case, | 
 | 460 |   // it may be i1 if we're doing a truncate because that's | 
 | 461 |   // easy and somewhat common. | 
 | 462 |   if (!TLI.isTypeLegal(DstVT)) | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 463 |     if (DstVT != MVT::i1 || Opcode != ISD::TRUNCATE) | 
| Dan Gohman | 91b6f97 | 2008-10-03 01:28:47 +0000 | [diff] [blame] | 464 |       // Unhandled type. Halt "fast" selection and bail. | 
 | 465 |       return false; | 
| Dan Gohman | 474d3b3 | 2009-03-13 23:53:06 +0000 | [diff] [blame] | 466 |  | 
 | 467 |   // Check if the source operand is legal. Or as a special case, | 
 | 468 |   // it may be i1 if we're doing zero-extension because that's | 
 | 469 |   // easy and somewhat common. | 
 | 470 |   if (!TLI.isTypeLegal(SrcVT)) | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 471 |     if (SrcVT != MVT::i1 || Opcode != ISD::ZERO_EXTEND) | 
| Dan Gohman | 474d3b3 | 2009-03-13 23:53:06 +0000 | [diff] [blame] | 472 |       // Unhandled type. Halt "fast" selection and bail. | 
 | 473 |       return false; | 
 | 474 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 475 |   unsigned InputReg = getRegForValue(I->getOperand(0)); | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 476 |   if (!InputReg) | 
 | 477 |     // Unhandled operand.  Halt "fast" selection and bail. | 
 | 478 |     return false; | 
| Dan Gohman | 14ea1ec | 2009-03-13 20:42:20 +0000 | [diff] [blame] | 479 |  | 
 | 480 |   // If the operand is i1, arrange for the high bits in the register to be zero. | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 481 |   if (SrcVT == MVT::i1) { | 
| Owen Anderson | 23b9b19 | 2009-08-12 00:36:31 +0000 | [diff] [blame] | 482 |    SrcVT = TLI.getTypeToTransformTo(I->getContext(), SrcVT); | 
| Dan Gohman | 14ea1ec | 2009-03-13 20:42:20 +0000 | [diff] [blame] | 483 |    InputReg = FastEmitZExtFromI1(SrcVT.getSimpleVT(), InputReg); | 
 | 484 |    if (!InputReg) | 
 | 485 |      return false; | 
 | 486 |   } | 
| Dan Gohman | 474d3b3 | 2009-03-13 23:53:06 +0000 | [diff] [blame] | 487 |   // If the result is i1, truncate to the target's type for i1 first. | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 488 |   if (DstVT == MVT::i1) | 
| Owen Anderson | 23b9b19 | 2009-08-12 00:36:31 +0000 | [diff] [blame] | 489 |     DstVT = TLI.getTypeToTransformTo(I->getContext(), DstVT); | 
| Dan Gohman | 14ea1ec | 2009-03-13 20:42:20 +0000 | [diff] [blame] | 490 |  | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 491 |   unsigned ResultReg = FastEmit_r(SrcVT.getSimpleVT(), | 
 | 492 |                                   DstVT.getSimpleVT(), | 
 | 493 |                                   Opcode, | 
 | 494 |                                   InputReg); | 
 | 495 |   if (!ResultReg) | 
 | 496 |     return false; | 
 | 497 |      | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 498 |   UpdateValueMap(I, ResultReg); | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 499 |   return true; | 
 | 500 | } | 
 | 501 |  | 
| Dan Gohman | 40b189e | 2008-09-05 18:18:20 +0000 | [diff] [blame] | 502 | bool FastISel::SelectBitCast(User *I) { | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 503 |   // If the bitcast doesn't change the type, just use the operand value. | 
 | 504 |   if (I->getType() == I->getOperand(0)->getType()) { | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 505 |     unsigned Reg = getRegForValue(I->getOperand(0)); | 
| Dan Gohman | a318dab | 2008-08-27 20:41:38 +0000 | [diff] [blame] | 506 |     if (Reg == 0) | 
 | 507 |       return false; | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 508 |     UpdateValueMap(I, Reg); | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 509 |     return true; | 
 | 510 |   } | 
 | 511 |  | 
 | 512 |   // Bitcasts of other values become reg-reg copies or BIT_CONVERT operators. | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 513 |   EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType()); | 
 | 514 |   EVT DstVT = TLI.getValueType(I->getType()); | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 515 |    | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 516 |   if (SrcVT == MVT::Other || !SrcVT.isSimple() || | 
 | 517 |       DstVT == MVT::Other || !DstVT.isSimple() || | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 518 |       !TLI.isTypeLegal(SrcVT) || !TLI.isTypeLegal(DstVT)) | 
 | 519 |     // Unhandled type. Halt "fast" selection and bail. | 
 | 520 |     return false; | 
 | 521 |    | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 522 |   unsigned Op0 = getRegForValue(I->getOperand(0)); | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 523 |   if (Op0 == 0) | 
 | 524 |     // Unhandled operand. Halt "fast" selection and bail. | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 525 |     return false; | 
 | 526 |    | 
| Dan Gohman | ad368ac | 2008-08-27 18:10:19 +0000 | [diff] [blame] | 527 |   // First, try to perform the bitcast by inserting a reg-reg copy. | 
 | 528 |   unsigned ResultReg = 0; | 
 | 529 |   if (SrcVT.getSimpleVT() == DstVT.getSimpleVT()) { | 
 | 530 |     TargetRegisterClass* SrcClass = TLI.getRegClassFor(SrcVT); | 
 | 531 |     TargetRegisterClass* DstClass = TLI.getRegClassFor(DstVT); | 
 | 532 |     ResultReg = createResultReg(DstClass); | 
 | 533 |      | 
 | 534 |     bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, | 
 | 535 |                                          Op0, DstClass, SrcClass); | 
 | 536 |     if (!InsertedCopy) | 
 | 537 |       ResultReg = 0; | 
 | 538 |   } | 
 | 539 |    | 
 | 540 |   // If the reg-reg copy failed, select a BIT_CONVERT opcode. | 
 | 541 |   if (!ResultReg) | 
 | 542 |     ResultReg = FastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), | 
 | 543 |                            ISD::BIT_CONVERT, Op0); | 
 | 544 |    | 
 | 545 |   if (!ResultReg) | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 546 |     return false; | 
 | 547 |    | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 548 |   UpdateValueMap(I, ResultReg); | 
| Owen Anderson | d0533c9 | 2008-08-26 23:46:32 +0000 | [diff] [blame] | 549 |   return true; | 
 | 550 | } | 
 | 551 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 552 | bool | 
 | 553 | FastISel::SelectInstruction(Instruction *I) { | 
| Dan Gohman | 6e3ff37 | 2009-12-05 01:27:58 +0000 | [diff] [blame] | 554 |   // First, try doing target-independent selection. | 
 | 555 |   if (SelectOperator(I, I->getOpcode())) | 
 | 556 |     return true; | 
 | 557 |  | 
 | 558 |   // Next, try calling the target to attempt to handle the instruction. | 
 | 559 |   if (TargetSelectInstruction(I)) | 
 | 560 |     return true; | 
 | 561 |  | 
 | 562 |   return false; | 
| Dan Gohman | 40b189e | 2008-09-05 18:18:20 +0000 | [diff] [blame] | 563 | } | 
 | 564 |  | 
| Dan Gohman | d98d620 | 2008-10-02 22:15:21 +0000 | [diff] [blame] | 565 | /// FastEmitBranch - Emit an unconditional branch to the given block, | 
 | 566 | /// unless it is the immediate (fall-through) successor, and update | 
 | 567 | /// the CFG. | 
 | 568 | void | 
 | 569 | FastISel::FastEmitBranch(MachineBasicBlock *MSucc) { | 
| Dan Gohman | d98d620 | 2008-10-02 22:15:21 +0000 | [diff] [blame] | 570 |   if (MBB->isLayoutSuccessor(MSucc)) { | 
 | 571 |     // The unconditional fall-through case, which needs no instructions. | 
 | 572 |   } else { | 
 | 573 |     // The unconditional branch case. | 
 | 574 |     TII.InsertBranch(*MBB, MSucc, NULL, SmallVector<MachineOperand, 0>()); | 
 | 575 |   } | 
 | 576 |   MBB->addSuccessor(MSucc); | 
 | 577 | } | 
 | 578 |  | 
| Dan Gohman | 3d45a85 | 2009-09-03 22:53:57 +0000 | [diff] [blame] | 579 | /// SelectFNeg - Emit an FNeg operation. | 
 | 580 | /// | 
 | 581 | bool | 
 | 582 | FastISel::SelectFNeg(User *I) { | 
 | 583 |   unsigned OpReg = getRegForValue(BinaryOperator::getFNegArgument(I)); | 
 | 584 |   if (OpReg == 0) return false; | 
 | 585 |  | 
| Dan Gohman | 4a215a1 | 2009-09-11 00:36:43 +0000 | [diff] [blame] | 586 |   // If the target has ISD::FNEG, use it. | 
 | 587 |   EVT VT = TLI.getValueType(I->getType()); | 
 | 588 |   unsigned ResultReg = FastEmit_r(VT.getSimpleVT(), VT.getSimpleVT(), | 
 | 589 |                                   ISD::FNEG, OpReg); | 
 | 590 |   if (ResultReg != 0) { | 
 | 591 |     UpdateValueMap(I, ResultReg); | 
 | 592 |     return true; | 
 | 593 |   } | 
 | 594 |  | 
| Dan Gohman | 5e5abb7 | 2009-09-11 00:34:46 +0000 | [diff] [blame] | 595 |   // Bitcast the value to integer, twiddle the sign bit with xor, | 
 | 596 |   // and then bitcast it back to floating-point. | 
| Dan Gohman | 3d45a85 | 2009-09-03 22:53:57 +0000 | [diff] [blame] | 597 |   if (VT.getSizeInBits() > 64) return false; | 
| Dan Gohman | 5e5abb7 | 2009-09-11 00:34:46 +0000 | [diff] [blame] | 598 |   EVT IntVT = EVT::getIntegerVT(I->getContext(), VT.getSizeInBits()); | 
 | 599 |   if (!TLI.isTypeLegal(IntVT)) | 
 | 600 |     return false; | 
 | 601 |  | 
 | 602 |   unsigned IntReg = FastEmit_r(VT.getSimpleVT(), IntVT.getSimpleVT(), | 
 | 603 |                                ISD::BIT_CONVERT, OpReg); | 
 | 604 |   if (IntReg == 0) | 
 | 605 |     return false; | 
 | 606 |  | 
 | 607 |   unsigned IntResultReg = FastEmit_ri_(IntVT.getSimpleVT(), ISD::XOR, IntReg, | 
 | 608 |                                        UINT64_C(1) << (VT.getSizeInBits()-1), | 
 | 609 |                                        IntVT.getSimpleVT()); | 
 | 610 |   if (IntResultReg == 0) | 
 | 611 |     return false; | 
 | 612 |  | 
 | 613 |   ResultReg = FastEmit_r(IntVT.getSimpleVT(), VT.getSimpleVT(), | 
 | 614 |                          ISD::BIT_CONVERT, IntResultReg); | 
| Dan Gohman | 3d45a85 | 2009-09-03 22:53:57 +0000 | [diff] [blame] | 615 |   if (ResultReg == 0) | 
 | 616 |     return false; | 
 | 617 |  | 
 | 618 |   UpdateValueMap(I, ResultReg); | 
 | 619 |   return true; | 
 | 620 | } | 
 | 621 |  | 
| Dan Gohman | 40b189e | 2008-09-05 18:18:20 +0000 | [diff] [blame] | 622 | bool | 
 | 623 | FastISel::SelectOperator(User *I, unsigned Opcode) { | 
 | 624 |   switch (Opcode) { | 
| Dan Gohman | ae3a0be | 2009-06-04 22:49:04 +0000 | [diff] [blame] | 625 |   case Instruction::Add: | 
 | 626 |     return SelectBinaryOp(I, ISD::ADD); | 
 | 627 |   case Instruction::FAdd: | 
 | 628 |     return SelectBinaryOp(I, ISD::FADD); | 
 | 629 |   case Instruction::Sub: | 
 | 630 |     return SelectBinaryOp(I, ISD::SUB); | 
 | 631 |   case Instruction::FSub: | 
| Dan Gohman | 3d45a85 | 2009-09-03 22:53:57 +0000 | [diff] [blame] | 632 |     // FNeg is currently represented in LLVM IR as a special case of FSub. | 
 | 633 |     if (BinaryOperator::isFNeg(I)) | 
 | 634 |       return SelectFNeg(I); | 
| Dan Gohman | ae3a0be | 2009-06-04 22:49:04 +0000 | [diff] [blame] | 635 |     return SelectBinaryOp(I, ISD::FSUB); | 
 | 636 |   case Instruction::Mul: | 
 | 637 |     return SelectBinaryOp(I, ISD::MUL); | 
 | 638 |   case Instruction::FMul: | 
 | 639 |     return SelectBinaryOp(I, ISD::FMUL); | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 640 |   case Instruction::SDiv: | 
 | 641 |     return SelectBinaryOp(I, ISD::SDIV); | 
 | 642 |   case Instruction::UDiv: | 
 | 643 |     return SelectBinaryOp(I, ISD::UDIV); | 
 | 644 |   case Instruction::FDiv: | 
 | 645 |     return SelectBinaryOp(I, ISD::FDIV); | 
 | 646 |   case Instruction::SRem: | 
 | 647 |     return SelectBinaryOp(I, ISD::SREM); | 
 | 648 |   case Instruction::URem: | 
 | 649 |     return SelectBinaryOp(I, ISD::UREM); | 
 | 650 |   case Instruction::FRem: | 
 | 651 |     return SelectBinaryOp(I, ISD::FREM); | 
 | 652 |   case Instruction::Shl: | 
 | 653 |     return SelectBinaryOp(I, ISD::SHL); | 
 | 654 |   case Instruction::LShr: | 
 | 655 |     return SelectBinaryOp(I, ISD::SRL); | 
 | 656 |   case Instruction::AShr: | 
 | 657 |     return SelectBinaryOp(I, ISD::SRA); | 
 | 658 |   case Instruction::And: | 
 | 659 |     return SelectBinaryOp(I, ISD::AND); | 
 | 660 |   case Instruction::Or: | 
 | 661 |     return SelectBinaryOp(I, ISD::OR); | 
 | 662 |   case Instruction::Xor: | 
 | 663 |     return SelectBinaryOp(I, ISD::XOR); | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 664 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 665 |   case Instruction::GetElementPtr: | 
 | 666 |     return SelectGetElementPtr(I); | 
| Dan Gohman | bdedd44 | 2008-08-20 00:11:48 +0000 | [diff] [blame] | 667 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 668 |   case Instruction::Br: { | 
 | 669 |     BranchInst *BI = cast<BranchInst>(I); | 
| Dan Gohman | bdedd44 | 2008-08-20 00:11:48 +0000 | [diff] [blame] | 670 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 671 |     if (BI->isUnconditional()) { | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 672 |       BasicBlock *LLVMSucc = BI->getSuccessor(0); | 
 | 673 |       MachineBasicBlock *MSucc = MBBMap[LLVMSucc]; | 
| Dan Gohman | d98d620 | 2008-10-02 22:15:21 +0000 | [diff] [blame] | 674 |       FastEmitBranch(MSucc); | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 675 |       return true; | 
| Owen Anderson | 9d5b416 | 2008-08-27 00:31:01 +0000 | [diff] [blame] | 676 |     } | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 677 |  | 
 | 678 |     // Conditional branches are not handed yet. | 
 | 679 |     // Halt "fast" selection and bail. | 
 | 680 |     return false; | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 681 |   } | 
 | 682 |  | 
| Dan Gohman | 087c850 | 2008-09-05 01:08:41 +0000 | [diff] [blame] | 683 |   case Instruction::Unreachable: | 
 | 684 |     // Nothing to emit. | 
 | 685 |     return true; | 
 | 686 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 687 |   case Instruction::PHI: | 
 | 688 |     // PHI nodes are already emitted. | 
 | 689 |     return true; | 
| Dan Gohman | 0586d91 | 2008-09-10 20:11:02 +0000 | [diff] [blame] | 690 |  | 
 | 691 |   case Instruction::Alloca: | 
 | 692 |     // FunctionLowering has the static-sized case covered. | 
 | 693 |     if (StaticAllocaMap.count(cast<AllocaInst>(I))) | 
 | 694 |       return true; | 
 | 695 |  | 
 | 696 |     // Dynamic-sized alloca is not handled yet. | 
 | 697 |     return false; | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 698 |      | 
| Dan Gohman | 33134c4 | 2008-09-25 17:05:24 +0000 | [diff] [blame] | 699 |   case Instruction::Call: | 
 | 700 |     return SelectCall(I); | 
 | 701 |    | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 702 |   case Instruction::BitCast: | 
 | 703 |     return SelectBitCast(I); | 
 | 704 |  | 
 | 705 |   case Instruction::FPToSI: | 
 | 706 |     return SelectCast(I, ISD::FP_TO_SINT); | 
 | 707 |   case Instruction::ZExt: | 
 | 708 |     return SelectCast(I, ISD::ZERO_EXTEND); | 
 | 709 |   case Instruction::SExt: | 
 | 710 |     return SelectCast(I, ISD::SIGN_EXTEND); | 
 | 711 |   case Instruction::Trunc: | 
 | 712 |     return SelectCast(I, ISD::TRUNCATE); | 
 | 713 |   case Instruction::SIToFP: | 
 | 714 |     return SelectCast(I, ISD::SINT_TO_FP); | 
 | 715 |  | 
 | 716 |   case Instruction::IntToPtr: // Deliberate fall-through. | 
 | 717 |   case Instruction::PtrToInt: { | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 718 |     EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType()); | 
 | 719 |     EVT DstVT = TLI.getValueType(I->getType()); | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 720 |     if (DstVT.bitsGT(SrcVT)) | 
 | 721 |       return SelectCast(I, ISD::ZERO_EXTEND); | 
 | 722 |     if (DstVT.bitsLT(SrcVT)) | 
 | 723 |       return SelectCast(I, ISD::TRUNCATE); | 
 | 724 |     unsigned Reg = getRegForValue(I->getOperand(0)); | 
 | 725 |     if (Reg == 0) return false; | 
 | 726 |     UpdateValueMap(I, Reg); | 
 | 727 |     return true; | 
 | 728 |   } | 
| Dan Gohman | d57dd5f | 2008-09-23 21:53:34 +0000 | [diff] [blame] | 729 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 730 |   default: | 
 | 731 |     // Unhandled instruction. Halt "fast" selection and bail. | 
 | 732 |     return false; | 
 | 733 |   } | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 734 | } | 
 | 735 |  | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 736 | FastISel::FastISel(MachineFunction &mf, | 
| Dan Gohman | d57dd5f | 2008-09-23 21:53:34 +0000 | [diff] [blame] | 737 |                    MachineModuleInfo *mmi, | 
| Devang Patel | 83489bb | 2009-01-13 00:35:13 +0000 | [diff] [blame] | 738 |                    DwarfWriter *dw, | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 739 |                    DenseMap<const Value *, unsigned> &vm, | 
| Dan Gohman | 0586d91 | 2008-09-10 20:11:02 +0000 | [diff] [blame] | 740 |                    DenseMap<const BasicBlock *, MachineBasicBlock *> &bm, | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 741 |                    DenseMap<const AllocaInst *, int> &am | 
 | 742 | #ifndef NDEBUG | 
 | 743 |                    , SmallSet<Instruction*, 8> &cil | 
 | 744 | #endif | 
 | 745 |                    ) | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 746 |   : MBB(0), | 
 | 747 |     ValueMap(vm), | 
 | 748 |     MBBMap(bm), | 
| Dan Gohman | 0586d91 | 2008-09-10 20:11:02 +0000 | [diff] [blame] | 749 |     StaticAllocaMap(am), | 
| Dan Gohman | dd5b58a | 2008-10-14 23:54:11 +0000 | [diff] [blame] | 750 | #ifndef NDEBUG | 
 | 751 |     CatchInfoLost(cil), | 
 | 752 | #endif | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 753 |     MF(mf), | 
| Dan Gohman | d57dd5f | 2008-09-23 21:53:34 +0000 | [diff] [blame] | 754 |     MMI(mmi), | 
| Devang Patel | 83489bb | 2009-01-13 00:35:13 +0000 | [diff] [blame] | 755 |     DW(dw), | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 756 |     MRI(MF.getRegInfo()), | 
| Dan Gohman | 0586d91 | 2008-09-10 20:11:02 +0000 | [diff] [blame] | 757 |     MFI(*MF.getFrameInfo()), | 
 | 758 |     MCP(*MF.getConstantPool()), | 
| Dan Gohman | 3df24e6 | 2008-09-03 23:12:08 +0000 | [diff] [blame] | 759 |     TM(MF.getTarget()), | 
| Dan Gohman | 22bb311 | 2008-08-22 00:20:26 +0000 | [diff] [blame] | 760 |     TD(*TM.getTargetData()), | 
 | 761 |     TII(*TM.getInstrInfo()), | 
| Owen Anderson | e922c02 | 2009-07-22 00:24:57 +0000 | [diff] [blame] | 762 |     TLI(*TM.getTargetLowering()) { | 
| Dan Gohman | bb46633 | 2008-08-20 21:05:57 +0000 | [diff] [blame] | 763 | } | 
 | 764 |  | 
| Dan Gohman | e285a74 | 2008-08-14 21:51:29 +0000 | [diff] [blame] | 765 | FastISel::~FastISel() {} | 
 | 766 |  | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 767 | unsigned FastISel::FastEmit_(MVT, MVT, | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 768 |                              unsigned) { | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 769 |   return 0; | 
 | 770 | } | 
 | 771 |  | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 772 | unsigned FastISel::FastEmit_r(MVT, MVT, | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 773 |                               unsigned, unsigned /*Op0*/) { | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 774 |   return 0; | 
 | 775 | } | 
 | 776 |  | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 777 | unsigned FastISel::FastEmit_rr(MVT, MVT,  | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 778 |                                unsigned, unsigned /*Op0*/, | 
| Owen Anderson | 0f84e4e | 2008-08-25 23:58:18 +0000 | [diff] [blame] | 779 |                                unsigned /*Op0*/) { | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 780 |   return 0; | 
 | 781 | } | 
 | 782 |  | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 783 | unsigned FastISel::FastEmit_i(MVT, MVT, unsigned, uint64_t /*Imm*/) { | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 784 |   return 0; | 
 | 785 | } | 
 | 786 |  | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 787 | unsigned FastISel::FastEmit_f(MVT, MVT, | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 788 |                               unsigned, ConstantFP * /*FPImm*/) { | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 789 |   return 0; | 
 | 790 | } | 
 | 791 |  | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 792 | unsigned FastISel::FastEmit_ri(MVT, MVT, | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 793 |                                unsigned, unsigned /*Op0*/, | 
| Owen Anderson | 0f84e4e | 2008-08-25 23:58:18 +0000 | [diff] [blame] | 794 |                                uint64_t /*Imm*/) { | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 795 |   return 0; | 
 | 796 | } | 
 | 797 |  | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 798 | unsigned FastISel::FastEmit_rf(MVT, MVT, | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 799 |                                unsigned, unsigned /*Op0*/, | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 800 |                                ConstantFP * /*FPImm*/) { | 
 | 801 |   return 0; | 
 | 802 | } | 
 | 803 |  | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 804 | unsigned FastISel::FastEmit_rri(MVT, MVT, | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 805 |                                 unsigned, | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 806 |                                 unsigned /*Op0*/, unsigned /*Op1*/, | 
 | 807 |                                 uint64_t /*Imm*/) { | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 808 |   return 0; | 
 | 809 | } | 
 | 810 |  | 
 | 811 | /// FastEmit_ri_ - This method is a wrapper of FastEmit_ri. It first tries | 
 | 812 | /// to emit an instruction with an immediate operand using FastEmit_ri. | 
 | 813 | /// If that fails, it materializes the immediate into a register and try | 
 | 814 | /// FastEmit_rr instead. | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 815 | unsigned FastISel::FastEmit_ri_(MVT VT, unsigned Opcode, | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 816 |                                 unsigned Op0, uint64_t Imm, | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 817 |                                 MVT ImmType) { | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 818 |   // First check if immediate type is legal. If not, we can't use the ri form. | 
| Dan Gohman | 151ed61 | 2008-08-27 18:15:05 +0000 | [diff] [blame] | 819 |   unsigned ResultReg = FastEmit_ri(VT, VT, Opcode, Op0, Imm); | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 820 |   if (ResultReg != 0) | 
 | 821 |     return ResultReg; | 
| Owen Anderson | 0f84e4e | 2008-08-25 23:58:18 +0000 | [diff] [blame] | 822 |   unsigned MaterialReg = FastEmit_i(ImmType, ImmType, ISD::Constant, Imm); | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 823 |   if (MaterialReg == 0) | 
 | 824 |     return 0; | 
| Owen Anderson | 0f84e4e | 2008-08-25 23:58:18 +0000 | [diff] [blame] | 825 |   return FastEmit_rr(VT, VT, Opcode, Op0, MaterialReg); | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 826 | } | 
 | 827 |  | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 828 | /// FastEmit_rf_ - This method is a wrapper of FastEmit_ri. It first tries | 
 | 829 | /// to emit an instruction with a floating-point immediate operand using | 
 | 830 | /// FastEmit_rf. If that fails, it materializes the immediate into a register | 
 | 831 | /// and try FastEmit_rr instead. | 
| Dan Gohman | 7c3ecb6 | 2010-01-05 22:26:32 +0000 | [diff] [blame] | 832 | unsigned FastISel::FastEmit_rf_(MVT VT, unsigned Opcode, | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 833 |                                 unsigned Op0, ConstantFP *FPImm, | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 834 |                                 MVT ImmType) { | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 835 |   // First check if immediate type is legal. If not, we can't use the rf form. | 
| Dan Gohman | 151ed61 | 2008-08-27 18:15:05 +0000 | [diff] [blame] | 836 |   unsigned ResultReg = FastEmit_rf(VT, VT, Opcode, Op0, FPImm); | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 837 |   if (ResultReg != 0) | 
 | 838 |     return ResultReg; | 
 | 839 |  | 
 | 840 |   // Materialize the constant in a register. | 
 | 841 |   unsigned MaterialReg = FastEmit_f(ImmType, ImmType, ISD::ConstantFP, FPImm); | 
 | 842 |   if (MaterialReg == 0) { | 
| Dan Gohman | 96a9999 | 2008-08-27 18:01:42 +0000 | [diff] [blame] | 843 |     // If the target doesn't have a way to directly enter a floating-point | 
 | 844 |     // value into a register, use an alternate approach. | 
 | 845 |     // TODO: The current approach only supports floating-point constants | 
 | 846 |     // that can be constructed by conversion from integer values. This should | 
 | 847 |     // be replaced by code that creates a load from a constant-pool entry, | 
 | 848 |     // which will require some target-specific work. | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 849 |     const APFloat &Flt = FPImm->getValueAPF(); | 
| Owen Anderson | e50ed30 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 850 |     EVT IntVT = TLI.getPointerTy(); | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 851 |  | 
 | 852 |     uint64_t x[2]; | 
 | 853 |     uint32_t IntBitWidth = IntVT.getSizeInBits(); | 
| Dale Johannesen | 23a9855 | 2008-10-09 23:00:39 +0000 | [diff] [blame] | 854 |     bool isExact; | 
 | 855 |     (void) Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true, | 
 | 856 |                              APFloat::rmTowardZero, &isExact); | 
 | 857 |     if (!isExact) | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 858 |       return 0; | 
 | 859 |     APInt IntVal(IntBitWidth, 2, x); | 
 | 860 |  | 
 | 861 |     unsigned IntegerReg = FastEmit_i(IntVT.getSimpleVT(), IntVT.getSimpleVT(), | 
 | 862 |                                      ISD::Constant, IntVal.getZExtValue()); | 
 | 863 |     if (IntegerReg == 0) | 
 | 864 |       return 0; | 
 | 865 |     MaterialReg = FastEmit_r(IntVT.getSimpleVT(), VT, | 
 | 866 |                              ISD::SINT_TO_FP, IntegerReg); | 
 | 867 |     if (MaterialReg == 0) | 
 | 868 |       return 0; | 
 | 869 |   } | 
 | 870 |   return FastEmit_rr(VT, VT, Opcode, Op0, MaterialReg); | 
 | 871 | } | 
 | 872 |  | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 873 | unsigned FastISel::createResultReg(const TargetRegisterClass* RC) { | 
 | 874 |   return MRI.createVirtualRegister(RC); | 
| Evan Cheng | 83785c8 | 2008-08-20 22:45:34 +0000 | [diff] [blame] | 875 | } | 
 | 876 |  | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 877 | unsigned FastISel::FastEmitInst_(unsigned MachineInstOpcode, | 
| Dan Gohman | 77ad796 | 2008-08-20 18:09:38 +0000 | [diff] [blame] | 878 |                                  const TargetRegisterClass* RC) { | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 879 |   unsigned ResultReg = createResultReg(RC); | 
| Dan Gohman | bb46633 | 2008-08-20 21:05:57 +0000 | [diff] [blame] | 880 |   const TargetInstrDesc &II = TII.get(MachineInstOpcode); | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 881 |  | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 882 |   BuildMI(MBB, DL, II, ResultReg); | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 883 |   return ResultReg; | 
 | 884 | } | 
 | 885 |  | 
 | 886 | unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode, | 
 | 887 |                                   const TargetRegisterClass *RC, | 
 | 888 |                                   unsigned Op0) { | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 889 |   unsigned ResultReg = createResultReg(RC); | 
| Dan Gohman | bb46633 | 2008-08-20 21:05:57 +0000 | [diff] [blame] | 890 |   const TargetInstrDesc &II = TII.get(MachineInstOpcode); | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 891 |  | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 892 |   if (II.getNumDefs() >= 1) | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 893 |     BuildMI(MBB, DL, II, ResultReg).addReg(Op0); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 894 |   else { | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 895 |     BuildMI(MBB, DL, II).addReg(Op0); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 896 |     bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, | 
 | 897 |                                          II.ImplicitDefs[0], RC, RC); | 
 | 898 |     if (!InsertedCopy) | 
 | 899 |       ResultReg = 0; | 
 | 900 |   } | 
 | 901 |  | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 902 |   return ResultReg; | 
 | 903 | } | 
 | 904 |  | 
 | 905 | unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode, | 
 | 906 |                                    const TargetRegisterClass *RC, | 
 | 907 |                                    unsigned Op0, unsigned Op1) { | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 908 |   unsigned ResultReg = createResultReg(RC); | 
| Dan Gohman | bb46633 | 2008-08-20 21:05:57 +0000 | [diff] [blame] | 909 |   const TargetInstrDesc &II = TII.get(MachineInstOpcode); | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 910 |  | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 911 |   if (II.getNumDefs() >= 1) | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 912 |     BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addReg(Op1); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 913 |   else { | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 914 |     BuildMI(MBB, DL, II).addReg(Op0).addReg(Op1); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 915 |     bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, | 
 | 916 |                                          II.ImplicitDefs[0], RC, RC); | 
 | 917 |     if (!InsertedCopy) | 
 | 918 |       ResultReg = 0; | 
 | 919 |   } | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 920 |   return ResultReg; | 
 | 921 | } | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 922 |  | 
 | 923 | unsigned FastISel::FastEmitInst_ri(unsigned MachineInstOpcode, | 
 | 924 |                                    const TargetRegisterClass *RC, | 
 | 925 |                                    unsigned Op0, uint64_t Imm) { | 
 | 926 |   unsigned ResultReg = createResultReg(RC); | 
 | 927 |   const TargetInstrDesc &II = TII.get(MachineInstOpcode); | 
 | 928 |  | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 929 |   if (II.getNumDefs() >= 1) | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 930 |     BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addImm(Imm); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 931 |   else { | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 932 |     BuildMI(MBB, DL, II).addReg(Op0).addImm(Imm); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 933 |     bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, | 
 | 934 |                                          II.ImplicitDefs[0], RC, RC); | 
 | 935 |     if (!InsertedCopy) | 
 | 936 |       ResultReg = 0; | 
 | 937 |   } | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 938 |   return ResultReg; | 
 | 939 | } | 
 | 940 |  | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 941 | unsigned FastISel::FastEmitInst_rf(unsigned MachineInstOpcode, | 
 | 942 |                                    const TargetRegisterClass *RC, | 
 | 943 |                                    unsigned Op0, ConstantFP *FPImm) { | 
 | 944 |   unsigned ResultReg = createResultReg(RC); | 
 | 945 |   const TargetInstrDesc &II = TII.get(MachineInstOpcode); | 
 | 946 |  | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 947 |   if (II.getNumDefs() >= 1) | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 948 |     BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addFPImm(FPImm); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 949 |   else { | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 950 |     BuildMI(MBB, DL, II).addReg(Op0).addFPImm(FPImm); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 951 |     bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, | 
 | 952 |                                          II.ImplicitDefs[0], RC, RC); | 
 | 953 |     if (!InsertedCopy) | 
 | 954 |       ResultReg = 0; | 
 | 955 |   } | 
| Dan Gohman | 10df0fa | 2008-08-27 01:09:54 +0000 | [diff] [blame] | 956 |   return ResultReg; | 
 | 957 | } | 
 | 958 |  | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 959 | unsigned FastISel::FastEmitInst_rri(unsigned MachineInstOpcode, | 
 | 960 |                                     const TargetRegisterClass *RC, | 
 | 961 |                                     unsigned Op0, unsigned Op1, uint64_t Imm) { | 
 | 962 |   unsigned ResultReg = createResultReg(RC); | 
 | 963 |   const TargetInstrDesc &II = TII.get(MachineInstOpcode); | 
 | 964 |  | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 965 |   if (II.getNumDefs() >= 1) | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 966 |     BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addReg(Op1).addImm(Imm); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 967 |   else { | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 968 |     BuildMI(MBB, DL, II).addReg(Op0).addReg(Op1).addImm(Imm); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 969 |     bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, | 
 | 970 |                                          II.ImplicitDefs[0], RC, RC); | 
 | 971 |     if (!InsertedCopy) | 
 | 972 |       ResultReg = 0; | 
 | 973 |   } | 
| Dan Gohman | d5fe57d | 2008-08-21 01:41:07 +0000 | [diff] [blame] | 974 |   return ResultReg; | 
 | 975 | } | 
| Owen Anderson | 6d0c25e | 2008-08-25 20:20:32 +0000 | [diff] [blame] | 976 |  | 
 | 977 | unsigned FastISel::FastEmitInst_i(unsigned MachineInstOpcode, | 
 | 978 |                                   const TargetRegisterClass *RC, | 
 | 979 |                                   uint64_t Imm) { | 
 | 980 |   unsigned ResultReg = createResultReg(RC); | 
 | 981 |   const TargetInstrDesc &II = TII.get(MachineInstOpcode); | 
 | 982 |    | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 983 |   if (II.getNumDefs() >= 1) | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 984 |     BuildMI(MBB, DL, II, ResultReg).addImm(Imm); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 985 |   else { | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 986 |     BuildMI(MBB, DL, II).addImm(Imm); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 987 |     bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, | 
 | 988 |                                          II.ImplicitDefs[0], RC, RC); | 
 | 989 |     if (!InsertedCopy) | 
 | 990 |       ResultReg = 0; | 
 | 991 |   } | 
| Owen Anderson | 6d0c25e | 2008-08-25 20:20:32 +0000 | [diff] [blame] | 992 |   return ResultReg; | 
| Evan Cheng | b41aec5 | 2008-08-25 22:20:39 +0000 | [diff] [blame] | 993 | } | 
| Owen Anderson | 8970f00 | 2008-08-27 22:30:02 +0000 | [diff] [blame] | 994 |  | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 995 | unsigned FastISel::FastEmitInst_extractsubreg(MVT RetVT, | 
| Evan Cheng | 536ab13 | 2009-01-22 09:10:11 +0000 | [diff] [blame] | 996 |                                               unsigned Op0, uint32_t Idx) { | 
| Owen Anderson | 40a468f | 2008-08-28 17:47:37 +0000 | [diff] [blame] | 997 |   const TargetRegisterClass* RC = MRI.getRegClass(Op0); | 
| Owen Anderson | 8970f00 | 2008-08-27 22:30:02 +0000 | [diff] [blame] | 998 |    | 
| Evan Cheng | 536ab13 | 2009-01-22 09:10:11 +0000 | [diff] [blame] | 999 |   unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT)); | 
| Chris Lattner | 518bb53 | 2010-02-09 19:54:29 +0000 | [diff] [blame] | 1000 |   const TargetInstrDesc &II = TII.get(TargetOpcode::EXTRACT_SUBREG); | 
| Owen Anderson | 8970f00 | 2008-08-27 22:30:02 +0000 | [diff] [blame] | 1001 |    | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 1002 |   if (II.getNumDefs() >= 1) | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 1003 |     BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addImm(Idx); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 1004 |   else { | 
| Bill Wendling | 9bc96a5 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 1005 |     BuildMI(MBB, DL, II).addReg(Op0).addImm(Idx); | 
| Evan Cheng | 5960e4e | 2008-09-08 08:38:20 +0000 | [diff] [blame] | 1006 |     bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, | 
 | 1007 |                                          II.ImplicitDefs[0], RC, RC); | 
 | 1008 |     if (!InsertedCopy) | 
 | 1009 |       ResultReg = 0; | 
 | 1010 |   } | 
| Owen Anderson | 8970f00 | 2008-08-27 22:30:02 +0000 | [diff] [blame] | 1011 |   return ResultReg; | 
 | 1012 | } | 
| Dan Gohman | 14ea1ec | 2009-03-13 20:42:20 +0000 | [diff] [blame] | 1013 |  | 
 | 1014 | /// FastEmitZExtFromI1 - Emit MachineInstrs to compute the value of Op | 
 | 1015 | /// with all but the least significant bit set to zero. | 
| Owen Anderson | 825b72b | 2009-08-11 20:47:22 +0000 | [diff] [blame] | 1016 | unsigned FastISel::FastEmitZExtFromI1(MVT VT, unsigned Op) { | 
| Dan Gohman | 14ea1ec | 2009-03-13 20:42:20 +0000 | [diff] [blame] | 1017 |   return FastEmit_ri(VT, VT, ISD::AND, Op, 1); | 
 | 1018 | } |