mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 21:32:39 +00:00
Add support for expanding trunc stores. Consider
storing an i170 on a 32 bit machine. This is first promoted to a trunc-i170 store of an i256. On a little-endian machine this expands to a store of an i128 and a trunc-i42 store of an i128. The trunc-i42 store is further expanded to a trunc-i42 store of an i64, then to a store of an i32 and a trunc-i10 store of an i32. At this point the operand type is legal (i32) and expansion stops (legalization of the trunc-i10 needs to be handled in LegalizeDAG.cpp). On big-endian machines the high bits are stored first, and some bit-fiddling is needed in order to generate aligned stores. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43499 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ba3b1d10fd
commit
01405f9284
@ -1936,75 +1936,139 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
|||||||
|
|
||||||
SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
|
SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
|
||||||
assert(OpNo == 1 && "Can only expand the stored value so far");
|
assert(OpNo == 1 && "Can only expand the stored value so far");
|
||||||
assert(!N->isTruncatingStore() && "Can't expand truncstore!");
|
|
||||||
|
|
||||||
unsigned IncrementSize = 0;
|
MVT::ValueType VT = N->getOperand(1).getValueType();
|
||||||
SDOperand Lo, Hi;
|
MVT::ValueType NVT = TLI.getTypeToTransformTo(VT);
|
||||||
|
SDOperand Ch = N->getChain();
|
||||||
// If this is a vector type, then we have to calculate the increment as
|
SDOperand Ptr = N->getBasePtr();
|
||||||
// the product of the element size in bytes, and the number of elements
|
int SVOffset = N->getSrcValueOffset();
|
||||||
// in the high half of the vector.
|
|
||||||
if (MVT::isVector(N->getValue().getValueType())) {
|
|
||||||
assert(0 && "Vectors not supported yet");
|
|
||||||
#if 0
|
|
||||||
SDNode *InVal = ST->getValue().Val;
|
|
||||||
unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
|
|
||||||
MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
|
|
||||||
|
|
||||||
// Figure out if there is a simple type corresponding to this Vector
|
|
||||||
// type. If so, convert to the vector type.
|
|
||||||
MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems);
|
|
||||||
if (TLI.isTypeLegal(TVT)) {
|
|
||||||
// Turn this into a normal store of the vector type.
|
|
||||||
Tmp3 = LegalizeOp(Node->getOperand(1));
|
|
||||||
Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
|
|
||||||
SVOffset, isVolatile, Alignment);
|
|
||||||
Result = LegalizeOp(Result);
|
|
||||||
break;
|
|
||||||
} else if (NumElems == 1) {
|
|
||||||
// Turn this into a normal store of the scalar type.
|
|
||||||
Tmp3 = ScalarizeVectorOp(Node->getOperand(1));
|
|
||||||
Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
|
|
||||||
SVOffset, isVolatile, Alignment);
|
|
||||||
// The scalarized value type may not be legal, e.g. it might require
|
|
||||||
// promotion or expansion. Relegalize the scalar store.
|
|
||||||
return LegalizeOp(Result);
|
|
||||||
} else {
|
|
||||||
SplitVectorOp(Node->getOperand(1), Lo, Hi);
|
|
||||||
IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
GetExpandedOp(N->getValue(), Lo, Hi);
|
|
||||||
IncrementSize = Hi.Val ? MVT::getSizeInBits(Hi.getValueType())/8 : 0;
|
|
||||||
|
|
||||||
if (!TLI.isLittleEndian())
|
|
||||||
std::swap(Lo, Hi);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDOperand Chain = N->getChain();
|
|
||||||
SDOperand Ptr = N->getBasePtr();
|
|
||||||
int SVOffset = N->getSrcValueOffset();
|
|
||||||
unsigned Alignment = N->getAlignment();
|
unsigned Alignment = N->getAlignment();
|
||||||
bool isVolatile = N->isVolatile();
|
bool isVolatile = N->isVolatile();
|
||||||
|
SDOperand Lo, Hi;
|
||||||
Lo = DAG.getStore(Chain, Lo, Ptr, N->getSrcValue(),
|
|
||||||
SVOffset, isVolatile, Alignment);
|
assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!");
|
||||||
|
|
||||||
assert(Hi.Val && "FIXME: int <-> float should be handled with promote!");
|
if (!N->isTruncatingStore()) {
|
||||||
#if 0
|
unsigned IncrementSize = 0;
|
||||||
if (Hi.Val == NULL) {
|
|
||||||
// Must be int <-> float one-to-one expansion.
|
// If this is a vector type, then we have to calculate the increment as
|
||||||
return Lo;
|
// the product of the element size in bytes, and the number of elements
|
||||||
|
// in the high half of the vector.
|
||||||
|
if (MVT::isVector(N->getValue().getValueType())) {
|
||||||
|
assert(0 && "Vectors not supported yet");
|
||||||
|
#if 0
|
||||||
|
SDNode *InVal = ST->getValue().Val;
|
||||||
|
unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
|
||||||
|
MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
|
||||||
|
|
||||||
|
// Figure out if there is a simple type corresponding to this Vector
|
||||||
|
// type. If so, convert to the vector type.
|
||||||
|
MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems);
|
||||||
|
if (TLI.isTypeLegal(TVT)) {
|
||||||
|
// Turn this into a normal store of the vector type.
|
||||||
|
Tmp3 = LegalizeOp(Node->getOperand(1));
|
||||||
|
Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
|
||||||
|
SVOffset, isVolatile, Alignment);
|
||||||
|
Result = LegalizeOp(Result);
|
||||||
|
break;
|
||||||
|
} else if (NumElems == 1) {
|
||||||
|
// Turn this into a normal store of the scalar type.
|
||||||
|
Tmp3 = ScalarizeVectorOp(Node->getOperand(1));
|
||||||
|
Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
|
||||||
|
SVOffset, isVolatile, Alignment);
|
||||||
|
// The scalarized value type may not be legal, e.g. it might require
|
||||||
|
// promotion or expansion. Relegalize the scalar store.
|
||||||
|
return LegalizeOp(Result);
|
||||||
|
} else {
|
||||||
|
SplitVectorOp(Node->getOperand(1), Lo, Hi);
|
||||||
|
IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
GetExpandedOp(N->getValue(), Lo, Hi);
|
||||||
|
IncrementSize = Hi.Val ? MVT::getSizeInBits(Hi.getValueType())/8 : 0;
|
||||||
|
|
||||||
|
if (!TLI.isLittleEndian())
|
||||||
|
std::swap(Lo, Hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(),
|
||||||
|
SVOffset, isVolatile, Alignment);
|
||||||
|
|
||||||
|
assert(Hi.Val && "FIXME: int <-> float should be handled with promote!");
|
||||||
|
#if 0
|
||||||
|
if (Hi.Val == NULL) {
|
||||||
|
// Must be int <-> float one-to-one expansion.
|
||||||
|
return Lo;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
|
||||||
|
getIntPtrConstant(IncrementSize));
|
||||||
|
assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
|
||||||
|
Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
|
||||||
|
isVolatile, MinAlign(Alignment, IncrementSize));
|
||||||
|
return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
|
||||||
|
} else if (MVT::getSizeInBits(N->getStoredVT()) <= MVT::getSizeInBits(NVT)) {
|
||||||
|
GetExpandedOp(N->getValue(), Lo, Hi);
|
||||||
|
return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
|
||||||
|
N->getStoredVT(), isVolatile, Alignment);
|
||||||
|
} else if (TLI.isLittleEndian()) {
|
||||||
|
// Little-endian - low bits are at low addresses.
|
||||||
|
GetExpandedOp(N->getValue(), Lo, Hi);
|
||||||
|
|
||||||
|
Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
|
||||||
|
isVolatile, Alignment);
|
||||||
|
|
||||||
|
unsigned ExcessBits =
|
||||||
|
MVT::getSizeInBits(N->getStoredVT()) - MVT::getSizeInBits(NVT);
|
||||||
|
MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits);
|
||||||
|
|
||||||
|
// Increment the pointer to the other half.
|
||||||
|
unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
|
||||||
|
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
|
||||||
|
getIntPtrConstant(IncrementSize));
|
||||||
|
Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
|
||||||
|
SVOffset+IncrementSize, NEVT,
|
||||||
|
isVolatile, MinAlign(Alignment, IncrementSize));
|
||||||
|
return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
|
||||||
|
} else {
|
||||||
|
// Big-endian - high bits are at low addresses. Favor aligned stores at
|
||||||
|
// the cost of some bit-fiddling.
|
||||||
|
GetExpandedOp(N->getValue(), Lo, Hi);
|
||||||
|
|
||||||
|
MVT::ValueType EVT = N->getStoredVT();
|
||||||
|
unsigned EBytes = (MVT::getSizeInBits(EVT) + 7)/8;
|
||||||
|
unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
|
||||||
|
unsigned ExcessBits = (EBytes - IncrementSize)*8;
|
||||||
|
MVT::ValueType HiVT =
|
||||||
|
MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits);
|
||||||
|
|
||||||
|
if (ExcessBits < MVT::getSizeInBits(NVT)) {
|
||||||
|
// Transfer high bits from the top of Lo to the bottom of Hi.
|
||||||
|
Hi = DAG.getNode(ISD::SHL, NVT, Hi,
|
||||||
|
DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits,
|
||||||
|
TLI.getShiftAmountTy()));
|
||||||
|
Hi = DAG.getNode(ISD::OR, NVT, Hi,
|
||||||
|
DAG.getNode(ISD::SRL, NVT, Lo,
|
||||||
|
DAG.getConstant(ExcessBits,
|
||||||
|
TLI.getShiftAmountTy())));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store both the high bits and maybe some of the low bits.
|
||||||
|
Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
|
||||||
|
SVOffset, HiVT, isVolatile, Alignment);
|
||||||
|
|
||||||
|
// Increment the pointer to the other half.
|
||||||
|
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
|
||||||
|
getIntPtrConstant(IncrementSize));
|
||||||
|
// Store the lowest ExcessBits bits in the second half.
|
||||||
|
Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(),
|
||||||
|
SVOffset+IncrementSize,
|
||||||
|
MVT::getIntegerType(ExcessBits),
|
||||||
|
isVolatile, MinAlign(Alignment, IncrementSize));
|
||||||
|
return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
|
|
||||||
getIntPtrConstant(IncrementSize));
|
|
||||||
assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
|
|
||||||
Hi = DAG.getStore(Chain, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
|
|
||||||
isVolatile, MinAlign(Alignment, IncrementSize));
|
|
||||||
return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user