PPCISelLowering.cpp revision 85fd97dc8810ac16197594304f9f985a13466d19
1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//===-- PPCISelLowering.cpp - PPC DAG Lowering Implementation -------------===// 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// The LLVM Compiler Infrastructure 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This file was developed by Chris Lattner and is distributed under 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the University of Illinois Open Source License. See LICENSE.TXT for details. 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//===----------------------------------------------------------------------===// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This file implements the PPCISelLowering class. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//===----------------------------------------------------------------------===// 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "PPCISelLowering.h" 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "PPCTargetMachine.h" 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "llvm/CodeGen/MachineFrameInfo.h" 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "llvm/CodeGen/MachineFunction.h" 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "llvm/CodeGen/MachineInstrBuilder.h" 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "llvm/CodeGen/SelectionDAG.h" 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "llvm/CodeGen/SSARegMap.h" 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "llvm/Constants.h" 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "llvm/Function.h" 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleusing namespace llvm; 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavillePPCTargetLowering::PPCTargetLowering(TargetMachine &TM) 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : TargetLowering(TM) { 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fold away setcc operations if possible. 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setSetCCIsExpensive(); 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setPow2DivIsCheap(); 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Use _setjmp/_longjmp instead of setjmp/longjmp. 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setUseUnderscoreSetJmpLongJmp(true); 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Set up the register classes. 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville addRegisterClass(MVT::i32, PPC::GPRCRegisterClass); 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville addRegisterClass(MVT::f32, PPC::F4RCRegisterClass); 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville addRegisterClass(MVT::f64, PPC::F8RCRegisterClass); 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC has no intrinsics for these particular operations 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::MEMSET, MVT::Other, Expand); 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::MEMCPY, MVT::Other, Expand); 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC has an i16 but no i8 (or i1) SEXTLOAD 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC has no SREM/UREM instructions 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SREM, MVT::i32, Expand); 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::UREM, MVT::i32, Expand); 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We don't support sin/cos/sqrt/fmod 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FSIN , MVT::f64, Expand); 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FCOS , MVT::f64, Expand); 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FREM , MVT::f64, Expand); 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FSIN , MVT::f32, Expand); 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FCOS , MVT::f32, Expand); 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FREM , MVT::f32, Expand); 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If we're enabling GP optimizations, use hardware square root 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!TM.getSubtarget<PPCSubtarget>().hasFSQRT()) { 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FSQRT, MVT::f64, Expand); 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FSQRT, MVT::f32, Expand); 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC does not have CTPOP or CTTZ 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::CTPOP, MVT::i32 , Expand); 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::CTTZ , MVT::i32 , Expand); 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC does not have Select 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SELECT, MVT::i32, Expand); 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SELECT, MVT::f32, Expand); 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SELECT, MVT::f64, Expand); 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC wants to turn select_cc of FP into fsel when possible. 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC does not have BRCOND* which requires SetCC 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::BRCOND, MVT::Other, Expand); 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores. 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC does not have [U|S]INT_TO_FP 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand); 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC does not have truncstore for i1. 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote); 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (TM.getSubtarget<PPCSubtarget>().is64Bit()) { 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // They also have instructions for converting between i64 and fp. 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PowerPC does not have FP_TO_UINT on 32 bit implementations. 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (TM.getSubtarget<PPCSubtarget>().has64BitRegs()) { 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 64 bit PowerPC implementations can support i64 types directly 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville addRegisterClass(MVT::i64, PPC::G8RCRegisterClass); 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // BUILD_PAIR can't be handled natively, and should be expanded to shl/or 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand); 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 32 bit PowerPC wants to expand i64 shifts itself. 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SHL, MVT::i64, Custom); 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SRL, MVT::i64, Custom); 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setOperationAction(ISD::SRA, MVT::i64, Custom); 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setSetCCResultContents(ZeroOrOneSetCCResult); 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville computeRegisterProperties(); 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/// isFloatingPointZero - Return true if this is 0.0 or -0.0. 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic bool isFloatingPointZero(SDOperand Op) { 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op)) 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else if (Op.getOpcode() == ISD::EXTLOAD || Op.getOpcode() == ISD::LOAD) { 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Maybe this has already been legalized into the constant pool? 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1))) 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->get())) 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/// LowerOperation - Provide custom lowering hooks for some operations. 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/// 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleSDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (Op.getOpcode()) { 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: assert(0 && "Wasn't expecting to be able to lower this!"); 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::FP_TO_SINT: { 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert(MVT::isFloatingPoint(Op.getOperand(0).getValueType())); 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Src = Op.getOperand(0); 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (Src.getValueType() == MVT::f32) 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Src = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Src); 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (Op.getValueType()) { 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: assert(0 && "Unhandled FP_TO_SINT type in custom expander!"); 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i32: 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Src); 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i64: 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Op = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Src); 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int FrameIdx = 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Op, FI, DAG.getSrcValue(0)); 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (Op.getOpcode() == PPCISD::FCTIDZ) { 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Op = DAG.getLoad(MVT::i64, ST, FI, DAG.getSrcValue(0)); 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32)); 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Op = DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Op; 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SINT_TO_FP: { 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert(MVT::i64 == Op.getOperand(0).getValueType() && 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Unhandled SINT_TO_FP type in custom expander!"); 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int FrameIdx = 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Op.getOperand(0), FI, DAG.getSrcValue(0)); 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand LD = DAG.getLoad(MVT::f64, ST, FI, DAG.getSrcValue(0)); 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand FP = DAG.getNode(PPCISD::FCFID, MVT::f64, LD); 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (MVT::f32 == Op.getValueType()) 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FP = DAG.getNode(ISD::FP_ROUND, MVT::f32, FP); 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FP; 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SELECT_CC: { 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Turn FP only select_cc's into fsel instructions. 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!MVT::isFloatingPoint(Op.getOperand(0).getValueType()) || 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville !MVT::isFloatingPoint(Op.getOperand(2).getValueType())) 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Cannot handle SETEQ/SETNE. 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (CC == ISD::SETEQ || CC == ISD::SETNE) break; 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MVT::ValueType ResVT = Op.getValueType(); 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MVT::ValueType CmpVT = Op.getOperand(0).getValueType(); 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1); 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand TV = Op.getOperand(2), FV = Op.getOperand(3); 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If the RHS of the comparison is a 0.0, we don't need to do the 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // subtraction at all. 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (isFloatingPointZero(RHS)) 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (CC) { 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: assert(0 && "Invalid FSEL condition"); abort(); 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETULT: 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETLT: 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville std::swap(TV, FV); // fsel is natively setge, swap operands for setlt 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETUGE: 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETGE: 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV); 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETUGT: 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETGT: 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville std::swap(TV, FV); // fsel is natively setge, swap operands for setlt 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETULE: 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETLE: 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(PPCISD::FSEL, ResVT, 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getNode(ISD::FNEG, MVT::f64, LHS), TV, FV); 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Cmp; 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (CC) { 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: assert(0 && "Invalid FSEL condition"); abort(); 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETULT: 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETLT: 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETUGE: 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETGE: 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV); 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETUGT: 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETGT: 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETULE: 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SETLE: 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV); 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SHL: { 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert(Op.getValueType() == MVT::i64 && 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The generic code does a fine job expanding shift by a constant. 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (isa<ConstantSDNode>(Op.getOperand(1))) break; 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Otherwise, expand into a bunch of logical ops. Note that these ops 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // depend on the PPC behavior for oversized shift amounts. 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(0, MVT::i32)); 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(1, MVT::i32)); 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Amt = Op.getOperand(1); 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(32, MVT::i32), Amt); 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp2 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Amt); 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp3 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Tmp1); 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(-32U, MVT::i32)); 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp6 = DAG.getNode(ISD::SHL, MVT::i32, Lo, Tmp5); 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand OutLo = DAG.getNode(ISD::SHL, MVT::i32, Lo, Amt); 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SRL: { 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert(Op.getValueType() == MVT::i64 && 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The generic code does a fine job expanding shift by a constant. 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (isa<ConstantSDNode>(Op.getOperand(1))) break; 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Otherwise, expand into a bunch of logical ops. Note that these ops 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // depend on the PPC behavior for oversized shift amounts. 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(0, MVT::i32)); 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(1, MVT::i32)); 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Amt = Op.getOperand(1); 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(32, MVT::i32), Amt); 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(-32U, MVT::i32)); 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp6 = DAG.getNode(ISD::SRL, MVT::i32, Hi, Tmp5); 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand OutHi = DAG.getNode(ISD::SRL, MVT::i32, Hi, Amt); 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ISD::SRA: { 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert(Op.getValueType() == MVT::i64 && 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!"); 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The generic code does a fine job expanding shift by a constant. 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (isa<ConstantSDNode>(Op.getOperand(1))) break; 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Otherwise, expand into a bunch of logical ops, followed by a select_cc. 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(0, MVT::i32)); 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(1, MVT::i32)); 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Amt = Op.getOperand(1); 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(32, MVT::i32), Amt); 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); 322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); 323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(-32U, MVT::i32)); 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Tmp6 = DAG.getNode(ISD::SRA, MVT::i32, Hi, Tmp5); 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand OutHi = DAG.getNode(ISD::SRA, MVT::i32, Hi, Amt); 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32), 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Tmp4, Tmp6, ISD::SETLE); 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SDOperand(); 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestd::vector<SDOperand> 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavillePPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // add beautiful description of PPC stack frame format, or at least some docs 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MachineFunction &MF = DAG.getMachineFunction(); 341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MachineFrameInfo *MFI = MF.getFrameInfo(); 342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MachineBasicBlock& BB = MF.front(); 343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SSARegMap *RegMap = MF.getSSARegMap(); 344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville std::vector<SDOperand> ArgValues; 345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned ArgOffset = 24; 347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned GPR_remaining = 8; 348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned FPR_remaining = 13; 349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned GPR_idx = 0, FPR_idx = 0; 350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const unsigned GPR[] = { 351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PPC::R3, PPC::R4, PPC::R5, PPC::R6, 352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PPC::R7, PPC::R8, PPC::R9, PPC::R10, 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville }; 354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const unsigned FPR[] = { 355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, 356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville }; 358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Add DAG nodes to load the arguments... On entry to a function on PPC, 360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the arguments start at offset 24, although they are likely to be passed 361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // in registers. 362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand newroot, argt; 364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned ObjSize; 365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool needsLoad = false; 366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ArgLive = !I->use_empty(); 367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MVT::ValueType ObjectVT = getValueType(I->getType()); 368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (ObjectVT) { 370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: assert(0 && "Unhandled argument type!"); 371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i1: 372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i8: 373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i16: 374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i32: 375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ObjSize = 4; 376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!ArgLive) break; 377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0) { 378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); 379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MF.addLiveIn(GPR[GPR_idx], VReg); 380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (ObjectVT != MVT::i32) { 382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : ISD::AssertZext; 384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argt = DAG.getNode(AssertOp, MVT::i32, argt, 385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getValueType(ObjectVT)); 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, argt); 387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville needsLoad = true; 390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i64: ObjSize = 8; 393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!ArgLive) break; 394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0) { 395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand argHi, argLo; 396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); 397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MF.addLiveIn(GPR[GPR_idx], VReg); 398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argHi = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If we have two or more remaining argument registers, then both halves 400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // of the i64 can be sourced from there. Otherwise, the lower half will 401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // have to come off the stack. This can happen when an i64 is preceded 402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // by 28 bytes of arguments. 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 1) { 404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); 405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MF.addLiveIn(GPR[GPR_idx+1], VReg); 406d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville argLo = DAG.getCopyFromReg(argHi, VReg, MVT::i32); 407d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int FI = MFI->CreateFixedObject(4, ArgOffset+4); 409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, 411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getSrcValue(NULL)); 412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Build the outgoing arg thingy 414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi); 415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville newroot = argLo; 416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville needsLoad = true; 418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::f32: 421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::f64: 422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ObjSize = (ObjectVT == MVT::f64) ? 8 : 4; 423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!ArgLive) break; 424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (FPR_remaining > 0) { 425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned VReg; 426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (ObjectVT == MVT::f32) 427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VReg = RegMap->createVirtualRegister(&PPC::F4RCRegClass); 428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else 429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass); 430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MF.addLiveIn(FPR[FPR_idx], VReg); 431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, ObjectVT); 432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --FPR_remaining; 433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++FPR_idx; 434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville needsLoad = true; 436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We need to load the argument to a virtual register if we determined above 441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // that we ran out of physical registers of the appropriate type 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (needsLoad) { 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned SubregOffset = 0; 444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3; 445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (ObjectVT == MVT::i16) SubregOffset = 2; 446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); 447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, 449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(SubregOffset, MVT::i32)); 450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, 451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getSrcValue(NULL)); 452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Every 4 bytes of argument space consumes one of the GPRs available for 455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // argument passing. 456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0) { 457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1; 458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GPR_remaining -= delta; 459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GPR_idx += delta; 460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArgOffset += ObjSize; 462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (newroot.Val) 463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.setRoot(newroot.getValue(1)); 464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArgValues.push_back(argt); 466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If the function takes variable number of arguments, make a frame index for 469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the start of the first vararg value... for expansion of llvm.va_start. 470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (F.isVarArg()) { 471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); 472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); 473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If this function is vararg, store any remaining integer argument regs 474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // to their spots on the stack so that they may be loaded by deferencing the 475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // result of va_next. 476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville std::vector<SDOperand> MemOps; 477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) { 478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); 479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MF.addLiveIn(GPR[GPR_idx], VReg); 480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Val = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), 482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Val, FIN, DAG.getSrcValue(NULL)); 483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MemOps.push_back(Store); 484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Increment the address by four for the next argument to store 485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand PtrOff = DAG.getConstant(4, getPointerTy()); 486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff); 487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps)); 489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Finally, inform the code generator which regs we return values in. 492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (getValueType(F.getReturnType())) { 493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: assert(0 && "Unknown type!"); 494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::isVoid: break; 495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i1: 496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i8: 497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i16: 498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i32: 499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MF.addLiveOut(PPC::R3); 500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i64: 502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MF.addLiveOut(PPC::R3); 503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MF.addLiveOut(PPC::R4); 504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::f32: 506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::f64: 507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MF.addLiveOut(PPC::F1); 508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return ArgValues; 512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestd::pair<SDOperand, SDOperand> 515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavillePPCTargetLowering::LowerCallTo(SDOperand Chain, 516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Type *RetTy, bool isVarArg, 517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned CallingConv, bool isTailCall, 518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Callee, ArgListTy &Args, 519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SelectionDAG &DAG) { 520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // args_to_use will accumulate outgoing args for the ISD::CALL case in 521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // SelectExpr to use to put the arguments in the appropriate registers. 522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville std::vector<SDOperand> args_to_use; 523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 524d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Count how many bytes are to be pushed on the stack, including the linkage 525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // area, and parameter passing area. 526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned NumBytes = 24; 527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (Args.empty()) { 529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, 530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(NumBytes, getPointerTy())); 531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (unsigned i = 0, e = Args.size(); i != e; ++i) { 533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (getValueType(Args[i].second)) { 534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: assert(0 && "Unknown value type!"); 535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i1: 536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i8: 537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i16: 538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i32: 539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::f32: 540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville NumBytes += 4; 541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i64: 543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::f64: 544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville NumBytes += 8; 545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Just to be safe, we'll always reserve the full 24 bytes of linkage area 550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // plus 32 bytes of argument space in case any called code gets funky on us. 551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // (Required by ABI to support var arg) 552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (NumBytes < 56) NumBytes = 56; 553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Adjust the stack pointer for the new arguments... 555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // These operations are automatically eliminated by the prolog/epilog pass 556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, 557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(NumBytes, getPointerTy())); 558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Set up a copy of the stack pointer for use loading and storing any 560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // arguments that may not fit in the registers available for argument 561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // passing. 562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), 563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PPC::R1, MVT::i32); 564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Figure out which arguments are going to go in registers, and which in 566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // memory. Also, if this is a vararg function, floating point operations 567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // must be stored to our stack, and loaded into integer regs as well, if 568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // any integer regs are available for argument passing. 569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned ArgOffset = 24; 570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned GPR_remaining = 8; 571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned FPR_remaining = 13; 572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville std::vector<SDOperand> MemOps; 574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (unsigned i = 0, e = Args.size(); i != e; ++i) { 575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PtrOff will be used to store the current argument to the stack if a 576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // register cannot be found for it. 577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); 578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); 579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MVT::ValueType ArgVT = getValueType(Args[i].second); 580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (ArgVT) { 582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: assert(0 && "Unexpected ValueType for argument!"); 583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i1: 584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i8: 585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i16: 586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Promote the integer to 32 bits. If the input type is signed use a 587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // sign extend, otherwise use a zero extend. 588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (Args[i].second->isSigned()) 589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); 590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else 591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); 592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // FALL THROUGH 593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i32: 594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0) { 595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args_to_use.push_back(Args[i].first); 596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --GPR_remaining; 597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args[i].first, PtrOff, 600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getSrcValue(NULL))); 601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArgOffset += 4; 603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::i64: 605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If we have one free GPR left, we can place the upper half of the i64 606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // in it, and store the other half to the stack. If we have two or more 607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // free GPRs, then we can pass both halves of the i64 in registers. 608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0) { 609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args[i].first, DAG.getConstant(1, MVT::i32)); 611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args[i].first, DAG.getConstant(0, MVT::i32)); 613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args_to_use.push_back(Hi); 614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --GPR_remaining; 615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0) { 616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args_to_use.push_back(Lo); 617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --GPR_remaining; 618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); 620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); 621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Lo, PtrOff, DAG.getSrcValue(NULL))); 623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args[i].first, PtrOff, 627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getSrcValue(NULL))); 628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArgOffset += 8; 630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::f32: 632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MVT::f64: 633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (FPR_remaining > 0) { 634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args_to_use.push_back(Args[i].first); 635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --FPR_remaining; 636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (isVarArg) { 637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, 638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args[i].first, PtrOff, 639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getSrcValue(NULL)); 640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MemOps.push_back(Store); 641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Float varargs are always shadowed in available integer registers 642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0) { 643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, 644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getSrcValue(NULL)); 645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MemOps.push_back(Load); 646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args_to_use.push_back(Load); 647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --GPR_remaining; 648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0 && MVT::f64 == ArgVT) { 650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); 651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); 652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, 653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getSrcValue(NULL)); 654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MemOps.push_back(Load); 655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args_to_use.push_back(Load); 656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --GPR_remaining; 657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If we have any FPRs remaining, we may also have GPRs remaining. 660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Args passed in FPRs consume either 1 (f32) or 2 (f64) available 661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // GPRs. 662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0) { 663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); 664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --GPR_remaining; 665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GPR_remaining > 0 && MVT::f64 == ArgVT) { 667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); 668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --GPR_remaining; 669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args[i].first, PtrOff, 674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getSrcValue(NULL))); 675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArgOffset += (ArgVT == MVT::f32) ? 4 : 8; 677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!MemOps.empty()) 681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps); 682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville std::vector<MVT::ValueType> RetVals; 685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MVT::ValueType RetTyVT = getValueType(RetTy); 686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MVT::ValueType ActualRetTyVT = RetTyVT; 687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i16) 688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ActualRetTyVT = MVT::i32; // Promote result to i32. 689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (RetTyVT != MVT::isVoid) 691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RetVals.push_back(ActualRetTyVT); 692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RetVals.push_back(MVT::Other); 693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand TheCall = SDOperand(DAG.getCall(RetVals, 695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Chain, Callee, args_to_use), 0); 696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Chain = TheCall.getValue(RetTyVT != MVT::isVoid); 697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, 698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(NumBytes, getPointerTy())); 699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand RetVal = TheCall; 700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If the result is a small value, add a note so that we keep track of the 702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // information about whether it is sign or zero extended. 703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (RetTyVT != ActualRetTyVT) { 704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext : ISD::AssertZext, 705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MVT::i32, RetVal, DAG.getValueType(RetTyVT)); 706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); 707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return std::make_pair(RetVal, Chain); 710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleSDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, 713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SelectionDAG &DAG) { 714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (Op.getValueType() == MVT::i64) { 715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(1, MVT::i32)); 717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DAG.getConstant(0, MVT::i32)); 719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi); 720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); 722 } 723} 724 725SDOperand PPCTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, 726 Value *VAListV, SelectionDAG &DAG) { 727 // vastart just stores the address of the VarArgsFrameIndex slot into the 728 // memory location argument. 729 SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); 730 return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, 731 DAG.getSrcValue(VAListV)); 732} 733 734std::pair<SDOperand,SDOperand> 735PPCTargetLowering::LowerVAArg(SDOperand Chain, 736 SDOperand VAListP, Value *VAListV, 737 const Type *ArgTy, SelectionDAG &DAG) { 738 MVT::ValueType ArgVT = getValueType(ArgTy); 739 740 SDOperand VAList = 741 DAG.getLoad(MVT::i32, Chain, VAListP, DAG.getSrcValue(VAListV)); 742 SDOperand Result = DAG.getLoad(ArgVT, Chain, VAList, DAG.getSrcValue(NULL)); 743 unsigned Amt; 744 if (ArgVT == MVT::i32 || ArgVT == MVT::f32) 745 Amt = 4; 746 else { 747 assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && 748 "Other types should have been promoted for varargs!"); 749 Amt = 8; 750 } 751 VAList = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, 752 DAG.getConstant(Amt, VAList.getValueType())); 753 Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, 754 VAList, VAListP, DAG.getSrcValue(VAListV)); 755 return std::make_pair(Result, Chain); 756} 757 758 759std::pair<SDOperand, SDOperand> PPCTargetLowering:: 760LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, 761 SelectionDAG &DAG) { 762 assert(0 && "LowerFrameReturnAddress unimplemented"); 763 abort(); 764} 765 766MachineBasicBlock * 767PPCTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, 768 MachineBasicBlock *BB) { 769 assert((MI->getOpcode() == PPC::SELECT_CC_Int || 770 MI->getOpcode() == PPC::SELECT_CC_F4 || 771 MI->getOpcode() == PPC::SELECT_CC_F8) && 772 "Unexpected instr type to insert"); 773 774 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 775 // control-flow pattern. The incoming instruction knows the destination vreg 776 // to set, the condition code register to branch on, the true/false values to 777 // select between, and a branch opcode to use. 778 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 779 ilist<MachineBasicBlock>::iterator It = BB; 780 ++It; 781 782 // thisMBB: 783 // ... 784 // TrueVal = ... 785 // cmpTY ccX, r1, r2 786 // bCC copy1MBB 787 // fallthrough --> copy0MBB 788 MachineBasicBlock *thisMBB = BB; 789 MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); 790 MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); 791 BuildMI(BB, MI->getOperand(4).getImmedValue(), 2) 792 .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB); 793 MachineFunction *F = BB->getParent(); 794 F->getBasicBlockList().insert(It, copy0MBB); 795 F->getBasicBlockList().insert(It, sinkMBB); 796 // Update machine-CFG edges 797 BB->addSuccessor(copy0MBB); 798 BB->addSuccessor(sinkMBB); 799 800 // copy0MBB: 801 // %FalseValue = ... 802 // # fallthrough to sinkMBB 803 BB = copy0MBB; 804 805 // Update machine-CFG edges 806 BB->addSuccessor(sinkMBB); 807 808 // sinkMBB: 809 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 810 // ... 811 BB = sinkMBB; 812 BuildMI(BB, PPC::PHI, 4, MI->getOperand(0).getReg()) 813 .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB) 814 .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); 815 816 delete MI; // The pseudo instruction is gone now. 817 return BB; 818} 819 820