LLVM API Documentation
00001 //===- TableGen'erated file -------------------------------------*- C++ -*-===// 00002 // 00003 // DAG Instruction Selector for the IA64 target 00004 // 00005 // Automatically generated file, do not edit! 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 // *** NOTE: This file is #included into the middle of the target 00010 // *** instruction selector class. These functions are really methods. 00011 00012 #if defined(__GNUC__) && \ 00013 ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) 00014 #define NOINLINE __attribute__((noinline)) 00015 #else 00016 00017 #define NOINLINE 00018 00019 #endif 00020 00021 // Instance var to keep track of multiply used nodes that have 00022 // already been selected. 00023 std::map<SDOperand, SDOperand> CodeGenMap; 00024 // Instance var to keep track of mapping of chain generating nodes 00025 // and their place handle nodes. 00026 std::map<SDOperand, SDOperand> HandleMap; 00027 // Instance var to keep track of mapping of place handle nodes 00028 // and their replacement nodes. 00029 std::map<SDOperand, SDOperand> ReplaceMap; 00030 // Keep track of nodes that are currently being selecte and therefore 00031 // should not be folded. 00032 std::set<SDNode*> InFlightSet; 00033 00034 static void findNonImmUse(SDNode* Use, SDNode* Def, bool &found, std::set<SDNode *> &Visited) { 00035 if (found || !Visited.insert(Use).second) return; 00036 for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) { 00037 SDNode *N = Use->getOperand(i).Val; 00038 if (N != Def) { 00039 findNonImmUse(N, Def, found, Visited); 00040 } else { 00041 found = true; 00042 break; 00043 } 00044 } 00045 } 00046 00047 static bool isNonImmUse(SDNode* Use, SDNode* Def) { 00048 std::set<SDNode *> Visited; 00049 bool found = false; 00050 for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) { 00051 SDNode *N = Use->getOperand(i).Val; 00052 if (N != Def) { 00053 findNonImmUse(N, Def, found, Visited); 00054 if (found) break; 00055 } 00056 } 00057 return found; 00058 } 00059 00060 // AddHandleReplacement - Note the pending replacement node for a 00061 // handle node in ReplaceMap. 00062 void AddHandleReplacement(SDNode *H, unsigned HNum, SDNode *R, unsigned RNum) { 00063 SDOperand N(H, HNum); 00064 std::map<SDOperand, SDOperand>::iterator HMI = HandleMap.find(N); 00065 if (HMI != HandleMap.end()) { 00066 ReplaceMap[HMI->second] = SDOperand(R, RNum); 00067 HandleMap.erase(N); 00068 } 00069 } 00070 00071 // SelectDanglingHandles - Select replacements for all `dangling` 00072 // handles.Some handles do not yet have replacements because the 00073 // nodes they replacements have only dead readers. 00074 void SelectDanglingHandles() { 00075 for (std::map<SDOperand, SDOperand>::iterator I = HandleMap.begin(), 00076 E = HandleMap.end(); I != E; ++I) { 00077 SDOperand N = I->first; 00078 SDOperand R; 00079 Select(R, N.getValue(0)); 00080 AddHandleReplacement(N.Val, N.ResNo, R.Val, R.ResNo); 00081 } 00082 } 00083 00084 // ReplaceHandles - Replace all the handles with the real target 00085 // specific nodes. 00086 void ReplaceHandles() { 00087 for (std::map<SDOperand, SDOperand>::iterator I = ReplaceMap.begin(), 00088 E = ReplaceMap.end(); I != E; ++I) { 00089 SDOperand From = I->first; 00090 SDOperand To = I->second; 00091 for (SDNode::use_iterator UI = From.Val->use_begin(), E = From.Val->use_end(); UI != E; ++UI) { 00092 SDNode *Use = *UI; 00093 std::vector<SDOperand> Ops; 00094 for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i){ 00095 SDOperand O = Use->getOperand(i); 00096 if (O.Val == From.Val) 00097 Ops.push_back(To); 00098 else 00099 Ops.push_back(O); 00100 } 00101 SDOperand U = SDOperand(Use, 0); 00102 CurDAG->UpdateNodeOperands(U, Ops); 00103 } 00104 } 00105 } 00106 00107 // SelectRoot - Top level entry to DAG isel. 00108 SDOperand SelectRoot(SDOperand N) { 00109 SDOperand ResNode; 00110 Select(ResNode, N); 00111 SelectDanglingHandles(); 00112 ReplaceHandles(); 00113 ReplaceMap.clear(); 00114 return ResNode; 00115 } 00116 00117 // Node transformations. 00118 00119 // Predicate functions. 00120 inline bool Predicate_immAllOnes(SDNode *inN) { 00121 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00122 return N->isAllOnesValue(); 00123 } 00124 inline bool Predicate_immAllOnesV(SDNode *N) { 00125 00126 return ISD::isBuildVectorAllOnes(N); 00127 00128 } 00129 inline bool Predicate_immAllOnesV_bc(SDNode *N) { 00130 00131 return ISD::isBuildVectorAllOnes(N); 00132 00133 } 00134 inline bool Predicate_immAllZerosV(SDNode *N) { 00135 00136 return ISD::isBuildVectorAllZeros(N); 00137 00138 } 00139 inline bool Predicate_immSExt14(SDNode *inN) { 00140 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00141 00142 // immSExt14 predicate - True if the immediate fits in a 14-bit sign extended 00143 // field. Used by instructions like 'adds'. 00144 int64_t v = (int64_t)N->getValue(); 00145 return (v <= 8191 && v >= -8192); 00146 00147 } 00148 inline bool Predicate_is32ones(SDNode *inN) { 00149 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00150 00151 // is32ones predicate - True if the immediate is 0x00000000FFFFFFFF 00152 // Used to create ZXT4s appropriately 00153 uint64_t v = (uint64_t)N->getValue(); 00154 return (v == 0x00000000FFFFFFFFLL); 00155 00156 } 00157 inline bool Predicate_isMIX1Lable(SDNode *inN) { 00158 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00159 00160 return((uint64_t)N->getValue()==0xFF00FF00FF00FF00LL); 00161 00162 } 00163 inline bool Predicate_isMIX1Rable(SDNode *inN) { 00164 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00165 00166 return((uint64_t)N->getValue()==0x00FF00FF00FF00FFLL); 00167 00168 } 00169 inline bool Predicate_isMIX2Lable(SDNode *inN) { 00170 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00171 00172 return((uint64_t)N->getValue()==0xFFFF0000FFFF0000LL); 00173 00174 } 00175 inline bool Predicate_isMIX2Rable(SDNode *inN) { 00176 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00177 00178 return((uint64_t)N->getValue()==0x0000FFFF0000FFFFLL); 00179 00180 } 00181 inline bool Predicate_isMIX4Lable(SDNode *inN) { 00182 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00183 00184 return((uint64_t)N->getValue()==0xFFFFFFFF00000000LL); 00185 00186 } 00187 inline bool Predicate_isMIX4Rable(SDNode *inN) { 00188 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00189 00190 return((uint64_t)N->getValue()==0x00000000FFFFFFFFLL); 00191 00192 } 00193 inline bool Predicate_isSHLADDimm(SDNode *inN) { 00194 ConstantSDNode *N = cast<ConstantSDNode>(inN); 00195 00196 // isSHLADDimm predicate - True if the immediate is exactly 1, 2, 3 or 4 00197 // - 0 is *not* okay. 00198 // Used to create shladd instructions appropriately 00199 int64_t v = (int64_t)N->getValue(); 00200 return (v >= 1 && v <= 4); 00201 00202 } 00203 inline bool Predicate_vtFP(SDNode *inN) { 00204 VTSDNode *N = cast<VTSDNode>(inN); 00205 return MVT::isFloatingPoint(N->getVT()); 00206 } 00207 inline bool Predicate_vtInt(SDNode *inN) { 00208 VTSDNode *N = cast<VTSDNode>(inN); 00209 return MVT::isInteger(N->getVT()); 00210 } 00211 00212 00213 void Emit_0(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N01, SDOperand &N1) NOINLINE { 00214 SDOperand Tmp1(0, 0); 00215 SDOperand Tmp2(0, 0); 00216 SDNode *ResNode = NULL; 00217 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N00.Val); 00218 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N01.Val); 00219 Select(Tmp1, N00); 00220 Select(Tmp2, N01); 00221 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N00.Val); 00222 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N01.Val); 00223 if (N.Val->hasOneUse()) { 00224 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 00225 } else { 00226 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 00227 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00228 Result = SDOperand(ResNode, 0); 00229 } 00230 return; 00231 } 00232 void Emit_1(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1, SDOperand &N10, SDOperand &N11) NOINLINE { 00233 SDOperand Tmp0(0, 0); 00234 SDOperand Tmp1(0, 0); 00235 SDOperand Tmp2(0, 0); 00236 SDNode *ResNode = NULL; 00237 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N10.Val); 00238 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00239 Select(Tmp0, N10); 00240 Tmp1 = CurDAG->getTargetConstant(((uint64_t) cast<ConstantSDNode>(N11)->getValue()), MVT::i64); 00241 Select(Tmp2, N0); 00242 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N10.Val); 00243 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00244 if (N.Val->hasOneUse()) { 00245 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1, Tmp2); 00246 } else { 00247 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1, Tmp2); 00248 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00249 Result = SDOperand(ResNode, 0); 00250 } 00251 return; 00252 } 00253 void Emit_2(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N01, SDOperand &N1) NOINLINE { 00254 SDOperand Tmp1(0, 0); 00255 SDOperand Tmp2(0, 0); 00256 SDNode *ResNode = NULL; 00257 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N00.Val); 00258 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 00259 Select(Tmp1, N00); 00260 Select(Tmp2, N1); 00261 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N00.Val); 00262 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 00263 if (N.Val->hasOneUse()) { 00264 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 00265 } else { 00266 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 00267 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00268 Result = SDOperand(ResNode, 0); 00269 } 00270 return; 00271 } 00272 void Emit_3(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N01, SDOperand &N1) NOINLINE { 00273 SDOperand Tmp1(0, 0); 00274 SDOperand Tmp2(0, 0); 00275 SDNode *ResNode = NULL; 00276 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N01.Val); 00277 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 00278 Select(Tmp1, N01); 00279 Select(Tmp2, N1); 00280 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N01.Val); 00281 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 00282 if (N.Val->hasOneUse()) { 00283 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 00284 } else { 00285 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 00286 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00287 Result = SDOperand(ResNode, 0); 00288 } 00289 return; 00290 } 00291 void Emit_4(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1, SDOperand &N10, SDOperand &N11) NOINLINE { 00292 SDOperand Tmp1(0, 0); 00293 SDOperand Tmp2(0, 0); 00294 SDNode *ResNode = NULL; 00295 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N10.Val); 00296 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N11.Val); 00297 Select(Tmp1, N10); 00298 Select(Tmp2, N11); 00299 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N10.Val); 00300 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N11.Val); 00301 if (N.Val->hasOneUse()) { 00302 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 00303 } else { 00304 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 00305 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00306 Result = SDOperand(ResNode, 0); 00307 } 00308 return; 00309 } 00310 void Emit_5(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1, SDOperand &N10, SDOperand &N11) NOINLINE { 00311 SDOperand Tmp1(0, 0); 00312 SDOperand Tmp2(0, 0); 00313 SDNode *ResNode = NULL; 00314 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N10.Val); 00315 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00316 Select(Tmp1, N10); 00317 Select(Tmp2, N0); 00318 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N10.Val); 00319 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00320 if (N.Val->hasOneUse()) { 00321 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 00322 } else { 00323 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 00324 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00325 Result = SDOperand(ResNode, 0); 00326 } 00327 return; 00328 } 00329 void Emit_6(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1, SDOperand &N10, SDOperand &N11) NOINLINE { 00330 SDOperand Tmp1(0, 0); 00331 SDOperand Tmp2(0, 0); 00332 SDNode *ResNode = NULL; 00333 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N11.Val); 00334 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00335 Select(Tmp1, N11); 00336 Select(Tmp2, N0); 00337 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N11.Val); 00338 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00339 if (N.Val->hasOneUse()) { 00340 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 00341 } else { 00342 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 00343 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00344 Result = SDOperand(ResNode, 0); 00345 } 00346 return; 00347 } 00348 void Emit_7(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N01, SDOperand &N1) NOINLINE { 00349 SDOperand Tmp0(0, 0); 00350 SDOperand Tmp1(0, 0); 00351 SDOperand Tmp2(0, 0); 00352 SDNode *ResNode = NULL; 00353 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N00.Val); 00354 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 00355 Select(Tmp0, N00); 00356 Tmp1 = CurDAG->getTargetConstant(((uint64_t) cast<ConstantSDNode>(N01)->getValue()), MVT::i64); 00357 Select(Tmp2, N1); 00358 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N00.Val); 00359 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 00360 if (N.Val->hasOneUse()) { 00361 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1, Tmp2); 00362 } else { 00363 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1, Tmp2); 00364 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00365 Result = SDOperand(ResNode, 0); 00366 } 00367 return; 00368 } 00369 void Emit_8(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1) NOINLINE { 00370 SDOperand Tmp0(0, 0); 00371 SDOperand Tmp1(0, 0); 00372 SDNode *ResNode = NULL; 00373 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00374 Select(Tmp0, N0); 00375 Tmp1 = CurDAG->getTargetConstant(((uint64_t) cast<ConstantSDNode>(N1)->getValue()), MVT::i64); 00376 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00377 if (N.Val->hasOneUse()) { 00378 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1); 00379 } else { 00380 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1); 00381 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00382 Result = SDOperand(ResNode, 0); 00383 } 00384 return; 00385 } 00386 void Emit_9(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1) NOINLINE { 00387 SDOperand Tmp0(0, 0); 00388 SDOperand Tmp1(0, 0); 00389 SDNode *ResNode = NULL; 00390 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00391 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 00392 Select(Tmp0, N0); 00393 Select(Tmp1, N1); 00394 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00395 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 00396 if (N.Val->hasOneUse()) { 00397 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1); 00398 } else { 00399 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1); 00400 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00401 Result = SDOperand(ResNode, 0); 00402 } 00403 return; 00404 } 00405 void Select_add(SDOperand &Result, SDOperand N) { 00406 SDOperand N0(0, 0); 00407 SDOperand N00(0, 0); 00408 SDOperand N01(0, 0); 00409 SDOperand N1(0, 0); 00410 SDOperand N10(0, 0); 00411 SDOperand N11(0, 0); 00412 SDOperand Tmp0(0, 0); 00413 SDOperand Tmp1(0, 0); 00414 SDOperand Tmp2(0, 0); 00415 SDNode *ResNode = NULL; 00416 N0 = N.getOperand(0); 00417 00418 // Pattern: (add:i64 (add:i64 GR:i64:$src1, GR:i64:$src2), 1:i64) 00419 // Emits: (ADD1:i64 GR:i64:$src1, GR:i64:$src2) 00420 // Pattern complexity = 7 cost = 1 size = 0 00421 if (N0.getOpcode() == ISD::ADD) { 00422 N00 = N0.getOperand(0); 00423 N01 = N0.getOperand(1); 00424 N1 = N.getOperand(1); 00425 if (isa<ConstantSDNode>(N1)) { 00426 int64_t CN0 = cast<ConstantSDNode>(N1)->getSignExtended(); 00427 if (CN0 == 1 && 00428 N.Val->getValueType(0) == MVT::i64) { 00429 Emit_0(Result, N, IA64::ADD1, MVT::i64, N0, N00, N01, N1); 00430 return; 00431 } 00432 } 00433 } 00434 00435 // Pattern: (add:i64 (sub:i64 GR:i64:$src1, GR:i64:$src2), -1:i64) 00436 // Emits: (SUB1:i64 GR:i64:$src1, GR:i64:$src2) 00437 // Pattern complexity = 7 cost = 1 size = 0 00438 if (N0.getOpcode() == ISD::SUB) { 00439 N00 = N0.getOperand(0); 00440 N01 = N0.getOperand(1); 00441 N1 = N.getOperand(1); 00442 if (isa<ConstantSDNode>(N1)) { 00443 int64_t CN0 = cast<ConstantSDNode>(N1)->getSignExtended(); 00444 if (CN0 == -1 && 00445 N.Val->getValueType(0) == MVT::i64) { 00446 Emit_0(Result, N, IA64::SUB1, MVT::i64, N0, N00, N01, N1); 00447 return; 00448 } 00449 } 00450 } 00451 00452 // Pattern: (add:i64 GR:i64:$src2, (shl:i64 GR:i64:$src1, (imm:i64)<<P:Predicate_isSHLADDimm>>:$imm)) 00453 // Emits: (SHLADD:i64 GR:i64:$src1, (imm:i64):$imm, GR:i64:$src2) 00454 // Pattern complexity = 7 cost = 1 size = 0 00455 { 00456 N1 = N.getOperand(1); 00457 if (N1.getOpcode() == ISD::SHL) { 00458 N10 = N1.getOperand(0); 00459 N11 = N1.getOperand(1); 00460 if (N11.getOpcode() == ISD::Constant && 00461 Predicate_isSHLADDimm(N11.Val) && 00462 N.Val->getValueType(0) == MVT::i64 && 00463 N11.Val->getValueType(0) == MVT::i64) { 00464 Emit_1(Result, N, IA64::SHLADD, MVT::i64, N0, N1, N10, N11); 00465 return; 00466 } 00467 } 00468 } 00469 if (N0.getOpcode() == ISD::ADD) { 00470 N00 = N0.getOperand(0); 00471 00472 // Pattern: (add:i64 (add:i64 GR:i64:$src1, 1:i64), GR:i64:$src2) 00473 // Emits: (ADD1:i64 GR:i64:$src1, GR:i64:$src2) 00474 // Pattern complexity = 7 cost = 1 size = 0 00475 { 00476 N01 = N0.getOperand(1); 00477 if (isa<ConstantSDNode>(N01)) { 00478 int64_t CN0 = cast<ConstantSDNode>(N01)->getSignExtended(); 00479 if (CN0 == 1) { 00480 N1 = N.getOperand(1); 00481 if (N.Val->getValueType(0) == MVT::i64) { 00482 Emit_2(Result, N, IA64::ADD1, MVT::i64, N0, N00, N01, N1); 00483 return; 00484 } 00485 } 00486 } 00487 } 00488 00489 // Pattern: (add:i64 (add:i64 1:i64, GR:i64:$src1), GR:i64:$src2) 00490 // Emits: (ADD1:i64 GR:i64:$src1, GR:i64:$src2) 00491 // Pattern complexity = 7 cost = 1 00492 if (isa<ConstantSDNode>(N00)) { 00493 int64_t CN0 = cast<ConstantSDNode>(N00)->getSignExtended(); 00494 if (CN0 == 1) { 00495 N01 = N0.getOperand(1); 00496 N1 = N.getOperand(1); 00497 if (N.Val->getValueType(0) == MVT::i64) { 00498 Emit_3(Result, N, IA64::ADD1, MVT::i64, N0, N00, N01, N1); 00499 return; 00500 } 00501 } 00502 } 00503 } 00504 00505 // Pattern: (add:i64 1:i64, (add:i64 GR:i64:$src1, GR:i64:$src2)) 00506 // Emits: (ADD1:i64 GR:i64:$src1, GR:i64:$src2) 00507 // Pattern complexity = 7 cost = 1 size = 0 00508 if (isa<ConstantSDNode>(N0)) { 00509 int64_t CN0 = cast<ConstantSDNode>(N0)->getSignExtended(); 00510 if (CN0 == 1) { 00511 N1 = N.getOperand(1); 00512 if (N1.getOpcode() == ISD::ADD) { 00513 N10 = N1.getOperand(0); 00514 N11 = N1.getOperand(1); 00515 if (N.Val->getValueType(0) == MVT::i64) { 00516 Emit_4(Result, N, IA64::ADD1, MVT::i64, N0, N1, N10, N11); 00517 return; 00518 } 00519 } 00520 } 00521 } 00522 { 00523 N1 = N.getOperand(1); 00524 if (N1.getOpcode() == ISD::ADD) { 00525 N10 = N1.getOperand(0); 00526 00527 // Pattern: (add:i64 GR:i64:$src2, (add:i64 GR:i64:$src1, 1:i64)) 00528 // Emits: (ADD1:i64 GR:i64:$src1, GR:i64:$src2) 00529 // Pattern complexity = 7 cost = 1 size = 0 00530 { 00531 N11 = N1.getOperand(1); 00532 if (isa<ConstantSDNode>(N11)) { 00533 int64_t CN0 = cast<ConstantSDNode>(N11)->getSignExtended(); 00534 if (CN0 == 1 && 00535 N.Val->getValueType(0) == MVT::i64) { 00536 Emit_5(Result, N, IA64::ADD1, MVT::i64, N0, N1, N10, N11); 00537 return; 00538 } 00539 } 00540 } 00541 00542 // Pattern: (add:i64 GR:i64:$src2, (add:i64 1:i64, GR:i64:$src1)) 00543 // Emits: (ADD1:i64 GR:i64:$src1, GR:i64:$src2) 00544 // Pattern complexity = 7 cost = 1 00545 if (isa<ConstantSDNode>(N10)) { 00546 int64_t CN0 = cast<ConstantSDNode>(N10)->getSignExtended(); 00547 if (CN0 == 1) { 00548 N11 = N1.getOperand(1); 00549 if (N.Val->getValueType(0) == MVT::i64) { 00550 Emit_6(Result, N, IA64::ADD1, MVT::i64, N0, N1, N10, N11); 00551 return; 00552 } 00553 } 00554 } 00555 } 00556 } 00557 00558 // Pattern: (add:i64 -1:i64, (sub:i64 GR:i64:$src1, GR:i64:$src2)) 00559 // Emits: (SUB1:i64 GR:i64:$src1, GR:i64:$src2) 00560 // Pattern complexity = 7 cost = 1 size = 0 00561 if (isa<ConstantSDNode>(N0)) { 00562 int64_t CN0 = cast<ConstantSDNode>(N0)->getSignExtended(); 00563 if (CN0 == -1) { 00564 N1 = N.getOperand(1); 00565 if (N1.getOpcode() == ISD::SUB) { 00566 N10 = N1.getOperand(0); 00567 N11 = N1.getOperand(1); 00568 if (N.Val->getValueType(0) == MVT::i64) { 00569 Emit_4(Result, N, IA64::SUB1, MVT::i64, N0, N1, N10, N11); 00570 return; 00571 } 00572 } 00573 } 00574 } 00575 00576 // Pattern: (add:i64 (shl:i64 GR:i64:$src1, (imm:i64)<<P:Predicate_isSHLADDimm>>:$imm), GR:i64:$src2) 00577 // Emits: (SHLADD:i64 GR:i64:$src1, (imm:i64):$imm, GR:i64:$src2) 00578 // Pattern complexity = 7 cost = 1 size = 0 00579 if (N0.getOpcode() == ISD::SHL) { 00580 N00 = N0.getOperand(0); 00581 N01 = N0.getOperand(1); 00582 if (N01.getOpcode() == ISD::Constant && 00583 Predicate_isSHLADDimm(N01.Val)) { 00584 N1 = N.getOperand(1); 00585 if (N.Val->getValueType(0) == MVT::i64 && 00586 N01.Val->getValueType(0) == MVT::i64) { 00587 Emit_7(Result, N, IA64::SHLADD, MVT::i64, N0, N00, N01, N1); 00588 return; 00589 } 00590 } 00591 } 00592 N1 = N.getOperand(1); 00593 00594 // Pattern: (add:i64 GR:i64:$src1, (imm:i64)<<P:Predicate_immSExt14>>:$imm) 00595 // Emits: (ADDS:i64 GR:i64:$src1, (imm:i64):$imm) 00596 // Pattern complexity = 5 cost = 1 size = 0 00597 if (N1.getOpcode() == ISD::Constant && 00598 Predicate_immSExt14(N1.Val) && 00599 N.Val->getValueType(0) == MVT::i64) { 00600 Emit_8(Result, N, IA64::ADDS, MVT::i64, N0, N1); 00601 return; 00602 } 00603 00604 // Pattern: (add:i64 GR:i64:$src1, GR:i64:$src2) 00605 // Emits: (ADD:i64 GR:i64:$src1, GR:i64:$src2) 00606 // Pattern complexity = 2 cost = 1 00607 if (N.Val->getValueType(0) == MVT::i64) { 00608 Emit_9(Result, N, IA64::ADD, MVT::i64, N0, N1); 00609 return; 00610 } 00611 std::cerr << "Cannot yet select: "; 00612 N.Val->dump(CurDAG); 00613 std::cerr << '\n'; 00614 abort(); 00615 } 00616 00617 void Emit_10(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1, SDOperand &N10, SDOperand &N11) NOINLINE { 00618 SDOperand Tmp0(0, 0); 00619 SDOperand Tmp1(0, 0); 00620 SDNode *ResNode = NULL; 00621 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00622 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N10.Val); 00623 Select(Tmp0, N0); 00624 Select(Tmp1, N10); 00625 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00626 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N10.Val); 00627 if (N.Val->hasOneUse()) { 00628 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1); 00629 } else { 00630 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1); 00631 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00632 Result = SDOperand(ResNode, 0); 00633 } 00634 return; 00635 } 00636 void Emit_11(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N01, SDOperand &N1) NOINLINE { 00637 SDOperand Tmp0(0, 0); 00638 SDOperand Tmp1(0, 0); 00639 SDNode *ResNode = NULL; 00640 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 00641 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N00.Val); 00642 Select(Tmp0, N1); 00643 Select(Tmp1, N00); 00644 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 00645 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N00.Val); 00646 if (N.Val->hasOneUse()) { 00647 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1); 00648 } else { 00649 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1); 00650 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00651 Result = SDOperand(ResNode, 0); 00652 } 00653 return; 00654 } 00655 void Emit_12(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1) NOINLINE { 00656 SDOperand Tmp1(0, 0); 00657 SDNode *ResNode = NULL; 00658 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00659 Select(Tmp1, N0); 00660 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00661 if (N.Val->hasOneUse()) { 00662 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1); 00663 } else { 00664 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1); 00665 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00666 Result = SDOperand(ResNode, 0); 00667 } 00668 return; 00669 } 00670 void Emit_13(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1) NOINLINE { 00671 SDOperand Tmp0(0, 0); 00672 SDNode *ResNode = NULL; 00673 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00674 Select(Tmp0, N0); 00675 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00676 if (N.Val->hasOneUse()) { 00677 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0); 00678 } else { 00679 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0); 00680 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00681 Result = SDOperand(ResNode, 0); 00682 } 00683 return; 00684 } 00685 void Emit_14(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1) NOINLINE { 00686 SDOperand Tmp1(0, 0); 00687 SDNode *ResNode = NULL; 00688 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 00689 Select(Tmp1, N1); 00690 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 00691 if (N.Val->hasOneUse()) { 00692 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1); 00693 } else { 00694 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1); 00695 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00696 Result = SDOperand(ResNode, 0); 00697 } 00698 return; 00699 } 00700 void Emit_15(SDOperand &Result, SDOperand &N, unsigned Opc0, unsigned Opc1, unsigned Opc2, unsigned Opc3, MVT::ValueType VT0, MVT::ValueType VT1, MVT::ValueType VT2, MVT::ValueType VT3, SDOperand &N0, SDOperand &N1) NOINLINE { 00701 SDOperand Tmp0(0, 0); 00702 SDOperand Tmp1(0, 0); 00703 SDOperand Tmp2(0, 0); 00704 SDOperand Tmp3(0, 0); 00705 SDOperand Tmp4(0, 0); 00706 SDOperand Tmp5(0, 0); 00707 SDOperand Tmp6(0, 0); 00708 SDNode *ResNode = NULL; 00709 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00710 Select(Tmp0, N0); 00711 Tmp1 = SDOperand(CurDAG->getTargetNode(Opc0, VT0, Tmp0), 0); 00712 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 00713 Tmp2 = CurDAG->getRegister(IA64::r0, MVT::i64); 00714 Tmp3 = CurDAG->getRegister(IA64::r0, MVT::i64); 00715 Tmp4 = SDOperand(CurDAG->getTargetNode(Opc1, VT1, Tmp2, Tmp3), 0); 00716 Select(Tmp5, N1); 00717 Tmp6 = SDOperand(CurDAG->getTargetNode(Opc2, VT2, Tmp4, Tmp5), 0); 00718 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00719 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 00720 if (N.Val->hasOneUse()) { 00721 Result = CurDAG->SelectNodeTo(N.Val, Opc3, VT3, Tmp1, Tmp6); 00722 } else { 00723 ResNode = CurDAG->getTargetNode(Opc3, VT3, Tmp1, Tmp6); 00724 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00725 Result = SDOperand(ResNode, 0); 00726 } 00727 return; 00728 } 00729 void Select_and(SDOperand &Result, SDOperand N) { 00730 SDOperand N0(0, 0); 00731 SDOperand N00(0, 0); 00732 SDOperand N01(0, 0); 00733 SDOperand N1(0, 0); 00734 SDOperand N10(0, 0); 00735 SDOperand N11(0, 0); 00736 SDOperand Tmp0(0, 0); 00737 SDOperand Tmp1(0, 0); 00738 SDOperand Tmp2(0, 0); 00739 SDOperand Tmp3(0, 0); 00740 SDOperand Tmp4(0, 0); 00741 SDOperand Tmp5(0, 0); 00742 SDOperand Tmp6(0, 0); 00743 SDNode *ResNode = NULL; 00744 N0 = N.getOperand(0); 00745 00746 // Pattern: (and:i64 GR:i64:$src1, (xor:i64 GR:i64:$src2, (imm:i64)<<P:Predicate_immAllOnes>>)) 00747 // Emits: (ANDCM:i64 GR:i64:$src1, GR:i64:$src2) 00748 // Pattern complexity = 7 cost = 1 size = 0 00749 { 00750 N1 = N.getOperand(1); 00751 if (N1.getOpcode() == ISD::XOR) { 00752 N10 = N1.getOperand(0); 00753 N11 = N1.getOperand(1); 00754 if (N11.getOpcode() == ISD::Constant && 00755 Predicate_immAllOnes(N11.Val) && 00756 N.Val->getValueType(0) == MVT::i64) { 00757 Emit_10(Result, N, IA64::ANDCM, MVT::i64, N0, N1, N10, N11); 00758 return; 00759 } 00760 } 00761 } 00762 00763 // Pattern: (and:i64 (xor:i64 GR:i64:$src2, (imm:i64)<<P:Predicate_immAllOnes>>), GR:i64:$src1) 00764 // Emits: (ANDCM:i64 GR:i64:$src1, GR:i64:$src2) 00765 // Pattern complexity = 7 cost = 1 size = 0 00766 if (N0.getOpcode() == ISD::XOR) { 00767 N00 = N0.getOperand(0); 00768 N01 = N0.getOperand(1); 00769 if (N01.getOpcode() == ISD::Constant && 00770 Predicate_immAllOnes(N01.Val)) { 00771 N1 = N.getOperand(1); 00772 if (N.Val->getValueType(0) == MVT::i64) { 00773 Emit_11(Result, N, IA64::ANDCM, MVT::i64, N0, N00, N01, N1); 00774 return; 00775 } 00776 } 00777 } 00778 { 00779 N1 = N.getOperand(1); 00780 if (isa<ConstantSDNode>(N1)) { 00781 int64_t CN0 = cast<ConstantSDNode>(N1)->getSignExtended(); 00782 00783 // Pattern: (and:i64 GR:i64:$src, 255:i64) 00784 // Emits: (ZXT1:i64 GR:i64:$src) 00785 // Pattern complexity = 5 cost = 1 size = 0 00786 if (CN0 == 255 && 00787 N.Val->getValueType(0) == MVT::i64) { 00788 Emit_12(Result, N, IA64::ZXT1, MVT::i64, N0, N1); 00789 return; 00790 } 00791 00792 // Pattern: (and:i64 GR:i64:$src, 65535:i64) 00793 // Emits: (ZXT2:i64 GR:i64:$src) 00794 // Pattern complexity = 5 cost = 1 00795 if (CN0 == 65535 && 00796 N.Val->getValueType(0) == MVT::i64) { 00797 Emit_12(Result, N, IA64::ZXT2, MVT::i64, N0, N1); 00798 return; 00799 } 00800 } 00801 00802 // Pattern: (and:i64 GR:i64:$src, (imm:i64)<<P:Predicate_is32ones>>) 00803 // Emits: (ZXT4:i64 GR:i64:$src) 00804 // Pattern complexity = 5 cost = 1 00805 if (N1.getOpcode() == ISD::Constant && 00806 Predicate_is32ones(N1.Val) && 00807 N.Val->getValueType(0) == MVT::i64) { 00808 Emit_13(Result, N, IA64::ZXT4, MVT::i64, N0, N1); 00809 return; 00810 } 00811 } 00812 if (isa<ConstantSDNode>(N0)) { 00813 int64_t CN0 = cast<ConstantSDNode>(N0)->getSignExtended(); 00814 00815 // Pattern: (and:i64 255:i64, GR:i64:$src) 00816 // Emits: (ZXT1:i64 GR:i64:$src) 00817 // Pattern complexity = 5 cost = 1 size = 0 00818 if (CN0 == 255) { 00819 N1 = N.getOperand(1); 00820 if (N.Val->getValueType(0) == MVT::i64) { 00821 Emit_14(Result, N, IA64::ZXT1, MVT::i64, N0, N1); 00822 return; 00823 } 00824 } 00825 00826 // Pattern: (and:i64 65535:i64, GR:i64:$src) 00827 // Emits: (ZXT2:i64 GR:i64:$src) 00828 // Pattern complexity = 5 cost = 1 00829 if (CN0 == 65535) { 00830 N1 = N.getOperand(1); 00831 if (N.Val->getValueType(0) == MVT::i64) { 00832 Emit_14(Result, N, IA64::ZXT2, MVT::i64, N0, N1); 00833 return; 00834 } 00835 } 00836 } 00837 N1 = N.getOperand(1); 00838 00839 // Pattern: (and:i64 GR:i64:$src1, GR:i64:$src2) 00840 // Emits: (AND:i64 GR:i64:$src1, GR:i64:$src2) 00841 // Pattern complexity = 2 cost = 1 size = 0 00842 if (N.Val->getValueType(0) == MVT::i64) { 00843 Emit_9(Result, N, IA64::AND, MVT::i64, N0, N1); 00844 return; 00845 } 00846 00847 // Pattern: (and:i1 PR:i1:$src1, PR:i1:$src2) 00848 // Emits: (TPCMPNER0R0:i1 (PCMPEQUNCR0R0:i1 PR:i1:$src1), (TPCMPNER0R0:i1 (CMPEQ:i1 r0:i64, r0:i64), PR:i1:$src2)) 00849 // Pattern complexity = 2 cost = 4 00850 if (N.Val->getValueType(0) == MVT::i1) { 00851 Emit_15(Result, N, IA64::PCMPEQUNCR0R0, IA64::CMPEQ, IA64::TPCMPNER0R0, IA64::TPCMPNER0R0, MVT::i1, MVT::i1, MVT::i1, MVT::i1, N0, N1); 00852 return; 00853 } 00854 std::cerr << "Cannot yet select: "; 00855 N.Val->dump(CurDAG); 00856 std::cerr << '\n'; 00857 abort(); 00858 } 00859 00860 void Emit_16(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0) NOINLINE { 00861 SDOperand Tmp0(0, 0); 00862 SDNode *ResNode = NULL; 00863 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00864 Select(Tmp0, N0); 00865 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00866 if (N.Val->hasOneUse()) { 00867 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0); 00868 } else { 00869 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0); 00870 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00871 Result = SDOperand(ResNode, 0); 00872 } 00873 return; 00874 } 00875 void Select_ctpop(SDOperand &Result, SDOperand N) { 00876 SDOperand N0(0, 0); 00877 SDOperand Tmp0(0, 0); 00878 SDNode *ResNode = NULL; 00879 N0 = N.getOperand(0); 00880 if (N.Val->getValueType(0) == MVT::i64) { 00881 Emit_16(Result, N, IA64::POPCNT, MVT::i64, N0); 00882 return; 00883 } 00884 std::cerr << "Cannot yet select: "; 00885 N.Val->dump(CurDAG); 00886 std::cerr << '\n'; 00887 abort(); 00888 } 00889 00890 void Emit_17(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0) NOINLINE { 00891 SDOperand Tmp0(0, 0); 00892 SDNode *ResNode = NULL; 00893 N0 = N.getOperand(0); 00894 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00895 Select(Tmp0, N0); 00896 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00897 if (N.Val->hasOneUse()) { 00898 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0); 00899 } else { 00900 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0); 00901 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00902 Result = SDOperand(ResNode, 0); 00903 } 00904 return; 00905 } 00906 void Select_fabs(SDOperand &Result, SDOperand N) { 00907 SDOperand N0(0, 0); 00908 SDOperand Tmp0(0, 0); 00909 SDNode *ResNode = NULL; 00910 Emit_17(Result, N, IA64::FABS, MVT::f64, N0); 00911 return; 00912 } 00913 00914 void Emit_18(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N01, SDOperand &N1) NOINLINE { 00915 SDOperand Tmp0(0, 0); 00916 SDOperand Tmp1(0, 0); 00917 SDOperand Tmp2(0, 0); 00918 SDNode *ResNode = NULL; 00919 N00 = N0.getOperand(0); 00920 N01 = N0.getOperand(1); 00921 N1 = N.getOperand(1); 00922 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N00.Val); 00923 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N01.Val); 00924 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 00925 Select(Tmp0, N00); 00926 Select(Tmp1, N01); 00927 Select(Tmp2, N1); 00928 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N00.Val); 00929 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N01.Val); 00930 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 00931 if (N.Val->hasOneUse()) { 00932 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1, Tmp2); 00933 } else { 00934 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1, Tmp2); 00935 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00936 Result = SDOperand(ResNode, 0); 00937 } 00938 return; 00939 } 00940 void Emit_19(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1, SDOperand &N10, SDOperand &N11) NOINLINE { 00941 SDOperand Tmp0(0, 0); 00942 SDOperand Tmp1(0, 0); 00943 SDOperand Tmp2(0, 0); 00944 SDNode *ResNode = NULL; 00945 N10 = N1.getOperand(0); 00946 N11 = N1.getOperand(1); 00947 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N10.Val); 00948 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N11.Val); 00949 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00950 Select(Tmp0, N10); 00951 Select(Tmp1, N11); 00952 Select(Tmp2, N0); 00953 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N10.Val); 00954 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N11.Val); 00955 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00956 if (N.Val->hasOneUse()) { 00957 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1, Tmp2); 00958 } else { 00959 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1, Tmp2); 00960 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00961 Result = SDOperand(ResNode, 0); 00962 } 00963 return; 00964 } 00965 void Emit_20(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1) NOINLINE { 00966 SDOperand Tmp0(0, 0); 00967 SDOperand Tmp1(0, 0); 00968 SDNode *ResNode = NULL; 00969 N0 = N.getOperand(0); 00970 N1 = N.getOperand(1); 00971 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 00972 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 00973 Select(Tmp0, N0); 00974 Select(Tmp1, N1); 00975 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 00976 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 00977 if (N.Val->hasOneUse()) { 00978 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1); 00979 } else { 00980 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1); 00981 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 00982 Result = SDOperand(ResNode, 0); 00983 } 00984 return; 00985 } 00986 void Select_fadd(SDOperand &Result, SDOperand N) { 00987 SDOperand N0(0, 0); 00988 SDOperand N00(0, 0); 00989 SDOperand N01(0, 0); 00990 SDOperand N1(0, 0); 00991 SDOperand N10(0, 0); 00992 SDOperand N11(0, 0); 00993 SDOperand Tmp0(0, 0); 00994 SDOperand Tmp1(0, 0); 00995 SDOperand Tmp2(0, 0); 00996 SDNode *ResNode = NULL; 00997 { 00998 N0 = N.getOperand(0); 00999 01000 // Pattern: (fadd:f64 (fmul:f64 FP:f64:$src1, FP:f64:$src2), FP:f64:$src3) 01001 // Emits: (FMA:f64 FP:f64:$src1, FP:f64:$src2, FP:f64:$src3) 01002 // Pattern complexity = 4 cost = 1 size = 0 01003 if (N0.getOpcode() == ISD::FMUL) { 01004 Emit_18(Result, N, IA64::FMA, MVT::f64, N0, N00, N01, N1); 01005 return; 01006 } 01007 01008 // Pattern: (fadd:f64 FP:f64:$src3, (fmul:f64 FP:f64:$src1, FP:f64:$src2)) 01009 // Emits: (FMA:f64 FP:f64:$src1, FP:f64:$src2, FP:f64:$src3) 01010 // Pattern complexity = 4 cost = 1 01011 N1 = N.getOperand(1); 01012 if (N1.getOpcode() == ISD::FMUL) { 01013 Emit_19(Result, N, IA64::FMA, MVT::f64, N0, N1, N10, N11); 01014 return; 01015 } 01016 } 01017 01018 // Pattern: (fadd:f64 FP:f64:$src1, FP:f64:$src2) 01019 // Emits: (FADD:f64 FP:f64:$src1, FP:f64:$src2) 01020 // Pattern complexity = 2 cost = 1 01021 Emit_20(Result, N, IA64::FADD, MVT::f64, N0, N1); 01022 return; 01023 } 01024 01025 void Select_fmul(SDOperand &Result, SDOperand N) { 01026 SDOperand N0(0, 0); 01027 SDOperand N1(0, 0); 01028 SDOperand Tmp0(0, 0); 01029 SDOperand Tmp1(0, 0); 01030 SDNode *ResNode = NULL; 01031 Emit_20(Result, N, IA64::FMPY, MVT::f64, N0, N1); 01032 return; 01033 } 01034 01035 void Emit_21(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N000, SDOperand &N001, SDOperand &N01) NOINLINE { 01036 SDOperand Tmp0(0, 0); 01037 SDOperand Tmp1(0, 0); 01038 SDOperand Tmp2(0, 0); 01039 SDNode *ResNode = NULL; 01040 N000 = N00.getOperand(0); 01041 N001 = N00.getOperand(1); 01042 N01 = N0.getOperand(1); 01043 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N000.Val); 01044 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N001.Val); 01045 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N01.Val); 01046 Select(Tmp0, N000); 01047 Select(Tmp1, N001); 01048 Select(Tmp2, N01); 01049 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N000.Val); 01050 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N001.Val); 01051 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N01.Val); 01052 if (N.Val->hasOneUse()) { 01053 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1, Tmp2); 01054 } else { 01055 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1, Tmp2); 01056 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01057 Result = SDOperand(ResNode, 0); 01058 } 01059 return; 01060 } 01061 void Emit_22(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N01, SDOperand &N010, SDOperand &N011) NOINLINE { 01062 SDOperand Tmp0(0, 0); 01063 SDOperand Tmp1(0, 0); 01064 SDOperand Tmp2(0, 0); 01065 SDNode *ResNode = NULL; 01066 N010 = N01.getOperand(0); 01067 N011 = N01.getOperand(1); 01068 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N010.Val); 01069 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N011.Val); 01070 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N00.Val); 01071 Select(Tmp0, N010); 01072 Select(Tmp1, N011); 01073 Select(Tmp2, N00); 01074 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N010.Val); 01075 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N011.Val); 01076 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N00.Val); 01077 if (N.Val->hasOneUse()) { 01078 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1, Tmp2); 01079 } else { 01080 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1, Tmp2); 01081 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01082 Result = SDOperand(ResNode, 0); 01083 } 01084 return; 01085 } 01086 void Emit_23(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00) NOINLINE { 01087 SDOperand Tmp0(0, 0); 01088 SDNode *ResNode = NULL; 01089 N00 = N0.getOperand(0); 01090 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N00.Val); 01091 Select(Tmp0, N00); 01092 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N00.Val); 01093 if (N.Val->hasOneUse()) { 01094 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0); 01095 } else { 01096 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0); 01097 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01098 Result = SDOperand(ResNode, 0); 01099 } 01100 return; 01101 } 01102 void Select_fneg(SDOperand &Result, SDOperand N) { 01103 SDOperand N0(0, 0); 01104 SDOperand N00(0, 0); 01105 SDOperand N000(0, 0); 01106 SDOperand N001(0, 0); 01107 SDOperand N01(0, 0); 01108 SDOperand N010(0, 0); 01109 SDOperand N011(0, 0); 01110 SDOperand Tmp0(0, 0); 01111 SDOperand Tmp1(0, 0); 01112 SDOperand Tmp2(0, 0); 01113 SDNode *ResNode = NULL; 01114 { 01115 N0 = N.getOperand(0); 01116 if (N0.getOpcode() == ISD::FADD) { 01117 N00 = N0.getOperand(0); 01118 01119 // Pattern: (fneg:f64 (fadd:f64 (fmul:f64 FP:f64:$src1, FP:f64:$src2), FP:f64:$src3)) 01120 // Emits: (FNMA:f64 FP:f64:$src1, FP:f64:$src2, FP:f64:$src3) 01121 // Pattern complexity = 6 cost = 1 size = 0 01122 if (N00.getOpcode() == ISD::FMUL) { 01123 Emit_21(Result, N, IA64::FNMA, MVT::f64, N0, N00, N000, N001, N01); 01124 return; 01125 } 01126 01127 // Pattern: (fneg:f64 (fadd:f64 FP:f64:$src3, (fmul:f64 FP:f64:$src1, FP:f64:$src2))) 01128 // Emits: (FNMA:f64 FP:f64:$src1, FP:f64:$src2, FP:f64:$src3) 01129 // Pattern complexity = 6 cost = 1 01130 N01 = N0.getOperand(1); 01131 if (N01.getOpcode() == ISD::FMUL) { 01132 Emit_22(Result, N, IA64::FNMA, MVT::f64, N0, N00, N01, N010, N011); 01133 return; 01134 } 01135 } 01136 01137 // Pattern: (fneg:f64 (fabs:f64 FP:f64:$src)) 01138 // Emits: (FNEGABS:f64 FP:f64:$src) 01139 // Pattern complexity = 4 cost = 1 01140 if (N0.getOpcode() == ISD::FABS) { 01141 Emit_23(Result, N, IA64::FNEGABS, MVT::f64, N0, N00); 01142 return; 01143 } 01144 } 01145 01146 // Pattern: (fneg:f64 FP:f64:$src) 01147 // Emits: (FNEG:f64 FP:f64:$src) 01148 // Pattern complexity = 2 cost = 1 01149 Emit_17(Result, N, IA64::FNEG, MVT::f64, N0); 01150 return; 01151 } 01152 01153 void Emit_24(SDOperand &Result, SDOperand &N, unsigned Opc0, unsigned Opc1, MVT::ValueType VT0, MVT::ValueType VT1, SDOperand &N0) NOINLINE { 01154 SDOperand Tmp0(0, 0); 01155 SDOperand Tmp1(0, 0); 01156 SDNode *ResNode = NULL; 01157 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 01158 Select(Tmp0, N0); 01159 Tmp1 = SDOperand(CurDAG->getTargetNode(Opc0, VT0, Tmp0), 0); 01160 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 01161 if (N.Val->hasOneUse()) { 01162 Result = CurDAG->SelectNodeTo(N.Val, Opc1, VT1, Tmp1); 01163 } else { 01164 ResNode = CurDAG->getTargetNode(Opc1, VT1, Tmp1); 01165 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01166 Result = SDOperand(ResNode, 0); 01167 } 01168 return; 01169 } 01170 void Select_fp_to_sint(SDOperand &Result, SDOperand N) { 01171 SDOperand N0(0, 0); 01172 SDOperand Tmp0(0, 0); 01173 SDOperand Tmp1(0, 0); 01174 SDNode *ResNode = NULL; 01175 N0 = N.getOperand(0); 01176 if (N.Val->getValueType(0) == MVT::i64) { 01177 Emit_24(Result, N, IA64::FCVTFXTRUNC, IA64::GETFSIG, MVT::f64, MVT::i64, N0); 01178 return; 01179 } 01180 std::cerr << "Cannot yet select: "; 01181 N.Val->dump(CurDAG); 01182 std::cerr << '\n'; 01183 abort(); 01184 } 01185 01186 void Select_fp_to_uint(SDOperand &Result, SDOperand N) { 01187 SDOperand N0(0, 0); 01188 SDOperand Tmp0(0, 0); 01189 SDOperand Tmp1(0, 0); 01190 SDNode *ResNode = NULL; 01191 N0 = N.getOperand(0); 01192 if (N.Val->getValueType(0) == MVT::i64) { 01193 Emit_24(Result, N, IA64::FCVTFXUTRUNC, IA64::GETFSIG, MVT::f64, MVT::i64, N0); 01194 return; 01195 } 01196 std::cerr << "Cannot yet select: "; 01197 N.Val->dump(CurDAG); 01198 std::cerr << '\n'; 01199 abort(); 01200 } 01201 01202 void Select_fsub(SDOperand &Result, SDOperand N) { 01203 SDOperand N0(0, 0); 01204 SDOperand N00(0, 0); 01205 SDOperand N01(0, 0); 01206 SDOperand N1(0, 0); 01207 SDOperand Tmp0(0, 0); 01208 SDOperand Tmp1(0, 0); 01209 SDOperand Tmp2(0, 0); 01210 SDNode *ResNode = NULL; 01211 01212 // Pattern: (fsub:f64 (fmul:f64 FP:f64:$src1, FP:f64:$src2), FP:f64:$src3) 01213 // Emits: (FMS:f64 FP:f64:$src1, FP:f64:$src2, FP:f64:$src3) 01214 // Pattern complexity = 4 cost = 1 size = 0 01215 { 01216 N0 = N.getOperand(0); 01217 if (N0.getOpcode() == ISD::FMUL) { 01218 Emit_18(Result, N, IA64::FMS, MVT::f64, N0, N00, N01, N1); 01219 return; 01220 } 01221 } 01222 01223 // Pattern: (fsub:f64 FP:f64:$src1, FP:f64:$src2) 01224 // Emits: (FSUB:f64 FP:f64:$src1, FP:f64:$src2) 01225 // Pattern complexity = 2 cost = 1 01226 Emit_20(Result, N, IA64::FSUB, MVT::f64, N0, N1); 01227 return; 01228 } 01229 01230 void Emit_25(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0) NOINLINE { 01231 SDOperand Tmp0(0, 0); 01232 SDOperand Tmp1(0, 0); 01233 SDNode *ResNode = NULL; 01234 Tmp0 = CurDAG->getRegister(IA64::r0, MVT::i64); 01235 Tmp1 = CurDAG->getTargetConstant(((uint64_t) cast<ConstantSDNode>(N)->getValue()), MVT::i64); 01236 if (N.Val->hasOneUse()) { 01237 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1); 01238 } else { 01239 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1); 01240 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01241 Result = SDOperand(ResNode, 0); 01242 } 01243 return; 01244 } 01245 void Emit_26(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0) NOINLINE { 01246 SDOperand Tmp0(0, 0); 01247 SDOperand Tmp1(0, 0); 01248 SDNode *ResNode = NULL; 01249 Tmp0 = CurDAG->getRegister(IA64::r0, MVT::i64); 01250 Tmp1 = CurDAG->getRegister(IA64::r0, MVT::i64); 01251 if (N.Val->hasOneUse()) { 01252 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1); 01253 } else { 01254 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1); 01255 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01256 Result = SDOperand(ResNode, 0); 01257 } 01258 return; 01259 } 01260 void Emit_27(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0) NOINLINE { 01261 SDOperand Tmp0(0, 0); 01262 SDNode *ResNode = NULL; 01263 Tmp0 = CurDAG->getTargetConstant(((uint64_t) cast<ConstantSDNode>(N)->getValue()), MVT::i64); 01264 if (N.Val->hasOneUse()) { 01265 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0); 01266 } else { 01267 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0); 01268 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01269 Result = SDOperand(ResNode, 0); 01270 } 01271 return; 01272 } 01273 void Select_imm(SDOperand &Result, SDOperand N) { 01274 SDOperand Tmp0(0, 0); 01275 SDOperand Tmp1(0, 0); 01276 SDNode *ResNode = NULL; 01277 01278 // Pattern: (imm:i64)<<P:Predicate_immSExt14>>:$imm 01279 // Emits: (ADDS:i64 r0:i64, (imm:i64)<<P:Predicate_immSExt14>>:$imm) 01280 // Pattern complexity = 3 cost = 1 size = 0 01281 if (Predicate_immSExt14(N.Val) && 01282 N.Val->getValueType(0) == MVT::i64) { 01283 Emit_25(Result, N, IA64::ADDS, MVT::i64); 01284 return; 01285 } 01286 01287 // Pattern: -1:i1 01288 // Emits: (CMPEQ:i1 r0:i64, r0:i64) 01289 // Pattern complexity = 3 cost = 1 size = 0 01290 if (cast<ConstantSDNode>(N)->getSignExtended() == -1 && 01291 N.Val->getValueType(0) == MVT::i1) { 01292 Emit_26(Result, N, IA64::CMPEQ, MVT::i1); 01293 return; 01294 } 01295 01296 // Pattern: 0:i1 01297 // Emits: (CMPNE:i1 r0:i64, r0:i64) 01298 // Pattern complexity = 3 cost = 1 size = 0 01299 if (cast<ConstantSDNode>(N)->getSignExtended() == 0 && 01300 N.Val->getValueType(0) == MVT::i1) { 01301 Emit_26(Result, N, IA64::CMPNE, MVT::i1); 01302 return; 01303 } 01304 if (N.Val->getValueType(0) == MVT::i64) { 01305 Emit_27(Result, N, IA64::MOVL, MVT::i64); 01306 return; 01307 } 01308 std::cerr << "Cannot yet select: "; 01309 N.Val->dump(CurDAG); 01310 std::cerr << '\n'; 01311 abort(); 01312 } 01313 01314 void Emit_28(SDOperand &Result, SDOperand &N, unsigned Opc0, unsigned Opc1, unsigned Opc2, unsigned Opc3, MVT::ValueType VT0, MVT::ValueType VT1, MVT::ValueType VT2, MVT::ValueType VT3, SDOperand &N0, SDOperand &N1) NOINLINE { 01315 SDOperand Tmp0(0, 0); 01316 SDOperand Tmp1(0, 0); 01317 SDOperand Tmp2(0, 0); 01318 SDOperand Tmp3(0, 0); 01319 SDOperand Tmp4(0, 0); 01320 SDOperand Tmp5(0, 0); 01321 SDNode *ResNode = NULL; 01322 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 01323 Select(Tmp0, N0); 01324 Tmp1 = SDOperand(CurDAG->getTargetNode(Opc0, VT0, Tmp0), 0); 01325 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 01326 Select(Tmp2, N1); 01327 Tmp3 = SDOperand(CurDAG->getTargetNode(Opc1, VT1, Tmp2), 0); 01328 Tmp4 = CurDAG->getRegister(IA64::F0, MVT::f64); 01329 Tmp5 = SDOperand(CurDAG->getTargetNode(Opc2, VT2, Tmp1, Tmp3, Tmp4), 0); 01330 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 01331 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 01332 if (N.Val->hasOneUse()) { 01333 Result = CurDAG->SelectNodeTo(N.Val, Opc3, VT3, Tmp5); 01334 } else { 01335 ResNode = CurDAG->getTargetNode(Opc3, VT3, Tmp5); 01336 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01337 Result = SDOperand(ResNode, 0); 01338 } 01339 return; 01340 } 01341 void Select_mul(SDOperand &Result, SDOperand N) { 01342 SDOperand N0(0, 0); 01343 SDOperand N1(0, 0); 01344 SDOperand Tmp0(0, 0); 01345 SDOperand Tmp1(0, 0); 01346 SDOperand Tmp2(0, 0); 01347 SDOperand Tmp3(0, 0); 01348 SDOperand Tmp4(0, 0); 01349 SDOperand Tmp5(0, 0); 01350 SDNode *ResNode = NULL; 01351 N0 = N.getOperand(0); 01352 N1 = N.getOperand(1); 01353 if (N.Val->getValueType(0) == MVT::i64) { 01354 Emit_28(Result, N, IA64::SETFSIGD, IA64::SETFSIGD, IA64::XMALD, IA64::GETFSIGD, MVT::f64, MVT::f64, MVT::f64, MVT::i64, N0, N1); 01355 return; 01356 } 01357 std::cerr << "Cannot yet select: "; 01358 N.Val->dump(CurDAG); 01359 std::cerr << '\n'; 01360 abort(); 01361 } 01362 01363 void Select_mulhs(SDOperand &Result, SDOperand N) { 01364 SDOperand N0(0, 0); 01365 SDOperand N1(0, 0); 01366 SDOperand Tmp0(0, 0); 01367 SDOperand Tmp1(0, 0); 01368 SDOperand Tmp2(0, 0); 01369 SDOperand Tmp3(0, 0); 01370 SDOperand Tmp4(0, 0); 01371 SDOperand Tmp5(0, 0); 01372 SDNode *ResNode = NULL; 01373 N0 = N.getOperand(0); 01374 N1 = N.getOperand(1); 01375 if (N.Val->getValueType(0) == MVT::i64) { 01376 Emit_28(Result, N, IA64::SETFSIGD, IA64::SETFSIGD, IA64::XMAHD, IA64::GETFSIGD, MVT::f64, MVT::f64, MVT::f64, MVT::i64, N0, N1); 01377 return; 01378 } 01379 std::cerr << "Cannot yet select: "; 01380 N.Val->dump(CurDAG); 01381 std::cerr << '\n'; 01382 abort(); 01383 } 01384 01385 void Select_mulhu(SDOperand &Result, SDOperand N) { 01386 SDOperand N0(0, 0); 01387 SDOperand N1(0, 0); 01388 SDOperand Tmp0(0, 0); 01389 SDOperand Tmp1(0, 0); 01390 SDOperand Tmp2(0, 0); 01391 SDOperand Tmp3(0, 0); 01392 SDOperand Tmp4(0, 0); 01393 SDOperand Tmp5(0, 0); 01394 SDNode *ResNode = NULL; 01395 N0 = N.getOperand(0); 01396 N1 = N.getOperand(1); 01397 if (N.Val->getValueType(0) == MVT::i64) { 01398 Emit_28(Result, N, IA64::SETFSIGD, IA64::SETFSIGD, IA64::XMAHUD, IA64::GETFSIGD, MVT::f64, MVT::f64, MVT::f64, MVT::i64, N0, N1); 01399 return; 01400 } 01401 std::cerr << "Cannot yet select: "; 01402 N.Val->dump(CurDAG); 01403 std::cerr << '\n'; 01404 abort(); 01405 } 01406 01407 void Emit_29(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N01, SDOperand &N1, SDOperand &N10, SDOperand &N100, SDOperand &N101, SDOperand &N11) NOINLINE { 01408 SDOperand Tmp1(0, 0); 01409 SDOperand Tmp2(0, 0); 01410 SDNode *ResNode = NULL; 01411 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N00.Val); 01412 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N100.Val); 01413 Select(Tmp1, N00); 01414 Select(Tmp2, N100); 01415 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N00.Val); 01416 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N100.Val); 01417 if (N.Val->hasOneUse()) { 01418 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 01419 } else { 01420 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 01421 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01422 Result = SDOperand(ResNode, 0); 01423 } 01424 return; 01425 } 01426 void Emit_30(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N000, SDOperand &N001, SDOperand &N01, SDOperand &N1, SDOperand &N10, SDOperand &N11) NOINLINE { 01427 SDOperand Tmp1(0, 0); 01428 SDOperand Tmp2(0, 0); 01429 SDNode *ResNode = NULL; 01430 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N000.Val); 01431 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N10.Val); 01432 Select(Tmp1, N000); 01433 Select(Tmp2, N10); 01434 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N000.Val); 01435 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N10.Val); 01436 if (N.Val->hasOneUse()) { 01437 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 01438 } else { 01439 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 01440 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01441 Result = SDOperand(ResNode, 0); 01442 } 01443 return; 01444 } 01445 void Emit_31(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N000, SDOperand &N001, SDOperand &N01, SDOperand &N1, SDOperand &N10, SDOperand &N11) NOINLINE { 01446 SDOperand Tmp1(0, 0); 01447 SDOperand Tmp2(0, 0); 01448 SDNode *ResNode = NULL; 01449 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N10.Val); 01450 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N000.Val); 01451 Select(Tmp1, N10); 01452 Select(Tmp2, N000); 01453 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N10.Val); 01454 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N000.Val); 01455 if (N.Val->hasOneUse()) { 01456 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 01457 } else { 01458 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 01459 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01460 Result = SDOperand(ResNode, 0); 01461 } 01462 return; 01463 } 01464 void Emit_32(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N00, SDOperand &N01, SDOperand &N1, SDOperand &N10, SDOperand &N100, SDOperand &N101, SDOperand &N11) NOINLINE { 01465 SDOperand Tmp1(0, 0); 01466 SDOperand Tmp2(0, 0); 01467 SDNode *ResNode = NULL; 01468 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N100.Val); 01469 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N00.Val); 01470 Select(Tmp1, N100); 01471 Select(Tmp2, N00); 01472 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N100.Val); 01473 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N00.Val); 01474 if (N.Val->hasOneUse()) { 01475 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp1, Tmp2); 01476 } else { 01477 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp1, Tmp2); 01478 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01479 Result = SDOperand(ResNode, 0); 01480 } 01481 return; 01482 } 01483 void Emit_33(SDOperand &Result, SDOperand &N, unsigned Opc0, unsigned Opc1, MVT::ValueType VT0, MVT::ValueType VT1, SDOperand &N0, SDOperand &N1) NOINLINE { 01484 SDOperand Tmp0(0, 0); 01485 SDOperand Tmp1(0, 0); 01486 SDOperand Tmp2(0, 0); 01487 SDNode *ResNode = NULL; 01488 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 01489 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 01490 Select(Tmp0, N0); 01491 Tmp1 = SDOperand(CurDAG->getTargetNode(Opc0, VT0, Tmp0), 0); 01492 Select(Tmp2, N1); 01493 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 01494 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 01495 if (N.Val->hasOneUse()) { 01496 Result = CurDAG->SelectNodeTo(N.Val, Opc1, VT1, Tmp1, Tmp2); 01497 } else { 01498 ResNode = CurDAG->getTargetNode(Opc1, VT1, Tmp1, Tmp2); 01499 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01500 Result = SDOperand(ResNode, 0); 01501 } 01502 return; 01503 } 01504 void Select_or(SDOperand &Result, SDOperand N) { 01505 SDOperand N0(0, 0); 01506 SDOperand N00(0, 0); 01507 SDOperand N000(0, 0); 01508 SDOperand N001(0, 0); 01509 SDOperand N01(0, 0); 01510 SDOperand N1(0, 0); 01511 SDOperand N10(0, 0); 01512 SDOperand N100(0, 0); 01513 SDOperand N101(0, 0); 01514 SDOperand N11(0, 0); 01515 SDOperand Tmp0(0, 0); 01516 SDOperand Tmp1(0, 0); 01517 SDOperand Tmp2(0, 0); 01518 SDNode *ResNode = NULL; 01519 N0 = N.getOperand(0); 01520 if (N0.getOpcode() == ISD::AND) { 01521 N00 = N0.getOperand(0); 01522 { 01523 N01 = N0.getOperand(1); 01524 if (N01.getOpcode() == ISD::Constant) { 01525 01526 // Pattern: (or:i64 (and:i64 GR:i64:$src1, (imm:i64)<<P:Predicate_isMIX1Lable>>), (and:i64 (srl:i64 GR:i64:$src2, 8:i64), (imm:i64)<<P:Predicate_isMIX1Lable>>)) 01527 // Emits: (MIX1L:i64 GR:i64:$src1, GR:i64:$src2) 01528 // Pattern complexity = 17 cost = 1 size = 0 01529 if (Predicate_isMIX1Lable(N01.Val)) { 01530 N1 = N.getOperand(1); 01531 if (N1.getOpcode() == ISD::AND) { 01532 N10 = N1.getOperand(0); 01533 if (N10.getOpcode() == ISD::SRL) { 01534 N100 = N10.getOperand(0); 01535 N101 = N10.getOperand(1); 01536 if (isa<ConstantSDNode>(N101)) { 01537 int64_t CN0 = cast<ConstantSDNode>(N101)->getSignExtended(); 01538 if (CN0 == 8) { 01539 N11 = N1.getOperand(1); 01540 if (N11.getOpcode() == ISD::Constant && 01541 Predicate_isMIX1Lable(N11.Val) && 01542 N.Val->getValueType(0) == MVT::i64 && 01543 N101.Val->getValueType(0) == MVT::i64) { 01544 Emit_29(Result, N, IA64::MIX1L, MVT::i64, N0, N00, N01, N1, N10, N100, N101, N11); 01545 return; 01546 } 01547 } 01548 } 01549 } 01550 } 01551 } 01552 01553 // Pattern: (or:i64 (and:i64 GR:i64:$src1, (imm:i64)<<P:Predicate_isMIX2Lable>>), (and:i64 (srl:i64 GR:i64:$src2, 16:i64), (imm:i64)<<P:Predicate_isMIX2Lable>>)) 01554 // Emits: (MIX2L:i64 GR:i64:$src1, GR:i64:$src2) 01555 // Pattern complexity = 17 cost = 1 size = 0 01556 if (Predicate_isMIX2Lable(N01.Val)) { 01557 N1 = N.getOperand(1); 01558 if (N1.getOpcode() == ISD::AND) { 01559 N10 = N1.getOperand(0); 01560 if (N10.getOpcode() == ISD::SRL) { 01561 N100 = N10.getOperand(0); 01562 N101 = N10.getOperand(1); 01563 if (isa<ConstantSDNode>(N101)) { 01564 int64_t CN0 = cast<ConstantSDNode>(N101)->getSignExtended(); 01565 if (CN0 == 16) { 01566 N11 = N1.getOperand(1); 01567 if (N11.getOpcode() == ISD::Constant && 01568 Predicate_isMIX2Lable(N11.Val) && 01569 N.Val->getValueType(0) == MVT::i64 && 01570 N101.Val->getValueType(0) == MVT::i64) { 01571 Emit_29(Result, N, IA64::MIX2L, MVT::i64, N0, N00, N01, N1, N10, N100, N101, N11); 01572 return; 01573 } 01574 } 01575 } 01576 } 01577 } 01578 } 01579 01580 // Pattern: (or:i64 (and:i64 GR:i64:$src1, (imm:i64)<<P:Predicate_isMIX4Lable>>), (and:i64 (srl:i64 GR:i64:$src2, 32:i64), (imm:i64)<<P:Predicate_isMIX4Lable>>)) 01581 // Emits: (MIX4L:i64 GR:i64:$src1, GR:i64:$src2) 01582 // Pattern complexity = 17 cost = 1 01583 if (Predicate_isMIX4Lable(N01.Val)) { 01584 N1 = N.getOperand(1); 01585 if (N1.getOpcode() == ISD::AND) { 01586 N10 = N1.getOperand(0); 01587 if (N10.getOpcode() == ISD::SRL) { 01588 N100 = N10.getOperand(0); 01589 N101 = N10.getOperand(1); 01590 if (isa<ConstantSDNode>(N101)) { 01591 int64_t CN0 = cast<ConstantSDNode>(N101)->getSignExtended(); 01592 if (CN0 == 32) { 01593 N11 = N1.getOperand(1); 01594 if (N11.getOpcode() == ISD::Constant && 01595 Predicate_isMIX4Lable(N11.Val) && 01596 N.Val->getValueType(0) == MVT::i64 && 01597 N101.Val->getValueType(0) == MVT::i64) { 01598 Emit_29(Result, N, IA64::MIX4L, MVT::i64, N0, N00, N01, N1, N10, N100, N101, N11); 01599 return; 01600 } 01601 } 01602 } 01603 } 01604 } 01605 } 01606 } 01607 } 01608 if (N00.getOpcode() == ISD::SHL) { 01609 N000 = N00.getOperand(0); 01610 N001 = N00.getOperand(1); 01611 if (isa<ConstantSDNode>(N001)) { 01612 int64_t CN0 = cast<ConstantSDNode>(N001)->getSignExtended(); 01613 01614 // Pattern: (or:i64 (and:i64 (shl:i64 GR:i64:$src1, 8:i64), (imm:i64)<<P:Predicate_isMIX1Rable>>), (and:i64 GR:i64:$src2, (imm:i64)<<P:Predicate_isMIX1Rable>>)) 01615 // Emits: (MIX1R:i64 GR:i64:$src1, GR:i64:$src2) 01616 // Pattern complexity = 17 cost = 1 size = 0 01617 if (CN0 == 8) { 01618 N01 = N0.getOperand(1); 01619 if (N01.getOpcode() == ISD::Constant && 01620 Predicate_isMIX1Rable(N01.Val)) { 01621 N1 = N.getOperand(1); 01622 if (N1.getOpcode() == ISD::AND) { 01623 N10 = N1.getOperand(0); 01624 N11 = N1.getOperand(1); 01625 if (N11.getOpcode() == ISD::Constant && 01626 Predicate_isMIX1Rable(N11.Val) && 01627 N.Val->getValueType(0) == MVT::i64 && 01628 N001.Val->getValueType(0) == MVT::i64) { 01629 Emit_30(Result, N, IA64::MIX1R, MVT::i64, N0, N00, N000, N001, N01, N1, N10, N11); 01630 return; 01631 } 01632 } 01633 } 01634 } 01635 01636 // Pattern: (or:i64 (and:i64 (shl:i64 GR:i64:$src1, 16:i64), (imm:i64)<<P:Predicate_isMIX2Rable>>), (and:i64 GR:i64:$src2, (imm:i64)<<P:Predicate_isMIX2Rable>>)) 01637 // Emits: (MIX2R:i64 GR:i64:$src1, GR:i64:$src2) 01638 // Pattern complexity = 17 cost = 1 size = 0 01639 if (CN0 == 16) { 01640 N01 = N0.getOperand(1); 01641 if (N01.getOpcode() == ISD::Constant && 01642 Predicate_isMIX2Rable(N01.Val)) { 01643 N1 = N.getOperand(1); 01644 if (N1.getOpcode() == ISD::AND) { 01645 N10 = N1.getOperand(0); 01646 N11 = N1.getOperand(1); 01647 if (N11.getOpcode() == ISD::Constant && 01648 Predicate_isMIX2Rable(N11.Val) && 01649 N.Val->getValueType(0) == MVT::i64 && 01650 N001.Val->getValueType(0) == MVT::i64) { 01651 Emit_30(Result, N, IA64::MIX2R, MVT::i64, N0, N00, N000, N001, N01, N1, N10, N11); 01652 return; 01653 } 01654 } 01655 } 01656 } 01657 01658 // Pattern: (or:i64 (and:i64 (shl:i64 GR:i64:$src1, 32:i64), (imm:i64)<<P:Predicate_isMIX4Rable>>), (and:i64 GR:i64:$src2, (imm:i64)<<P:Predicate_isMIX4Rable>>)) 01659 // Emits: (MIX4R:i64 GR:i64:$src1, GR:i64:$src2) 01660 // Pattern complexity = 17 cost = 1 01661 if (CN0 == 32) { 01662 N01 = N0.getOperand(1); 01663 if (N01.getOpcode() == ISD::Constant && 01664 Predicate_isMIX4Rable(N01.Val)) { 01665 N1 = N.getOperand(1); 01666 if (N1.getOpcode() == ISD::AND) { 01667 N10 = N1.getOperand(0); 01668 N11 = N1.getOperand(1); 01669 if (N11.getOpcode() == ISD::Constant && 01670 Predicate_isMIX4Rable(N11.Val) && 01671 N.Val->getValueType(0) == MVT::i64 && 01672 N001.Val->getValueType(0) == MVT::i64) { 01673 Emit_30(Result, N, IA64::MIX4R, MVT::i64, N0, N00, N000, N001, N01, N1, N10, N11); 01674 return; 01675 } 01676 } 01677 } 01678 } 01679 } 01680 } 01681 if (N00.getOpcode() == ISD::SRL) { 01682 N000 = N00.getOperand(0); 01683 N001 = N00.getOperand(1); 01684 if (isa<ConstantSDNode>(N001)) { 01685 int64_t CN0 = cast<ConstantSDNode>(N001)->getSignExtended(); 01686 01687 // Pattern: (or:i64 (and:i64 (srl:i64 GR:i64:$src2, 8:i64), (imm:i64)<<P:Predicate_isMIX1Lable>>), (and:i64 GR:i64:$src1, (imm:i64)<<P:Predicate_isMIX1Lable>>)) 01688 // Emits: (MIX1L:i64 GR:i64:$src1, GR:i64:$src2) 01689 // Pattern complexity = 17 cost = 1 size = 0 01690 if (CN0 == 8) { 01691 N01 = N0.getOperand(1); 01692 if (N01.getOpcode() == ISD::Constant && 01693 Predicate_isMIX1Lable(N01.Val)) { 01694 N1 = N.getOperand(1); 01695 if (N1.getOpcode() == ISD::AND) { 01696 N10 = N1.getOperand(0); 01697 N11 = N1.getOperand(1); 01698 if (N11.getOpcode() == ISD::Constant && 01699 Predicate_isMIX1Lable(N11.Val) && 01700 N.Val->getValueType(0) == MVT::i64 && 01701 N001.Val->getValueType(0) == MVT::i64) { 01702 Emit_31(Result, N, IA64::MIX1L, MVT::i64, N0, N00, N000, N001, N01, N1, N10, N11); 01703 return; 01704 } 01705 } 01706 } 01707 } 01708 01709 // Pattern: (or:i64 (and:i64 (srl:i64 GR:i64:$src2, 16:i64), (imm:i64)<<P:Predicate_isMIX2Lable>>), (and:i64 GR:i64:$src1, (imm:i64)<<P:Predicate_isMIX2Lable>>)) 01710 // Emits: (MIX2L:i64 GR:i64:$src1, GR:i64:$src2) 01711 // Pattern complexity = 17 cost = 1 size = 0 01712 if (CN0 == 16) { 01713 N01 = N0.getOperand(1); 01714 if (N01.getOpcode() == ISD::Constant && 01715 Predicate_isMIX2Lable(N01.Val)) { 01716 N1 = N.getOperand(1); 01717 if (N1.getOpcode() == ISD::AND) { 01718 N10 = N1.getOperand(0); 01719 N11 = N1.getOperand(1); 01720 if (N11.getOpcode() == ISD::Constant && 01721 Predicate_isMIX2Lable(N11.Val) && 01722 N.Val->getValueType(0) == MVT::i64 && 01723 N001.Val->getValueType(0) == MVT::i64) { 01724 Emit_31(Result, N, IA64::MIX2L, MVT::i64, N0, N00, N000, N001, N01, N1, N10, N11); 01725 return; 01726 } 01727 } 01728 } 01729 } 01730 01731 // Pattern: (or:i64 (and:i64 (srl:i64 GR:i64:$src2, 32:i64), (imm:i64)<<P:Predicate_isMIX4Lable>>), (and:i64 GR:i64:$src1, (imm:i64)<<P:Predicate_isMIX4Lable>>)) 01732 // Emits: (MIX4L:i64 GR:i64:$src1, GR:i64:$src2) 01733 // Pattern complexity = 17 cost = 1 01734 if (CN0 == 32) { 01735 N01 = N0.getOperand(1); 01736 if (N01.getOpcode() == ISD::Constant && 01737 Predicate_isMIX4Lable(N01.Val)) { 01738 N1 = N.getOperand(1); 01739 if (N1.getOpcode() == ISD::AND) { 01740 N10 = N1.getOperand(0); 01741 N11 = N1.getOperand(1); 01742 if (N11.getOpcode() == ISD::Constant && 01743 Predicate_isMIX4Lable(N11.Val) && 01744 N.Val->getValueType(0) == MVT::i64 && 01745 N001.Val->getValueType(0) == MVT::i64) { 01746 Emit_31(Result, N, IA64::MIX4L, MVT::i64, N0, N00, N000, N001, N01, N1, N10, N11); 01747 return; 01748 } 01749 } 01750 } 01751 } 01752 } 01753 } 01754 N01 = N0.getOperand(1); 01755 if (N01.getOpcode() == ISD::Constant) { 01756 01757 // Pattern: (or:i64 (and:i64 GR:i64:$src2, (imm:i64)<<P:Predicate_isMIX1Rable>>), (and:i64 (shl:i64 GR:i64:$src1, 8:i64), (imm:i64)<<P:Predicate_isMIX1Rable>>)) 01758 // Emits: (MIX1R:i64 GR:i64:$src1, GR:i64:$src2) 01759 // Pattern complexity = 17 cost = 1 size = 0 01760 if (Predicate_isMIX1Rable(N01.Val)) { 01761 N1 = N.getOperand(1); 01762 if (N1.getOpcode() == ISD::AND) { 01763 N10 = N1.getOperand(0); 01764 if (N10.getOpcode() == ISD::SHL) { 01765 N100 = N10.getOperand(0); 01766 N101 = N10.getOperand(1); 01767 if (isa<ConstantSDNode>(N101)) { 01768 int64_t CN0 = cast<ConstantSDNode>(N101)->getSignExtended(); 01769 if (CN0 == 8) { 01770 N11 = N1.getOperand(1); 01771 if (N11.getOpcode() == ISD::Constant && 01772 Predicate_isMIX1Rable(N11.Val) && 01773 N.Val->getValueType(0) == MVT::i64 && 01774 N101.Val->getValueType(0) == MVT::i64) { 01775 Emit_32(Result, N, IA64::MIX1R, MVT::i64, N0, N00, N01, N1, N10, N100, N101, N11); 01776 return; 01777 } 01778 } 01779 } 01780 } 01781 } 01782 } 01783 01784 // Pattern: (or:i64 (and:i64 GR:i64:$src2, (imm:i64)<<P:Predicate_isMIX2Rable>>), (and:i64 (shl:i64 GR:i64:$src1, 16:i64), (imm:i64)<<P:Predicate_isMIX2Rable>>)) 01785 // Emits: (MIX2R:i64 GR:i64:$src1, GR:i64:$src2) 01786 // Pattern complexity = 17 cost = 1 size = 0 01787 if (Predicate_isMIX2Rable(N01.Val)) { 01788 N1 = N.getOperand(1); 01789 if (N1.getOpcode() == ISD::AND) { 01790 N10 = N1.getOperand(0); 01791 if (N10.getOpcode() == ISD::SHL) { 01792 N100 = N10.getOperand(0); 01793 N101 = N10.getOperand(1); 01794 if (isa<ConstantSDNode>(N101)) { 01795 int64_t CN0 = cast<ConstantSDNode>(N101)->getSignExtended(); 01796 if (CN0 == 16) { 01797 N11 = N1.getOperand(1); 01798 if (N11.getOpcode() == ISD::Constant && 01799 Predicate_isMIX2Rable(N11.Val) && 01800 N.Val->getValueType(0) == MVT::i64 && 01801 N101.Val->getValueType(0) == MVT::i64) { 01802 Emit_32(Result, N, IA64::MIX2R, MVT::i64, N0, N00, N01, N1, N10, N100, N101, N11); 01803 return; 01804 } 01805 } 01806 } 01807 } 01808 } 01809 } 01810 01811 // Pattern: (or:i64 (and:i64 GR:i64:$src2, (imm:i64)<<P:Predicate_isMIX4Rable>>), (and:i64 (shl:i64 GR:i64:$src1, 32:i64), (imm:i64)<<P:Predicate_isMIX4Rable>>)) 01812 // Emits: (MIX4R:i64 GR:i64:$src1, GR:i64:$src2) 01813 // Pattern complexity = 17 cost = 1 01814 if (Predicate_isMIX4Rable(N01.Val)) { 01815 N1 = N.getOperand(1); 01816 if (N1.getOpcode() == ISD::AND) { 01817 N10 = N1.getOperand(0); 01818 if (N10.getOpcode() == ISD::SHL) { 01819 N100 = N10.getOperand(0); 01820 N101 = N10.getOperand(1); 01821 if (isa<ConstantSDNode>(N101)) { 01822 int64_t CN0 = cast<ConstantSDNode>(N101)->getSignExtended(); 01823 if (CN0 == 32) { 01824 N11 = N1.getOperand(1); 01825 if (N11.getOpcode() == ISD::Constant && 01826 Predicate_isMIX4Rable(N11.Val) && 01827 N.Val->getValueType(0) == MVT::i64 && 01828 N101.Val->getValueType(0) == MVT::i64) { 01829 Emit_32(Result, N, IA64::MIX4R, MVT::i64, N0, N00, N01, N1, N10, N100, N101, N11); 01830 return; 01831 } 01832 } 01833 } 01834 } 01835 } 01836 } 01837 } 01838 } 01839 N1 = N.getOperand(1); 01840 01841 // Pattern: (or:i64 GR:i64:$src1, GR:i64:$src2) 01842 // Emits: (OR:i64 GR:i64:$src1, GR:i64:$src2) 01843 // Pattern complexity = 2 cost = 1 size = 0 01844 if (N.Val->getValueType(0) == MVT::i64) { 01845 Emit_9(Result, N, IA64::OR, MVT::i64, N0, N1); 01846 return; 01847 } 01848 01849 // Pattern: (or:i1 PR:i1:$src1, PR:i1:$src2) 01850 // Emits: (TPCMPEQR0R0:i1 (PCMPEQUNCR0R0:i1 PR:i1:$src1), PR:i1:$src2) 01851 // Pattern complexity = 2 cost = 2 01852 if (N.Val->getValueType(0) == MVT::i1) { 01853 Emit_33(Result, N, IA64::PCMPEQUNCR0R0, IA64::TPCMPEQR0R0, MVT::i1, MVT::i1, N0, N1); 01854 return; 01855 } 01856 std::cerr << "Cannot yet select: "; 01857 N.Val->dump(CurDAG); 01858 std::cerr << '\n'; 01859 abort(); 01860 } 01861 01862 void Emit_34(SDOperand &Result, SDOperand &N, unsigned Opc0, SDOperand &Chain) NOINLINE { 01863 SDNode *ResNode = NULL; 01864 Chain = N.getOperand(0); 01865 Select(Chain, Chain); 01866 ResNode = CurDAG->getTargetNode(Opc0, MVT::Other, Chain); 01867 Chain = SDOperand(ResNode, 0); 01868 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Chain.Val, Chain.ResNo); 01869 Result = SDOperand(ResNode, N.ResNo); 01870 return; 01871 } 01872 void Select_ret(SDOperand &Result, SDOperand N) { 01873 SDOperand Chain(0, 0); 01874 SDNode *ResNode = NULL; 01875 Emit_34(Result, N, IA64::RET, Chain); 01876 return; 01877 } 01878 01879 void Emit_35(SDOperand &Result, SDOperand &N, unsigned Opc0, SDOperand &Chain, bool HasInFlag) NOINLINE { 01880 SDOperand InFlag(0, 0); 01881 SDNode *ResNode = NULL; 01882 Chain = N.getOperand(0); 01883 HasInFlag = (N.getOperand(N.getNumOperands()-1).getValueType() == MVT::Flag); 01884 Select(Chain, Chain); 01885 if (HasInFlag) 01886 Select(InFlag, N.getOperand(N.getNumOperands()-1)); 01887 ResNode = HasInFlag ? CurDAG->getTargetNode(Opc0, MVT::Other, Chain, InFlag) : CurDAG->getTargetNode(Opc0, MVT::Other, Chain); 01888 Chain = SDOperand(ResNode, 0); 01889 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Chain.Val, Chain.ResNo); 01890 Result = SDOperand(ResNode, N.ResNo); 01891 return; 01892 } 01893 void Select_retflag(SDOperand &Result, SDOperand N) { 01894 SDOperand Chain(0, 0); 01895 SDOperand InFlag(0, 0); 01896 SDNode *ResNode = NULL; 01897 bool HasInFlag = false; 01898 Emit_35(Result, N, IA64::RET, Chain, HasInFlag); 01899 return; 01900 } 01901 01902 void Emit_36(SDOperand &Result, SDOperand &N, unsigned Opc0, unsigned Opc1, MVT::ValueType VT0, MVT::ValueType VT1, SDOperand &N0, SDOperand &N1, SDOperand &N2) NOINLINE { 01903 SDOperand Tmp0(0, 0); 01904 SDOperand Tmp1(0, 0); 01905 SDOperand Tmp2(0, 0); 01906 SDOperand Tmp3(0, 0); 01907 SDNode *ResNode = NULL; 01908 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 01909 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 01910 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N2.Val); 01911 Select(Tmp0, N2); 01912 Tmp1 = SDOperand(CurDAG->getTargetNode(Opc0, VT0, Tmp0), 0); 01913 Select(Tmp2, N1); 01914 Select(Tmp3, N0); 01915 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 01916 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 01917 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N2.Val); 01918 if (N.Val->hasOneUse()) { 01919 Result = CurDAG->SelectNodeTo(N.Val, Opc1, VT1, Tmp1, Tmp2, Tmp3); 01920 } else { 01921 ResNode = CurDAG->getTargetNode(Opc1, VT1, Tmp1, Tmp2, Tmp3); 01922 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01923 Result = SDOperand(ResNode, 0); 01924 } 01925 return; 01926 } 01927 void Emit_37(SDOperand &Result, SDOperand &N, unsigned Opc0, unsigned Opc1, unsigned Opc2, unsigned Opc3, unsigned Opc4, unsigned Opc5, unsigned Opc6, MVT::ValueType VT0, MVT::ValueType VT1, MVT::ValueType VT2, MVT::ValueType VT3, MVT::ValueType VT4, MVT::ValueType VT5, MVT::ValueType VT6, SDOperand &N0, SDOperand &N1, SDOperand &N2) NOINLINE { 01928 SDOperand Tmp0(0, 0); 01929 SDOperand Tmp1(0, 0); 01930 SDOperand Tmp10(0, 0); 01931 SDOperand Tmp11(0, 0); 01932 SDOperand Tmp12(0, 0); 01933 SDOperand Tmp13(0, 0); 01934 SDOperand Tmp14(0, 0); 01935 SDOperand Tmp15(0, 0); 01936 SDOperand Tmp2(0, 0); 01937 SDOperand Tmp3(0, 0); 01938 SDOperand Tmp4(0, 0); 01939 SDOperand Tmp5(0, 0); 01940 SDOperand Tmp6(0, 0); 01941 SDOperand Tmp7(0, 0); 01942 SDOperand Tmp8(0, 0); 01943 SDOperand Tmp9(0, 0); 01944 SDNode *ResNode = NULL; 01945 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 01946 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N2.Val); 01947 Tmp0 = CurDAG->getRegister(IA64::r0, MVT::i64); 01948 Tmp1 = CurDAG->getTargetConstant(0, MVT::i64); 01949 Tmp2 = SDOperand(CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1), 0); 01950 Tmp3 = CurDAG->getTargetConstant(1, MVT::i64); 01951 Select(Tmp4, N2); 01952 Tmp5 = SDOperand(CurDAG->getTargetNode(Opc1, VT1, Tmp2, Tmp3, Tmp4), 0); 01953 Tmp6 = SDOperand(CurDAG->getTargetNode(Opc2, VT2, Tmp5), 0); 01954 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 01955 Tmp7 = CurDAG->getRegister(IA64::r0, MVT::i64); 01956 Tmp8 = CurDAG->getTargetConstant(0, MVT::i64); 01957 Tmp9 = SDOperand(CurDAG->getTargetNode(Opc3, VT3, Tmp7, Tmp8), 0); 01958 Tmp10 = CurDAG->getTargetConstant(1, MVT::i64); 01959 Select(Tmp11, N1); 01960 Tmp12 = SDOperand(CurDAG->getTargetNode(Opc4, VT4, Tmp9, Tmp10, Tmp11), 0); 01961 Select(Tmp13, N0); 01962 Tmp14 = SDOperand(CurDAG->getTargetNode(Opc5, VT5, Tmp6, Tmp12, Tmp13), 0); 01963 Tmp15 = CurDAG->getRegister(IA64::r0, MVT::i64); 01964 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 01965 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N2.Val); 01966 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 01967 if (N.Val->hasOneUse()) { 01968 Result = CurDAG->SelectNodeTo(N.Val, Opc6, VT6, Tmp14, Tmp15); 01969 } else { 01970 ResNode = CurDAG->getTargetNode(Opc6, VT6, Tmp14, Tmp15); 01971 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 01972 Result = SDOperand(ResNode, 0); 01973 } 01974 return; 01975 } 01976 void Select_select(SDOperand &Result, SDOperand N) { 01977 SDOperand N0(0, 0); 01978 SDOperand N1(0, 0); 01979 SDOperand N2(0, 0); 01980 SDOperand Tmp0(0, 0); 01981 SDOperand Tmp1(0, 0); 01982 SDOperand Tmp10(0, 0); 01983 SDOperand Tmp11(0, 0); 01984 SDOperand Tmp12(0, 0); 01985 SDOperand Tmp13(0, 0); 01986 SDOperand Tmp14(0, 0); 01987 SDOperand Tmp15(0, 0); 01988 SDOperand Tmp2(0, 0); 01989 SDOperand Tmp3(0, 0); 01990 SDOperand Tmp4(0, 0); 01991 SDOperand Tmp5(0, 0); 01992 SDOperand Tmp6(0, 0); 01993 SDOperand Tmp7(0, 0); 01994 SDOperand Tmp8(0, 0); 01995 SDOperand Tmp9(0, 0); 01996 SDNode *ResNode = NULL; 01997 N0 = N.getOperand(0); 01998 N1 = N.getOperand(1); 01999 N2 = N.getOperand(2); 02000 02001 // Pattern: (select:f64 PR:i1:$which, FP:f64:$src1, FP:f64:$src2) 02002 // Emits: (CFMOV:f64 (FMOV:f64 FP:f64:$src2), FP:f64:$src1, PR:i1:$which) 02003 // Pattern complexity = 2 cost = 2 size = 0 02004 if (N.Val->getValueType(0) == MVT::f64 && 02005 N0.Val->getValueType(0) == MVT::i1) { 02006 Emit_36(Result, N, IA64::FMOV, IA64::CFMOV, MVT::f64, MVT::f64, N0, N1, N2); 02007 return; 02008 } 02009 02010 // Pattern: (select:i64 PR:i1:$which, GR:i64:$src1, GR:i64:$src2) 02011 // Emits: (CMOV:i64 (MOV:i64 GR:i64:$src2), GR:i64:$src1, PR:i1:$which) 02012 // Pattern complexity = 2 cost = 2 size = 0 02013 if (N.Val->getValueType(0) == MVT::i64 && 02014 N0.Val->getValueType(0) == MVT::i1) { 02015 Emit_36(Result, N, IA64::MOV, IA64::CMOV, MVT::i64, MVT::i64, N0, N1, N2); 02016 return; 02017 } 02018 02019 // Pattern: (select:i1 PR:i1:$which, PR:i1:$src1, PR:i1:$src2) 02020 // Emits: (CMPNE:i1 (CMOV:i64 (MOV:i64 (TPCADDIMM22:i64 (ADDS:i64 r0:i64, 0:i64), 1:i64, PR:i1:$src2)), (TPCADDIMM22:i64 (ADDS:i64 r0:i64, 0:i64), 1:i64, PR:i1:$src1), PR:i1:$which), r0:i64) 02021 // Pattern complexity = 2 cost = 7 02022 if (N.Val->getValueType(0) == MVT::i1 && 02023 N0.Val->getValueType(0) == MVT::i1) { 02024 Emit_37(Result, N, IA64::ADDS, IA64::TPCADDIMM22, IA64::MOV, IA64::ADDS, IA64::TPCADDIMM22, IA64::CMOV, IA64::CMPNE, MVT::i64, MVT::i64, MVT::i64, MVT::i64, MVT::i64, MVT::i64, MVT::i1, N0, N1, N2); 02025 return; 02026 } 02027 std::cerr << "Cannot yet select: "; 02028 N.Val->dump(CurDAG); 02029 std::cerr << '\n'; 02030 abort(); 02031 } 02032 02033 void Emit_38(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0, SDOperand &N1, SDOperand &N2) NOINLINE { 02034 SDOperand Tmp0(0, 0); 02035 SDOperand Tmp1(0, 0); 02036 SDNode *ResNode = NULL; 02037 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 02038 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 02039 Select(Tmp0, N0); 02040 Select(Tmp1, N1); 02041 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 02042 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 02043 if (N.Val->hasOneUse()) { 02044 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1); 02045 } else { 02046 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1); 02047 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 02048 Result = SDOperand(ResNode, 0); 02049 } 02050 return; 02051 } 02052 void Select_setcc(SDOperand &Result, SDOperand N) { 02053 SDOperand N0(0, 0); 02054 SDOperand N1(0, 0); 02055 SDOperand N2(0, 0); 02056 SDOperand Tmp0(0, 0); 02057 SDOperand Tmp1(0, 0); 02058 SDNode *ResNode = NULL; 02059 N0 = N.getOperand(0); 02060 N1 = N.getOperand(1); 02061 N2 = N.getOperand(2); 02062 02063 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETEQ:Other) 02064 // Emits: (CMPEQ:i1 GR:i64:$src1, GR:i64:$src2) 02065 // Pattern complexity = 2 cost = 1 size = 0 02066 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETEQ && 02067 N.Val->getValueType(0) == MVT::i1 && 02068 N0.Val->getValueType(0) == MVT::i64) { 02069 Emit_38(Result, N, IA64::CMPEQ, MVT::i1, N0, N1, N2); 02070 return; 02071 } 02072 02073 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETGT:Other) 02074 // Emits: (CMPGT:i1 GR:i64:$src1, GR:i64:$src2) 02075 // Pattern complexity = 2 cost = 1 size = 0 02076 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETGT && 02077 N.Val->getValueType(0) == MVT::i1 && 02078 N0.Val->getValueType(0) == MVT::i64) { 02079 Emit_38(Result, N, IA64::CMPGT, MVT::i1, N0, N1, N2); 02080 return; 02081 } 02082 02083 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETGE:Other) 02084 // Emits: (CMPGE:i1 GR:i64:$src1, GR:i64:$src2) 02085 // Pattern complexity = 2 cost = 1 size = 0 02086 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETGE && 02087 N.Val->getValueType(0) == MVT::i1 && 02088 N0.Val->getValueType(0) == MVT::i64) { 02089 Emit_38(Result, N, IA64::CMPGE, MVT::i1, N0, N1, N2); 02090 return; 02091 } 02092 02093 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETLT:Other) 02094 // Emits: (CMPLT:i1 GR:i64:$src1, GR:i64:$src2) 02095 // Pattern complexity = 2 cost = 1 size = 0 02096 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETLT && 02097 N.Val->getValueType(0) == MVT::i1 && 02098 N0.Val->getValueType(0) == MVT::i64) { 02099 Emit_38(Result, N, IA64::CMPLT, MVT::i1, N0, N1, N2); 02100 return; 02101 } 02102 02103 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETLE:Other) 02104 // Emits: (CMPLE:i1 GR:i64:$src1, GR:i64:$src2) 02105 // Pattern complexity = 2 cost = 1 size = 0 02106 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETLE && 02107 N.Val->getValueType(0) == MVT::i1 && 02108 N0.Val->getValueType(0) == MVT::i64) { 02109 Emit_38(Result, N, IA64::CMPLE, MVT::i1, N0, N1, N2); 02110 return; 02111 } 02112 02113 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETNE:Other) 02114 // Emits: (CMPNE:i1 GR:i64:$src1, GR:i64:$src2) 02115 // Pattern complexity = 2 cost = 1 size = 0 02116 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETNE && 02117 N.Val->getValueType(0) == MVT::i1 && 02118 N0.Val->getValueType(0) == MVT::i64) { 02119 Emit_38(Result, N, IA64::CMPNE, MVT::i1, N0, N1, N2); 02120 return; 02121 } 02122 02123 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETULT:Other) 02124 // Emits: (CMPLTU:i1 GR:i64:$src1, GR:i64:$src2) 02125 // Pattern complexity = 2 cost = 1 size = 0 02126 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETULT && 02127 N.Val->getValueType(0) == MVT::i1 && 02128 N0.Val->getValueType(0) == MVT::i64) { 02129 Emit_38(Result, N, IA64::CMPLTU, MVT::i1, N0, N1, N2); 02130 return; 02131 } 02132 02133 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETUGT:Other) 02134 // Emits: (CMPGTU:i1 GR:i64:$src1, GR:i64:$src2) 02135 // Pattern complexity = 2 cost = 1 size = 0 02136 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETUGT && 02137 N.Val->getValueType(0) == MVT::i1 && 02138 N0.Val->getValueType(0) == MVT::i64) { 02139 Emit_38(Result, N, IA64::CMPGTU, MVT::i1, N0, N1, N2); 02140 return; 02141 } 02142 02143 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETULE:Other) 02144 // Emits: (CMPLEU:i1 GR:i64:$src1, GR:i64:$src2) 02145 // Pattern complexity = 2 cost = 1 size = 0 02146 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETULE && 02147 N.Val->getValueType(0) == MVT::i1 && 02148 N0.Val->getValueType(0) == MVT::i64) { 02149 Emit_38(Result, N, IA64::CMPLEU, MVT::i1, N0, N1, N2); 02150 return; 02151 } 02152 02153 // Pattern: (setcc:i1 GR:i64:$src1, GR:i64:$src2, SETUGE:Other) 02154 // Emits: (CMPGEU:i1 GR:i64:$src1, GR:i64:$src2) 02155 // Pattern complexity = 2 cost = 1 size = 0 02156 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETUGE && 02157 N.Val->getValueType(0) == MVT::i1 && 02158 N0.Val->getValueType(0) == MVT::i64) { 02159 Emit_38(Result, N, IA64::CMPGEU, MVT::i1, N0, N1, N2); 02160 return; 02161 } 02162 02163 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETEQ:Other) 02164 // Emits: (FCMPEQ:i1 FP:f64:$src1, FP:f64:$src2) 02165 // Pattern complexity = 2 cost = 1 size = 0 02166 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETEQ && 02167 N.Val->getValueType(0) == MVT::i1 && 02168 N0.Val->getValueType(0) == MVT::f64) { 02169 Emit_38(Result, N, IA64::FCMPEQ, MVT::i1, N0, N1, N2); 02170 return; 02171 } 02172 02173 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETGT:Other) 02174 // Emits: (FCMPGT:i1 FP:f64:$src1, FP:f64:$src2) 02175 // Pattern complexity = 2 cost = 1 size = 0 02176 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETGT && 02177 N.Val->getValueType(0) == MVT::i1 && 02178 N0.Val->getValueType(0) == MVT::f64) { 02179 Emit_38(Result, N, IA64::FCMPGT, MVT::i1, N0, N1, N2); 02180 return; 02181 } 02182 02183 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETGE:Other) 02184 // Emits: (FCMPGE:i1 FP:f64:$src1, FP:f64:$src2) 02185 // Pattern complexity = 2 cost = 1 size = 0 02186 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETGE && 02187 N.Val->getValueType(0) == MVT::i1 && 02188 N0.Val->getValueType(0) == MVT::f64) { 02189 Emit_38(Result, N, IA64::FCMPGE, MVT::i1, N0, N1, N2); 02190 return; 02191 } 02192 02193 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETLT:Other) 02194 // Emits: (FCMPLT:i1 FP:f64:$src1, FP:f64:$src2) 02195 // Pattern complexity = 2 cost = 1 size = 0 02196 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETLT && 02197 N.Val->getValueType(0) == MVT::i1 && 02198 N0.Val->getValueType(0) == MVT::f64) { 02199 Emit_38(Result, N, IA64::FCMPLT, MVT::i1, N0, N1, N2); 02200 return; 02201 } 02202 02203 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETLE:Other) 02204 // Emits: (FCMPLE:i1 FP:f64:$src1, FP:f64:$src2) 02205 // Pattern complexity = 2 cost = 1 size = 0 02206 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETLE && 02207 N.Val->getValueType(0) == MVT::i1 && 02208 N0.Val->getValueType(0) == MVT::f64) { 02209 Emit_38(Result, N, IA64::FCMPLE, MVT::i1, N0, N1, N2); 02210 return; 02211 } 02212 02213 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETNE:Other) 02214 // Emits: (FCMPNE:i1 FP:f64:$src1, FP:f64:$src2) 02215 // Pattern complexity = 2 cost = 1 size = 0 02216 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETNE && 02217 N.Val->getValueType(0) == MVT::i1 && 02218 N0.Val->getValueType(0) == MVT::f64) { 02219 Emit_38(Result, N, IA64::FCMPNE, MVT::i1, N0, N1, N2); 02220 return; 02221 } 02222 02223 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETULT:Other) 02224 // Emits: (FCMPLTU:i1 FP:f64:$src1, FP:f64:$src2) 02225 // Pattern complexity = 2 cost = 1 size = 0 02226 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETULT && 02227 N.Val->getValueType(0) == MVT::i1 && 02228 N0.Val->getValueType(0) == MVT::f64) { 02229 Emit_38(Result, N, IA64::FCMPLTU, MVT::i1, N0, N1, N2); 02230 return; 02231 } 02232 02233 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETUGT:Other) 02234 // Emits: (FCMPGTU:i1 FP:f64:$src1, FP:f64:$src2) 02235 // Pattern complexity = 2 cost = 1 size = 0 02236 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETUGT && 02237 N.Val->getValueType(0) == MVT::i1 && 02238 N0.Val->getValueType(0) == MVT::f64) { 02239 Emit_38(Result, N, IA64::FCMPGTU, MVT::i1, N0, N1, N2); 02240 return; 02241 } 02242 02243 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETULE:Other) 02244 // Emits: (FCMPLEU:i1 FP:f64:$src1, FP:f64:$src2) 02245 // Pattern complexity = 2 cost = 1 size = 0 02246 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETULE && 02247 N.Val->getValueType(0) == MVT::i1 && 02248 N0.Val->getValueType(0) == MVT::f64) { 02249 Emit_38(Result, N, IA64::FCMPLEU, MVT::i1, N0, N1, N2); 02250 return; 02251 } 02252 02253 // Pattern: (setcc:i1 FP:f64:$src1, FP:f64:$src2, SETUGE:Other) 02254 // Emits: (FCMPGEU:i1 FP:f64:$src1, FP:f64:$src2) 02255 // Pattern complexity = 2 cost = 1 02256 if (cast<CondCodeSDNode>(N2)->get() == ISD::SETUGE && 02257 N.Val->getValueType(0) == MVT::i1 && 02258 N0.Val->getValueType(0) == MVT::f64) { 02259 Emit_38(Result, N, IA64::FCMPGEU, MVT::i1, N0, N1, N2); 02260 return; 02261 } 02262 std::cerr << "Cannot yet select: "; 02263 N.Val->dump(CurDAG); 02264 std::cerr << '\n'; 02265 abort(); 02266 } 02267 02268 void Select_sext_inreg(SDOperand &Result, SDOperand N) { 02269 SDOperand N0(0, 0); 02270 SDOperand N1(0, 0); 02271 SDOperand Tmp0(0, 0); 02272 SDNode *ResNode = NULL; 02273 N0 = N.getOperand(0); 02274 N1 = N.getOperand(1); 02275 02276 // Pattern: (sext_inreg:i64 GR:i64:$src, i8:Other) 02277 // Emits: (SXT1:i64 GR:i64:$src) 02278 // Pattern complexity = 2 cost = 1 size = 0 02279 if (cast<VTSDNode>(N1)->getVT() == MVT::i8 && 02280 N.Val->getValueType(0) == MVT::i64) { 02281 Emit_13(Result, N, IA64::SXT1, MVT::i64, N0, N1); 02282 return; 02283 } 02284 02285 // Pattern: (sext_inreg:i64 GR:i64:$src, i16:Other) 02286 // Emits: (SXT2:i64 GR:i64:$src) 02287 // Pattern complexity = 2 cost = 1 size = 0 02288 if (cast<VTSDNode>(N1)->getVT() == MVT::i16 && 02289 N.Val->getValueType(0) == MVT::i64) { 02290 Emit_13(Result, N, IA64::SXT2, MVT::i64, N0, N1); 02291 return; 02292 } 02293 02294 // Pattern: (sext_inreg:i64 GR:i64:$src, i32:Other) 02295 // Emits: (SXT4:i64 GR:i64:$src) 02296 // Pattern complexity = 2 cost = 1 02297 if (cast<VTSDNode>(N1)->getVT() == MVT::i32 && 02298 N.Val->getValueType(0) == MVT::i64) { 02299 Emit_13(Result, N, IA64::SXT4, MVT::i64, N0, N1); 02300 return; 02301 } 02302 std::cerr << "Cannot yet select: "; 02303 N.Val->dump(CurDAG); 02304 std::cerr << '\n'; 02305 abort(); 02306 } 02307 02308 void Select_shl(SDOperand &Result, SDOperand N) { 02309 SDOperand N0(0, 0); 02310 SDOperand N1(0, 0); 02311 SDOperand Tmp0(0, 0); 02312 SDOperand Tmp1(0, 0); 02313 SDNode *ResNode = NULL; 02314 N0 = N.getOperand(0); 02315 N1 = N.getOperand(1); 02316 if (N.Val->getValueType(0) == MVT::i64 && 02317 N1.Val->getValueType(0) == MVT::i64) { 02318 Emit_9(Result, N, IA64::SHL, MVT::i64, N0, N1); 02319 return; 02320 } 02321 std::cerr << "Cannot yet select: "; 02322 N.Val->dump(CurDAG); 02323 std::cerr << '\n'; 02324 abort(); 02325 } 02326 02327 void Emit_39(SDOperand &Result, SDOperand &N, unsigned Opc0, unsigned Opc1, unsigned Opc2, MVT::ValueType VT0, MVT::ValueType VT1, MVT::ValueType VT2, SDOperand &N0) NOINLINE { 02328 SDOperand Tmp0(0, 0); 02329 SDOperand Tmp1(0, 0); 02330 SDOperand Tmp2(0, 0); 02331 SDNode *ResNode = NULL; 02332 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 02333 Select(Tmp0, N0); 02334 Tmp1 = SDOperand(CurDAG->getTargetNode(Opc0, VT0, Tmp0), 0); 02335 Tmp2 = SDOperand(CurDAG->getTargetNode(Opc1, VT1, Tmp1), 0); 02336 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 02337 if (N.Val->hasOneUse()) { 02338 Result = CurDAG->SelectNodeTo(N.Val, Opc2, VT2, Tmp2); 02339 } else { 02340 ResNode = CurDAG->getTargetNode(Opc2, VT2, Tmp2); 02341 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 02342 Result = SDOperand(ResNode, 0); 02343 } 02344 return; 02345 } 02346 void Select_sint_to_fp(SDOperand &Result, SDOperand N) { 02347 SDOperand N0(0, 0); 02348 SDOperand Tmp0(0, 0); 02349 SDOperand Tmp1(0, 0); 02350 SDOperand Tmp2(0, 0); 02351 SDNode *ResNode = NULL; 02352 N0 = N.getOperand(0); 02353 if (N0.Val->getValueType(0) == MVT::i64) { 02354 Emit_39(Result, N, IA64::SETFSIG, IA64::FCVTXF, IA64::FNORMD, MVT::f64, MVT::f64, MVT::f64, N0); 02355 return; 02356 } 02357 std::cerr << "Cannot yet select: "; 02358 N.Val->dump(CurDAG); 02359 std::cerr << '\n'; 02360 abort(); 02361 } 02362 02363 void Select_sra(SDOperand &Result, SDOperand N) { 02364 SDOperand N0(0, 0); 02365 SDOperand N1(0, 0); 02366 SDOperand Tmp0(0, 0); 02367 SDOperand Tmp1(0, 0); 02368 SDNode *ResNode = NULL; 02369 N0 = N.getOperand(0); 02370 N1 = N.getOperand(1); 02371 if (N.Val->getValueType(0) == MVT::i64 && 02372 N1.Val->getValueType(0) == MVT::i64) { 02373 Emit_9(Result, N, IA64::SHRS, MVT::i64, N0, N1); 02374 return; 02375 } 02376 std::cerr << "Cannot yet select: "; 02377 N.Val->dump(CurDAG); 02378 std::cerr << '\n'; 02379 abort(); 02380 } 02381 02382 void Select_srl(SDOperand &Result, SDOperand N) { 02383 SDOperand N0(0, 0); 02384 SDOperand N1(0, 0); 02385 SDOperand Tmp0(0, 0); 02386 SDOperand Tmp1(0, 0); 02387 SDNode *ResNode = NULL; 02388 N0 = N.getOperand(0); 02389 N1 = N.getOperand(1); 02390 if (N.Val->getValueType(0) == MVT::i64 && 02391 N1.Val->getValueType(0) == MVT::i64) { 02392 Emit_9(Result, N, IA64::SHRU, MVT::i64, N0, N1); 02393 return; 02394 } 02395 std::cerr << "Cannot yet select: "; 02396 N.Val->dump(CurDAG); 02397 std::cerr << '\n'; 02398 abort(); 02399 } 02400 02401 void Select_sub(SDOperand &Result, SDOperand N) { 02402 SDOperand N0(0, 0); 02403 SDOperand N1(0, 0); 02404 SDOperand Tmp0(0, 0); 02405 SDOperand Tmp1(0, 0); 02406 SDNode *ResNode = NULL; 02407 N0 = N.getOperand(0); 02408 N1 = N.getOperand(1); 02409 if (N.Val->getValueType(0) == MVT::i64) { 02410 Emit_9(Result, N, IA64::SUB, MVT::i64, N0, N1); 02411 return; 02412 } 02413 std::cerr << "Cannot yet select: "; 02414 N.Val->dump(CurDAG); 02415 std::cerr << '\n'; 02416 abort(); 02417 } 02418 02419 void Emit_40(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0, SDOperand &N0) NOINLINE { 02420 SDOperand Tmp0(0, 0); 02421 SDOperand Tmp1(0, 0); 02422 SDNode *ResNode = NULL; 02423 N0 = N.getOperand(0); 02424 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 02425 Select(Tmp0, N0); 02426 Tmp1 = CurDAG->getRegister(IA64::r0, MVT::i64); 02427 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 02428 if (N.Val->hasOneUse()) { 02429 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0, Tmp0, Tmp1); 02430 } else { 02431 ResNode = CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1); 02432 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 02433 Result = SDOperand(ResNode, 0); 02434 } 02435 return; 02436 } 02437 void Select_trunc(SDOperand &Result, SDOperand N) { 02438 SDOperand N0(0, 0); 02439 SDOperand Tmp0(0, 0); 02440 SDOperand Tmp1(0, 0); 02441 SDNode *ResNode = NULL; 02442 Emit_40(Result, N, IA64::CMPNE, MVT::i1, N0); 02443 return; 02444 } 02445 02446 void Select_uint_to_fp(SDOperand &Result, SDOperand N) { 02447 SDOperand N0(0, 0); 02448 SDOperand Tmp0(0, 0); 02449 SDOperand Tmp1(0, 0); 02450 SDOperand Tmp2(0, 0); 02451 SDNode *ResNode = NULL; 02452 N0 = N.getOperand(0); 02453 if (N0.Val->getValueType(0) == MVT::i64) { 02454 Emit_39(Result, N, IA64::SETFSIG, IA64::FCVTXUF, IA64::FNORMD, MVT::f64, MVT::f64, MVT::f64, N0); 02455 return; 02456 } 02457 std::cerr << "Cannot yet select: "; 02458 N.Val->dump(CurDAG); 02459 std::cerr << '\n'; 02460 abort(); 02461 } 02462 02463 void Emit_41(SDOperand &Result, SDOperand &N, unsigned Opc0, MVT::ValueType VT0) NOINLINE { 02464 SDNode *ResNode = NULL; 02465 if (N.Val->hasOneUse()) { 02466 Result = CurDAG->SelectNodeTo(N.Val, Opc0, VT0); 02467 } else { 02468 ResNode = CurDAG->getTargetNode(Opc0, VT0); 02469 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 02470 Result = SDOperand(ResNode, 0); 02471 } 02472 return; 02473 } 02474 void Select_undef(SDOperand &Result, SDOperand N) { 02475 SDNode *ResNode = NULL; 02476 02477 // Pattern: (undef:i64) 02478 // Emits: (IDEF_GR_D:i64) 02479 // Pattern complexity = 2 cost = 1 size = 0 02480 if (N.Val->getValueType(0) == MVT::i64) { 02481 Emit_41(Result, N, IA64::IDEF_GR_D, MVT::i64); 02482 return; 02483 } 02484 02485 // Pattern: (undef:f64) 02486 // Emits: (IDEF_FP_D:f64) 02487 // Pattern complexity = 2 cost = 1 size = 0 02488 if (N.Val->getValueType(0) == MVT::f64) { 02489 Emit_41(Result, N, IA64::IDEF_FP_D, MVT::f64); 02490 return; 02491 } 02492 02493 // Pattern: (undef:i1) 02494 // Emits: (IDEF_PR_D:i1) 02495 // Pattern complexity = 2 cost = 1 02496 if (N.Val->getValueType(0) == MVT::i1) { 02497 Emit_41(Result, N, IA64::IDEF_PR_D, MVT::i1); 02498 return; 02499 } 02500 std::cerr << "Cannot yet select: "; 02501 N.Val->dump(CurDAG); 02502 std::cerr << '\n'; 02503 abort(); 02504 } 02505 02506 void Emit_42(SDOperand &Result, SDOperand &N, unsigned Opc0, unsigned Opc1, unsigned Opc2, unsigned Opc3, MVT::ValueType VT0, MVT::ValueType VT1, MVT::ValueType VT2, MVT::ValueType VT3, SDOperand &N0, SDOperand &N1) NOINLINE { 02507 SDOperand Tmp0(0, 0); 02508 SDOperand Tmp1(0, 0); 02509 SDOperand Tmp2(0, 0); 02510 SDOperand Tmp3(0, 0); 02511 SDOperand Tmp4(0, 0); 02512 SDOperand Tmp5(0, 0); 02513 SDOperand Tmp6(0, 0); 02514 SDOperand Tmp7(0, 0); 02515 SDOperand Tmp8(0, 0); 02516 SDNode *ResNode = NULL; 02517 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 02518 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N1.Val); 02519 Select(Tmp0, N1); 02520 Tmp1 = SDOperand(CurDAG->getTargetNode(Opc0, VT0, Tmp0), 0); 02521 Tmp2 = CurDAG->getTargetConstant(1, MVT::i64); 02522 SelectionDAG::InsertInFlightSetEntry(InFlightSet, Tmp0.Val); 02523 Tmp3 = CurDAG->getRegister(IA64::r0, MVT::i64); 02524 Tmp4 = CurDAG->getTargetConstant(0, MVT::i64); 02525 Tmp5 = SDOperand(CurDAG->getTargetNode(Opc1, VT1, Tmp3, Tmp4), 0); 02526 Tmp6 = CurDAG->getTargetConstant(1, MVT::i64); 02527 Tmp7 = SDOperand(CurDAG->getTargetNode(Opc2, VT2, Tmp5, Tmp6, Tmp0), 0); 02528 Select(Tmp8, N0); 02529 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 02530 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N1.Val); 02531 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, Tmp0.Val); 02532 if (N.Val->hasOneUse()) { 02533 Result = CurDAG->SelectNodeTo(N.Val, Opc3, VT3, Tmp1, Tmp2, Tmp7, Tmp8); 02534 } else { 02535 ResNode = CurDAG->getTargetNode(Opc3, VT3, Tmp1, Tmp2, Tmp7, Tmp8); 02536 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 02537 Result = SDOperand(ResNode, 0); 02538 } 02539 return; 02540 } 02541 void Select_xor(SDOperand &Result, SDOperand N) { 02542 SDOperand N0(0, 0); 02543 SDOperand N1(0, 0); 02544 SDOperand Tmp0(0, 0); 02545 SDOperand Tmp1(0, 0); 02546 SDOperand Tmp2(0, 0); 02547 SDOperand Tmp3(0, 0); 02548 SDOperand Tmp4(0, 0); 02549 SDOperand Tmp5(0, 0); 02550 SDOperand Tmp6(0, 0); 02551 SDOperand Tmp7(0, 0); 02552 SDOperand Tmp8(0, 0); 02553 SDNode *ResNode = NULL; 02554 N0 = N.getOperand(0); 02555 N1 = N.getOperand(1); 02556 02557 // Pattern: (xor:i64 GR:i64:$src1, GR:i64:$src2) 02558 // Emits: (XOR:i64 GR:i64:$src1, GR:i64:$src2) 02559 // Pattern complexity = 2 cost = 1 size = 0 02560 if (N.Val->getValueType(0) == MVT::i64) { 02561 Emit_9(Result, N, IA64::XOR, MVT::i64, N0, N1); 02562 return; 02563 } 02564 02565 // Pattern: (xor:i1 PR:i1:$src1, PR:i1:$src2) 02566 // Emits: (TPCMPIMM8NE:i1 (PCMPEQUNCR0R0:i1 PR:i1:$src2), 1:i64, (TPCADDS:i64 (ADDS:i64 r0:i64, 0:i64), 1:i64, PR:i1:$src2), PR:i1:$src1) 02567 // Pattern complexity = 2 cost = 4 02568 if (N.Val->getValueType(0) == MVT::i1) { 02569 Emit_42(Result, N, IA64::PCMPEQUNCR0R0, IA64::ADDS, IA64::TPCADDS, IA64::TPCMPIMM8NE, MVT::i1, MVT::i64, MVT::i64, MVT::i1, N0, N1); 02570 return; 02571 } 02572 std::cerr << "Cannot yet select: "; 02573 N.Val->dump(CurDAG); 02574 std::cerr << '\n'; 02575 abort(); 02576 } 02577 02578 void Emit_43(SDOperand &Result, SDOperand &N, unsigned Opc0, unsigned Opc1, MVT::ValueType VT0, MVT::ValueType VT1, SDOperand &N0) NOINLINE { 02579 SDOperand Tmp0(0, 0); 02580 SDOperand Tmp1(0, 0); 02581 SDOperand Tmp2(0, 0); 02582 SDOperand Tmp3(0, 0); 02583 SDOperand Tmp4(0, 0); 02584 SDNode *ResNode = NULL; 02585 N0 = N.getOperand(0); 02586 SelectionDAG::InsertInFlightSetEntry(InFlightSet, N0.Val); 02587 Tmp0 = CurDAG->getRegister(IA64::r0, MVT::i64); 02588 Tmp1 = CurDAG->getTargetConstant(0, MVT::i64); 02589 Tmp2 = SDOperand(CurDAG->getTargetNode(Opc0, VT0, Tmp0, Tmp1), 0); 02590 Tmp3 = CurDAG->getTargetConstant(1, MVT::i64); 02591 Select(Tmp4, N0); 02592 SelectionDAG::RemoveInFlightSetEntry(InFlightSet, N0.Val); 02593 if (N.Val->hasOneUse()) { 02594 Result = CurDAG->SelectNodeTo(N.Val, Opc1, VT1, Tmp2, Tmp3, Tmp4); 02595 } else { 02596 ResNode = CurDAG->getTargetNode(Opc1, VT1, Tmp2, Tmp3, Tmp4); 02597 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, ResNode, 0); 02598 Result = SDOperand(ResNode, 0); 02599 } 02600 return; 02601 } 02602 void Select_zext(SDOperand &Result, SDOperand N) { 02603 SDOperand N0(0, 0); 02604 SDOperand Tmp0(0, 0); 02605 SDOperand Tmp1(0, 0); 02606 SDOperand Tmp2(0, 0); 02607 SDOperand Tmp3(0, 0); 02608 SDOperand Tmp4(0, 0); 02609 SDNode *ResNode = NULL; 02610 Emit_43(Result, N, IA64::ADDS, IA64::TPCADDIMM22, MVT::i64, MVT::i64, N0); 02611 return; 02612 } 02613 02614 void Select_INLINEASM(SDOperand& Result, SDOperand N) { 02615 std::vector<SDOperand> Ops(N.Val->op_begin(), N.Val->op_end()); 02616 Select(Ops[0], N.getOperand(0)); // Select the chain. 02617 02618 // Select the flag operand. 02619 if (Ops.back().getValueType() == MVT::Flag) 02620 Select(Ops.back(), Ops.back()); 02621 SelectInlineAsmMemoryOperands(Ops, *CurDAG); 02622 std::vector<MVT::ValueType> VTs; 02623 VTs.push_back(MVT::Other); 02624 VTs.push_back(MVT::Flag); 02625 SDOperand New = CurDAG->getNode(ISD::INLINEASM, VTs, Ops); 02626 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, New.Val, 0); 02627 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, New.Val, 1); 02628 Result = New.getValue(N.ResNo); 02629 return; 02630 } 02631 02632 // The main instruction selector code. 02633 void SelectCode(SDOperand &Result, SDOperand N) { 02634 if (N.getOpcode() >= ISD::BUILTIN_OP_END && 02635 N.getOpcode() < (ISD::BUILTIN_OP_END+IA64::INSTRUCTION_LIST_END)) { 02636 Result = N; 02637 return; // Already selected. 02638 } 02639 02640 std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(N); 02641 if (CGMI != CodeGenMap.end()) { 02642 Result = CGMI->second; 02643 return; 02644 } 02645 02646 switch (N.getOpcode()) { 02647 default: break; 02648 case ISD::EntryToken: // These leaves remain the same. 02649 case ISD::BasicBlock: 02650 case ISD::Register: 02651 case ISD::HANDLENODE: 02652 case ISD::TargetConstant: 02653 case ISD::TargetConstantPool: 02654 case ISD::TargetFrameIndex: 02655 case ISD::TargetJumpTable: 02656 case ISD::TargetGlobalAddress: { 02657 Result = N; 02658 return; 02659 } 02660 case ISD::AssertSext: 02661 case ISD::AssertZext: { 02662 SDOperand Tmp0; 02663 Select(Tmp0, N.getOperand(0)); 02664 if (!N.Val->hasOneUse()) 02665 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, Tmp0.Val, Tmp0.ResNo); 02666 Result = Tmp0; 02667 return; 02668 } 02669 case ISD::TokenFactor: 02670 if (N.getNumOperands() == 2) { 02671 SDOperand Op0, Op1; 02672 Select(Op0, N.getOperand(0)); 02673 Select(Op1, N.getOperand(1)); 02674 Result = 02675 CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1); 02676 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, Result.Val, Result.ResNo); 02677 } else { 02678 std::vector<SDOperand> Ops; 02679 for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i) { 02680 SDOperand Val; 02681 Select(Val, N.getOperand(i)); 02682 Ops.push_back(Val); 02683 } 02684 Result = 02685 CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops); 02686 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, Result.Val, Result.ResNo); 02687 } 02688 return; 02689 case ISD::CopyFromReg: { 02690 SDOperand Chain; 02691 Select(Chain, N.getOperand(0)); 02692 unsigned Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg(); 02693 MVT::ValueType VT = N.Val->getValueType(0); 02694 if (N.Val->getNumValues() == 2) { 02695 if (Chain == N.getOperand(0)) { 02696 Result = N; // No change 02697 return; 02698 } 02699 SDOperand New = CurDAG->getCopyFromReg(Chain, Reg, VT); 02700 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, New.Val, 0); 02701 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, New.Val, 1); 02702 Result = New.getValue(N.ResNo); 02703 return; 02704 } else { 02705 SDOperand Flag; 02706 if (N.getNumOperands() == 3) Select(Flag, N.getOperand(2)); 02707 if (Chain == N.getOperand(0) && 02708 (N.getNumOperands() == 2 || Flag == N.getOperand(2))) { 02709 Result = N; // No change 02710 return; 02711 } 02712 SDOperand New = CurDAG->getCopyFromReg(Chain, Reg, VT, Flag); 02713 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, New.Val, 0); 02714 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, New.Val, 1); 02715 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 2, New.Val, 2); 02716 Result = New.getValue(N.ResNo); 02717 return; 02718 } 02719 } 02720 case ISD::CopyToReg: { 02721 SDOperand Chain; 02722 Select(Chain, N.getOperand(0)); 02723 unsigned Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg(); 02724 SDOperand Val; 02725 Select(Val, N.getOperand(2)); 02726 Result = N; 02727 if (N.Val->getNumValues() == 1) { 02728 if (Chain != N.getOperand(0) || Val != N.getOperand(2)) 02729 Result = CurDAG->getCopyToReg(Chain, Reg, Val); 02730 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Result.Val, 0); 02731 } else { 02732 SDOperand Flag(0, 0); 02733 if (N.getNumOperands() == 4) Select(Flag, N.getOperand(3)); 02734 if (Chain != N.getOperand(0) || Val != N.getOperand(2) || 02735 (N.getNumOperands() == 4 && Flag != N.getOperand(3))) 02736 Result = CurDAG->getCopyToReg(Chain, Reg, Val, Flag); 02737 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Result.Val, 0); 02738 SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, Result.Val, 1); 02739 Result = Result.getValue(N.ResNo); 02740 } 02741 return; 02742 } 02743 case ISD::INLINEASM: Select_INLINEASM(Result, N); return; 02744 case ISD::ADD: Select_add(Result, N); return; 02745 case ISD::AND: Select_and(Result, N); return; 02746 case ISD::CTPOP: Select_ctpop(Result, N); return; 02747 case ISD::FABS: Select_fabs(Result, N); return; 02748 case ISD::FADD: Select_fadd(Result, N); return; 02749 case ISD::FMUL: Select_fmul(Result, N); return; 02750 case ISD::FNEG: Select_fneg(Result, N); return; 02751 case ISD::FP_TO_SINT: Select_fp_to_sint(Result, N); return; 02752 case ISD::FP_TO_UINT: Select_fp_to_uint(Result, N); return; 02753 case ISD::FSUB: Select_fsub(Result, N); return; 02754 case ISD::Constant: Select_imm(Result, N); return; 02755 case ISD::MUL: Select_mul(Result, N); return; 02756 case ISD::MULHS: Select_mulhs(Result, N); return; 02757 case ISD::MULHU: Select_mulhu(Result, N); return; 02758 case ISD::OR: Select_or(Result, N); return; 02759 case ISD::RET: Select_ret(Result, N); return; 02760 case IA64ISD::RET_FLAG: Select_retflag(Result, N); return; 02761 case ISD::SELECT: Select_select(Result, N); return; 02762 case ISD::SETCC: Select_setcc(Result, N); return; 02763 case ISD::SIGN_EXTEND_INREG: Select_sext_inreg(Result, N); return; 02764 case ISD::SHL: Select_shl(Result, N); return; 02765 case ISD::SINT_TO_FP: Select_sint_to_fp(Result, N); return; 02766 case ISD::SRA: Select_sra(Result, N); return; 02767 case ISD::SRL: Select_srl(Result, N); return; 02768 case ISD::SUB: Select_sub(Result, N); return; 02769 case ISD::TRUNCATE: Select_trunc(Result, N); return; 02770 case ISD::UINT_TO_FP: Select_uint_to_fp(Result, N); return; 02771 case ISD::UNDEF: Select_undef(Result, N); return; 02772 case ISD::XOR: Select_xor(Result, N); return; 02773 case ISD::ZERO_EXTEND: Select_zext(Result, N); return; 02774 } // end of big switch. 02775 02776 std::cerr << "Cannot yet select: "; 02777 if (N.getOpcode() != ISD::INTRINSIC_W_CHAIN && 02778 N.getOpcode() != ISD::INTRINSIC_WO_CHAIN && 02779 N.getOpcode() != ISD::INTRINSIC_VOID) { 02780 N.Val->dump(CurDAG); 02781 } else { 02782 unsigned iid = cast<ConstantSDNode>(N.getOperand(N.getOperand(0).getValueType() == MVT::Other))->getValue(); 02783 std::cerr << "intrinsic %"<< Intrinsic::getName((Intrinsic::ID)iid); 02784 } 02785 std::cerr << '\n'; 02786 abort(); 02787 }