#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);
}
}
+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::LowerCall(SDValue Chain, SDValue Callee,
+ const Type *RetTy,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
+ 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:
// 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
DebugLoc dl = LHS.getDebugLoc();
return DAG.getNode((isUnsigned ? SystemZISD::UCMP : SystemZISD::CMP),
- dl, MVT::Flag, LHS, RHS);
+ dl, MVT::i64, LHS, RHS);
}
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);