mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 21:32:39 +00:00
Add some fairly duplicated code to let type legalization split illegal
typed atomics. This will lower exclusively to libcalls at the moment. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122979 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
01cdc2016d
commit
8d93d19076
@ -1019,6 +1019,24 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
|
||||
case ISD::UREM: ExpandIntRes_UREM(N, Lo, Hi); break;
|
||||
case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
|
||||
|
||||
case ISD::ATOMIC_LOAD_ADD:
|
||||
case ISD::ATOMIC_LOAD_SUB:
|
||||
case ISD::ATOMIC_LOAD_AND:
|
||||
case ISD::ATOMIC_LOAD_OR:
|
||||
case ISD::ATOMIC_LOAD_XOR:
|
||||
case ISD::ATOMIC_LOAD_NAND:
|
||||
case ISD::ATOMIC_LOAD_MIN:
|
||||
case ISD::ATOMIC_LOAD_MAX:
|
||||
case ISD::ATOMIC_LOAD_UMIN:
|
||||
case ISD::ATOMIC_LOAD_UMAX:
|
||||
case ISD::ATOMIC_SWAP: {
|
||||
SDValue Ch = N->getOperand(0);
|
||||
std::pair<SDValue, SDValue> Tmp = ExpandAtomic(N);
|
||||
SplitInteger(Tmp.first, Lo, Hi);
|
||||
ReplaceValueWith(SDValue(N, 1), Tmp.second);
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::AND:
|
||||
case ISD::OR:
|
||||
case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break;
|
||||
|
@ -1050,6 +1050,125 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, EVT RetVT,
|
||||
return CallInfo.first;
|
||||
}
|
||||
|
||||
// ExpandChainLibCall - Expand a node into a call to a libcall. Similar to
|
||||
// ExpandLibCall except that the first operand is the in-chain.
|
||||
std::pair<SDValue, SDValue>
|
||||
DAGTypeLegalizer::ExpandChainLibCall(RTLIB::Libcall LC,
|
||||
SDNode *Node,
|
||||
bool isSigned) {
|
||||
SDValue InChain = Node->getOperand(0);
|
||||
|
||||
TargetLowering::ArgListTy Args;
|
||||
TargetLowering::ArgListEntry Entry;
|
||||
for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) {
|
||||
EVT ArgVT = Node->getOperand(i).getValueType();
|
||||
const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
|
||||
Entry.Node = Node->getOperand(i);
|
||||
Entry.Ty = ArgTy;
|
||||
Entry.isSExt = isSigned;
|
||||
Entry.isZExt = !isSigned;
|
||||
Args.push_back(Entry);
|
||||
}
|
||||
SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
|
||||
TLI.getPointerTy());
|
||||
|
||||
// Splice the libcall in wherever FindInputOutputChains tells us to.
|
||||
const Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext());
|
||||
std::pair<SDValue, SDValue> CallInfo =
|
||||
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
|
||||
0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false,
|
||||
/*isReturnValueUsed=*/true,
|
||||
Callee, Args, DAG, Node->getDebugLoc());
|
||||
|
||||
return CallInfo;
|
||||
}
|
||||
|
||||
std::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
|
||||
unsigned Opc = Node->getOpcode();
|
||||
MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
|
||||
RTLIB::Libcall LC;
|
||||
|
||||
switch (Opc) {
|
||||
default:
|
||||
llvm_unreachable("Unhandled atomic intrinsic Expand!");
|
||||
break;
|
||||
case ISD::ATOMIC_SWAP:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_8; break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_CMP_SWAP:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8; break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_ADD:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_ADD_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_ADD_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_ADD_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_ADD_8; break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_SUB:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_SUB_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_SUB_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_SUB_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_SUB_8; break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_AND:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_AND_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_AND_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_AND_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_AND_8; break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_OR:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_OR_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_OR_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_OR_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_OR_8; break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_XOR:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_XOR_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_XOR_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_XOR_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_XOR_8; break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_NAND:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_NAND_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_NAND_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_NAND_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_NAND_8; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ExpandChainLibCall(LC, Node, false);
|
||||
}
|
||||
|
||||
/// PromoteTargetBoolean - Promote the given target boolean to a target boolean
|
||||
/// of the given type. A target boolean is an integer value, not necessarily of
|
||||
/// type i1, the bits of which conform to getBooleanContents.
|
||||
|
@ -192,6 +192,10 @@ private:
|
||||
SDValue MakeLibCall(RTLIB::Libcall LC, EVT RetVT,
|
||||
const SDValue *Ops, unsigned NumOps, bool isSigned,
|
||||
DebugLoc dl);
|
||||
std::pair<SDValue, SDValue> ExpandChainLibCall(RTLIB::Libcall LC,
|
||||
SDNode *Node, bool isSigned);
|
||||
std::pair<SDValue, SDValue> ExpandAtomic(SDNode *Node);
|
||||
|
||||
SDValue PromoteTargetBoolean(SDValue Bool, EVT VT);
|
||||
void ReplaceValueWith(SDValue From, SDValue To);
|
||||
void SplitInteger(SDValue Op, SDValue &Lo, SDValue &Hi);
|
||||
|
Loading…
x
Reference in New Issue
Block a user