#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Intrinsics.h"
-#include "llvm/ParameterAttributes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
// PowerPC does not have ROTR
setOperationAction(ISD::ROTR, MVT::i32 , Expand);
+ setOperationAction(ISD::ROTR, MVT::i64 , Expand);
// PowerPC does not have Select
setOperationAction(ISD::SELECT, MVT::i32, Expand);
// TRAP is legal.
setOperationAction(ISD::TRAP, MVT::Other, Legal);
-
+
+ // TRAMPOLINE is custom lowered.
+ setOperationAction(ISD::TRAMPOLINE, MVT::Other, Custom);
+
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
setOperationAction(ISD::VASTART , MVT::Other, Custom);
setLibcallName(RTLIB::REM_PPCF128, "fmodl$LDBL128");
setLibcallName(RTLIB::SIN_PPCF128, "sinl$LDBL128");
setLibcallName(RTLIB::SQRT_PPCF128, "sqrtl$LDBL128");
+ setLibcallName(RTLIB::LOG_PPCF128, "logl$LDBL128");
+ setLibcallName(RTLIB::LOG2_PPCF128, "log2l$LDBL128");
+ setLibcallName(RTLIB::LOG10_PPCF128, "log10l$LDBL128");
+ setLibcallName(RTLIB::EXP_PPCF128, "expl$LDBL128");
+ setLibcallName(RTLIB::EXP2_PPCF128, "exp2l$LDBL128");
}
computeRegisterProperties();
static bool isFloatingPointZero(SDValue Op) {
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op))
return CFP->getValueAPF().isZero();
- else if (ISD::isEXTLoad(Op.Val) || ISD::isNON_EXTLoad(Op.Val)) {
+ else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) {
// Maybe this has already been legalized into the constant pool?
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1)))
if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
/// true if Op is undef or if it matches the specified value.
static bool isConstantOrUndef(SDValue Op, unsigned Val) {
return Op.getOpcode() == ISD::UNDEF ||
- cast<ConstantSDNode>(Op)->getValue() == Val;
+ cast<ConstantSDNode>(Op)->getZExtValue() == Val;
}
/// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a
// Otherwise, check to see if the rest of the elements are consequtively
// numbered from this value.
- unsigned ShiftAmt = cast<ConstantSDNode>(N->getOperand(i))->getValue();
+ unsigned ShiftAmt = cast<ConstantSDNode>(N->getOperand(i))->getZExtValue();
if (ShiftAmt < i) return -1;
ShiftAmt -= i;
unsigned ElementBase = 0;
SDValue Elt = N->getOperand(0);
if (ConstantSDNode *EltV = dyn_cast<ConstantSDNode>(Elt))
- ElementBase = EltV->getValue();
+ ElementBase = EltV->getZExtValue();
else
return false; // FIXME: Handle UNDEF elements too!
- if (cast<ConstantSDNode>(Elt)->getValue() >= 16)
+ if (cast<ConstantSDNode>(Elt)->getZExtValue() >= 16)
return false;
// Check that they are consequtive.
for (unsigned i = 1; i != EltSize; ++i) {
if (!isa<ConstantSDNode>(N->getOperand(i)) ||
- cast<ConstantSDNode>(N->getOperand(i))->getValue() != i+ElementBase)
+ cast<ConstantSDNode>(N->getOperand(i))->getZExtValue() != i+ElementBase)
return false;
}
/// specified isSplatShuffleMask VECTOR_SHUFFLE mask.
unsigned PPC::getVSPLTImmediate(SDNode *N, unsigned EltSize) {
assert(isSplatShuffleMask(N, EltSize));
- return cast<ConstantSDNode>(N->getOperand(0))->getValue() / EltSize;
+ return cast<ConstantSDNode>(N->getOperand(0))->getZExtValue() / EltSize;
}
/// get_VSPLTI_elt - If this is a build_vector of constants which can be formed
if (!isa<ConstantSDNode>(N->getOperand(i))) return SDValue();
- if (UniquedVals[i&(Multiple-1)].Val == 0)
+ if (UniquedVals[i&(Multiple-1)].getNode() == 0)
UniquedVals[i&(Multiple-1)] = N->getOperand(i);
else if (UniquedVals[i&(Multiple-1)] != N->getOperand(i))
return SDValue(); // no match.
bool LeadingZero = true;
bool LeadingOnes = true;
for (unsigned i = 0; i != Multiple-1; ++i) {
- if (UniquedVals[i].Val == 0) continue; // Must have been undefs.
+ if (UniquedVals[i].getNode() == 0) continue; // Must have been undefs.
LeadingZero &= cast<ConstantSDNode>(UniquedVals[i])->isNullValue();
LeadingOnes &= cast<ConstantSDNode>(UniquedVals[i])->isAllOnesValue();
}
// Finally, check the least significant entry.
if (LeadingZero) {
- if (UniquedVals[Multiple-1].Val == 0)
+ if (UniquedVals[Multiple-1].getNode() == 0)
return DAG.getTargetConstant(0, MVT::i32); // 0,0,0,undef
- int Val = cast<ConstantSDNode>(UniquedVals[Multiple-1])->getValue();
+ int Val = cast<ConstantSDNode>(UniquedVals[Multiple-1])->getZExtValue();
if (Val < 16)
return DAG.getTargetConstant(Val, MVT::i32); // 0,0,0,4 -> vspltisw(4)
}
if (LeadingOnes) {
- if (UniquedVals[Multiple-1].Val == 0)
+ if (UniquedVals[Multiple-1].getNode() == 0)
return DAG.getTargetConstant(~0U, MVT::i32); // -1,-1,-1,undef
int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSignExtended();
if (Val >= -16) // -1,-1,-1,-2 -> vspltisw(-2)
// Check to see if this buildvec has a single non-undef value in its elements.
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
- if (OpVal.Val == 0)
+ if (OpVal.getNode() == 0)
OpVal = N->getOperand(i);
else if (OpVal != N->getOperand(i))
return SDValue();
}
- if (OpVal.Val == 0) return SDValue(); // All UNDEF: use implicit def.
+ if (OpVal.getNode() == 0) return SDValue(); // All UNDEF: use implicit def.
unsigned ValSizeInBytes = 0;
uint64_t Value = 0;
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
- Value = CN->getValue();
+ Value = CN->getZExtValue();
ValSizeInBytes = CN->getValueType(0).getSizeInBits()/8;
} else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
assert(CN->getValueType(0) == MVT::f32 && "Only one legal FP vector type!");
if (N->getOpcode() != ISD::Constant)
return false;
- Imm = (short)cast<ConstantSDNode>(N)->getValue();
+ Imm = (short)cast<ConstantSDNode>(N)->getZExtValue();
if (N->getValueType(0) == MVT::i32)
- return Imm == (int32_t)cast<ConstantSDNode>(N)->getValue();
+ return Imm == (int32_t)cast<ConstantSDNode>(N)->getZExtValue();
else
- return Imm == (int64_t)cast<ConstantSDNode>(N)->getValue();
+ return Imm == (int64_t)cast<ConstantSDNode>(N)->getZExtValue();
}
static bool isIntS16Immediate(SDValue Op, short &Imm) {
- return isIntS16Immediate(Op.Val, Imm);
+ return isIntS16Immediate(Op.getNode(), Imm);
}
return true; // [r+i]
} else if (N.getOperand(1).getOpcode() == PPCISD::Lo) {
// Match LOAD (ADD (X, Lo(G))).
- assert(!cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->getValue()
+ assert(!cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->getZExtValue()
&& "Cannot handle constant offsets yet!");
Disp = N.getOperand(1).getOperand(0); // The global address.
assert(Disp.getOpcode() == ISD::TargetGlobalAddress ||
// Handle 32-bit sext immediates with LIS + addr mode.
if (CN->getValueType(0) == MVT::i32 ||
- (int64_t)CN->getValue() == (int)CN->getValue()) {
- int Addr = (int)CN->getValue();
+ (int64_t)CN->getZExtValue() == (int)CN->getZExtValue()) {
+ int Addr = (int)CN->getZExtValue();
// Otherwise, break this down into an LIS + disp.
Disp = DAG.getTargetConstant((short)Addr, MVT::i32);
return true; // [r+i]
} else if (N.getOperand(1).getOpcode() == PPCISD::Lo) {
// Match LOAD (ADD (X, Lo(G))).
- assert(!cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->getValue()
+ assert(!cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->getZExtValue()
&& "Cannot handle constant offsets yet!");
Disp = N.getOperand(1).getOperand(0); // The global address.
assert(Disp.getOpcode() == ISD::TargetGlobalAddress ||
}
} else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
// Loading from a constant address. Verify low two bits are clear.
- if ((CN->getValue() & 3) == 0) {
+ if ((CN->getZExtValue() & 3) == 0) {
// If this address fits entirely in a 14-bit sext immediate field, codegen
// this as "d, 0"
short Imm;
// Fold the low-part of 32-bit absolute addresses into addr mode.
if (CN->getValueType(0) == MVT::i32 ||
- (int64_t)CN->getValue() == (int)CN->getValue()) {
- int Addr = (int)CN->getValue();
+ (int64_t)CN->getZExtValue() == (int)CN->getZExtValue()) {
+ int Addr = (int)CN->getZExtValue();
// Otherwise, break this down into an LIS + disp.
Disp = DAG.getTargetConstant((short)Addr >> 2, MVT::i32);
return SDValue(); // Not reached
}
+SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) {
+ SDValue Chain = Op.getOperand(0);
+ SDValue Trmp = Op.getOperand(1); // trampoline
+ SDValue FPtr = Op.getOperand(2); // nested function
+ SDValue Nest = Op.getOperand(3); // 'nest' parameter value
+
+ MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+ bool isPPC64 = (PtrVT == MVT::i64);
+ const Type *IntPtrTy =
+ DAG.getTargetLoweringInfo().getTargetData()->getIntPtrType();
+
+ TargetLowering::ArgListTy Args;
+ TargetLowering::ArgListEntry Entry;
+
+ Entry.Ty = IntPtrTy;
+ Entry.Node = Trmp; Args.push_back(Entry);
+
+ // TrampSize == (isPPC64 ? 48 : 40);
+ Entry.Node = DAG.getConstant(isPPC64 ? 48 : 40,
+ isPPC64 ? MVT::i64 : MVT::i32);
+ Args.push_back(Entry);
+
+ Entry.Node = FPtr; Args.push_back(Entry);
+ Entry.Node = Nest; Args.push_back(Entry);
+
+ // Lower to a call to __trampoline_setup(Trmp, TrampSize, FPtr, ctx_reg)
+ std::pair<SDValue, SDValue> CallResult =
+ LowerCallTo(Chain, Op.getValueType().getTypeForMVT(), false, false,
+ false, CallingConv::C, false,
+ DAG.getExternalSymbol("__trampoline_setup", PtrVT),
+ Args, DAG);
+
+ SDValue Ops[] =
+ { CallResult.first, CallResult.second };
+
+ return DAG.getMergeValues(Ops, 2, false);
+}
+
SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG,
- int VarArgsFrameIndex,
- int VarArgsStackOffset,
- unsigned VarArgsNumGPR,
- unsigned VarArgsNumFPR,
- const PPCSubtarget &Subtarget) {
+ int VarArgsFrameIndex,
+ int VarArgsStackOffset,
+ unsigned VarArgsNumGPR,
+ unsigned VarArgsNumFPR,
+ const PPCSubtarget &Subtarget) {
if (Subtarget.isMachoABI()) {
// vastart just stores the address of the VarArgsFrameIndex slot into the
/// CalculateStackSlotSize - Calculates the size reserved for this argument on
/// the stack.
-static unsigned CalculateStackSlotSize(SDValue Arg, SDValue Flag,
+static unsigned CalculateStackSlotSize(SDValue Arg, ISD::ArgFlagsTy Flags,
bool isVarArg, unsigned PtrByteSize) {
MVT ArgVT = Arg.getValueType();
- ISD::ArgFlagsTy Flags = cast<ARG_FLAGSSDNode>(Flag)->getArgFlags();
unsigned ArgSize =ArgVT.getSizeInBits()/8;
if (Flags.isByVal())
ArgSize = Flags.getByValSize();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
SmallVector<SDValue, 8> ArgValues;
SDValue Root = Op.getOperand(0);
- bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
+ bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
bool isPPC64 = PtrVT == MVT::i64;
// to handle Elf here.
unsigned VecArgOffset = ArgOffset;
if (!isVarArg && !isPPC64) {
- for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e;
+ for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues()-1; ArgNo != e;
++ArgNo) {
MVT ObjectVT = Op.getValue(ArgNo).getValueType();
unsigned ObjSize = ObjectVT.getSizeInBits()/8;
SmallVector<SDValue, 8> MemOps;
unsigned nAltivecParamsAtEnd = 0;
- for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
+ for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
+ ArgNo != e; ++ArgNo) {
SDValue ArgVal;
bool needsLoad = false;
MVT ObjectVT = Op.getValue(ArgNo).getValueType();
if (isVarArg || isPPC64) {
MinReservedArea = ((MinReservedArea+15)/16)*16;
MinReservedArea += CalculateStackSlotSize(Op.getValue(ArgNo),
- Op.getOperand(ArgNo+3),
+ Flags,
isVarArg,
PtrByteSize);
} else nAltivecParamsAtEnd++;
} else
// Calculate min reserved area.
MinReservedArea += CalculateStackSlotSize(Op.getValue(ArgNo),
- Op.getOperand(ArgNo+3),
+ Flags,
isVarArg,
PtrByteSize);
ArgValues.push_back(Root);
// Return the new list of results.
- return DAG.getMergeValues(Op.Val->getVTList(), &ArgValues[0],
+ return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0],
ArgValues.size());
}
bool isMachoABI,
bool isVarArg,
unsigned CC,
- SDValue Call,
+ CallSDNode *TheCall,
unsigned &nAltivecParamsAtEnd) {
// Count how many bytes are to be pushed on the stack, including the linkage
// area, and parameter passing area. We start with 24/48 bytes, which is
// prereserved space for [SP][CR][LR][3 x unused].
unsigned NumBytes = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
- unsigned NumOps = (Call.getNumOperands() - 5) / 2;
+ unsigned NumOps = TheCall->getNumArgs();
unsigned PtrByteSize = isPPC64 ? 8 : 4;
// Add up all the space actually used.
// 16-byte aligned.
nAltivecParamsAtEnd = 0;
for (unsigned i = 0; i != NumOps; ++i) {
- SDValue Arg = Call.getOperand(5+2*i);
- SDValue Flag = Call.getOperand(5+2*i+1);
+ SDValue Arg = TheCall->getArg(i);
+ ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i);
MVT ArgVT = Arg.getValueType();
// Varargs Altivec parameters are padded to a 16 byte boundary.
if (ArgVT==MVT::v4f32 || ArgVT==MVT::v4i32 ||
// Varargs and 64-bit Altivec parameters are padded to 16 byte boundary.
NumBytes = ((NumBytes+15)/16)*16;
}
- NumBytes += CalculateStackSlotSize(Arg, Flag, isVarArg, PtrByteSize);
+ NumBytes += CalculateStackSlotSize(Arg, Flags, isVarArg, PtrByteSize);
}
// Allow for Altivec parameters at the end, if needed.
/// calling conventions match, currently only fastcc supports tail calls, and
/// the function CALL is immediatly followed by a RET.
bool
-PPCTargetLowering::IsEligibleForTailCallOptimization(SDValue Call,
+PPCTargetLowering::IsEligibleForTailCallOptimization(CallSDNode *TheCall,
SDValue Ret,
SelectionDAG& DAG) const {
// Variable argument functions are not supported.
- if (!PerformTailCallOpt ||
- cast<ConstantSDNode>(Call.getOperand(2))->getValue() != 0) return false;
+ if (!PerformTailCallOpt || TheCall->isVarArg())
+ return false;
- if (CheckTailCallReturnConstraints(Call, Ret)) {
+ if (CheckTailCallReturnConstraints(TheCall, Ret)) {
MachineFunction &MF = DAG.getMachineFunction();
unsigned CallerCC = MF.getFunction()->getCallingConv();
- unsigned CalleeCC = cast<ConstantSDNode>(Call.getOperand(1))->getValue();
+ unsigned CalleeCC = TheCall->getCallingConv();
if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) {
// Functions containing by val parameters are not supported.
- for (unsigned i = 0; i != ((Call.getNumOperands()-5)/2); i++) {
- ISD::ArgFlagsTy Flags = cast<ARG_FLAGSSDNode>(Call.getOperand(5+2*i+1))
- ->getArgFlags();
+ for (unsigned i = 0; i != TheCall->getNumArgs(); i++) {
+ ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i);
if (Flags.isByVal()) return false;
}
- SDValue Callee = Call.getOperand(4);
+ SDValue Callee = TheCall->getCallee();
// Non PIC/GOT tail calls are supported.
if (getTargetMachine().getRelocationModel() != Reloc::PIC_)
return true;
ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
if (!C) return 0;
- int Addr = C->getValue();
+ int Addr = C->getZExtValue();
if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero.
(Addr << 6 >> 6) != Addr)
return 0; // Top 6 bits have to be sext of immediate.
- return DAG.getConstant((int)C->getValue() >> 2,
- DAG.getTargetLoweringInfo().getPointerTy()).Val;
+ return DAG.getConstant((int)C->getZExtValue() >> 2,
+ DAG.getTargetLoweringInfo().getPointerTy()).getNode();
}
namespace {
MVT VT = PPCSubTarget.isPPC64() ? MVT::i64 : MVT::i32;
LROpOut = getReturnAddrFrameIndex(DAG);
LROpOut = DAG.getLoad(VT, Chain, LROpOut, NULL, 0);
- Chain = SDValue(LROpOut.Val, 1);
+ Chain = SDValue(LROpOut.getNode(), 1);
FPOpOut = getFramePointerFrameIndex(DAG);
FPOpOut = DAG.getLoad(VT, Chain, FPOpOut, NULL, 0);
- Chain = SDValue(FPOpOut.Val, 1);
+ Chain = SDValue(FPOpOut.getNode(), 1);
}
return Chain;
}
SDValue PPCTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG,
const PPCSubtarget &Subtarget,
TargetMachine &TM) {
- SDValue Chain = Op.getOperand(0);
- bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
- unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
- bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0 &&
- CC == CallingConv::Fast && PerformTailCallOpt;
- SDValue Callee = Op.getOperand(4);
- unsigned NumOps = (Op.getNumOperands() - 5) / 2;
+ CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
+ SDValue Chain = TheCall->getChain();
+ bool isVarArg = TheCall->isVarArg();
+ unsigned CC = TheCall->getCallingConv();
+ bool isTailCall = TheCall->isTailCall()
+ && CC == CallingConv::Fast && PerformTailCallOpt;
+ SDValue Callee = TheCall->getCallee();
+ unsigned NumOps = TheCall->getNumArgs();
bool isMachoABI = Subtarget.isMachoABI();
bool isELF32_ABI = Subtarget.isELF32_ABI();
// prereserved space for [SP][CR][LR][3 x unused].
unsigned NumBytes =
CalculateParameterAndLinkageAreaSize(DAG, isPPC64, isMachoABI, isVarArg, CC,
- Op, nAltivecParamsAtEnd);
+ TheCall, nAltivecParamsAtEnd);
// Calculate by how many bytes the stack has to be adjusted in case of tail
// call optimization.
SmallVector<SDValue, 8> MemOpChains;
for (unsigned i = 0; i != NumOps; ++i) {
bool inMem = false;
- SDValue Arg = Op.getOperand(5+2*i);
- ISD::ArgFlagsTy Flags =
- cast<ARG_FLAGSSDNode>(Op.getOperand(5+2*i+1))->getArgFlags();
+ SDValue Arg = TheCall->getArg(i);
+ ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i);
// See if next argument requires stack alignment in ELF
bool Align = Flags.isSplit();
SDValue Const = DAG.getConstant(4 - Size, PtrOff.getValueType());
SDValue AddPtr = DAG.getNode(ISD::ADD, PtrVT, PtrOff, Const);
SDValue MemcpyCall = CreateCopyOfByValArgument(Arg, AddPtr,
- CallSeqStart.Val->getOperand(0),
+ CallSeqStart.getNode()->getOperand(0),
Flags, DAG, Size);
// This must go outside the CALLSEQ_START..END.
SDValue NewCallSeqStart = DAG.getCALLSEQ_START(MemcpyCall,
- CallSeqStart.Val->getOperand(1));
- DAG.ReplaceAllUsesWith(CallSeqStart.Val, NewCallSeqStart.Val);
+ CallSeqStart.getNode()->getOperand(1));
+ DAG.ReplaceAllUsesWith(CallSeqStart.getNode(),
+ NewCallSeqStart.getNode());
Chain = CallSeqStart = NewCallSeqStart;
ArgOffset += PtrByteSize;
}
// code assumes it is there, even if it could be put entirely into
// registers. (This is not what the doc says.)
SDValue MemcpyCall = CreateCopyOfByValArgument(Arg, PtrOff,
- CallSeqStart.Val->getOperand(0),
+ CallSeqStart.getNode()->getOperand(0),
Flags, DAG, Size);
// This must go outside the CALLSEQ_START..END.
SDValue NewCallSeqStart = DAG.getCALLSEQ_START(MemcpyCall,
- CallSeqStart.Val->getOperand(1));
- DAG.ReplaceAllUsesWith(CallSeqStart.Val, NewCallSeqStart.Val);
+ CallSeqStart.getNode()->getOperand(1));
+ DAG.ReplaceAllUsesWith(CallSeqStart.getNode(), NewCallSeqStart.getNode());
Chain = CallSeqStart = NewCallSeqStart;
// And copy the pieces of it that fit into registers.
for (unsigned j=0; j<Size; j+=PtrByteSize) {
ArgOffset = ((ArgOffset+15)/16)*16;
ArgOffset += 12*16;
for (unsigned i = 0; i != NumOps; ++i) {
- SDValue Arg = Op.getOperand(5+2*i);
+ SDValue Arg = TheCall->getArg(i);
MVT ArgType = Arg.getValueType();
if (ArgType==MVT::v4f32 || ArgType==MVT::v4i32 ||
ArgType==MVT::v8i16 || ArgType==MVT::v16i8) {
CallSeqOps.push_back(Chain);
CallSeqOps.push_back(DAG.getIntPtrConstant(NumBytes));
CallSeqOps.push_back(DAG.getIntPtrConstant(0));
- if (InFlag.Val)
+ if (InFlag.getNode())
CallSeqOps.push_back(InFlag);
Chain = DAG.getNode(ISD::CALLSEQ_END, CallSeqNodeTys, &CallSeqOps[0],
CallSeqOps.size());
// Otherwise, this is an indirect call. We have to use a MTCTR/BCTRL pair
// to do the call, we can't use PPCISD::CALL.
SDValue MTCTROps[] = {Chain, Callee, InFlag};
- Chain = DAG.getNode(PPCISD::MTCTR, NodeTys, MTCTROps, 2+(InFlag.Val!=0));
+ Chain = DAG.getNode(PPCISD::MTCTR, NodeTys, MTCTROps,
+ 2 + (InFlag.getNode() != 0));
InFlag = Chain.getValue(1);
// Copy the callee address into R12/X12 on darwin.
NodeTys.push_back(MVT::Flag);
Ops.push_back(Chain);
CallOpc = isMachoABI ? PPCISD::BCTRL_Macho : PPCISD::BCTRL_ELF;
- Callee.Val = 0;
+ Callee.setNode(0);
// Add CTR register as callee so a bctr can be emitted later.
if (isTailCall)
Ops.push_back(DAG.getRegister(PPC::CTR, getPointerTy()));
}
// If this is a direct call, pass the chain and the callee.
- if (Callee.Val) {
+ if (Callee.getNode()) {
Ops.push_back(Chain);
Ops.push_back(Callee);
}
int BytesCalleePops =
(CC==CallingConv::Fast && PerformTailCallOpt) ? NumBytes : 0;
- if (InFlag.Val)
+ if (InFlag.getNode())
Ops.push_back(InFlag);
// Emit tail call.
if (isTailCall) {
- assert(InFlag.Val &&
+ assert(InFlag.getNode() &&
"Flag must be set. Depend on flag being set in LowerRET");
Chain = DAG.getNode(PPCISD::TAILCALL,
- Op.Val->getVTList(), &Ops[0], Ops.size());
- return SDValue(Chain.Val, Op.getResNo());
+ TheCall->getVTList(), &Ops[0], Ops.size());
+ return SDValue(Chain.getNode(), Op.getResNo());
}
Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
DAG.getConstant(NumBytes, PtrVT),
DAG.getConstant(BytesCalleePops, PtrVT),
InFlag);
- if (Op.Val->getValueType(0) != MVT::Other)
+ if (TheCall->getValueType(0) != MVT::Other)
InFlag = Chain.getValue(1);
SmallVector<SDValue, 16> ResultVals;
SmallVector<CCValAssign, 16> RVLocs;
unsigned CallerCC = DAG.getMachineFunction().getFunction()->getCallingConv();
CCState CCInfo(CallerCC, isVarArg, TM, RVLocs);
- CCInfo.AnalyzeCallResult(Op.Val, RetCC_PPC);
+ CCInfo.AnalyzeCallResult(TheCall, RetCC_PPC);
// Copy all of the result registers out of their specified physreg.
for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
// Otherwise, merge everything together with a MERGE_VALUES node.
ResultVals.push_back(Chain);
- SDValue Res = DAG.getMergeValues(Op.Val->getVTList(), &ResultVals[0],
+ SDValue Res = DAG.getMergeValues(TheCall->getVTList(), &ResultVals[0],
ResultVals.size());
return Res.getValue(Op.getResNo());
}
unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
CCState CCInfo(CC, isVarArg, TM, RVLocs);
- CCInfo.AnalyzeReturn(Op.Val, RetCC_PPC);
+ CCInfo.AnalyzeReturn(Op.getNode(), RetCC_PPC);
// If this is the first return lowered for this function, add the regs to the
// liveout set for the function.
Flag = Chain.getValue(1);
}
- if (Flag.Val)
+ if (Flag.getNode())
return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Chain, Flag);
else
return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Chain);
switch (CC) {
default: break; // SETUO etc aren't handled by fsel.
case ISD::SETULT:
- case ISD::SETOLT:
case ISD::SETLT:
std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
- case ISD::SETUGE:
case ISD::SETOGE:
case ISD::SETGE:
if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits
LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS);
return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV);
case ISD::SETUGT:
- case ISD::SETOGT:
case ISD::SETGT:
std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
- case ISD::SETULE:
case ISD::SETOLE:
case ISD::SETLE:
if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits
switch (CC) {
default: break; // SETUO etc aren't handled by fsel.
case ISD::SETULT:
- case ISD::SETOLT:
case ISD::SETLT:
Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS);
if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits
Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp);
return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV);
- case ISD::SETUGE:
case ISD::SETOGE:
case ISD::SETGE:
Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS);
Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp);
return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV);
case ISD::SETUGT:
- case ISD::SETOGT:
case ISD::SETGT:
Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS);
if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits
Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp);
return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV);
- case ISD::SETULE:
case ISD::SETOLE:
case ISD::SETLE:
Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS);
SDValue PPCTargetLowering::LowerFP_ROUND_INREG(SDValue Op,
SelectionDAG &DAG) {
assert(Op.getValueType() == MVT::ppcf128);
- SDNode *Node = Op.Val;
+ SDNode *Node = Op.getNode();
assert(Node->getOperand(0).getValueType() == MVT::ppcf128);
- assert(Node->getOperand(0).Val->getOpcode() == ISD::BUILD_PAIR);
- SDValue Lo = Node->getOperand(0).Val->getOperand(0);
- SDValue Hi = Node->getOperand(0).Val->getOperand(1);
+ assert(Node->getOperand(0).getNode()->getOpcode() == ISD::BUILD_PAIR);
+ SDValue Lo = Node->getOperand(0).getNode()->getOperand(0);
+ SDValue Hi = Node->getOperand(0).getNode()->getOperand(1);
// This sequence changes FPSCR to do round-to-zero, adds the two halves
// of the long double, and puts FPSCR back the way it was. We do not
UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
continue;
} else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(OpVal)) {
- EltBits = CN->getValue() & (~0U >> (32-EltBitSize));
+ EltBits = CN->getZExtValue() & (~0U >> (32-EltBitSize));
} else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
// zero.
uint64_t VectorBits[2];
uint64_t UndefBits[2];
- if (GetConstantBuildVectorBits(Op.Val, VectorBits, UndefBits))
+ if (GetConstantBuildVectorBits(Op.getNode(), VectorBits, UndefBits))
return SDValue(); // Not a constant vector.
// If this is a splat (repetition) of a value across the whole vector, return
static SDValue GeneratePerfectShuffle(unsigned PFEntry, SDValue LHS,
SDValue RHS, SelectionDAG &DAG) {
unsigned OpNum = (PFEntry >> 26) & 0x0F;
- unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
+ unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
enum {
// (such as vsplt*) should be left as VECTOR_SHUFFLE nodes so they can be
// selected by the instruction selector.
if (V2.getOpcode() == ISD::UNDEF) {
- if (PPC::isSplatShuffleMask(PermMask.Val, 1) ||
- PPC::isSplatShuffleMask(PermMask.Val, 2) ||
- PPC::isSplatShuffleMask(PermMask.Val, 4) ||
- PPC::isVPKUWUMShuffleMask(PermMask.Val, true) ||
- PPC::isVPKUHUMShuffleMask(PermMask.Val, true) ||
- PPC::isVSLDOIShuffleMask(PermMask.Val, true) != -1 ||
- PPC::isVMRGLShuffleMask(PermMask.Val, 1, true) ||
- PPC::isVMRGLShuffleMask(PermMask.Val, 2, true) ||
- PPC::isVMRGLShuffleMask(PermMask.Val, 4, true) ||
- PPC::isVMRGHShuffleMask(PermMask.Val, 1, true) ||
- PPC::isVMRGHShuffleMask(PermMask.Val, 2, true) ||
- PPC::isVMRGHShuffleMask(PermMask.Val, 4, true)) {
+ if (PPC::isSplatShuffleMask(PermMask.getNode(), 1) ||
+ PPC::isSplatShuffleMask(PermMask.getNode(), 2) ||
+ PPC::isSplatShuffleMask(PermMask.getNode(), 4) ||
+ PPC::isVPKUWUMShuffleMask(PermMask.getNode(), true) ||
+ PPC::isVPKUHUMShuffleMask(PermMask.getNode(), true) ||
+ PPC::isVSLDOIShuffleMask(PermMask.getNode(), true) != -1 ||
+ PPC::isVMRGLShuffleMask(PermMask.getNode(), 1, true) ||
+ PPC::isVMRGLShuffleMask(PermMask.getNode(), 2, true) ||
+ PPC::isVMRGLShuffleMask(PermMask.getNode(), 4, true) ||
+ PPC::isVMRGHShuffleMask(PermMask.getNode(), 1, true) ||
+ PPC::isVMRGHShuffleMask(PermMask.getNode(), 2, true) ||
+ PPC::isVMRGHShuffleMask(PermMask.getNode(), 4, true)) {
return Op;
}
}
// Altivec has a variety of "shuffle immediates" that take two vector inputs
// and produce a fixed permutation. If any of these match, do not lower to
// VPERM.
- if (PPC::isVPKUWUMShuffleMask(PermMask.Val, false) ||
- PPC::isVPKUHUMShuffleMask(PermMask.Val, false) ||
- PPC::isVSLDOIShuffleMask(PermMask.Val, false) != -1 ||
- PPC::isVMRGLShuffleMask(PermMask.Val, 1, false) ||
- PPC::isVMRGLShuffleMask(PermMask.Val, 2, false) ||
- PPC::isVMRGLShuffleMask(PermMask.Val, 4, false) ||
- PPC::isVMRGHShuffleMask(PermMask.Val, 1, false) ||
- PPC::isVMRGHShuffleMask(PermMask.Val, 2, false) ||
- PPC::isVMRGHShuffleMask(PermMask.Val, 4, false))
+ if (PPC::isVPKUWUMShuffleMask(PermMask.getNode(), false) ||
+ PPC::isVPKUHUMShuffleMask(PermMask.getNode(), false) ||
+ PPC::isVSLDOIShuffleMask(PermMask.getNode(), false) != -1 ||
+ PPC::isVMRGLShuffleMask(PermMask.getNode(), 1, false) ||
+ PPC::isVMRGLShuffleMask(PermMask.getNode(), 2, false) ||
+ PPC::isVMRGLShuffleMask(PermMask.getNode(), 4, false) ||
+ PPC::isVMRGHShuffleMask(PermMask.getNode(), 1, false) ||
+ PPC::isVMRGHShuffleMask(PermMask.getNode(), 2, false) ||
+ PPC::isVMRGHShuffleMask(PermMask.getNode(), 4, false))
return Op;
// Check to see if this is a shuffle of 4-byte values. If so, we can use our
continue; // Undef, ignore it.
unsigned ByteSource =
- cast<ConstantSDNode>(PermMask.getOperand(i*4+j))->getValue();
+ cast<ConstantSDNode>(PermMask.getOperand(i*4+j))->getZExtValue();
if ((ByteSource & 3) != j) {
isFourElementShuffle = false;
break;
if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
SrcElt = 0;
else
- SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
+ SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getZExtValue();
for (unsigned j = 0; j != BytesPerElement; ++j)
ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
/// information about the intrinsic.
static bool getAltivecCompareInfo(SDValue Intrin, int &CompareOpc,
bool &isDot) {
- unsigned IntrinsicID = cast<ConstantSDNode>(Intrin.getOperand(0))->getValue();
+ unsigned IntrinsicID =
+ cast<ConstantSDNode>(Intrin.getOperand(0))->getZExtValue();
CompareOpc = -1;
isDot = false;
switch (IntrinsicID) {
// Unpack the result based on how the target uses it.
unsigned BitNo; // Bit # of CR6.
bool InvertBit; // Invert result?
- switch (cast<ConstantSDNode>(Op.getOperand(1))->getValue()) {
+ switch (cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue()) {
default: // Can't happen, don't crash on invalid number though.
case 0: // Return the value of the EQ bit of CR6.
BitNo = 0; InvertBit = false;
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
case ISD::SETCC: return LowerSETCC(Op, DAG);
+ case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG);
case ISD::VASTART:
return LowerVASTART(Op, DAG, VarArgsFrameIndex, VarArgsStackOffset,
VarArgsNumGPR, VarArgsNumFPR, PPCSubTarget);
// Use MERGE_VALUES to drop the chain result value and get a node with one
// result. This requires turning off getMergeValues simplification, since
// otherwise it will give us Res back.
- return DAG.getMergeValues(&Res, 1, false).Val;
+ return DAG.getMergeValues(&Res, 1, false).getNode();
}
}
}
MachineBasicBlock *
PPCTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
bool is64bit, unsigned BinOpcode) {
+ // This also handles ATOMIC_SWAP, indicated by BinOpcode==0.
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
const BasicBlock *LLVM_BB = BB->getBasicBlock();
exitMBB->transferSuccessors(BB);
MachineRegisterInfo &RegInfo = F->getRegInfo();
- unsigned TmpReg = RegInfo.createVirtualRegister(
- is64bit ? (const TargetRegisterClass *) &PPC::GPRCRegClass :
- (const TargetRegisterClass *) &PPC::G8RCRegClass);
+ unsigned TmpReg = (!BinOpcode) ? incr :
+ RegInfo.createVirtualRegister(
+ is64bit ? (const TargetRegisterClass *) &PPC::G8RCRegClass :
+ (const TargetRegisterClass *) &PPC::GPRCRegClass);
// thisMBB:
// ...
BB = loopMBB;
BuildMI(BB, TII->get(is64bit ? PPC::LDARX : PPC::LWARX), dest)
.addReg(ptrA).addReg(ptrB);
- BuildMI(BB, TII->get(BinOpcode), TmpReg).addReg(incr).addReg(dest);
+ if (BinOpcode)
+ BuildMI(BB, TII->get(BinOpcode), TmpReg).addReg(incr).addReg(dest);
BuildMI(BB, TII->get(is64bit ? PPC::STDCX : PPC::STWCX))
.addReg(TmpReg).addReg(ptrA).addReg(ptrB);
BuildMI(BB, TII->get(PPC::BCC))
MachineBasicBlock *BB,
bool is8bit, // operation
unsigned BinOpcode) {
+ // This also handles ATOMIC_SWAP, indicated by BinOpcode==0.
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
// In 64 bit mode we have to use 64 bits for addresses, even though the
// lwarx/stwcx are 32 bits. With the 32-bit atomics we can use address
MachineRegisterInfo &RegInfo = F->getRegInfo();
const TargetRegisterClass *RC =
- is64bit ? (const TargetRegisterClass *) &PPC::GPRCRegClass :
- (const TargetRegisterClass *) &PPC::G8RCRegClass;
- unsigned TmpReg = RegInfo.createVirtualRegister(RC);
+ is64bit ? (const TargetRegisterClass *) &PPC::G8RCRegClass :
+ (const TargetRegisterClass *) &PPC::GPRCRegClass;
unsigned PtrReg = RegInfo.createVirtualRegister(RC);
unsigned Shift1Reg = RegInfo.createVirtualRegister(RC);
unsigned ShiftReg = RegInfo.createVirtualRegister(RC);
unsigned Tmp2Reg = RegInfo.createVirtualRegister(RC);
unsigned Tmp3Reg = RegInfo.createVirtualRegister(RC);
unsigned Tmp4Reg = RegInfo.createVirtualRegister(RC);
+ unsigned TmpDestReg = RegInfo.createVirtualRegister(RC);
unsigned Ptr1Reg;
+ unsigned TmpReg = (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(RC);
// thisMBB:
// ...
// anywhere in the word. Hence all this nasty bookkeeping code.
// add ptr1, ptrA, ptrB [copy if ptrA==0]
// rlwinm shift1, ptr1, 3, 27, 28 [3, 27, 27]
- // xor shift, shift1, 24 [16]
+ // xori shift, shift1, 24 [16]
// rlwinm ptr, ptr1, 0, 0, 29
// slw incr2, incr, shift
// li mask2, 255 [li mask3, 0; ori mask2, mask3, 65535]
// slw mask, mask2, shift
// loopMBB:
- // l[wd]arx dest, ptr
- // add tmp, dest, incr2
- // andc tmp2, dest, mask
+ // lwarx tmpDest, ptr
+ // add tmp, tmpDest, incr2
+ // andc tmp2, tmpDest, mask
// and tmp3, tmp, mask
// or tmp4, tmp3, tmp2
- // st[wd]cx. tmp4, ptr
+ // stwcx. tmp4, ptr
// bne- loopMBB
// fallthrough --> exitMBB
+ // srw dest, tmpDest, shift
if (ptrA!=PPC::R0) {
Ptr1Reg = RegInfo.createVirtualRegister(RC);
}
BuildMI(BB, TII->get(PPC::RLWINM), Shift1Reg).addReg(Ptr1Reg)
.addImm(3).addImm(27).addImm(is8bit ? 28 : 27);
- BuildMI(BB, TII->get(is64bit ? PPC::XOR8 : PPC::XOR), ShiftReg)
+ BuildMI(BB, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg)
.addReg(Shift1Reg).addImm(is8bit ? 24 : 16);
if (is64bit)
BuildMI(BB, TII->get(PPC::RLDICR), PtrReg)
.addReg(Mask2Reg).addReg(ShiftReg);
BB = loopMBB;
- BuildMI(BB, TII->get(PPC::LWARX), dest)
+ BuildMI(BB, TII->get(PPC::LWARX), TmpDestReg)
.addReg(PPC::R0).addReg(PtrReg);
- BuildMI(BB, TII->get(BinOpcode), TmpReg).addReg(Incr2Reg).addReg(dest);
+ if (BinOpcode)
+ BuildMI(BB, TII->get(BinOpcode), TmpReg)
+ .addReg(Incr2Reg).addReg(TmpDestReg);
BuildMI(BB, TII->get(is64bit ? PPC::ANDC8 : PPC::ANDC), Tmp2Reg)
- .addReg(dest).addReg(MaskReg);
+ .addReg(TmpDestReg).addReg(MaskReg);
BuildMI(BB, TII->get(is64bit ? PPC::AND8 : PPC::AND), Tmp3Reg)
.addReg(TmpReg).addReg(MaskReg);
BuildMI(BB, TII->get(is64bit ? PPC::OR8 : PPC::OR), Tmp4Reg)
// exitMBB:
// ...
BB = exitMBB;
+ BuildMI(BB, TII->get(PPC::SRW), dest).addReg(TmpDestReg).addReg(ShiftReg);
return BB;
}
BB = EmitAtomicBinary(MI, BB, true, PPC::XOR8);
else if (MI->getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
- BB = EmitPartwordAtomicBinary(MI, BB, true, PPC::NAND);
+ BB = EmitPartwordAtomicBinary(MI, BB, true, PPC::ANDC);
else if (MI->getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
- BB = EmitPartwordAtomicBinary(MI, BB, false, PPC::NAND);
+ BB = EmitPartwordAtomicBinary(MI, BB, false, PPC::ANDC);
else if (MI->getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
- BB = EmitAtomicBinary(MI, BB, false, PPC::NAND);
+ BB = EmitAtomicBinary(MI, BB, false, PPC::ANDC);
else if (MI->getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
- BB = EmitAtomicBinary(MI, BB, true, PPC::NAND8);
+ BB = EmitAtomicBinary(MI, BB, true, PPC::ANDC8);
else if (MI->getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
BB = EmitPartwordAtomicBinary(MI, BB, true, PPC::SUBF);
else if (MI->getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
BB = EmitAtomicBinary(MI, BB, true, PPC::SUBF8);
+ else if (MI->getOpcode() == PPC::ATOMIC_SWAP_I8)
+ BB = EmitPartwordAtomicBinary(MI, BB, true, 0);
+ else if (MI->getOpcode() == PPC::ATOMIC_SWAP_I16)
+ BB = EmitPartwordAtomicBinary(MI, BB, false, 0);
+ else if (MI->getOpcode() == PPC::ATOMIC_SWAP_I32)
+ BB = EmitAtomicBinary(MI, BB, false, 0);
+ else if (MI->getOpcode() == PPC::ATOMIC_SWAP_I64)
+ BB = EmitAtomicBinary(MI, BB, true, 0);
+
else if (MI->getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
MI->getOpcode() == PPC::ATOMIC_CMP_SWAP_I64) {
bool is64bit = MI->getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
// exitMBB:
// ...
BB = exitMBB;
- }
- else if (MI->getOpcode() == PPC::ATOMIC_SWAP_I32 ||
- MI->getOpcode() == PPC::ATOMIC_SWAP_I64) {
- bool is64bit = MI->getOpcode() == PPC::ATOMIC_SWAP_I64;
+ } else if (MI->getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
+ MI->getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
+ // We must use 64-bit registers for addresses when targeting 64-bit,
+ // since we're actually doing arithmetic on them. Other registers
+ // can be 32-bit.
+ bool is64bit = PPCSubTarget.isPPC64();
+ bool is8bit = MI->getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
unsigned dest = MI->getOperand(0).getReg();
unsigned ptrA = MI->getOperand(1).getReg();
unsigned ptrB = MI->getOperand(2).getReg();
- unsigned newval = MI->getOperand(3).getReg();
+ unsigned oldval = MI->getOperand(3).getReg();
+ unsigned newval = MI->getOperand(4).getReg();
- MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *loop1MBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *loop2MBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *midMBB = F->CreateMachineBasicBlock(LLVM_BB);
MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
- F->insert(It, loopMBB);
+ F->insert(It, loop1MBB);
+ F->insert(It, loop2MBB);
+ F->insert(It, midMBB);
F->insert(It, exitMBB);
exitMBB->transferSuccessors(BB);
+ MachineRegisterInfo &RegInfo = F->getRegInfo();
+ const TargetRegisterClass *RC =
+ is64bit ? (const TargetRegisterClass *) &PPC::G8RCRegClass :
+ (const TargetRegisterClass *) &PPC::GPRCRegClass;
+ unsigned PtrReg = RegInfo.createVirtualRegister(RC);
+ unsigned Shift1Reg = RegInfo.createVirtualRegister(RC);
+ unsigned ShiftReg = RegInfo.createVirtualRegister(RC);
+ unsigned NewVal2Reg = RegInfo.createVirtualRegister(RC);
+ unsigned NewVal3Reg = RegInfo.createVirtualRegister(RC);
+ unsigned OldVal2Reg = RegInfo.createVirtualRegister(RC);
+ unsigned OldVal3Reg = RegInfo.createVirtualRegister(RC);
+ unsigned MaskReg = RegInfo.createVirtualRegister(RC);
+ unsigned Mask2Reg = RegInfo.createVirtualRegister(RC);
+ unsigned Mask3Reg = RegInfo.createVirtualRegister(RC);
+ unsigned Tmp2Reg = RegInfo.createVirtualRegister(RC);
+ unsigned Tmp4Reg = RegInfo.createVirtualRegister(RC);
+ unsigned TmpDestReg = RegInfo.createVirtualRegister(RC);
+ unsigned Ptr1Reg;
+ unsigned TmpReg = RegInfo.createVirtualRegister(RC);
// thisMBB:
// ...
// fallthrough --> loopMBB
- BB->addSuccessor(loopMBB);
+ BB->addSuccessor(loop1MBB);
- // loopMBB:
- // l[wd]arx dest, ptr
- // st[wd]cx. newval, ptr
- // bne- loopMBB
- // fallthrough --> exitMBB
- BB = loopMBB;
- BuildMI(BB, TII->get(is64bit ? PPC::LDARX : PPC::LWARX), dest)
- .addReg(ptrA).addReg(ptrB);
- BuildMI(BB, TII->get(is64bit ? PPC::STDCX : PPC::STWCX))
- .addReg(newval).addReg(ptrA).addReg(ptrB);
+ // The 4-byte load must be aligned, while a char or short may be
+ // anywhere in the word. Hence all this nasty bookkeeping code.
+ // add ptr1, ptrA, ptrB [copy if ptrA==0]
+ // rlwinm shift1, ptr1, 3, 27, 28 [3, 27, 27]
+ // xori shift, shift1, 24 [16]
+ // rlwinm ptr, ptr1, 0, 0, 29
+ // slw newval2, newval, shift
+ // slw oldval2, oldval,shift
+ // li mask2, 255 [li mask3, 0; ori mask2, mask3, 65535]
+ // slw mask, mask2, shift
+ // and newval3, newval2, mask
+ // and oldval3, oldval2, mask
+ // loop1MBB:
+ // lwarx tmpDest, ptr
+ // and tmp, tmpDest, mask
+ // cmpw tmp, oldval3
+ // bne- midMBB
+ // loop2MBB:
+ // andc tmp2, tmpDest, mask
+ // or tmp4, tmp2, newval3
+ // stwcx. tmp4, ptr
+ // bne- loop1MBB
+ // b exitBB
+ // midMBB:
+ // stwcx. tmpDest, ptr
+ // exitBB:
+ // srw dest, tmpDest, shift
+ if (ptrA!=PPC::R0) {
+ Ptr1Reg = RegInfo.createVirtualRegister(RC);
+ BuildMI(BB, TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
+ .addReg(ptrA).addReg(ptrB);
+ } else {
+ Ptr1Reg = ptrB;
+ }
+ BuildMI(BB, TII->get(PPC::RLWINM), Shift1Reg).addReg(Ptr1Reg)
+ .addImm(3).addImm(27).addImm(is8bit ? 28 : 27);
+ BuildMI(BB, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg)
+ .addReg(Shift1Reg).addImm(is8bit ? 24 : 16);
+ if (is64bit)
+ BuildMI(BB, TII->get(PPC::RLDICR), PtrReg)
+ .addReg(Ptr1Reg).addImm(0).addImm(61);
+ else
+ BuildMI(BB, TII->get(PPC::RLWINM), PtrReg)
+ .addReg(Ptr1Reg).addImm(0).addImm(0).addImm(29);
+ BuildMI(BB, TII->get(PPC::SLW), NewVal2Reg)
+ .addReg(newval).addReg(ShiftReg);
+ BuildMI(BB, TII->get(PPC::SLW), OldVal2Reg)
+ .addReg(oldval).addReg(ShiftReg);
+ if (is8bit)
+ BuildMI(BB, TII->get(PPC::LI), Mask2Reg).addImm(255);
+ else {
+ BuildMI(BB, TII->get(PPC::LI), Mask3Reg).addImm(0);
+ BuildMI(BB, TII->get(PPC::ORI), Mask2Reg).addReg(Mask3Reg).addImm(65535);
+ }
+ BuildMI(BB, TII->get(PPC::SLW), MaskReg)
+ .addReg(Mask2Reg).addReg(ShiftReg);
+ BuildMI(BB, TII->get(PPC::AND), NewVal3Reg)
+ .addReg(NewVal2Reg).addReg(MaskReg);
+ BuildMI(BB, TII->get(PPC::AND), OldVal3Reg)
+ .addReg(OldVal2Reg).addReg(MaskReg);
+
+ BB = loop1MBB;
+ BuildMI(BB, TII->get(PPC::LWARX), TmpDestReg)
+ .addReg(PPC::R0).addReg(PtrReg);
+ BuildMI(BB, TII->get(PPC::AND),TmpReg).addReg(TmpDestReg).addReg(MaskReg);
+ BuildMI(BB, TII->get(PPC::CMPW), PPC::CR0)
+ .addReg(TmpReg).addReg(OldVal3Reg);
+ BuildMI(BB, TII->get(PPC::BCC))
+ .addImm(PPC::PRED_NE).addReg(PPC::CR0).addMBB(midMBB);
+ BB->addSuccessor(loop2MBB);
+ BB->addSuccessor(midMBB);
+
+ BB = loop2MBB;
+ BuildMI(BB, TII->get(PPC::ANDC),Tmp2Reg).addReg(TmpDestReg).addReg(MaskReg);
+ BuildMI(BB, TII->get(PPC::OR),Tmp4Reg).addReg(Tmp2Reg).addReg(NewVal3Reg);
+ BuildMI(BB, TII->get(PPC::STWCX)).addReg(Tmp4Reg)
+ .addReg(PPC::R0).addReg(PtrReg);
BuildMI(BB, TII->get(PPC::BCC))
- .addImm(PPC::PRED_NE).addReg(PPC::CR0).addMBB(loopMBB);
- BB->addSuccessor(loopMBB);
+ .addImm(PPC::PRED_NE).addReg(PPC::CR0).addMBB(loop1MBB);
+ BuildMI(BB, TII->get(PPC::B)).addMBB(exitMBB);
+ BB->addSuccessor(loop1MBB);
BB->addSuccessor(exitMBB);
+ BB = midMBB;
+ BuildMI(BB, TII->get(PPC::STWCX)).addReg(TmpDestReg)
+ .addReg(PPC::R0).addReg(PtrReg);
+ BB->addSuccessor(exitMBB);
+
// exitMBB:
// ...
BB = exitMBB;
- }
- else {
+ BuildMI(BB, TII->get(PPC::SRW),dest).addReg(TmpReg).addReg(ShiftReg);
+ } else {
assert(0 && "Unexpected instr type to insert");
}
default: break;
case PPCISD::SHL:
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
- if (C->getValue() == 0) // 0 << V -> 0.
+ if (C->getZExtValue() == 0) // 0 << V -> 0.
return N->getOperand(0);
}
break;
case PPCISD::SRL:
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
- if (C->getValue() == 0) // 0 >>u V -> 0.
+ if (C->getZExtValue() == 0) // 0 >>u V -> 0.
return N->getOperand(0);
}
break;
case PPCISD::SRA:
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
- if (C->getValue() == 0 || // 0 >>s V -> 0.
+ if (C->getZExtValue() == 0 || // 0 >>s V -> 0.
C->isAllOnesValue()) // -1 >>s V -> -1.
return N->getOperand(0);
}
SDValue Val = N->getOperand(0).getOperand(0);
if (Val.getValueType() == MVT::f32) {
Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val);
- DCI.AddToWorklist(Val.Val);
+ DCI.AddToWorklist(Val.getNode());
}
Val = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Val);
- DCI.AddToWorklist(Val.Val);
+ DCI.AddToWorklist(Val.getNode());
Val = DAG.getNode(PPCISD::FCFID, MVT::f64, Val);
- DCI.AddToWorklist(Val.Val);
+ DCI.AddToWorklist(Val.getNode());
if (N->getValueType(0) == MVT::f32) {
Val = DAG.getNode(ISD::FP_ROUND, MVT::f32, Val,
DAG.getIntPtrConstant(0));
- DCI.AddToWorklist(Val.Val);
+ DCI.AddToWorklist(Val.getNode());
}
return Val;
} else if (N->getOperand(0).getValueType() == MVT::i32) {
SDValue Val = N->getOperand(1).getOperand(0);
if (Val.getValueType() == MVT::f32) {
Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val);
- DCI.AddToWorklist(Val.Val);
+ DCI.AddToWorklist(Val.getNode());
}
Val = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Val);
- DCI.AddToWorklist(Val.Val);
+ DCI.AddToWorklist(Val.getNode());
Val = DAG.getNode(PPCISD::STFIWX, MVT::Other, N->getOperand(0), Val,
N->getOperand(2), N->getOperand(3));
- DCI.AddToWorklist(Val.Val);
+ DCI.AddToWorklist(Val.getNode());
return Val;
}
// Turn STORE (BSWAP) -> sthbrx/stwbrx.
if (N->getOperand(1).getOpcode() == ISD::BSWAP &&
- N->getOperand(1).Val->hasOneUse() &&
+ N->getOperand(1).getNode()->hasOneUse() &&
(N->getOperand(1).getValueType() == MVT::i32 ||
N->getOperand(1).getValueType() == MVT::i16)) {
SDValue BSwapOp = N->getOperand(1).getOperand(0);
break;
case ISD::BSWAP:
// Turn BSWAP (LOAD) -> lhbrx/lwbrx.
- if (ISD::isNON_EXTLoad(N->getOperand(0).Val) &&
+ if (ISD::isNON_EXTLoad(N->getOperand(0).getNode()) &&
N->getOperand(0).hasOneUse() &&
(N->getValueType(0) == MVT::i32 || N->getValueType(0) == MVT::i16)) {
SDValue Load = N->getOperand(0);
// Next, combine the load away, we give it a bogus result value but a real
// chain result. The result value is dead because the bswap is dead.
- DCI.CombineTo(Load.Val, ResVal, BSLoad.getValue(1));
+ DCI.CombineTo(Load.getNode(), ResVal, BSLoad.getValue(1));
// Return N so it doesn't get rechecked!
return SDValue(N, 0);
// Scan all of the users of the LHS, looking for VCMPo's that match.
SDNode *VCMPoNode = 0;
- SDNode *LHSN = N->getOperand(0).Val;
+ SDNode *LHSN = N->getOperand(0).getNode();
for (SDNode::use_iterator UI = LHSN->use_begin(), E = LHSN->use_end();
UI != E; ++UI)
if (UI->getOpcode() == PPCISD::VCMPo &&
// If this is a comparison against something other than 0/1, then we know
// that the condition is never/always true.
- unsigned Val = cast<ConstantSDNode>(RHS)->getValue();
+ unsigned Val = cast<ConstantSDNode>(RHS)->getZExtValue();
if (Val != 0 && Val != 1) {
if (CC == ISD::SETEQ) // Cond never true, remove branch.
return N->getOperand(0);
// Unpack the result based on how the target uses it.
PPC::Predicate CompOpc;
- switch (cast<ConstantSDNode>(LHS.getOperand(1))->getValue()) {
+ switch (cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue()) {
default: // Can't happen, don't crash on invalid number though.
case 0: // Branch on the value of the EQ bit of CR6.
CompOpc = BranchOnWhenPredTrue ? PPC::PRED_EQ : PPC::PRED_NE;
break;
}
case ISD::INTRINSIC_WO_CHAIN: {
- switch (cast<ConstantSDNode>(Op.getOperand(0))->getValue()) {
+ switch (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue()) {
default: break;
case Intrinsic::ppc_altivec_vcmpbfp_p:
case Intrinsic::ppc_altivec_vcmpeqfp_p:
case 'P': {
ConstantSDNode *CST = dyn_cast<ConstantSDNode>(Op);
if (!CST) return; // Must be an immediate to match.
- unsigned Value = CST->getValue();
+ unsigned Value = CST->getZExtValue();
switch (Letter) {
default: assert(0 && "Unknown constraint letter!");
case 'I': // "I" is a signed 16-bit constant.
}
}
- if (Result.Val) {
+ if (Result.getNode()) {
Ops.push_back(Result);
return;
}
SDValue PPCTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
// Depths > 0 not supported yet!
- if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
+ if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0)
return SDValue();
MachineFunction &MF = DAG.getMachineFunction();
SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
// Depths > 0 not supported yet!
- if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
+ if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0)
return SDValue();
MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();