#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/VectorExtras.h"
using namespace llvm;
if (!UseSoftFloat) {
addRegisterClass(MVT::f32, SystemZ::FP32RegisterClass);
addRegisterClass(MVT::f64, SystemZ::FP64RegisterClass);
-
- addLegalFPImmediate(APFloat(+0.0)); // lzer
- addLegalFPImmediate(APFloat(+0.0f)); // lzdr
- addLegalFPImmediate(APFloat(-0.0)); // lzer + lner
- addLegalFPImmediate(APFloat(-0.0f)); // lzdr + lndr
}
// Compute derived properties from the register classes
setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
setStackPointerRegisterToSaveRestore(SystemZ::R15D);
- setSchedulingPreference(SchedulingForLatency);
+
+ // TODO: It may be better to default to latency-oriented scheduling, however
+ // LLVM's current latency-oriented scheduler can't handle physreg definitions
+ // such as SystemZ has with PSW, so set this to the register-pressure
+ // scheduler, because it can.
+ setSchedulingPreference(SchedulingForRegPressure);
+
setBooleanContents(ZeroOrOneBooleanContent);
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
- // Funny enough: we don't have 64-bit signed versions of these stuff, but have
- // unsigned.
setOperationAction(ISD::MULHS, MVT::i64, Expand);
setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
+ // FIXME: Can we support these natively?
+ setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
+ setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand);
+ setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand);
+ setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
+
// Lower some FP stuff
setOperationAction(ISD::FSIN, MVT::f32, Expand);
setOperationAction(ISD::FSIN, MVT::f64, Expand);
}
}
+bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
+ if (UseSoftFloat || (VT != MVT::f32 && VT != MVT::f64))
+ return false;
+
+ // +0.0 lzer
+ // +0.0f lzdr
+ // -0.0 lzer + lner
+ // -0.0f lzdr + lndr
+ return Imm.isZero() || Imm.isNegZero();
+}
+
//===----------------------------------------------------------------------===//
// SystemZ Inline Assembly Support
//===----------------------------------------------------------------------===//
SDValue
SystemZTargetLowering::LowerFormalArguments(SDValue Chain,
- unsigned CallConv,
+ CallingConv::ID CallConv,
bool isVarArg,
const SmallVectorImpl<ISD::InputArg>
&Ins,
SDValue
SystemZTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
- unsigned CallConv, bool isVarArg,
- bool isTailCall,
+ const Type *RetTy,
+ CallingConv::ID CallConv, bool isVarArg,
+ bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
+ // SystemZ target does not yet support tail call optimization.
+ isTailCall = false;
switch (CallConv) {
default:
// FIXME: varargs
SDValue
SystemZTargetLowering::LowerCCCArguments(SDValue Chain,
- unsigned CallConv,
+ CallingConv::ID CallConv,
bool isVarArg,
const SmallVectorImpl<ISD::InputArg>
&Ins,
switch (LocVT.getSimpleVT().SimpleTy) {
default:
#ifndef NDEBUG
- cerr << "LowerFormalArguments Unhandled argument type: "
+ errs() << "LowerFormalArguments Unhandled argument type: "
<< LocVT.getSimpleVT().SimpleTy
<< "\n";
#endif
// Create the nodes corresponding to a load from this parameter slot.
// Create the frame index object for this incoming parameter...
int FI = MFI->CreateFixedObject(LocVT.getSizeInBits()/8,
- VA.getLocMemOffset());
+ VA.getLocMemOffset(), true, false);
// Create the SelectionDAG nodes corresponding to a load
// from this parameter
/// TODO: sret.
SDValue
SystemZTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
- unsigned CallConv, bool isVarArg,
+ CallingConv::ID CallConv, bool isVarArg,
bool isTailCall,
const SmallVectorImpl<ISD::OutputArg>
&Outs,
///
SDValue
SystemZTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
- unsigned CallConv, bool isVarArg,
+ CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg>
&Ins,
DebugLoc dl, SelectionDAG &DAG,
SDValue
SystemZTargetLowering::LowerReturn(SDValue Chain,
- unsigned CallConv, bool isVarArg,
+ CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
DebugLoc dl, SelectionDAG &DAG) {
DebugLoc dl = LHS.getDebugLoc();
return DAG.getNode((isUnsigned ? SystemZISD::UCMP : SystemZISD::CMP),
- dl, MVT::Flag, LHS, RHS);
+ dl, MVT::i64, LHS, RHS);
}
MachineBasicBlock*
SystemZTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
- MachineBasicBlock *BB) const {
+ MachineBasicBlock *BB,
+ DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
const SystemZInstrInfo &TII = *TM.getInstrInfo();
DebugLoc dl = MI->getDebugLoc();
assert((MI->getOpcode() == SystemZ::Select32 ||
BuildMI(BB, dl, TII.getBrCond(CC)).addMBB(copy1MBB);
F->insert(I, copy0MBB);
F->insert(I, copy1MBB);
+ // Inform sdisel of the edge changes.
+ for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
+ SE = BB->succ_end(); SI != SE; ++SI)
+ EM->insert(std::make_pair(*SI, copy1MBB));
// Update machine-CFG edges by transferring all successors of the current
// block to the new block which will contain the Phi node for the select.
copy1MBB->transferSuccessors(BB);