PPCISelLowering.cpp revision 5b3224fe7ecafd486b75ebfa113a95783112ec3d
1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===-- PPC32ISelLowering.cpp - PPC32 DAG Lowering Implementation ---------===// 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// The LLVM Compiler Infrastructure 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// This file was developed by Chris Lattner and is distributed under 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// the University of Illinois Open Source License. See LICENSE.TXT for details. 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===// 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// This file implements the PPC32ISelLowering class. 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===// 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "PPC32ISelLowering.h" 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "PPC32TargetMachine.h" 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/CodeGen/MachineFrameInfo.h" 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/CodeGen/MachineFunction.h" 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/CodeGen/MachineInstrBuilder.h" 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/CodeGen/SelectionDAG.h" 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/Constants.h" 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/Function.h" 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing namespace llvm; 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM) 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project : TargetLowering(TM) { 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Fold away setcc operations if possible. 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setSetCCIsExpensive(); 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Set up the register classes. 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass); 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass); 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass); 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC has no intrinsics for these particular operations 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::MEMSET, MVT::Other, Expand); 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::MEMCPY, MVT::Other, Expand); 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC has an i16 but no i8 (or i1) SEXTLOAD 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC has no SREM/UREM instructions 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SREM, MVT::i32, Expand); 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::UREM, MVT::i32, Expand); 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // We don't support sin/cos/sqrt/fmod 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::FSIN , MVT::f64, Expand); 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::FCOS , MVT::f64, Expand); 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SREM , MVT::f64, Expand); 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::FSIN , MVT::f32, Expand); 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::FCOS , MVT::f32, Expand); 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SREM , MVT::f32, Expand); 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // If we're enabling GP optimizations, use hardware square root 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!TM.getSubtarget<PPCSubtarget>().isGigaProcessor()) { 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::FSQRT, MVT::f64, Expand); 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::FSQRT, MVT::f32, Expand); 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC does not have CTPOP or CTTZ 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::CTPOP, MVT::i32 , Expand); 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::CTTZ , MVT::i32 , Expand); 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC does not have Select 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SELECT, MVT::i32, Expand); 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SELECT, MVT::f32, Expand); 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SELECT, MVT::f64, Expand); 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC wants to turn select_cc of FP into fsel when possible. 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC wants to expand i64 shifts itself. 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SHL, MVT::i64, Custom); 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SRL, MVT::i64, Custom); 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SRA, MVT::i64, Custom); 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC does not have BRCOND* which requires SetCC 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::BRCOND, MVT::Other, Expand); 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC does not have FP_TO_UINT 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores. 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PowerPC does not have [U|S]INT_TO_FP 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand); 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project setSetCCResultContents(ZeroOrOneSetCCResult); 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project computeRegisterProperties(); 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/// isFloatingPointZero - Return true if this is 0.0 or -0.0. 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic bool isFloatingPointZero(SDOperand Op) { 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op)) 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if (Op.getOpcode() == ISD::EXTLOAD || Op.getOpcode() == ISD::LOAD) { 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Maybe this has already been legalized into the constant pool? 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1))) 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->get())) 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return false; 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/// LowerOperation - Provide custom lowering hooks for some operations. 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/// 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectSDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (Op.getOpcode()) { 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: assert(0 && "Wasn't expecting to be able to lower this!"); 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::FP_TO_SINT: { 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(Op.getValueType() == MVT::i32 && 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MVT::isFloatingPoint(Op.getOperand(0).getValueType())); 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0)); 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int FrameIdx = 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Op, FI, DAG.getSrcValue(0)); 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32)); 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SELECT_CC: { 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Turn FP only select_cc's into fsel instructions. 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!MVT::isFloatingPoint(Op.getOperand(0).getValueType()) || 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project !MVT::isFloatingPoint(Op.getOperand(2).getValueType())) 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Cannot handle SETEQ/SETNE. 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (CC == ISD::SETEQ || CC == ISD::SETNE) break; 140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MVT::ValueType ResVT = Op.getValueType(); 142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MVT::ValueType CmpVT = Op.getOperand(0).getValueType(); 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1); 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand TV = Op.getOperand(2), FV = Op.getOperand(3); 145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // If the RHS of the comparison is a 0.0, we don't need to do the 147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // subtraction at all. 148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (isFloatingPointZero(RHS)) 149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (CC) { 150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: assert(0 && "Invalid FSEL condition"); abort(); 151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETULT: 152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETLT: 153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project std::swap(TV, FV); // fsel is natively setge, swap operands for setlt 154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETUGE: 155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETGE: 156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV); 157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETUGT: 158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETGT: 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project std::swap(TV, FV); // fsel is natively setge, swap operands for setlt 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETULE: 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETLE: 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(PPCISD::FSEL, ResVT, 163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV); 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (CC) { 167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: assert(0 && "Invalid FSEL condition"); abort(); 168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETULT: 169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETLT: 170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(PPCISD::FSEL, ResVT, 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV, TV); 172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETUGE: 173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETGE: 174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(PPCISD::FSEL, ResVT, 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV, FV); 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETUGT: 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETGT: 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(PPCISD::FSEL, ResVT, 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV, TV); 180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETULE: 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SETLE: 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(PPCISD::FSEL, ResVT, 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV, FV); 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SHL: { 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(Op.getValueType() == MVT::i64 && 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // The generic code does a fine job expanding shift by a constant. 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (isa<ConstantSDNode>(Op.getOperand(1))) break; 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Otherwise, expand into a bunch of logical ops. Note that these ops 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // depend on the PPC behavior for oversized shift amounts. 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(0, MVT::i32)); 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(1, MVT::i32)); 199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Amt = Op.getOperand(1); 200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(32, MVT::i32), Amt); 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp2 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Amt); 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp3 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Tmp1); 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(-32U, MVT::i32)); 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp6 = DAG.getNode(ISD::SHL, MVT::i32, Lo, Tmp5); 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand OutLo = DAG.getNode(ISD::SHL, MVT::i32, Lo, Amt); 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SRL: { 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(Op.getValueType() == MVT::i64 && 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // The generic code does a fine job expanding shift by a constant. 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (isa<ConstantSDNode>(Op.getOperand(1))) break; 218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Otherwise, expand into a bunch of logical ops. Note that these ops 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // depend on the PPC behavior for oversized shift amounts. 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(0, MVT::i32)); 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(1, MVT::i32)); 225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Amt = Op.getOperand(1); 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(32, MVT::i32), Amt); 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); 231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(-32U, MVT::i32)); 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp6 = DAG.getNode(ISD::SRL, MVT::i32, Hi, Tmp5); 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand OutHi = DAG.getNode(ISD::SRL, MVT::i32, Hi, Amt); 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ISD::SRA: { 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(Op.getValueType() == MVT::i64 && 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!"); 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // The generic code does a fine job expanding shift by a constant. 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (isa<ConstantSDNode>(Op.getOperand(1))) break; 244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Otherwise, expand into a bunch of logical ops, followed by a select_cc. 246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(0, MVT::i32)); 248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), 249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(1, MVT::i32)); 250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Amt = Op.getOperand(1); 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(32, MVT::i32), Amt); 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(-32U, MVT::i32)); 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Tmp6 = DAG.getNode(ISD::SRA, MVT::i32, Hi, Tmp5); 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand OutHi = DAG.getNode(ISD::SRA, MVT::i32, Hi, Amt); 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32), 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Tmp4, Tmp6, ISD::SETLE); 263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return SDOperand(); 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstd::vector<SDOperand> 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // add beautiful description of PPC stack frame format, or at least some docs 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MachineFunction &MF = DAG.getMachineFunction(); 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MachineFrameInfo *MFI = MF.getFrameInfo(); 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MachineBasicBlock& BB = MF.front(); 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project std::vector<SDOperand> ArgValues; 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Due to the rather complicated nature of the PowerPC ABI, rather than a 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // fixed size array of physical args, for the sake of simplicity let the STL 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // handle tracking them for us. 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project std::vector<unsigned> argVR, argPR, argOp; 283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned ArgOffset = 24; 284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned GPR_remaining = 8; 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned FPR_remaining = 13; 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned GPR_idx = 0, FPR_idx = 0; 287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project static const unsigned GPR[] = { 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PPC::R3, PPC::R4, PPC::R5, PPC::R6, 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PPC::R7, PPC::R8, PPC::R9, PPC::R10, 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project }; 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project static const unsigned FPR[] = { 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project }; 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Add DAG nodes to load the arguments... On entry to a function on PPC, 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // the arguments start at offset 24, although they are likely to be passed 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // in registers. 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand newroot, argt; 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned ObjSize; 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bool needsLoad = false; 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bool ArgLive = !I->use_empty(); 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MVT::ValueType ObjectVT = getValueType(I->getType()); 305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (ObjectVT) { 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: assert(0 && "Unhandled argument type!"); 308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i1: 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i8: 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i16: 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i32: 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ObjSize = 4; 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ArgLive) break; 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0) { 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MF.addLiveIn(GPR[GPR_idx]); 316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), 317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project GPR[GPR_idx], MVT::i32); 318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ObjectVT != MVT::i32) { 319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project : ISD::AssertZext; 321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project argt = DAG.getNode(AssertOp, MVT::i32, argt, 322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getValueType(ObjectVT)); 323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, argt); 324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project needsLoad = true; 327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i64: ObjSize = 8; 330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ArgLive) break; 331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0) { 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand argHi, argLo; 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MF.addLiveIn(GPR[GPR_idx]); 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project argHi = DAG.getCopyFromReg(DAG.getRoot(), GPR[GPR_idx], MVT::i32); 335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // If we have two or more remaining argument registers, then both halves 336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // of the i64 can be sourced from there. Otherwise, the lower half will 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // have to come off the stack. This can happen when an i64 is preceded 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // by 28 bytes of arguments. 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 1) { 340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MF.addLiveIn(GPR[GPR_idx+1]); 341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project argLo = DAG.getCopyFromReg(argHi, GPR[GPR_idx+1], MVT::i32); 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int FI = MFI->CreateFixedObject(4, ArgOffset+4); 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getSrcValue(NULL)); 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Build the outgoing arg thingy 349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi); 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project newroot = argLo; 351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project needsLoad = true; 353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::f32: 356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::f64: 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ObjSize = (ObjectVT == MVT::f64) ? 8 : 4; 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!ArgLive) break; 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (FPR_remaining > 0) { 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MF.addLiveIn(FPR[FPR_idx]); 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project FPR[FPR_idx], ObjectVT); 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --FPR_remaining; 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ++FPR_idx; 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project needsLoad = true; 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // We need to load the argument to a virtual register if we determined above 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // that we ran out of physical registers of the appropriate type 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (needsLoad) { 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned SubregOffset = 0; 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3; 376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ObjectVT == MVT::i16) SubregOffset = 2; 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(SubregOffset, MVT::i32)); 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, 382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getSrcValue(NULL)); 383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Every 4 bytes of argument space consumes one of the GPRs available for 386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // argument passing. 387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0) { 388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1; 389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project GPR_remaining -= delta; 390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project GPR_idx += delta; 391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ArgOffset += ObjSize; 393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (newroot.Val) 394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.setRoot(newroot.getValue(1)); 395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ArgValues.push_back(argt); 397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // If the function takes variable number of arguments, make a frame index for 400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // the start of the first vararg value... for expansion of llvm.va_start. 401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (F.isVarArg()) { 402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); 403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); 404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // If this function is vararg, store any remaining integer argument regs 405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // to their spots on the stack so that they may be loaded by deferencing the 406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // result of va_next. 407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project std::vector<SDOperand> MemOps; 408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) { 409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MF.addLiveIn(GPR[GPR_idx]); 410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Val = DAG.getCopyFromReg(DAG.getRoot(), GPR[GPR_idx], MVT::i32); 411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), 412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Val, FIN, DAG.getSrcValue(NULL)); 413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MemOps.push_back(Store); 414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Increment the address by four for the next argument to store 415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand PtrOff = DAG.getConstant(4, getPointerTy()); 416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff); 417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps)); 419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Finally, inform the code generator which regs we return values in. 422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (getValueType(F.getReturnType())) { 423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: assert(0 && "Unknown type!"); 424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::isVoid: break; 425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i1: 426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i8: 427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i16: 428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i32: 429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MF.addLiveOut(PPC::R3); 430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i64: 432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MF.addLiveOut(PPC::R3); 433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MF.addLiveOut(PPC::R4); 434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::f32: 436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::f64: 437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MF.addLiveOut(PPC::F1); 438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ArgValues; 442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstd::pair<SDOperand, SDOperand> 445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::LowerCallTo(SDOperand Chain, 446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const Type *RetTy, bool isVarArg, 447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned CallingConv, bool isTailCall, 448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Callee, ArgListTy &Args, 449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SelectionDAG &DAG) { 450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // args_to_use will accumulate outgoing args for the ISD::CALL case in 451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // SelectExpr to use to put the arguments in the appropriate registers. 452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project std::vector<SDOperand> args_to_use; 453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Count how many bytes are to be pushed on the stack, including the linkage 455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // area, and parameter passing area. 456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned NumBytes = 24; 457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (Args.empty()) { 459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(NumBytes, getPointerTy())); 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (unsigned i = 0, e = Args.size(); i != e; ++i) { 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (getValueType(Args[i].second)) { 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: assert(0 && "Unknown value type!"); 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i1: 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i8: 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i16: 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i32: 469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::f32: 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NumBytes += 4; 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i64: 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::f64: 474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NumBytes += 8; 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Just to be safe, we'll always reserve the full 24 bytes of linkage area 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // plus 32 bytes of argument space in case any called code gets funky on us. 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // (Required by ABI to support var arg) 482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (NumBytes < 56) NumBytes = 56; 483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Adjust the stack pointer for the new arguments... 485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // These operations are automatically eliminated by the prolog/epilog pass 486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, 487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(NumBytes, getPointerTy())); 488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Set up a copy of the stack pointer for use loading and storing any 490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // arguments that may not fit in the registers available for argument 491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // passing. 492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), 493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PPC::R1, MVT::i32); 494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Figure out which arguments are going to go in registers, and which in 496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // memory. Also, if this is a vararg function, floating point operations 497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // must be stored to our stack, and loaded into integer regs as well, if 498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // any integer regs are available for argument passing. 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned ArgOffset = 24; 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned GPR_remaining = 8; 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned FPR_remaining = 13; 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project std::vector<SDOperand> MemOps; 504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (unsigned i = 0, e = Args.size(); i != e; ++i) { 505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // PtrOff will be used to store the current argument to the stack if a 506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // register cannot be found for it. 507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); 508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); 509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MVT::ValueType ArgVT = getValueType(Args[i].second); 510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (ArgVT) { 512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: assert(0 && "Unexpected ValueType for argument!"); 513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i1: 514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i8: 515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i16: 516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Promote the integer to 32 bits. If the input type is signed use a 517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // sign extend, otherwise use a zero extend. 518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (Args[i].second->isSigned()) 519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); 520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); 522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // FALL THROUGH 523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i32: 524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0) { 525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project args_to_use.push_back(Args[i].first); 526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --GPR_remaining; 527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Args[i].first, PtrOff, 530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getSrcValue(NULL))); 531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ArgOffset += 4; 533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::i64: 535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // If we have one free GPR left, we can place the upper half of the i64 536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // in it, and store the other half to the stack. If we have two or more 537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // free GPRs, then we can pass both halves of the i64 in registers. 538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0) { 539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Args[i].first, DAG.getConstant(1, MVT::i32)); 541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Args[i].first, DAG.getConstant(0, MVT::i32)); 543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project args_to_use.push_back(Hi); 544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --GPR_remaining; 545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0) { 546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project args_to_use.push_back(Lo); 547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --GPR_remaining; 548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); 550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); 551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Lo, PtrOff, DAG.getSrcValue(NULL))); 553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Args[i].first, PtrOff, 557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getSrcValue(NULL))); 558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ArgOffset += 8; 560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::f32: 562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case MVT::f64: 563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (FPR_remaining > 0) { 564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project args_to_use.push_back(Args[i].first); 565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --FPR_remaining; 566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (isVarArg) { 567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, 568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Args[i].first, PtrOff, 569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getSrcValue(NULL)); 570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MemOps.push_back(Store); 571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Float varargs are always shadowed in available integer registers 572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0) { 573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, 574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getSrcValue(NULL)); 575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MemOps.push_back(Load); 576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project args_to_use.push_back(Load); 577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --GPR_remaining; 578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0 && MVT::f64 == ArgVT) { 580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); 581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); 582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, 583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getSrcValue(NULL)); 584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MemOps.push_back(Load); 585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project args_to_use.push_back(Load); 586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --GPR_remaining; 587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // If we have any FPRs remaining, we may also have GPRs remaining. 590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Args passed in FPRs consume either 1 (f32) or 2 (f64) available 591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // GPRs. 592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0) { 593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); 594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --GPR_remaining; 595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (GPR_remaining > 0 && MVT::f64 == ArgVT) { 597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); 598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project --GPR_remaining; 599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Args[i].first, PtrOff, 604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getSrcValue(NULL))); 605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ArgOffset += (ArgVT == MVT::f32) ? 4 : 8; 607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!MemOps.empty()) 611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps); 612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project std::vector<MVT::ValueType> RetVals; 615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MVT::ValueType RetTyVT = getValueType(RetTy); 616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (RetTyVT != MVT::isVoid) 617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project RetVals.push_back(RetTyVT); 618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project RetVals.push_back(MVT::Other); 619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand TheCall = SDOperand(DAG.getCall(RetVals, 621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Chain, Callee, args_to_use), 0); 622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Chain = TheCall.getValue(RetTyVT != MVT::isVoid); 623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, 624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(NumBytes, getPointerTy())); 625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return std::make_pair(TheCall, Chain); 626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectSDOperand PPC32TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, 629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Value *VAListV, SelectionDAG &DAG) { 630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // vastart just stores the address of the VarArgsFrameIndex slot into the 631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // memory location argument. 632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); 633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, 634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getSrcValue(VAListV)); 635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstd::pair<SDOperand,SDOperand> 638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::LowerVAArg(SDOperand Chain, 639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand VAListP, Value *VAListV, 640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const Type *ArgTy, SelectionDAG &DAG) { 641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MVT::ValueType ArgVT = getValueType(ArgTy); 642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand VAList = 644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getLoad(MVT::i32, Chain, VAListP, DAG.getSrcValue(VAListV)); 645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SDOperand Result = DAG.getLoad(ArgVT, Chain, VAList, DAG.getSrcValue(NULL)); 646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned Amt; 647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ArgVT == MVT::i32 || ArgVT == MVT::f32) 648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Amt = 4; 649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else { 650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && 651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project "Other types should have been promoted for varargs!"); 652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Amt = 8; 653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project VAList = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, 655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DAG.getConstant(Amt, VAList.getValueType())); 656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, 657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project VAList, VAListP, DAG.getSrcValue(VAListV)); 658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return std::make_pair(Result, Chain); 659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstd::pair<SDOperand, SDOperand> PPC32TargetLowering:: 663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectLowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, 664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SelectionDAG &DAG) { 665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(0 && "LowerFrameReturnAddress unimplemented"); 666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project abort(); 667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectMachineBasicBlock * 670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, 671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MachineBasicBlock *BB) { 672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert((MI->getOpcode() == PPC::SELECT_CC_Int || 673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MI->getOpcode() == PPC::SELECT_CC_FP) && 674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project "Unexpected instr type to insert"); 675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // control-flow pattern. The incoming instruction knows the destination vreg 678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // to set, the condition code register to branch on, the true/false values to 679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // select between, and a branch opcode to use. 680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BasicBlock *LLVM_BB = BB->getBasicBlock(); 681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ilist<MachineBasicBlock>::iterator It = BB; 682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ++It; 683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // thisMBB: 685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // ... 686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // TrueVal = ... 687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // cmpTY ccX, r1, r2 688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // bCC copy1MBB 689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // fallthrough --> copy0MBB 690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MachineBasicBlock *thisMBB = BB; 691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); 692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); 693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BuildMI(BB, MI->getOperand(4).getImmedValue(), 2) 694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB); 695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project MachineFunction *F = BB->getParent(); 696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project F->getBasicBlockList().insert(It, copy0MBB); 697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project F->getBasicBlockList().insert(It, sinkMBB); 698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Update machine-CFG edges 699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BB->addSuccessor(copy0MBB); 700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BB->addSuccessor(sinkMBB); 701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // copy0MBB: 703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // %FalseValue = ... 704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // # fallthrough to sinkMBB 705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BB = copy0MBB; 706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Update machine-CFG edges 708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BB->addSuccessor(sinkMBB); 709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // sinkMBB: 711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // ... 713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BB = sinkMBB; 714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BuildMI(BB, PPC::PHI, 4, MI->getOperand(0).getReg()) 715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB) 716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); 717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project delete MI; // The pseudo instruction is gone now. 719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BB; 720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project