PPCISelLowering.cpp revision caad163496a3ad207a75009f4ad16bae1b1527ae
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===-- PPCISelLowering.cpp - PPC DAG Lowering Implementation -------------===// 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The LLVM Compiler Infrastructure 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This file was developed by Chris Lattner and is distributed under 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// the University of Illinois Open Source License. See LICENSE.TXT for details. 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This file implements the PPCISelLowering class. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "PPCISelLowering.h" 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "PPCTargetMachine.h" 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/ADT/VectorExtras.h" 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/Analysis/ScalarEvolutionExpressions.h" 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/CodeGen/MachineFrameInfo.h" 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/CodeGen/MachineFunction.h" 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/CodeGen/MachineInstrBuilder.h" 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/CodeGen/SelectionDAG.h" 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/CodeGen/SSARegMap.h" 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/Constants.h" 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/Function.h" 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/Intrinsics.h" 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/Support/MathExtras.h" 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/Target/TargetOptions.h" 281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)using namespace llvm; 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) 3181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) : TargetLowering(TM) { 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // Fold away setcc operations if possible. 349bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) setSetCCIsExpensive(); 3581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) setPow2DivIsCheap(); 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // Use _setjmp/_longjmp instead of setjmp/longjmp. 381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) setUseUnderscoreSetJmpLongJmp(true); 39e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 40a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // Set up the register classes. 418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) addRegisterClass(MVT::i32, PPC::GPRCRegisterClass); 42e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) addRegisterClass(MVT::f32, PPC::F4RCRegisterClass); 43e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) addRegisterClass(MVT::f64, PPC::F8RCRegisterClass); 44e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) 45e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) setOperationAction(ISD::ConstantFP, MVT::f64, Expand); 4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::ConstantFP, MVT::f32, Expand); 47e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 48f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) // PowerPC has no intrinsics for these particular operations 4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); 5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::MEMSET, MVT::Other, Expand); 5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::MEMCPY, MVT::Other, Expand); 5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // PowerPC has an i16 but no i8 (or i1) SEXTLOAD 5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); 5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); 5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // PowerPC has no SREM/UREM instructions 581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) setOperationAction(ISD::SREM, MVT::i32, Expand); 598abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) setOperationAction(ISD::UREM, MVT::i32, Expand); 608abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // We don't support sin/cos/sqrt/fmod 6253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::FSIN , MVT::f64, Expand); 6353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::FCOS , MVT::f64, Expand); 6453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::FREM , MVT::f64, Expand); 6553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::FSIN , MVT::f32, Expand); 6653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::FCOS , MVT::f32, Expand); 6753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::FREM , MVT::f32, Expand); 6853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 6953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // If we're enabling GP optimizations, use hardware square root 7053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!TM.getSubtarget<PPCSubtarget>().hasFSQRT()) { 7193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) setOperationAction(ISD::FSQRT, MVT::f64, Expand); 7293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) setOperationAction(ISD::FSQRT, MVT::f32, Expand); 7393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 74e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) 75a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); 761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); 77a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 78a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // PowerPC does not have BSWAP, CTPOP or CTTZ 79a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) setOperationAction(ISD::BSWAP, MVT::i32 , Expand); 801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) setOperationAction(ISD::CTPOP, MVT::i32 , Expand); 81591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch setOperationAction(ISD::CTTZ , MVT::i32 , Expand); 82591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // PowerPC does not have ROTR 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::ROTR, MVT::i32 , Expand); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // PowerPC does not have Select 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SELECT, MVT::i32, Expand); 88e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) setOperationAction(ISD::SELECT, MVT::f32, Expand); 89e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) setOperationAction(ISD::SELECT, MVT::f64, Expand); 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // PowerPC wants to turn select_cc of FP into fsel when possible. 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // PowerPC wants to optimize integer setcc a bit 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SETCC, MVT::i32, Custom); 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // PowerPC does not have BRCOND which requires SetCC 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::BRCOND, MVT::Other, Expand); 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores. 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // PowerPC does not have [U|S]INT_TO_FP 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // PowerPC does not have truncstore for i1. 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote); 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Support label based line numbers. 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::LOCATION, MVT::Other, Expand); 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME - use subtarget debug flags 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!TM.getSubtarget<PPCSubtarget>().isDarwin()) 119a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); 120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We want to legalize GlobalAddress and ConstantPool nodes into the 122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // appropriate instructions to materialize the address. 123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::ConstantPool, MVT::i32, Custom); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // RET must be custom lowered, to meet ABI requirements 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::RET , MVT::Other, Custom); 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // VASTART needs to be custom lowered to use the VarArgsFrameIndex 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::VASTART , MVT::Other, Custom); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Use the default implementation. 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::VAARG , MVT::Other, Expand); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::VACOPY , MVT::Other, Expand); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::VAEND , MVT::Other, Expand); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We want to custom lower some of our intrinsics. 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (TM.getSubtarget<PPCSubtarget>().is64Bit()) { 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // They also have instructions for converting between i64 and fp. 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: disable this lowered code. This generates 64-bit register values, 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and we don't model the fact that the top part is clobbered by calls. We 150591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // need to flag these together so that the value isn't live across a call. 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) //setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // PowerPC does not have FP_TO_UINT on 32-bit implementations. 1571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); 1581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 1591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 1601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (TM.getSubtarget<PPCSubtarget>().has64BitRegs()) { 1611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // 64 bit PowerPC implementations can support i64 types directly 1621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) addRegisterClass(MVT::i64, PPC::G8RCRegisterClass); 1631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // BUILD_PAIR can't be handled natively, and should be expanded to shl/or 1641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand); 1651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } else { 1661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // 32 bit PowerPC wants to expand i64 shifts itself. 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SHL, MVT::i64, Custom); 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SRL, MVT::i64, Custom); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SRA, MVT::i64, Custom); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (TM.getSubtarget<PPCSubtarget>().hasAltivec()) { 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // First set operation action for all vector types to expand. Then we 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // will selectively turn on ones that can be effectively codegen'd. 17551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE; 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) VT != (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) { 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // add/sub/and/or/xor are legal for all supported vector VT's. 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::ADD , (MVT::ValueType)VT, Legal); 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SUB , (MVT::ValueType)VT, Legal); 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::AND , (MVT::ValueType)VT, Legal); 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::OR , (MVT::ValueType)VT, Legal); 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::XOR , (MVT::ValueType)VT, Legal); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We promote all shuffles to v16i8. 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Promote); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AddPromotedToType(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, MVT::v16i8); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::MUL , (MVT::ValueType)VT, Expand); 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand); 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand); 191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand); 19253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand); 1931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand); 1948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand); 195bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Expand); 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1978abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Expand); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2008abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // We can custom expand all VECTOR_SHUFFLEs to VPERM, others we can handle 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // with merges, splats, etc. 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v16i8, Custom); 2038abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 2048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) addRegisterClass(MVT::v4f32, PPC::VRRCRegisterClass); 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addRegisterClass(MVT::v4i32, PPC::VRRCRegisterClass); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addRegisterClass(MVT::v8i16, PPC::VRRCRegisterClass); 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addRegisterClass(MVT::v16i8, PPC::VRRCRegisterClass); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::MUL, MVT::v4f32, Legal); 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i32, Custom); 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::BUILD_VECTOR, MVT::v16i8, Custom); 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::BUILD_VECTOR, MVT::v8i16, Custom); 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::BUILD_VECTOR, MVT::v4i32, Custom); 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Custom); 218bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 219bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setSetCCResultContents(ZeroOrOneSetCCResult); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setStackPointerRegisterToSaveRestore(PPC::R1); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We have target-specific dag combine patterns for the following nodes: 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setTargetDAGCombine(ISD::SINT_TO_FP); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setTargetDAGCombine(ISD::STORE); 22651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeRegisterProperties(); 228591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (Opcode) { 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: return 0; 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::FSEL: return "PPCISD::FSEL"; 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::FCFID: return "PPCISD::FCFID"; 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::FCTIDZ: return "PPCISD::FCTIDZ"; 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::FCTIWZ: return "PPCISD::FCTIWZ"; 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::STFIWX: return "PPCISD::STFIWX"; 238591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case PPCISD::VMADDFP: return "PPCISD::VMADDFP"; 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::VNMSUBFP: return "PPCISD::VNMSUBFP"; 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::VPERM: return "PPCISD::VPERM"; 2418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) case PPCISD::Hi: return "PPCISD::Hi"; 2428abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) case PPCISD::Lo: return "PPCISD::Lo"; 2438abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) case PPCISD::GlobalBaseReg: return "PPCISD::GlobalBaseReg"; 2448abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) case PPCISD::SRL: return "PPCISD::SRL"; 2458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) case PPCISD::SRA: return "PPCISD::SRA"; 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::SHL: return "PPCISD::SHL"; 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::EXTSW_32: return "PPCISD::EXTSW_32"; 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::STD_32: return "PPCISD::STD_32"; 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::CALL: return "PPCISD::CALL"; 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG"; 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::MFCR: return "PPCISD::MFCR"; 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::VCMP: return "PPCISD::VCMP"; 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::VCMPo: return "PPCISD::VCMPo"; 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// isFloatingPointZero - Return true if this is 0.0 or -0.0. 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isFloatingPointZero(SDOperand Op) { 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op)) 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (Op.getOpcode() == ISD::EXTLOAD || Op.getOpcode() == ISD::LOAD) { 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Maybe this has already been legalized into the constant pool? 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1))) 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->get())) 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); 26651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// isConstantOrUndef - Op is either an undef node or a ConstantSDNode. Return 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// true if Op is undef or if it matches the specified value. 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isConstantOrUndef(SDOperand Op, unsigned Val) { 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Op.getOpcode() == ISD::UNDEF || 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cast<ConstantSDNode>(Op)->getValue() == Val; 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// VPKUHUM instruction. 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool PPC::isVPKUHUMShuffleMask(SDNode *N) { 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i != 16; ++i) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isConstantOrUndef(N->getOperand(i), i*2+1)) 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// VPKUWUM instruction. 2888abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)bool PPC::isVPKUWUMShuffleMask(SDNode *N) { 28951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) for (unsigned i = 0; i != 16; i += 2) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isConstantOrUndef(N->getOperand(i ), i*2+2) || 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !isConstantOrUndef(N->getOperand(i+1), i*2+3)) 292926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 293926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 294926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 295926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// isVMerge - Common function, used to match vmrg* shuffles. 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isVMerge(SDNode *N, unsigned UnitSize, 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned LHSStart, unsigned RHSStart) { 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(N->getOpcode() == ISD::BUILD_VECTOR && 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!"); 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) && 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "Unsupported merge size!"); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i != 8/UnitSize; ++i) // Step over units 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned j = 0; j != UnitSize; ++j) { // Step over bytes within unit 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isConstantOrUndef(N->getOperand(i*UnitSize*2+j), 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LHSStart+j+i*UnitSize) || 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !isConstantOrUndef(N->getOperand(i*UnitSize*2+UnitSize+j), 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RHSStart+j+i*UnitSize)) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// a VRGL* instruction with the specified unit size (1,2 or 4 bytes). 3188abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)bool PPC::isVMRGLShuffleMask(SDNode *N, unsigned UnitSize, bool isUnary) { 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isUnary) 320e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return isVMerge(N, UnitSize, 8, 24); 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isVMerge(N, UnitSize, 8, 8); 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// a VRGH* instruction with the specified unit size (1,2 or 4 bytes). 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool PPC::isVMRGHShuffleMask(SDNode *N, unsigned UnitSize, bool isUnary) { 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isUnary) 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isVMerge(N, UnitSize, 0, 16); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isVMerge(N, UnitSize, 0, 0); 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 331591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 332926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 333926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift 3347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch/// amount, otherwise return -1. 3357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochint PPC::isVSLDOIShuffleMask(SDNode *N) { 336fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch assert(N->getOpcode() == ISD::BUILD_VECTOR && 337fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!"); 338fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch // Find the first non-undef value in the shuffle mask. 339926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned i; 340926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (i = 0; i != 16 && N->getOperand(i).getOpcode() == ISD::UNDEF; ++i) 341926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) /*search*/; 342926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 343926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (i == 16) return -1; // all undef. 3448abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 345926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Otherwise, check to see if the rest of the elements are consequtively 346926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // numbered from this value. 347926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned ShiftAmt = cast<ConstantSDNode>(N->getOperand(i))->getValue(); 348926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (ShiftAmt < i) return -1; 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ShiftAmt -= i; 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check the rest of the elements to see if they are consequtive. 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (++i; i != 16; ++i) 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isConstantOrUndef(N->getOperand(i), ShiftAmt+i)) 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ShiftAmt; 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// isVSLDOIRotateShuffleMask - If this is a vsldoi rotate shuffle mask, 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// return the shift amount, otherwise return -1. Note that vlsdoi(x,x) will 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// result in the shuffle being changed to shuffle(x,undef, ...) with 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// transformed byte numbers. 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int PPC::isVSLDOIRotateShuffleMask(SDNode *N) { 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!"); 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Find the first non-undef value in the shuffle mask. 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned i; 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (i = 0; i != 16 && N->getOperand(i).getOpcode() == ISD::UNDEF; ++i) 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /*search*/; 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (i == 16) return -1; // all undef. 3718abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Otherwise, check to see if the rest of the elements are consequtively 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // numbered from this value. 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned ShiftAmt = cast<ConstantSDNode>(N->getOperand(i))->getValue(); 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ShiftAmt < i) return -1; 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ShiftAmt -= i; 3778abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check the rest of the elements to see if they are consequtive. 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (++i; i != 16; ++i) 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isConstantOrUndef(N->getOperand(i), (ShiftAmt+i) & 15)) 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ShiftAmt; 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// specifies a splat of a single element that is suitable for input to 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// VSPLTB/VSPLTH/VSPLTW. 389591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochbool PPC::isSplatShuffleMask(SDNode *N, unsigned EltSize) { 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(N->getOpcode() == ISD::BUILD_VECTOR && 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) N->getNumOperands() == 16 && 3928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) (EltSize == 1 || EltSize == 2 || EltSize == 4)); 3938abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This is a splat operation if each element of the permute is the same, and 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // if the value doesn't reference the second vector. 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned ElementBase = 0; 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Elt = N->getOperand(0); 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ConstantSDNode *EltV = dyn_cast<ConstantSDNode>(Elt)) 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ElementBase = EltV->getValue(); 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; // FIXME: Handle UNDEF elements too! 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cast<ConstantSDNode>(Elt)->getValue() >= 16) 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 406521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Check that they are consequtive. 407521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) for (unsigned i = 1; i != EltSize; ++i) { 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isa<ConstantSDNode>(N->getOperand(i)) || 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cast<ConstantSDNode>(N->getOperand(i))->getValue() != i+ElementBase) 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(isa<ConstantSDNode>(Elt) && "Invalid VECTOR_SHUFFLE mask!"); 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = EltSize, e = 16; i != e; i += EltSize) { 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(isa<ConstantSDNode>(N->getOperand(i)) && 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "Invalid VECTOR_SHUFFLE mask!"); 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned j = 0; j != EltSize; ++j) 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (N->getOperand(i+j) != N->getOperand(j)) 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// getVSPLTImmediate - Return the appropriate VSPLT* immediate to splat the 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// specified isSplatShuffleMask VECTOR_SHUFFLE mask. 427926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)unsigned PPC::getVSPLTImmediate(SDNode *N, unsigned EltSize) { 428926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) assert(isSplatShuffleMask(N, EltSize)); 4298abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return cast<ConstantSDNode>(N->getOperand(0))->getValue() / EltSize; 4308abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)} 431a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 432a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)/// isVecSplatImm - Return true if this is a build_vector of constants which 433a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)/// can be formed by using a vspltis[bhw] instruction. The ByteSize field 434a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)/// indicates the number of bytes of each element [124] -> [bhw]. 435a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool PPC::isVecSplatImm(SDNode *N, unsigned ByteSize, char *Val) { 436926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand OpVal(0, 0); 437926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Check to see if this buildvec has a single non-undef value in its elements. 438926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue; 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (OpVal.Val == 0) 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OpVal = N->getOperand(i); 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (OpVal != N->getOperand(i)) 443926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 444926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 445926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (OpVal.Val == 0) return false; // All UNDEF: use implicit def. 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned ValSizeInBytes = 0; 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint64_t Value = 0; 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) { 4511fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch Value = CN->getValue(); 4521fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch ValSizeInBytes = MVT::getSizeInBits(CN->getValueType(0))/8; 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) { 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(CN->getValueType(0) == MVT::f32 && "Only one legal FP vector type!"); 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Value = FloatToBits(CN->getValue()); 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ValSizeInBytes = 4; 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4588abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 4598abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // If the splat value is larger than the element value, then we can never do 4608abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // this splat. The only case that we could fit the replicated bits into our 4618abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // immediate field for would be zero, and we prefer to use vxor for it. 4628abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (ValSizeInBytes < ByteSize) return false; 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the element value is larger than the splat value, cut it in half and 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // check to see if the two halves are equal. Continue doing this until we 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // get to ByteSize. This allows us to handle 0x01010101 as 0x01. 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (ValSizeInBytes > ByteSize) { 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ValSizeInBytes >>= 1; 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the top half equals the bottom half, we're still ok. 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (((Value >> (ValSizeInBytes*8)) & ((1 << (8*ValSizeInBytes))-1)) != 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (Value & ((1 << (8*ValSizeInBytes))-1))) 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Properly sign extend the value. 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int ShAmt = (4-ByteSize)*8; 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int MaskVal = ((int)Value << ShAmt) >> ShAmt; 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If this is zero, don't match, zero matches ISD::isBuildVectorAllZeros. 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (MaskVal == 0) return false; 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (Val) *Val = MaskVal; 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Finally, if this value fits in a 5 bit sext field, return true. 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ((MaskVal << (32-5)) >> (32-5)) == MaskVal; 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// LowerOperation - Provide custom lowering hooks for some operations. 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// 49277e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles)SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (Op.getOpcode()) { 49477e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) default: assert(0 && "Wasn't expecting to be able to lower this!"); 49577e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) case ISD::FP_TO_SINT: { 49677e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) assert(MVT::isFloatingPoint(Op.getOperand(0).getValueType())); 497926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand Src = Op.getOperand(0); 4988abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (Src.getValueType() == MVT::f32) 49977e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) Src = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Src); 500926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 501926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand Tmp; 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (Op.getValueType()) { 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: assert(0 && "Unhandled FP_TO_SINT type in custom expander!"); 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::i32: 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Tmp = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Src); 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 50777e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) case MVT::i64: 50877e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) Tmp = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Src); 50977e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) break; 51077e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) } 511591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Convert the FP value to an int value through memory. 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Bits = DAG.getNode(ISD::BIT_CONVERT, MVT::i64, Tmp); 51477e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) if (Op.getValueType() == MVT::i32) 51577e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) Bits = DAG.getNode(ISD::TRUNCATE, MVT::i32, Bits); 51677e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) return Bits; 51777e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) } 518591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case ISD::SINT_TO_FP: 5191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (Op.getOperand(0).getValueType() == MVT::i64) { 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Bits = DAG.getNode(ISD::BIT_CONVERT, MVT::f64, Op.getOperand(0)); 52177e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) SDOperand FP = DAG.getNode(PPCISD::FCFID, MVT::f64, Bits); 52277e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) if (Op.getValueType() == MVT::f32) 52377e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) FP = DAG.getNode(ISD::FP_ROUND, MVT::f32, FP); 52477e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) return FP; 52577e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) } else { 52677e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) assert(Op.getOperand(0).getValueType() == MVT::i32 && 52777e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) "Unhandled SINT_TO_FP type in custom expander!"); 52877e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) // Since we only generate this in 64-bit mode, we can take advantage of 52977e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) // 64-bit registers. In particular, sign extend the input value into the 53077e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) // 64-bit register with extsw, store the WHOLE 64-bit value into the stack 53177e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) // then lfd it and fcfid it. 53277e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo(); 53377e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) int FrameIdx = FrameInfo->CreateStackObject(8, 8); 53477e14d17900500683cd1ec2d19ba0d6e760fc132Torne (Richard Coles) SDOperand FIdx = DAG.getFrameIndex(FrameIdx, MVT::i32); 535591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Ext64 = DAG.getNode(PPCISD::EXTSW_32, MVT::i32, 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Op.getOperand(0)); 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // STD the extended value into the stack slot. 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Store = DAG.getNode(PPCISD::STD_32, MVT::Other, 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getEntryNode(), Ext64, FIdx, 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getSrcValue(NULL)); 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Load the value as a double. 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Ld = DAG.getLoad(MVT::f64, Store, FIdx, DAG.getSrcValue(NULL)); 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FCFID it and return it. 547591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SDOperand FP = DAG.getNode(PPCISD::FCFID, MVT::f64, Ld); 5488abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (Op.getValueType() == MVT::f32) 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FP = DAG.getNode(ISD::FP_ROUND, MVT::f32, FP); 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return FP; 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 554a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case ISD::SELECT_CC: { 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Turn FP only select_cc's into fsel instructions. 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!MVT::isFloatingPoint(Op.getOperand(0).getValueType()) || 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !MVT::isFloatingPoint(Op.getOperand(2).getValueType())) 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 559926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 560926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Cannot handle SETEQ/SETNE. 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (CC == ISD::SETEQ || CC == ISD::SETNE) break; 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 565926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) MVT::ValueType ResVT = Op.getValueType(); 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MVT::ValueType CmpVT = Op.getOperand(0).getValueType(); 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1); 568591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SDOperand TV = Op.getOperand(2), FV = Op.getOperand(3); 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the RHS of the comparison is a 0.0, we don't need to do the 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // subtraction at all. 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isFloatingPointZero(RHS)) 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (CC) { 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: break; // SETUO etc aren't handled by fsel. 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETULT: 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETLT: 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::swap(TV, FV); // fsel is natively setge, swap operands for setlt 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETUGE: 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETGE: 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV); 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETUGT: 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETGT: 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::swap(TV, FV); // fsel is natively setge, swap operands for setlt 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETULE: 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETLE: 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); 59006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return DAG.getNode(PPCISD::FSEL, ResVT, 59151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) DAG.getNode(ISD::FNEG, MVT::f64, LHS), TV, FV); 59206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 59306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Cmp; 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (CC) { 59606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) default: break; // SETUO etc aren't handled by fsel. 59706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) case ISD::SETULT: 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETLT: 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); 6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETUGE: 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETGE: 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV); 609591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case ISD::SETUGT: 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETGT: 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); 61206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits 61306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETULE: 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETLE: 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV); 6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SHL: { 6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(Op.getValueType() == MVT::i64 && 6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); 6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The generic code does a fine job expanding shift by a constant. 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isa<ConstantSDNode>(Op.getOperand(1))) break; 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Otherwise, expand into a bunch of logical ops. Note that these ops 6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // depend on the PPC behavior for oversized shift amounts. 6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(0, MVT::i32)); 6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(1, MVT::i32)); 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Amt = Op.getOperand(1); 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 638e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(32, MVT::i32), Amt); 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp2 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Amt); 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp3 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Tmp1); 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(-32U, MVT::i32)); 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp6 = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Tmp5); 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand OutLo = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Amt); 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); 6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SRL: { 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(Op.getValueType() == MVT::i64 && 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The generic code does a fine job expanding shift by a constant. 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isa<ConstantSDNode>(Op.getOperand(1))) break; 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Otherwise, expand into a bunch of logical ops. Note that these ops 6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // depend on the PPC behavior for oversized shift amounts. 6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(0, MVT::i32)); 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(1, MVT::i32)); 6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Amt = Op.getOperand(1); 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(32, MVT::i32), Amt); 666591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SDOperand Tmp2 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Amt); 667591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SDOperand Tmp3 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Tmp1); 6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, 670926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DAG.getConstant(-32U, MVT::i32)); 671926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand Tmp6 = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Tmp5); 672926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); 6738abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) SDOperand OutHi = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Amt); 674926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); 6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SRA: { 6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(Op.getValueType() == MVT::i64 && 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!"); 679591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // The generic code does a fine job expanding shift by a constant. 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isa<ConstantSDNode>(Op.getOperand(1))) break; 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Otherwise, expand into a bunch of logical ops, followed by a select_cc. 6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(0, MVT::i32)); 6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 68693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) DAG.getConstant(1, MVT::i32)); 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Amt = Op.getOperand(1); 6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(32, MVT::i32), Amt); 6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp2 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Amt); 692e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch SDOperand Tmp3 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Tmp1); 6938abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); 6948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, 6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(-32U, MVT::i32)); 6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Tmp6 = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Tmp5); 6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand OutHi = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Amt); 698591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32), 6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Tmp4, Tmp6, ISD::SETLE); 7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); 7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::ConstantPool: { 703e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 704926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Constant *C = CP->get(); 705926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i32, CP->getAlignment()); 7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Zero = DAG.getConstant(0, MVT::i32); 7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (getTargetMachine().getRelocationModel() == Reloc::Static) { 709926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Generate non-pic code that has direct accesses to the constant pool. 7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The address of the global is just (hi(&g)+lo(&g)). 7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); 7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, CPI, Zero); 713926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); 714521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 715521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 716521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Only lower ConstantPool on Darwin. 717521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (!getTargetMachine().getSubtarget<PPCSubtarget>().isDarwin()) break; 718521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); 719521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (getTargetMachine().getRelocationModel() == Reloc::PIC) { 720521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // With PIC, the first instruction is actually "GR+hi(&G)". 721926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Hi = DAG.getNode(ISD::ADD, MVT::i32, 7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); 7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, CPI, Zero); 726e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); 727926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return Lo; 728926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::GlobalAddress: { 7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op); 7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GlobalValue *GV = GSDN->getGlobal(); 732926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32, GSDN->getOffset()); 7335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) SDOperand Zero = DAG.getConstant(0, MVT::i32); 734926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (getTargetMachine().getRelocationModel() == Reloc::Static) { 7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Generate non-pic code that has direct accesses to globals. 737926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // The address of the global is just (hi(&g)+lo(&g)). 738926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); 739926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero); 740926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); 741926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 742926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 743926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Only lower GlobalAddress on Darwin. 744926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!getTargetMachine().getSubtarget<PPCSubtarget>().isDarwin()) break; 745926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 746926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); 747926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (getTargetMachine().getRelocationModel() == Reloc::PIC) { 748926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // With PIC, the first instruction is actually "GR+hi(&G)". 749926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Hi = DAG.getNode(ISD::ADD, MVT::i32, 750926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); 751926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 752926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 753926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero); 754926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); 7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!GV->hasWeakLinkage() && !GV->hasLinkOnceLinkage() && 757926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) (!GV->isExternal() || GV->hasNotBeenReadFromBytecode())) 758926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return Lo; 7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 760926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If the global is weak or external, we have to go through the lazy 7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // resolution stub. 7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Lo, DAG.getSrcValue(0)); 7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SETCC: { 765926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 766926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we're comparing for equality to zero, expose the fact that this is 768926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // implented as a ctlz/srl pair on ppc, so that the dag combiner can 7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // fold the new nodes. 7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { 7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (C->isNullValue() && CC == ISD::SETEQ) { 7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MVT::ValueType VT = Op.getOperand(0).getValueType(); 773926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand Zext = Op.getOperand(0); 774926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (VT < MVT::i32) { 7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) VT = MVT::i32; 776926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Zext = DAG.getNode(ISD::ZERO_EXTEND, VT, Op.getOperand(0)); 7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned Log2b = Log2_32(MVT::getSizeInBits(VT)); 7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Clz = DAG.getNode(ISD::CTLZ, VT, Zext); 7805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Scc = DAG.getNode(ISD::SRL, VT, Clz, 781926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DAG.getConstant(Log2b, getShiftAmountTy())); 782926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return DAG.getNode(ISD::TRUNCATE, getSetCCResultTy(), Scc); 7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Leave comparisons against 0 and -1 alone for now, since they're usually 7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // optimized. FIXME: revisit this when we can custom lower all setcc 7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // optimizations. 7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (C->isAllOnesValue() || C->isNullValue()) 7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we have an integer seteq/setne, turn it into a compare against zero 7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // by subtracting the rhs from the lhs, which is faster than setting a 7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // condition register, reading it back out, and masking the correct bit. 79453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) MVT::ValueType LHSVT = Op.getOperand(0).getValueType(); 7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (MVT::isInteger(LHSVT) && (CC == ISD::SETEQ || CC == ISD::SETNE)) { 7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MVT::ValueType VT = Op.getValueType(); 797591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SDOperand Sub = DAG.getNode(ISD::SUB, LHSVT, Op.getOperand(0), 7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Op.getOperand(1)); 7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getSetCC(VT, Sub, DAG.getConstant(0, LHSVT), CC); 800926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 801926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) break; 8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::VASTART: { 8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // vastart just stores the address of the VarArgsFrameIndex slot into the 8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // memory location argument. 8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Replace MVT::i32 with PointerTy 8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); 8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, 8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Op.getOperand(1), Op.getOperand(2)); 8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::RET: { 8125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Copy; 8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch(Op.getNumOperands()) { 8155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(0 && "Do not know how to return this many arguments!"); 8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) abort(); 818926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case 1: 8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return SDOperand(); // ret void is legal 8205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 2: { 8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); 8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned ArgReg = MVT::isInteger(ArgVT) ? PPC::R3 : PPC::F1; 8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Copy = DAG.getCopyToReg(Op.getOperand(0), ArgReg, Op.getOperand(1), 8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand()); 8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 3: 8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Copy = DAG.getCopyToReg(Op.getOperand(0), PPC::R3, Op.getOperand(2), 8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand()); 8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Copy = DAG.getCopyToReg(Copy, PPC::R4, Op.getOperand(1),Copy.getValue(1)); 8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); 8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::SCALAR_TO_VECTOR: { 8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Create a stack slot that is 16-byte aligned. 8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo(); 8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int FrameIdx = FrameInfo->CreateStackObject(16, 16); 8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand FIdx = DAG.getFrameIndex(FrameIdx, MVT::i32); 8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Store the input value into Value#0 of the stack slot. 8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), 8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Op.getOperand(0), FIdx,DAG.getSrcValue(NULL)); 8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Load it out. 8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DAG.getLoad(Op.getValueType(), Store, FIdx, DAG.getSrcValue(NULL)); 8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::BUILD_VECTOR: 8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If this is a case we can't handle, return null and let the default 8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // expansion code take care of it. If we CAN select this case, return Op. 8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See if this is all zeros. 8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: We should handle splat(-0.0), and other cases here. 853e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (ISD::isBuildVectorAllZeros(Op.Val)) 854e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return Op; 855e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 856e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (PPC::isVecSplatImm(Op.Val, 1) || // vspltisb 857e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVecSplatImm(Op.Val, 2) || // vspltish 8588abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) PPC::isVecSplatImm(Op.Val, 4)) // vspltisw 859e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return Op; 860e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 861e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return SDOperand(); 862e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 863e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case ISD::VECTOR_SHUFFLE: { 864e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) SDOperand V1 = Op.getOperand(0); 865e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) SDOperand V2 = Op.getOperand(1); 866e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) SDOperand PermMask = Op.getOperand(2); 867a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 868e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // Cases that are handled by instructions that take permute immediates 86951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // (such as vsplt*) should be left as VECTOR_SHUFFLE nodes so they can be 87051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // selected by the instruction selector. 871e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (V2.getOpcode() == ISD::UNDEF) { 872e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (PPC::isSplatShuffleMask(PermMask.Val, 1) || 873e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isSplatShuffleMask(PermMask.Val, 2) || 874e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isSplatShuffleMask(PermMask.Val, 4) || 875e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1 || 876e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGLShuffleMask(PermMask.Val, 1, true) || 877e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGLShuffleMask(PermMask.Val, 2, true) || 878e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGLShuffleMask(PermMask.Val, 4, true) || 879e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGHShuffleMask(PermMask.Val, 1, true) || 880e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGHShuffleMask(PermMask.Val, 2, true) || 881e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGHShuffleMask(PermMask.Val, 4, true)) { 882e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return Op; 883e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 884e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 885e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 886e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (PPC::isVPKUWUMShuffleMask(PermMask.Val) || 887e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVPKUHUMShuffleMask(PermMask.Val) || 888e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVSLDOIShuffleMask(PermMask.Val) != -1 || 889e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGLShuffleMask(PermMask.Val, 1, false) || 890e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGLShuffleMask(PermMask.Val, 2, false) || 891e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGLShuffleMask(PermMask.Val, 4, false) || 892e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) PPC::isVMRGHShuffleMask(PermMask.Val, 1, false) || 8931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) PPC::isVMRGHShuffleMask(PermMask.Val, 2, false) || 8941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) PPC::isVMRGHShuffleMask(PermMask.Val, 4, false)) 8958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return Op; 8968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 8978abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // TODO: Handle more cases, and also handle cases that are cheaper to do as 8988abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // multiple such instructions than as a constant pool load/vperm pair. 8998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 9008abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Lower this to a VPERM(V1, V2, V3) expression, where V3 is a constant 9018abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // vector that will get spilled to the constant pool. 9028abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (V2.getOpcode() == ISD::UNDEF) V2 = V1; 903e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 9048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // The SHUFFLE_VECTOR mask is almost exactly what we want for vperm, except 905e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // that it is in input element units, not in bytes. Convert now. 9068abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) MVT::ValueType EltVT = MVT::getVectorBaseType(V1.getValueType()); 9078abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8; 9088abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 9098abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) std::vector<SDOperand> ResultMask; 9108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) { 9118abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) unsigned SrcElt =cast<ConstantSDNode>(PermMask.getOperand(i))->getValue(); 912e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 9138abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) for (unsigned j = 0; j != BytesPerElement; ++j) 9148abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j, 915a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) MVT::i8)); 916a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 917a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 918a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) SDOperand VPermMask =DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, ResultMask); 9198abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return DAG.getNode(PPCISD::VPERM, V1.getValueType(), V1, V2, VPermMask); 920e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 921a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case ISD::INTRINSIC_WO_CHAIN: { 922a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getValue(); 923e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 924e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // If this is a lowered altivec predicate compare, CompareOpc is set to the 9258abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // opcode number of the comparison. 926e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) int CompareOpc = -1; 927a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) bool isDot = false; 928a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) switch (IntNo) { 929a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) default: return SDOperand(); // Don't custom lower most intrinsics. 930a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // Comparison predicates. 931e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpbfp_p: CompareOpc = 966; isDot = 1; break; 932e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpeqfp_p: CompareOpc = 198; isDot = 1; break; 933e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpequb_p: CompareOpc = 6; isDot = 1; break; 934e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpequh_p: CompareOpc = 70; isDot = 1; break; 935e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpequw_p: CompareOpc = 134; isDot = 1; break; 936e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgefp_p: CompareOpc = 454; isDot = 1; break; 937e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtfp_p: CompareOpc = 710; isDot = 1; break; 938e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtsb_p: CompareOpc = 774; isDot = 1; break; 939e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtsh_p: CompareOpc = 838; isDot = 1; break; 940e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtsw_p: CompareOpc = 902; isDot = 1; break; 94151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtub_p: CompareOpc = 518; isDot = 1; break; 942e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtuh_p: CompareOpc = 582; isDot = 1; break; 943e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtuw_p: CompareOpc = 646; isDot = 1; break; 9448abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 9458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Normal Comparisons. 9468abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpbfp: CompareOpc = 966; isDot = 0; break; 947e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpeqfp: CompareOpc = 198; isDot = 0; break; 9488abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpequb: CompareOpc = 6; isDot = 0; break; 949e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpequh: CompareOpc = 70; isDot = 0; break; 950e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpequw: CompareOpc = 134; isDot = 0; break; 951e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgefp: CompareOpc = 454; isDot = 0; break; 952e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtfp: CompareOpc = 710; isDot = 0; break; 953e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtsb: CompareOpc = 774; isDot = 0; break; 954e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtsh: CompareOpc = 838; isDot = 0; break; 955e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtsw: CompareOpc = 902; isDot = 0; break; 956e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtub: CompareOpc = 518; isDot = 0; break; 957e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtuh: CompareOpc = 582; isDot = 0; break; 958e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtuw: CompareOpc = 646; isDot = 0; break; 9598abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) } 960e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 961e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) assert(CompareOpc>0 && "We only lower altivec predicate compares so far!"); 962e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 963e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // If this is a non-dot comparison, make the VCMP node. 964e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (!isDot) 96551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return DAG.getNode(PPCISD::VCMP, Op.getOperand(2).getValueType(), 966e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) Op.getOperand(1), Op.getOperand(2), 967e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) DAG.getConstant(CompareOpc, MVT::i32)); 968e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 969e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // Create the PPCISD altivec 'dot' comparison node. 9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::vector<SDOperand> Ops; 9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::vector<MVT::ValueType> VTs; 9727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch Ops.push_back(Op.getOperand(2)); // LHS 9737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch Ops.push_back(Op.getOperand(3)); // RHS 9747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch Ops.push_back(DAG.getConstant(CompareOpc, MVT::i32)); 9757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch VTs.push_back(Op.getOperand(2).getValueType()); 9767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch VTs.push_back(MVT::Flag); 9775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand CompNode = DAG.getNode(PPCISD::VCMPo, VTs, Ops); 9785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now that we have the comparison, emit a copy from the CR to a GPR. 980f21500f839d2ad369a2bd176fb90f26895a9a097Ben Murdoch // This is flagged to the above dot comparison. 981f21500f839d2ad369a2bd176fb90f26895a9a097Ben Murdoch SDOperand Flags = DAG.getNode(PPCISD::MFCR, MVT::i32, 982f21500f839d2ad369a2bd176fb90f26895a9a097Ben Murdoch DAG.getRegister(PPC::CR6, MVT::i32), 9838abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) CompNode.getValue(1)); 9848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 985926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Unpack the result based on how the target uses it. 986e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch unsigned BitNo; // Bit # of CR6. 987926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) bool InvertBit; // Invert result? 9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (cast<ConstantSDNode>(Op.getOperand(1))->getValue()) { 9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: // Can't happen, don't crash on invalid number though. 9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 0: // Return the value of the EQ bit of CR6. 991926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) BitNo = 0; InvertBit = false; 992926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) break; 993926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case 1: // Return the inverted value of the EQ bit of CR6. 9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BitNo = 0; InvertBit = true; 9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 2: // Return the value of the LT bit of CR6. 9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BitNo = 2; InvertBit = false; 9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 3: // Return the inverted value of the LT bit of CR6. 10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BitNo = 2; InvertBit = true; 10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1002a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 1003a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1004a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // Shift the bit into the low position. 1005a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) Flags = DAG.getNode(ISD::SRL, MVT::i32, Flags, 10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(8-(3-BitNo), MVT::i32)); 10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Isolate the bit. 10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Flags = DAG.getNode(ISD::AND, MVT::i32, Flags, 10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(1, MVT::i32)); 10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we are supposed to, toggle the bit. 10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (InvertBit) 1013e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) Flags = DAG.getNode(ISD::XOR, MVT::i32, Flags, 10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(1, MVT::i32)); 1015e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return Flags; 1016e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 1017e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 1018e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return SDOperand(); 10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1020e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 1021e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)std::vector<SDOperand> 1022e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)PPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { 1023e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // 1024e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // add beautiful description of PPC stack frame format, or at least some docs 1025e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // 1026e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) MachineFunction &MF = DAG.getMachineFunction(); 1027e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) MachineFrameInfo *MFI = MF.getFrameInfo(); 10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MachineBasicBlock& BB = MF.front(); 10298abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) SSARegMap *RegMap = MF.getSSARegMap(); 10308abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) std::vector<SDOperand> ArgValues; 10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned ArgOffset = 24; 10335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned GPR_remaining = 8; 10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned FPR_remaining = 13; 10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned GPR_idx = 0, FPR_idx = 0; 10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static const unsigned GPR[] = { 103719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) PPC::R3, PPC::R4, PPC::R5, PPC::R6, 103819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) PPC::R7, PPC::R8, PPC::R9, PPC::R10, 103919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) }; 104019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) static const unsigned FPR[] = { 104119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, 104219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 104319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) }; 104419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) 104519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) // Add DAG nodes to load the arguments... On entry to a function on PPC, 104619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) // the arguments start at offset 24, although they are likely to be passed 104719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) // in registers. 104819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { 10498abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) SDOperand newroot, argt; 10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned ObjSize; 10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool needsLoad = false; 10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool ArgLive = !I->use_empty(); 1053591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch MVT::ValueType ObjectVT = getValueType(I->getType()); 10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (ObjectVT) { 10569bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) default: assert(0 && "Unhandled argument type!"); 10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::i1: 10588abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) case MVT::i8: 10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::i16: 10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::i32: 10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ObjSize = 4; 10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!ArgLive) break; 10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 0) { 10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); 10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MF.addLiveIn(GPR[GPR_idx], VReg); 10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ObjectVT != MVT::i32) { 10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 1069591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch : ISD::AssertZext; 10707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch argt = DAG.getNode(AssertOp, MVT::i32, argt, 10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getValueType(ObjectVT)); 10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, argt); 10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needsLoad = true; 10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::i64: 10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ObjSize = 8; 10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!ArgLive) break; 10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 0) { 10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand argHi, argLo; 10835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); 10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MF.addLiveIn(GPR[GPR_idx], VReg); 10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) argHi = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we have two or more remaining argument registers, then both halves 1087bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // of the i64 can be sourced from there. Otherwise, the lower half will 10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // have to come off the stack. This can happen when an i64 is preceded 10895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // by 28 bytes of arguments. 10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 1) { 10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); 10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MF.addLiveIn(GPR[GPR_idx+1], VReg); 10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) argLo = DAG.getCopyFromReg(argHi, VReg, MVT::i32); 10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 10953c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch int FI = MFI->CreateFixedObject(4, ArgOffset+4); 10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 10973c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, 10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getSrcValue(NULL)); 10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Build the outgoing arg thingy 11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi); 11027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch newroot = argLo; 11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1104e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) needsLoad = true; 110551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::f32: 11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::f64: 1109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ObjSize = (ObjectVT == MVT::f64) ? 8 : 4; 1110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!ArgLive) { 11119bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (FPR_remaining > 0) { 11125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --FPR_remaining; 11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++FPR_idx; 1114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 1115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) break; 11161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 11171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (FPR_remaining > 0) { 11181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) unsigned VReg; 11191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (ObjectVT == MVT::f32) 1120a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) VReg = RegMap->createVirtualRegister(&PPC::F4RCRegClass); 1121a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) else 1122a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass); 1123a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) MF.addLiveIn(FPR[FPR_idx], VReg); 1124a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, ObjectVT); 1125a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) --FPR_remaining; 1126a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ++FPR_idx; 1127a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } else { 11281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) needsLoad = true; 11291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 11301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) break; 1131a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 11321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 11331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // We need to load the argument to a virtual register if we determined above 11341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // that we ran out of physical registers of the appropriate type 11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (needsLoad) { 113653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) unsigned SubregOffset = 0; 11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3; 11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ObjectVT == MVT::i16) SubregOffset = 2; 11398abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); 11407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, 114253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) DAG.getConstant(SubregOffset, MVT::i32)); 11438abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, 11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getSrcValue(NULL)); 11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Every 4 bytes of argument space consumes one of the GPRs available for 1148bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // argument passing. 11495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 0) { 1150e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1; 11515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GPR_remaining -= delta; 11527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch GPR_idx += delta; 11535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArgOffset += ObjSize; 11555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (newroot.Val) 11565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.setRoot(newroot.getValue(1)); 11575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11588abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ArgValues.push_back(argt); 11598abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) } 11608abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 1161f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // If the function takes variable number of arguments, make a frame index for 1162f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // the start of the first vararg value... for expansion of llvm.va_start. 11639bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (F.isVarArg()) { 1164f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); 1165f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); 11667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // If this function is vararg, store any remaining integer argument regs 11677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // to their spots on the stack so that they may be loaded by deferencing the 11687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // result of va_next. 11697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch std::vector<SDOperand> MemOps; 11707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) { 11717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); 11728abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) MF.addLiveIn(GPR[GPR_idx], VReg); 11738abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) SDOperand Val = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 117453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), 117553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) Val, FIN, DAG.getSrcValue(NULL)); 117651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) MemOps.push_back(Store); 117751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // Increment the address by four for the next argument to store 117851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) SDOperand PtrOff = DAG.getConstant(4, getPointerTy()); 117951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff); 118051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 118151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!MemOps.empty()) { 118251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) MemOps.push_back(DAG.getRoot()); 118351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps)); 118451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 118551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 1186a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1187a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // Finally, inform the code generator which regs we return values in. 1188a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) switch (getValueType(F.getReturnType())) { 1189a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) default: assert(0 && "Unknown type!"); 1190a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::isVoid: break; 1191a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i1: 1192a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i8: 1193a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i16: 1194a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i32: 1195a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) MF.addLiveOut(PPC::R3); 1196a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) break; 1197a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i64: 1198a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) MF.addLiveOut(PPC::R3); 1199a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) MF.addLiveOut(PPC::R4); 1200a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) break; 1201a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::f32: 1202a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::f64: 1203a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) MF.addLiveOut(PPC::F1); 1204a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) break; 120551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 1206a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1207a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return ArgValues; 1208a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 1209a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 121051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)std::pair<SDOperand, SDOperand> 1211a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)PPCTargetLowering::LowerCallTo(SDOperand Chain, 1212a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) const Type *RetTy, bool isVarArg, 121351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) unsigned CallingConv, bool isTailCall, 121451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) SDOperand Callee, ArgListTy &Args, 1215a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) SelectionDAG &DAG) { 1216a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // args_to_use will accumulate outgoing args for the PPCISD::CALL case in 1217a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // SelectExpr to use to put the arguments in the appropriate registers. 1218a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) std::vector<SDOperand> args_to_use; 1219a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1220a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // Count how many bytes are to be pushed on the stack, including the linkage 1221a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // area, and parameter passing area. 1222a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) unsigned NumBytes = 24; 1223a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1224a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (Args.empty()) { 1225a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) Chain = DAG.getCALLSEQ_START(Chain, 1226a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) DAG.getConstant(NumBytes, getPointerTy())); 1227a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } else { 1228a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) for (unsigned i = 0, e = Args.size(); i != e; ++i) { 1229a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) switch (getValueType(Args[i].second)) { 1230a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) default: assert(0 && "Unknown value type!"); 1231a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i1: 1232a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i8: 1233a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i16: 1234a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i32: 1235a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::f32: 1236a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) NumBytes += 4; 1237a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) break; 1238a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::i64: 1239a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) case MVT::f64: 124051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) NumBytes += 8; 124151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) break; 1242a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 12435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Just to be safe, we'll always reserve the full 24 bytes of linkage area 1246926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // plus 32 bytes of argument space in case any called code gets funky on us. 12475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (Required by ABI to support var arg) 12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (NumBytes < 56) NumBytes = 56; 1249926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Adjust the stack pointer for the new arguments... 12515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // These operations are automatically eliminated by the prolog/epilog pass 12525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Chain = DAG.getCALLSEQ_START(Chain, 12535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(NumBytes, getPointerTy())); 1254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Set up a copy of the stack pointer for use loading and storing any 12565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // arguments that may not fit in the registers available for argument 12575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // passing. 12585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand StackPtr = DAG.getRegister(PPC::R1, MVT::i32); 12595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1260a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // Figure out which arguments are going to go in registers, and which in 12615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // memory. Also, if this is a vararg function, floating point operations 12625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // must be stored to our stack, and loaded into integer regs as well, if 1263a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // any integer regs are available for argument passing. 1264f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) unsigned ArgOffset = 24; 1265f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) unsigned GPR_remaining = 8; 12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned FPR_remaining = 13; 1267a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 12685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::vector<SDOperand> MemOps; 12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0, e = Args.size(); i != e; ++i) { 1270591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // PtrOff will be used to store the current argument to the stack if a 12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // register cannot be found for it. 127251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); 127351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); 12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MVT::ValueType ArgVT = getValueType(Args[i].second); 12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (ArgVT) { 1277591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch default: assert(0 && "Unexpected ValueType for argument!"); 12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::i1: 12795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::i8: 128053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case MVT::i16: 1281926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Promote the integer to 32 bits. If the input type is signed use a 12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // sign extend, otherwise use a zero extend. 12835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (Args[i].second->isSigned()) 12845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); 12855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); 12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FALL THROUGH 12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::i32: 12895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 0) { 12905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) args_to_use.push_back(Args[i].first); 12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --GPR_remaining; 12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 12935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 12945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Args[i].first, PtrOff, 12955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getSrcValue(NULL))); 1296591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArgOffset += 4; 12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 12995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::i64: 13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we have one free GPR left, we can place the upper half of the i64 13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // in it, and store the other half to the stack. If we have two or more 130253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // free GPRs, then we can pass both halves of the i64 in registers. 13035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 0) { 130453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Args[i].first, DAG.getConstant(1, MVT::i32)); 13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Args[i].first, DAG.getConstant(0, MVT::i32)); 13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) args_to_use.push_back(Hi); 13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --GPR_remaining; 13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 0) { 13115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) args_to_use.push_back(Lo); 13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --GPR_remaining; 13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 13145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); 13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); 13165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Lo, PtrOff, DAG.getSrcValue(NULL))); 13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Args[i].first, PtrOff, 13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getSrcValue(NULL))); 13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArgOffset += 8; 13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::f32: 13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case MVT::f64: 13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (FPR_remaining > 0) { 13295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) args_to_use.push_back(Args[i].first); 1330f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) --FPR_remaining; 13315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isVarArg) { 13325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, 13335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Args[i].first, PtrOff, 13345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getSrcValue(NULL)); 13355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MemOps.push_back(Store); 13365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Float varargs are always shadowed in available integer registers 13375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 0) { 1338926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, 1339bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) DAG.getSrcValue(NULL)); 13401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) MemOps.push_back(Load.getValue(1)); 13415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) args_to_use.push_back(Load); 13425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --GPR_remaining; 13435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 134453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (GPR_remaining > 0 && MVT::f64 == ArgVT) { 13455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); 13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); 13475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, 13485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getSrcValue(NULL)); 13495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MemOps.push_back(Load.getValue(1)); 13505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) args_to_use.push_back(Load); 13515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --GPR_remaining; 13525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 13545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we have any FPRs remaining, we may also have GPRs remaining. 13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Args passed in FPRs consume either 1 (f32) or 2 (f64) available 13565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // GPRs. 13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 0) { 13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); 13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --GPR_remaining; 13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GPR_remaining > 0 && MVT::f64 == ArgVT) { 13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); 13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --GPR_remaining; 13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 13685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Args[i].first, PtrOff, 13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getSrcValue(NULL))); 13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArgOffset += (ArgVT == MVT::f32) ? 4 : 8; 13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!MemOps.empty()) 13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps); 13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::vector<MVT::ValueType> RetVals; 13805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MVT::ValueType RetTyVT = getValueType(RetTy); 13815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MVT::ValueType ActualRetTyVT = RetTyVT; 13825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i16) 13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ActualRetTyVT = MVT::i32; // Promote result to i32. 13845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RetTyVT == MVT::i64) { 13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RetVals.push_back(MVT::i32); 13875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RetVals.push_back(MVT::i32); 13885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (RetTyVT != MVT::isVoid) { 13895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RetVals.push_back(ActualRetTyVT); 13905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RetVals.push_back(MVT::Other); 13925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the callee is a GlobalAddress node (quite common, every direct call is) 13945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 13955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 13965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32); 13975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::vector<SDOperand> Ops; 13995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Ops.push_back(Chain); 14005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Ops.push_back(Callee); 14015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Ops.insert(Ops.end(), args_to_use.begin(), args_to_use.end()); 14025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand TheCall = DAG.getNode(PPCISD::CALL, RetVals, Ops); 14035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Chain = TheCall.getValue(TheCall.Val->getNumValues()-1); 14045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, 14055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DAG.getConstant(NumBytes, getPointerTy())); 14065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand RetVal = TheCall; 14075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the result is a small value, add a note so that we keep track of the 14095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // information about whether it is sign or zero extended. 1410926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (RetTyVT != ActualRetTyVT) { 1411926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext : ISD::AssertZext, 1412926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) MVT::i32, RetVal, DAG.getValueType(RetTyVT)); 141353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); 141453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } else if (RetTyVT == MVT::i64) { 1415926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, RetVal, RetVal.getValue(1)); 1416926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 1417926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1418926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return std::make_pair(RetVal, Chain); 14195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 142153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)MachineBasicBlock * 14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PPCTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, 14235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MachineBasicBlock *BB) { 1424926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) assert((MI->getOpcode() == PPC::SELECT_CC_Int || 14255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MI->getOpcode() == PPC::SELECT_CC_F4 || 1426f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) MI->getOpcode() == PPC::SELECT_CC_F8) && 14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "Unexpected instr type to insert"); 14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 14301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // control-flow pattern. The incoming instruction knows the destination vreg 14311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // to set, the condition code register to branch on, the true/false values to 14321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // select between, and a branch opcode to use. 14331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) const BasicBlock *LLVM_BB = BB->getBasicBlock(); 14341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ilist<MachineBasicBlock>::iterator It = BB; 14355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++It; 14365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // thisMBB: 14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ... 14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // TrueVal = ... 14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // cmpTY ccX, r1, r2 14415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // bCC copy1MBB 14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // fallthrough --> copy0MBB 14435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MachineBasicBlock *thisMBB = BB; 14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); 14455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); 14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BuildMI(BB, MI->getOperand(4).getImmedValue(), 2) 14475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB); 14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MachineFunction *F = BB->getParent(); 14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) F->getBasicBlockList().insert(It, copy0MBB); 14505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) F->getBasicBlockList().insert(It, sinkMBB); 145153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // Update machine-CFG edges by first adding all successors of the current 14525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // block to the new block which will contain the Phi node for the select. 14535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for(MachineBasicBlock::succ_iterator i = BB->succ_begin(), 14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) e = BB->succ_end(); i != e; ++i) 145553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) sinkMBB->addSuccessor(*i); 1456bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Next, remove all successors of the current block, and add the true 1457bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // and fallthrough blocks as its successors. 1458bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) while(!BB->succ_empty()) 1459bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) BB->removeSuccessor(BB->succ_begin()); 14609bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) BB->addSuccessor(copy0MBB); 14619bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) BB->addSuccessor(sinkMBB); 146253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 146353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // copy0MBB: 146453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // %FalseValue = ... 146553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // # fallthrough to sinkMBB 146653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) BB = copy0MBB; 146753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 14685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Update machine-CFG edges 1469591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch BB->addSuccessor(sinkMBB); 14705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // sinkMBB: 14725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 14739bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) // ... 14741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) BB = sinkMBB; 14759bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) BuildMI(BB, PPC::PHI, 4, MI->getOperand(0).getReg()) 14769bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB) 14779bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); 14789bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) 14799bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) delete MI; // The pseudo instruction is gone now. 14809bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) return BB; 14819bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)} 14829bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) 14839bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N, 1484bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) DAGCombinerInfo &DCI) const { 14859bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) TargetMachine &TM = getTargetMachine(); 14869bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) SelectionDAG &DAG = DCI.DAG; 14879bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) switch (N->getOpcode()) { 14889bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) default: break; 14899bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) case ISD::SINT_TO_FP: 14909bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (TM.getSubtarget<PPCSubtarget>().is64Bit()) { 14919bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (N->getOperand(0).getOpcode() == ISD::FP_TO_SINT) { 14929bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) // Turn (sint_to_fp (fp_to_sint X)) -> fctidz/fcfid without load/stores. 14935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We allow the src/dst to be either f32/f64, but the intermediate 14945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // type must be i64. 14955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (N->getOperand(0).getValueType() == MVT::i64) { 14965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Val = N->getOperand(0).getOperand(0); 14975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (Val.getValueType() == MVT::f32) { 14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val); 14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCI.AddToWorklist(Val.Val); 15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Val = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Val); 15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCI.AddToWorklist(Val.Val); 15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Val = DAG.getNode(PPCISD::FCFID, MVT::f64, Val); 15055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCI.AddToWorklist(Val.Val); 15065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (N->getValueType(0) == MVT::f32) { 15075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Val = DAG.getNode(ISD::FP_ROUND, MVT::f32, Val); 1508926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DCI.AddToWorklist(Val.Val); 1509bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Val; 15115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (N->getOperand(0).getValueType() == MVT::i32) { 15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the intermediate type is i32, we can avoid the load/store here 15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // too. 151453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 15155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 15185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::STORE: 15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Turn STORE (FP_TO_SINT F) -> STFIWX(FCTIWZ(F)). 15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (TM.getSubtarget<PPCSubtarget>().hasSTFIWX() && 15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) N->getOperand(1).getOpcode() == ISD::FP_TO_SINT && 15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) N->getOperand(1).getValueType() == MVT::i32) { 15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDOperand Val = N->getOperand(1).getOperand(0); 1524926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (Val.getValueType() == MVT::f32) { 1525bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val); 15265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCI.AddToWorklist(Val.Val); 15275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Val = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Val); 15295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCI.AddToWorklist(Val.Val); 15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Val = DAG.getNode(PPCISD::STFIWX, MVT::Other, N->getOperand(0), Val, 15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) N->getOperand(2), N->getOperand(3)); 15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCI.AddToWorklist(Val.Val); 15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Val; 15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case PPCISD::VCMP: { 15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If a VCMPo node already exists with exactly the same operands as this 15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // node, use its result instead of this node (VCMPo computes both a CR6 and 15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // a normal output). 15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!N->getOperand(0).hasOneUse() && 15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !N->getOperand(1).hasOneUse() && 15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !N->getOperand(2).hasOneUse()) { 15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Scan all of the users of the LHS, looking for VCMPo's that match. 15475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDNode *VCMPoNode = 0; 15485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SDNode *LHSN = N->getOperand(0).Val; 15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (SDNode::use_iterator UI = LHSN->use_begin(), E = LHSN->use_end(); 15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UI != E; ++UI) 15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((*UI)->getOpcode() == PPCISD::VCMPo && 15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (*UI)->getOperand(1) == N->getOperand(1) && 15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (*UI)->getOperand(2) == N->getOperand(2) && 15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (*UI)->getOperand(0) == N->getOperand(0)) { 15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) VCMPoNode = *UI; 15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If there are non-zero uses of the flag value, use the VCMPo node! 15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (VCMPoNode && !VCMPoNode->hasNUsesOfValue(0, 1)) 15625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return SDOperand(VCMPoNode, 0); 15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return SDOperand(); 15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void PPCTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, 15725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint64_t Mask, 15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint64_t &KnownZero, 15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint64_t &KnownOne, 15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned Depth) const { 15765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) KnownZero = 0; 15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) KnownOne = 0; 15785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (Op.getOpcode()) { 15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: break; 15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ISD::INTRINSIC_WO_CHAIN: { 15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (cast<ConstantSDNode>(Op.getOperand(0))->getValue()) { 15825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: break; 15835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpbfp_p: 15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpeqfp_p: 15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpequb_p: 15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpequh_p: 15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpequw_p: 15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgefp_p: 15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtfp_p: 15905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtsb_p: 1591c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtsh_p: 1592c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtsw_p: 15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtub_p: 15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtuh_p: 15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Intrinsic::ppc_altivec_vcmpgtuw_p: 15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) KnownZero = ~1U; // All bits but the low one are known to be zero. 15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// getConstraintType - Given a constraint letter, return the type of 16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// constraint it is for this target. 16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PPCTargetLowering::ConstraintType 16075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PPCTargetLowering::getConstraintType(char ConstraintLetter) const { 16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (ConstraintLetter) { 16095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: break; 16105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'b': 16115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'r': 16125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'f': 16135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'v': 1614926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case 'y': 16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return C_RegisterClass; 16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return TargetLowering::getConstraintType(ConstraintLetter); 16185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1620591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)std::vector<unsigned> PPCTargetLowering:: 16225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)getRegClassForInlineAsmConstraint(const std::string &Constraint, 16235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MVT::ValueType VT) const { 16245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (Constraint.size() == 1) { 16255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (Constraint[0]) { // GCC RS6000 Constraint Letters 162653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) default: break; // Unknown constriant letter 162753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case 'b': 162853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return make_vector<unsigned>(/*no R0*/ PPC::R1 , PPC::R2 , PPC::R3 , 1629e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch PPC::R4 , PPC::R5 , PPC::R6 , PPC::R7 , 163053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) PPC::R8 , PPC::R9 , PPC::R10, PPC::R11, 16315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R12, PPC::R13, PPC::R14, PPC::R15, 16325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R16, PPC::R17, PPC::R18, PPC::R19, 16335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R20, PPC::R21, PPC::R22, PPC::R23, 16345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R24, PPC::R25, PPC::R26, PPC::R27, 16355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R28, PPC::R29, PPC::R30, PPC::R31, 16365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0); 16375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'r': 16385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return make_vector<unsigned>(PPC::R0 , PPC::R1 , PPC::R2 , PPC::R3 , 16395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R4 , PPC::R5 , PPC::R6 , PPC::R7 , 16405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R8 , PPC::R9 , PPC::R10, PPC::R11, 16415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R12, PPC::R13, PPC::R14, PPC::R15, 16425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R16, PPC::R17, PPC::R18, PPC::R19, 16435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::R20, PPC::R21, PPC::R22, PPC::R23, 1644926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) PPC::R24, PPC::R25, PPC::R26, PPC::R27, 1645926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) PPC::R28, PPC::R29, PPC::R30, PPC::R31, 16465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0); 16475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'f': 16485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return make_vector<unsigned>(PPC::F0 , PPC::F1 , PPC::F2 , PPC::F3 , 16495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::F4 , PPC::F5 , PPC::F6 , PPC::F7 , 16505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::F8 , PPC::F9 , PPC::F10, PPC::F11, 16515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::F12, PPC::F13, PPC::F14, PPC::F15, 16525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::F16, PPC::F17, PPC::F18, PPC::F19, 16535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::F20, PPC::F21, PPC::F22, PPC::F23, 16545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::F24, PPC::F25, PPC::F26, PPC::F27, 16555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::F28, PPC::F29, PPC::F30, PPC::F31, 16565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0); 16575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'v': 16585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return make_vector<unsigned>(PPC::V0 , PPC::V1 , PPC::V2 , PPC::V3 , 16595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::V4 , PPC::V5 , PPC::V6 , PPC::V7 , 16605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::V8 , PPC::V9 , PPC::V10, PPC::V11, 16615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::V12, PPC::V13, PPC::V14, PPC::V15, 16625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::V16, PPC::V17, PPC::V18, PPC::V19, 16635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::V20, PPC::V21, PPC::V22, PPC::V23, 16645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::V24, PPC::V25, PPC::V26, PPC::V27, 16655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PPC::V28, PPC::V29, PPC::V30, PPC::V31, 1666926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 0); 1667926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) case 'y': 1668926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return make_vector<unsigned>(PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3, 1669926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7, 1670926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 0); 1671926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 16725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return std::vector<unsigned>(); 16755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} 16765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 16775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)// isOperandValidForConstraint 16785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)bool PPCTargetLowering:: 16795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)isOperandValidForConstraint(SDOperand Op, char Letter) { 16805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) switch (Letter) { 16815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) default: break; 16825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) case 'I': 16835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) case 'J': 16845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) case 'K': 16855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'L': 16865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'M': 16875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'N': 16885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'O': 16895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'P': { 16905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isa<ConstantSDNode>(Op)) return false; // Must be an immediate. 16915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned Value = cast<ConstantSDNode>(Op)->getValue(); 16925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (Letter) { 16933c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch default: assert(0 && "Unknown constraint letter!"); 16945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'I': // "I" is a signed 16-bit constant. 16955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (short)Value == (int)Value; 16965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'J': // "J" is a constant with only the high-order 16 bits nonzero. 1697bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) case 'L': // "L" is a signed 16-bit constant shifted left 16 bits. 1698bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return (short)Value == 0; 1699bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) case 'K': // "K" is a constant with only the low-order 16 bits nonzero. 1700bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return (Value >> 16) == 0; 1701bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) case 'M': // "M" is a constant that is greater than 31. 1702bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return Value > 31; 1703bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) case 'N': // "N" is a positive constant that is an exact power of two. 1704bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return (int)Value > 0 && isPowerOf2_32(Value); 1705bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) case 'O': // "O" is the constant zero. 1706bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return Value == 0; 1707bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) case 'P': // "P" is a constant whose negation is a signed 16-bit constant. 17085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (short)-Value == (int)-Value; 17095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1711e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) } 1712e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) } 1713e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) 1714e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) // Handle standard constraint letters. 1715e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) return TargetLowering::isOperandValidForConstraint(Op, Letter); 1716f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} 17175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1718e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)/// isLegalAddressImmediate - Return true if the integer value can be used 1719926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/// as the offset of the target addressing mode. 1720926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool PPCTargetLowering::isLegalAddressImmediate(int64_t V) const { 17215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // PPC allows a sign-extended 16-bit immediate field. 1722a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return (V > -(1 << 16) && V < (1 << 16)-1); 1723a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 1724a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)