mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-14 17:28:53 +00:00
Support for expanding extending loads of integers with
funky bit-widths. llvm-svn: 43225
This commit is contained in:
parent
68fc6d7395
commit
b47c73b341
@ -935,17 +935,19 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
|
|||||||
int SVOffset = N->getSrcValueOffset();
|
int SVOffset = N->getSrcValueOffset();
|
||||||
unsigned Alignment = N->getAlignment();
|
unsigned Alignment = N->getAlignment();
|
||||||
bool isVolatile = N->isVolatile();
|
bool isVolatile = N->isVolatile();
|
||||||
|
|
||||||
|
assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!");
|
||||||
|
|
||||||
if (ExtType == ISD::NON_EXTLOAD) {
|
if (ExtType == ISD::NON_EXTLOAD) {
|
||||||
Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
|
Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
|
||||||
isVolatile, Alignment);
|
isVolatile, Alignment);
|
||||||
// Increment the pointer to the other half.
|
// Increment the pointer to the other half.
|
||||||
unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
|
unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
|
||||||
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
|
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
|
||||||
getIntPtrConstant(IncrementSize));
|
getIntPtrConstant(IncrementSize));
|
||||||
Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
|
Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
|
||||||
isVolatile, std::max(Alignment, IncrementSize));
|
isVolatile, std::max(Alignment, IncrementSize));
|
||||||
|
|
||||||
// Build a factor node to remember that this load is independent of the
|
// Build a factor node to remember that this load is independent of the
|
||||||
// other one.
|
// other one.
|
||||||
Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
|
Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
|
||||||
@ -954,19 +956,15 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
|
|||||||
// Handle endianness of the load.
|
// Handle endianness of the load.
|
||||||
if (!TLI.isLittleEndian())
|
if (!TLI.isLittleEndian())
|
||||||
std::swap(Lo, Hi);
|
std::swap(Lo, Hi);
|
||||||
} else {
|
} else if (MVT::getSizeInBits(N->getLoadedVT()) <= MVT::getSizeInBits(NVT)) {
|
||||||
MVT::ValueType EVT = N->getLoadedVT();
|
MVT::ValueType EVT = N->getLoadedVT();
|
||||||
|
|
||||||
if (EVT == NVT)
|
Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT,
|
||||||
Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(),
|
isVolatile, Alignment);
|
||||||
SVOffset, isVolatile, Alignment);
|
|
||||||
else
|
|
||||||
Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
|
|
||||||
SVOffset, EVT, isVolatile,
|
|
||||||
Alignment);
|
|
||||||
// Remember the chain.
|
// Remember the chain.
|
||||||
Ch = Lo.getValue(1);
|
Ch = Lo.getValue(1);
|
||||||
|
|
||||||
if (ExtType == ISD::SEXTLOAD) {
|
if (ExtType == ISD::SEXTLOAD) {
|
||||||
// The high part is obtained by SRA'ing all but one of the bits of the
|
// The high part is obtained by SRA'ing all but one of the bits of the
|
||||||
// lo part.
|
// lo part.
|
||||||
@ -981,13 +979,70 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
|
|||||||
// The high part is undefined.
|
// The high part is undefined.
|
||||||
Hi = DAG.getNode(ISD::UNDEF, NVT);
|
Hi = DAG.getNode(ISD::UNDEF, NVT);
|
||||||
}
|
}
|
||||||
|
} else if (TLI.isLittleEndian()) {
|
||||||
|
// Little-endian - low bits are at low addresses.
|
||||||
|
Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
|
||||||
|
isVolatile, Alignment);
|
||||||
|
|
||||||
|
unsigned ExcessBits =
|
||||||
|
MVT::getSizeInBits(N->getLoadedVT()) - 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.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
|
||||||
|
SVOffset+IncrementSize, NEVT,
|
||||||
|
isVolatile, std::max(Alignment, IncrementSize));
|
||||||
|
|
||||||
|
// Build a factor node to remember that this load is independent of the
|
||||||
|
// other one.
|
||||||
|
Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
|
||||||
|
Hi.getValue(1));
|
||||||
|
} else {
|
||||||
|
// Big-endian - high bits are at low addresses. Favor aligned loads at
|
||||||
|
// the cost of some bit-fiddling.
|
||||||
|
MVT::ValueType EVT = N->getLoadedVT();
|
||||||
|
unsigned EBytes = (MVT::getSizeInBits(EVT) + 7)/8;
|
||||||
|
unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
|
||||||
|
unsigned ExcessBits = (EBytes - IncrementSize)*8;
|
||||||
|
|
||||||
|
// Load both the high bits and maybe some of the low bits.
|
||||||
|
Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
|
||||||
|
MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits),
|
||||||
|
isVolatile, Alignment);
|
||||||
|
|
||||||
|
// Increment the pointer to the other half.
|
||||||
|
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
|
||||||
|
getIntPtrConstant(IncrementSize));
|
||||||
|
// Load the rest of the low bits.
|
||||||
|
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(),
|
||||||
|
SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits),
|
||||||
|
isVolatile, std::max(Alignment, IncrementSize));
|
||||||
|
|
||||||
|
// Build a factor node to remember that this load is independent of the
|
||||||
|
// other one.
|
||||||
|
Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
|
||||||
|
Hi.getValue(1));
|
||||||
|
|
||||||
|
if (ExcessBits < MVT::getSizeInBits(NVT)) {
|
||||||
|
// Transfer low bits from the bottom of Hi to the top of Lo.
|
||||||
|
Lo = DAG.getNode(ISD::OR, NVT, Lo,
|
||||||
|
DAG.getNode(ISD::SHL, NVT, Hi,
|
||||||
|
DAG.getConstant(ExcessBits,
|
||||||
|
TLI.getShiftAmountTy())));
|
||||||
|
// Move high bits to the right position in Hi.
|
||||||
|
Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi,
|
||||||
|
DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits,
|
||||||
|
TLI.getShiftAmountTy()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legalized the chain result - switch anything that used the old chain to
|
// Legalized the chain result - switch anything that used the old chain to
|
||||||
// use the new one.
|
// use the new one.
|
||||||
ReplaceLegalValueWith(SDOperand(N, 1), Ch);
|
ReplaceLegalValueWith(SDOperand(N, 1), Ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N,
|
void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N,
|
||||||
SDOperand &Lo, SDOperand &Hi) {
|
SDOperand &Lo, SDOperand &Hi) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user