OpcodeDispatcher: select hardware addressing modes

Now that we have a framework to do this in.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig 2024-05-31 11:11:08 -04:00
parent 97966930e9
commit abfd974d70

View File

@ -4286,6 +4286,32 @@ OrderedNode* OpDispatchBuilder::LoadEffectiveAddress(AddressMode A, bool AllowUp
}
AddressMode OpDispatchBuilder::SelectAddressMode(AddressMode A, bool AtomicTSO, bool Vector, unsigned AccessSize) {
// In the future this also needs to account for LRCPC3.
bool SupportsRegIndex = Vector || !AtomicTSO;
// Try a constant offset. For 64-bit, this maps directly. For 32-bit, this
// works only for displacements with magnitude < 16KB, since those bottom
// addresses are reserved and therefore wrap around is invalid.
//
// TODO: Also handle GPR TSO if we can guarantee the constant inlines.
if (A.Base && A.Offset && !A.Index && SupportsRegIndex) {
const bool Const_16K = A.Offset > -16384 && A.Offset < 16384 && CTX->GetGPRSize() == 4;
if ((A.AddrSize == 8) || Const_16K) {
return {
.Base = A.Base,
.Index = _Constant(A.Offset),
.IndexType = (Const_16K && A.Offset < 0) ? MEM_OFFSET_SXTW : MEM_OFFSET_SXTX,
.IndexScale = 1,
};
}
}
// Try a (possibly scaled) register index.
if (A.AddrSize == 8 && A.Base && A.Index && !A.Offset && (A.IndexScale == 1 || A.IndexScale == AccessSize) && SupportsRegIndex) {
return A;
}
// Fallback on software address calculation
return {
.Base = LoadEffectiveAddress(A),