mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-18 13:34:04 +00:00
SDAG: Merge the meat of two ExpandAtomic implementations.
The copies already diverged, don't let them become any worse. Reduce redundancy in code with a little macro metaprogramming. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231401 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
77f46f4f9f
commit
f74b5c6198
@ -425,6 +425,10 @@ namespace RTLIB {
|
||||
/// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or
|
||||
/// UNKNOWN_LIBCALL if there is none.
|
||||
Libcall getUINTTOFP(EVT OpVT, EVT RetVT);
|
||||
|
||||
/// Return the SYNC_FETCH_AND_* value for the given opcode and type, or
|
||||
/// UNKNOWN_LIBCALL if there is none.
|
||||
Libcall getATOMIC(unsigned Opc, MVT VT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2817,132 +2817,8 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op,
|
||||
std::pair <SDValue, SDValue> SelectionDAGLegalize::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!");
|
||||
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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_LOCK_TEST_AND_SET_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_ADD_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_SUB_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_AND_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_OR_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_XOR_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_NAND_16;break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_MAX:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_MAX_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_MAX_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_MAX_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_MAX_8; break;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_MAX_16;break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_UMAX:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_UMAX_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_UMAX_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_UMAX_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_UMAX_8; break;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_UMAX_16;break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_MIN:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_MIN_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_MIN_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_MIN_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_MIN_8; break;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_MIN_16;break;
|
||||
}
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_UMIN:
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type for atomic!");
|
||||
case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_UMIN_1; break;
|
||||
case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_UMIN_2; break;
|
||||
case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_UMIN_4; break;
|
||||
case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_UMIN_8; break;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_UMIN_16;break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
RTLIB::Libcall LC = RTLIB::getATOMIC(Opc, VT);
|
||||
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected atomic op or value type!");
|
||||
|
||||
return ExpandChainLibCall(LC, Node, false);
|
||||
}
|
||||
|
@ -1323,92 +1323,8 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
|
||||
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!");
|
||||
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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_LOCK_TEST_AND_SET_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_ADD_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_SUB_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_AND_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_OR_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_XOR_16;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;
|
||||
case MVT::i128:LC = RTLIB::SYNC_FETCH_AND_NAND_16;break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
RTLIB::Libcall LC = RTLIB::getATOMIC(Opc, VT);
|
||||
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected atomic op or value type!");
|
||||
|
||||
return ExpandChainLibCall(LC, Node, false);
|
||||
}
|
||||
|
@ -664,6 +664,44 @@ RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) {
|
||||
return UNKNOWN_LIBCALL;
|
||||
}
|
||||
|
||||
RTLIB::Libcall RTLIB::getATOMIC(unsigned Opc, MVT VT) {
|
||||
#define OP_TO_LIBCALL(Name, Enum) \
|
||||
case Name: \
|
||||
switch (VT.SimpleTy) { \
|
||||
default: \
|
||||
return UNKNOWN_LIBCALL; \
|
||||
case MVT::i8: \
|
||||
return Enum##_1; \
|
||||
case MVT::i16: \
|
||||
return Enum##_2; \
|
||||
case MVT::i32: \
|
||||
return Enum##_4; \
|
||||
case MVT::i64: \
|
||||
return Enum##_8; \
|
||||
case MVT::i128: \
|
||||
return Enum##_16; \
|
||||
}
|
||||
|
||||
switch (Opc) {
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_SWAP, SYNC_LOCK_TEST_AND_SET)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_CMP_SWAP, SYNC_VAL_COMPARE_AND_SWAP)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_ADD, SYNC_FETCH_AND_ADD)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_SUB, SYNC_FETCH_AND_SUB)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_AND, SYNC_FETCH_AND_AND)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_OR, SYNC_FETCH_AND_OR)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_XOR, SYNC_FETCH_AND_XOR)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_NAND, SYNC_FETCH_AND_NAND)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_MAX, SYNC_FETCH_AND_MAX)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_UMAX, SYNC_FETCH_AND_UMAX)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_MIN, SYNC_FETCH_AND_MIN)
|
||||
OP_TO_LIBCALL(ISD::ATOMIC_LOAD_UMIN, SYNC_FETCH_AND_UMIN)
|
||||
}
|
||||
|
||||
#undef OP_TO_LIBCALL
|
||||
|
||||
return UNKNOWN_LIBCALL;
|
||||
}
|
||||
|
||||
/// InitCmpLibcallCCs - Set default comparison libcall CC.
|
||||
///
|
||||
static void InitCmpLibcallCCs(ISD::CondCode *CCs) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user