-//===-- PPC32ISelLowering.cpp - PPC32 DAG Lowering Implementation ---------===//
+//===-- PPCISelLowering.cpp - PPC DAG Lowering Implementation -------------===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
//
-// This file implements the PPC32ISelLowering class.
+// This file implements the PPCISelLowering class.
//
//===----------------------------------------------------------------------===//
-#include "PPC32ISelLowering.h"
-#include "PPC32TargetMachine.h"
+#include "PPCISelLowering.h"
+#include "PPCTargetMachine.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Function.h"
using namespace llvm;
-PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
+PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
: TargetLowering(TM) {
// Fold away setcc operations if possible.
setSetCCIsExpensive();
+ setPow2DivIsCheap();
// Use _setjmp/_longjmp instead of setjmp/longjmp.
setUseUnderscoreSetJmpLongJmp(true);
// Set up the register classes.
- addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass);
- addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass);
- addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass);
+ addRegisterClass(MVT::i32, PPC::GPRCRegisterClass);
+ addRegisterClass(MVT::f32, PPC::F4RCRegisterClass);
+ addRegisterClass(MVT::f64, PPC::F8RCRegisterClass);
// PowerPC has no intrinsics for these particular operations
setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
- // PowerPC wants to expand i64 shifts itself.
- setOperationAction(ISD::SHL, MVT::i64, Custom);
- setOperationAction(ISD::SRL, MVT::i64, Custom);
- setOperationAction(ISD::SRA, MVT::i64, Custom);
-
// PowerPC does not have BRCOND* which requires SetCC
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
// PowerPC does not have truncstore for i1.
setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote);
- // 64 bit PowerPC implementations have instructions to facilitate conversion
- // between i64 and fp.
if (TM.getSubtarget<PPCSubtarget>().is64Bit()) {
+ // They also have instructions for converting between i64 and fp.
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
}
+
+ if (TM.getSubtarget<PPCSubtarget>().has64BitRegs()) {
+ // 64 bit PowerPC implementations can support i64 types directly
+ addRegisterClass(MVT::i64, PPC::G8RCRegisterClass);
+ // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
+ setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
+ } else {
+ // 32 bit PowerPC wants to expand i64 shifts itself.
+ setOperationAction(ISD::SHL, MVT::i64, Custom);
+ setOperationAction(ISD::SRL, MVT::i64, Custom);
+ setOperationAction(ISD::SRA, MVT::i64, Custom);
+ }
setSetCCResultContents(ZeroOrOneSetCCResult);
/// LowerOperation - Provide custom lowering hooks for some operations.
///
-SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
+SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
default: assert(0 && "Wasn't expecting to be able to lower this!");
case ISD::FP_TO_SINT: {
assert(MVT::isFloatingPoint(Op.getOperand(0).getValueType()));
+ SDOperand Src = Op.getOperand(0);
+ if (Src.getValueType() == MVT::f32)
+ Src = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Src);
+
switch (Op.getValueType()) {
default: assert(0 && "Unhandled FP_TO_SINT type in custom expander!");
case MVT::i32:
- Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0));
+ Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Src);
break;
case MVT::i64:
- Op = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Op.getOperand(0));
+ Op = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Src);
break;
}
}
std::vector<SDOperand>
-PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
+PPCTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
//
// add beautiful description of PPC stack frame format, or at least some docs
//
ObjSize = 4;
if (!ArgLive) break;
if (GPR_remaining > 0) {
- unsigned VReg = RegMap->createVirtualRegister(&PPC32::GPRCRegClass);
+ unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
MF.addLiveIn(GPR[GPR_idx], VReg);
argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
if (ObjectVT != MVT::i32) {
if (!ArgLive) break;
if (GPR_remaining > 0) {
SDOperand argHi, argLo;
- unsigned VReg = RegMap->createVirtualRegister(&PPC32::GPRCRegClass);
+ unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
MF.addLiveIn(GPR[GPR_idx], VReg);
argHi = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
// If we have two or more remaining argument registers, then both halves
// have to come off the stack. This can happen when an i64 is preceded
// by 28 bytes of arguments.
if (GPR_remaining > 1) {
- unsigned VReg = RegMap->createVirtualRegister(&PPC32::GPRCRegClass);
+ unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
MF.addLiveIn(GPR[GPR_idx+1], VReg);
argLo = DAG.getCopyFromReg(argHi, VReg, MVT::i32);
} else {
ObjSize = (ObjectVT == MVT::f64) ? 8 : 4;
if (!ArgLive) break;
if (FPR_remaining > 0) {
- unsigned VReg = RegMap->createVirtualRegister(&PPC32::FPRCRegClass);
+ unsigned VReg;
+ if (ObjectVT == MVT::f32)
+ VReg = RegMap->createVirtualRegister(&PPC::F4RCRegClass);
+ else
+ VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass);
MF.addLiveIn(FPR[FPR_idx], VReg);
argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, ObjectVT);
--FPR_remaining;
// result of va_next.
std::vector<SDOperand> MemOps;
for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
- unsigned VReg = RegMap->createVirtualRegister(&PPC32::GPRCRegClass);
+ unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
MF.addLiveIn(GPR[GPR_idx], VReg);
SDOperand Val = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
}
std::pair<SDOperand, SDOperand>
-PPC32TargetLowering::LowerCallTo(SDOperand Chain,
- const Type *RetTy, bool isVarArg,
- unsigned CallingConv, bool isTailCall,
- SDOperand Callee, ArgListTy &Args,
- SelectionDAG &DAG) {
+PPCTargetLowering::LowerCallTo(SDOperand Chain,
+ const Type *RetTy, bool isVarArg,
+ unsigned CallingConv, bool isTailCall,
+ SDOperand Callee, ArgListTy &Args,
+ SelectionDAG &DAG) {
// args_to_use will accumulate outgoing args for the ISD::CALL case in
// SelectExpr to use to put the arguments in the appropriate registers.
std::vector<SDOperand> args_to_use;
return std::make_pair(RetVal, Chain);
}
-SDOperand PPC32TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
- Value *VAListV, SelectionDAG &DAG) {
+SDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
+ SelectionDAG &DAG) {
+ if (Op.getValueType() == MVT::i64) {
+ SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
+ DAG.getConstant(1, MVT::i32));
+ SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
+ DAG.getConstant(0, MVT::i32));
+ return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi);
+ } else {
+ return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
+ }
+}
+
+SDOperand PPCTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
+ Value *VAListV, SelectionDAG &DAG) {
// vastart just stores the address of the VarArgsFrameIndex slot into the
// memory location argument.
SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
}
std::pair<SDOperand,SDOperand>
-PPC32TargetLowering::LowerVAArg(SDOperand Chain,
- SDOperand VAListP, Value *VAListV,
- const Type *ArgTy, SelectionDAG &DAG) {
+PPCTargetLowering::LowerVAArg(SDOperand Chain,
+ SDOperand VAListP, Value *VAListV,
+ const Type *ArgTy, SelectionDAG &DAG) {
MVT::ValueType ArgVT = getValueType(ArgTy);
SDOperand VAList =
}
-std::pair<SDOperand, SDOperand> PPC32TargetLowering::
+std::pair<SDOperand, SDOperand> PPCTargetLowering::
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG) {
assert(0 && "LowerFrameReturnAddress unimplemented");
}
MachineBasicBlock *
-PPC32TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
- MachineBasicBlock *BB) {
+PPCTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
+ MachineBasicBlock *BB) {
assert((MI->getOpcode() == PPC::SELECT_CC_Int ||
- MI->getOpcode() == PPC::SELECT_CC_FP) &&
+ MI->getOpcode() == PPC::SELECT_CC_F4 ||
+ MI->getOpcode() == PPC::SELECT_CC_F8) &&
"Unexpected instr type to insert");
// To "insert" a SELECT_CC instruction, we actually have to insert the diamond