#include "SPUISelLowering.h"
#include "SPUTargetMachine.h"
#include "SPUFrameInfo.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/VectorExtras.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Intrinsics.h"
#include "llvm/CallingConv.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Intrinsics.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Target/TargetOptions.h"
-
+#include "llvm/Support/raw_ostream.h"
#include <map>
using namespace llvm;
#ifndef NDEBUG
if (retval == 0) {
- cerr << "getValueTypeMapEntry returns NULL for "
- << VT.getMVTString()
- << "\n";
- abort();
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "getValueTypeMapEntry returns NULL for "
+ << VT.getMVTString();
+ llvm_report_error(Msg.str());
}
#endif
TargetLowering::ArgListEntry Entry;
for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
MVT ArgVT = Op.getOperand(i).getValueType();
- const Type *ArgTy = ArgVT.getTypeForMVT();
+ const Type *ArgTy = ArgVT.getTypeForMVT(*DAG.getContext());
Entry.Node = Op.getOperand(i);
Entry.Ty = ArgTy;
Entry.isSExt = isSigned;
TLI.getPointerTy());
// Splice the libcall in wherever FindInputOutputChains tells us to.
- const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT();
+ const Type *RetTy =
+ Op.getNode()->getValueType(0).getTypeForMVT(*DAG.getContext());
std::pair<SDValue, SDValue> CallInfo =
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
- CallingConv::C, false, Callee, Args, DAG,
+ 0, CallingConv::C, false, Callee, Args, DAG,
Op.getDebugLoc());
return CallInfo.first;
}
SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
- : TargetLowering(TM),
- SPUTM(TM)
-{
+ : TargetLowering(TM, new TargetLoweringObjectFileELF()),
+ SPUTM(TM) {
// Fold away setcc operations if possible.
setPow2DivIsCheap();
setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
+ setTruncStoreAction(MVT::i128, MVT::i64, Expand);
+ setTruncStoreAction(MVT::i128, MVT::i32, Expand);
+ setTruncStoreAction(MVT::i128, MVT::i16, Expand);
+ setTruncStoreAction(MVT::i128, MVT::i8, Expand);
+
+ setTruncStoreAction(MVT::f64, MVT::f32, Expand);
+
// SPU constant load actions are custom lowered:
setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
// SPU has no intrinsics for these particular operations:
setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
- // SPU has no SREM/UREM instructions
- setOperationAction(ISD::SREM, MVT::i32, Expand);
- setOperationAction(ISD::UREM, MVT::i32, Expand);
- setOperationAction(ISD::SREM, MVT::i64, Expand);
- setOperationAction(ISD::UREM, MVT::i64, Expand);
+ // SPU has no division/remainder instructions
+ setOperationAction(ISD::SREM, MVT::i8, Expand);
+ setOperationAction(ISD::UREM, MVT::i8, Expand);
+ setOperationAction(ISD::SDIV, MVT::i8, Expand);
+ setOperationAction(ISD::UDIV, MVT::i8, Expand);
+ setOperationAction(ISD::SDIVREM, MVT::i8, Expand);
+ setOperationAction(ISD::UDIVREM, MVT::i8, Expand);
+ setOperationAction(ISD::SREM, MVT::i16, Expand);
+ setOperationAction(ISD::UREM, MVT::i16, Expand);
+ setOperationAction(ISD::SDIV, MVT::i16, Expand);
+ setOperationAction(ISD::UDIV, MVT::i16, Expand);
+ setOperationAction(ISD::SDIVREM, MVT::i16, Expand);
+ setOperationAction(ISD::UDIVREM, MVT::i16, Expand);
+ setOperationAction(ISD::SREM, MVT::i32, Expand);
+ setOperationAction(ISD::UREM, MVT::i32, Expand);
+ setOperationAction(ISD::SDIV, MVT::i32, Expand);
+ setOperationAction(ISD::UDIV, MVT::i32, Expand);
+ setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
+ setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
+ setOperationAction(ISD::SREM, MVT::i64, Expand);
+ setOperationAction(ISD::UREM, MVT::i64, Expand);
+ setOperationAction(ISD::SDIV, MVT::i64, Expand);
+ setOperationAction(ISD::UDIV, MVT::i64, Expand);
+ setOperationAction(ISD::SDIVREM, MVT::i64, Expand);
+ setOperationAction(ISD::UDIVREM, MVT::i64, Expand);
+ setOperationAction(ISD::SREM, MVT::i128, Expand);
+ setOperationAction(ISD::UREM, MVT::i128, Expand);
+ setOperationAction(ISD::SDIV, MVT::i128, Expand);
+ setOperationAction(ISD::UDIV, MVT::i128, Expand);
+ setOperationAction(ISD::SDIVREM, MVT::i128, Expand);
+ setOperationAction(ISD::UDIVREM, MVT::i128, Expand);
// We don't support sin/cos/sqrt/fmod
setOperationAction(ISD::FSIN , MVT::f64, Expand);
setOperationAction(ISD::CTPOP, MVT::i16, Custom);
setOperationAction(ISD::CTPOP, MVT::i32, Custom);
setOperationAction(ISD::CTPOP, MVT::i64, Custom);
+ setOperationAction(ISD::CTPOP, MVT::i128, Expand);
+ setOperationAction(ISD::CTTZ , MVT::i8, Expand);
+ setOperationAction(ISD::CTTZ , MVT::i16, Expand);
setOperationAction(ISD::CTTZ , MVT::i32, Expand);
setOperationAction(ISD::CTTZ , MVT::i64, Expand);
+ setOperationAction(ISD::CTTZ , MVT::i128, Expand);
+ setOperationAction(ISD::CTLZ , MVT::i8, Promote);
+ setOperationAction(ISD::CTLZ , MVT::i16, Promote);
setOperationAction(ISD::CTLZ , MVT::i32, Legal);
+ setOperationAction(ISD::CTLZ , MVT::i64, Expand);
+ setOperationAction(ISD::CTLZ , MVT::i128, Expand);
// SPU has a version of select that implements (a&~c)|(b&c), just like
// select ought to work:
// Custom lower i128 -> i64 truncates
setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
+ setOperationAction(ISD::FP_TO_SINT, MVT::i8, Promote);
+ setOperationAction(ISD::FP_TO_UINT, MVT::i8, Promote);
+ setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote);
+ setOperationAction(ISD::FP_TO_UINT, MVT::i16, Promote);
// SPU has a legal FP -> signed INT instruction for f32, but for f64, need
// to expand to a libcall, hence the custom lowering:
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
+ setOperationAction(ISD::FP_TO_SINT, MVT::i64, Expand);
+ setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
+ setOperationAction(ISD::FP_TO_SINT, MVT::i128, Expand);
+ setOperationAction(ISD::FP_TO_UINT, MVT::i128, Expand);
// FDIV on SPU requires custom lowering
setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
return ((i != node_names.end()) ? i->second : 0);
}
-/// getFunctionAlignment - Return the function alignment.
+/// getFunctionAlignment - Return the Log2 alignment of this function.
unsigned SPUTargetLowering::getFunctionAlignment(const Function *) const {
return 3;
}
case ISD::POST_INC:
case ISD::POST_DEC:
case ISD::LAST_INDEXED_MODE:
- cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
+ {
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
"UNINDEXED\n";
- cerr << (unsigned) LN->getAddressingMode() << "\n";
- abort();
- /*NOTREACHED*/
+ Msg << (unsigned) LN->getAddressingMode();
+ llvm_report_error(Msg.str());
+ /*NOTREACHED*/
+ }
}
return SDValue();
case ISD::POST_INC:
case ISD::POST_DEC:
case ISD::LAST_INDEXED_MODE:
- cerr << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
+ {
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "LowerLOAD: Got a LoadSDNode with an addr mode other than "
"UNINDEXED\n";
- cerr << (unsigned) SN->getAddressingMode() << "\n";
- abort();
- /*NOTREACHED*/
+ Msg << (unsigned) SN->getAddressingMode();
+ llvm_report_error(Msg.str());
+ /*NOTREACHED*/
+ }
}
return SDValue();
}
}
- assert(0 &&
- "LowerConstantPool: Relocation model other than static"
- " not supported.");
+ llvm_unreachable("LowerConstantPool: Relocation model other than static"
+ " not supported.");
return SDValue();
}
}
}
- assert(0 &&
- "LowerJumpTable: Relocation model other than static not supported.");
+ llvm_unreachable("LowerJumpTable: Relocation model other than static"
+ " not supported.");
return SDValue();
}
return DAG.getNode(SPUISD::IndirectAddr, dl, PtrVT, Hi, Lo);
}
} else {
- cerr << "LowerGlobalAddress: Relocation model other than static not "
- << "supported.\n";
- abort();
+ llvm_report_error("LowerGlobalAddress: Relocation model other than static"
+ "not supported.");
/*NOTREACHED*/
}
switch (ObjectVT.getSimpleVT()) {
default: {
- cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
- << ObjectVT.getMVTString()
- << "\n";
- abort();
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
+ << ObjectVT.getMVTString();
+ llvm_report_error(Msg.str());
}
case MVT::i8:
ArgRegClass = &SPU::R8CRegClass;
PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
switch (Arg.getValueType().getSimpleVT()) {
- default: assert(0 && "Unexpected ValueType for argument!");
+ default: llvm_unreachable("Unexpected ValueType for argument!");
case MVT::i8:
case MVT::i16:
case MVT::i32:
// If the call has results, copy the values out of the ret val registers.
switch (TheCall->getValueType(0).getSimpleVT()) {
- default: assert(0 && "Unexpected ret value!");
+ default: llvm_unreachable("Unexpected ret value!");
case MVT::Other: break;
case MVT::i32:
if (TheCall->getValueType(1) == MVT::i32) {
unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
DebugLoc dl = Op.getDebugLoc();
- CCState CCInfo(CC, isVarArg, TM, RVLocs);
+ CCState CCInfo(CC, isVarArg, TM, RVLocs, *DAG.getContext());
CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU);
// If this is the first return lowered for this function, add the regs to the
uint64_t SplatBits = APSplatBits.getZExtValue();
switch (VT.getSimpleVT()) {
- default:
- cerr << "CellSPU: Unhandled VT in LowerBUILD_VECTOR, VT = "
- << VT.getMVTString()
- << "\n";
- abort();
+ default: {
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "CellSPU: Unhandled VT in LowerBUILD_VECTOR, VT = "
+ << VT.getMVTString();
+ llvm_report_error(Msg.str());
/*NOTREACHED*/
+ }
case MVT::v4f32: {
uint32_t Value32 = uint32_t(SplatBits);
assert(SplatBitSize == 32
} else if (EltVT == MVT::i64 || EltVT == MVT::f64) {
V2EltIdx0 = 2;
} else
- assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE");
+ llvm_unreachable("Unhandled vector type in LowerVECTOR_SHUFFLE");
for (unsigned i = 0; i != MaxElts; ++i) {
if (SVN->getMaskElt(i) < 0)
// Create a constant vector:
switch (Op.getValueType().getSimpleVT()) {
- default: assert(0 && "Unexpected constant value type in "
- "LowerSCALAR_TO_VECTOR");
+ default: llvm_unreachable("Unexpected constant value type in "
+ "LowerSCALAR_TO_VECTOR");
case MVT::v16i8: n_copies = 16; VT = MVT::i8; break;
case MVT::v8i16: n_copies = 8; VT = MVT::i16; break;
case MVT::v4i32: n_copies = 4; VT = MVT::i32; break;
} else {
// Otherwise, copy the value from one register to another:
switch (Op0.getValueType().getSimpleVT()) {
- default: assert(0 && "Unexpected value type in LowerSCALAR_TO_VECTOR");
+ default: llvm_unreachable("Unexpected value type in LowerSCALAR_TO_VECTOR");
case MVT::i8:
case MVT::i16:
case MVT::i32:
// sanity checks:
if (VT == MVT::i8 && EltNo >= 16)
- assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
+ llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i8 extraction slot > 15");
else if (VT == MVT::i16 && EltNo >= 8)
- assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
+ llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i16 extraction slot > 7");
else if (VT == MVT::i32 && EltNo >= 4)
- assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
+ llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i32 extraction slot > 4");
else if (VT == MVT::i64 && EltNo >= 2)
- assert(0 && "SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
+ llvm_unreachable("SPU LowerEXTRACT_VECTOR_ELT: i64 extraction slot > 2");
if (EltNo == 0 && (VT == MVT::i32 || VT == MVT::i64)) {
// i32 and i64: Element 0 is the preferred slot
// slot 0 across the vector
MVT VecVT = N.getValueType();
if (!VecVT.isSimple() || !VecVT.isVector() || !VecVT.is128BitVector()) {
- cerr << "LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit vector type!\n";
- abort();
+ llvm_report_error("LowerEXTRACT_VECTOR_ELT: Must have a simple, 128-bit"
+ "vector type!");
}
// Make life easier by making sure the index is zero-extended to i32
switch (VT.getSimpleVT()) {
default:
- cerr << "LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector type\n";
- abort();
+ llvm_report_error("LowerEXTRACT_VECTOR_ELT(varable): Unhandled vector"
+ "type");
/*NOTREACHED*/
case MVT::i8: {
SDValue factor = DAG.getConstant(0x00000000, MVT::i32);
assert(Op.getValueType() == MVT::i8);
switch (Opc) {
default:
- assert(0 && "Unhandled i8 math operator");
+ llvm_unreachable("Unhandled i8 math operator");
/*NOTREACHED*/
break;
case ISD::ADD: {
case ISD::SETONE:
compareOp = ISD::SETNE; break;
default:
- cerr << "CellSPU ISel Select: unimplemented f64 condition\n";
- abort();
- break;
+ llvm_report_error("CellSPU ISel Select: unimplemented f64 condition");
}
SDValue result =
switch (Opc) {
default: {
+#ifndef NDEBUG
cerr << "SPUTargetLowering::LowerOperation(): need to lower this!\n";
cerr << "Op.getOpcode() = " << Opc << "\n";
cerr << "*Op.getNode():\n";
Op.getNode()->dump();
- abort();
+#endif
+ llvm_unreachable(0);
}
case ISD::LOAD:
case ISD::EXTLOAD: