mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-01-07 22:24:28 +00:00
Support unaligned load/store on more ARM targets
This patch matches GCC behavior: the code used to only allow unaligned load/store on ARM for v6+ Darwin, it will now allow unaligned load/store for v6+ Darwin as well as for v7+ on Linux and NaCl. The distinction is made because v6 doesn't guarantee support (but LLVM assumes that Apple controls hardware+kernel and therefore have conformant v6 CPUs), whereas v7 does provide this guarantee (and Linux/NaCl behave sanely). The patch keeps the -arm-strict-align command line option, and adds -arm-no-strict-align. They behave similarly to GCC's -mstrict-align and -mnostrict-align. I originally encountered this discrepancy in FastIsel tests which expect unaligned load/store generation. Overall this should slightly improve performance in most cases because of reduced I$ pressure. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182175 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -38,9 +38,24 @@ static cl::opt<bool>
|
||||
UseFusedMulOps("arm-use-mulops",
|
||||
cl::init(true), cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
StrictAlign("arm-strict-align", cl::Hidden,
|
||||
cl::desc("Disallow all unaligned memory accesses"));
|
||||
enum AlignMode {
|
||||
DefaultAlign,
|
||||
StrictAlign,
|
||||
NoStrictAlign
|
||||
};
|
||||
|
||||
static cl::opt<AlignMode>
|
||||
Align(cl::desc("Load/store alignment support"),
|
||||
cl::Hidden, cl::init(DefaultAlign),
|
||||
cl::values(
|
||||
clEnumValN(DefaultAlign, "arm-default-align",
|
||||
"Generate unaligned accesses only on hardware/OS "
|
||||
"combinations that are known to support them"),
|
||||
clEnumValN(StrictAlign, "arm-strict-align",
|
||||
"Disallow all unaligned memory accesses"),
|
||||
clEnumValN(NoStrictAlign, "arm-no-strict-align",
|
||||
"Allow unaligned memory accesses"),
|
||||
clEnumValEnd));
|
||||
|
||||
ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
|
||||
const std::string &FS, const TargetOptions &Options)
|
||||
@@ -162,10 +177,32 @@ void ARMSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) {
|
||||
if (!isThumb() || hasThumb2())
|
||||
PostRAScheduler = true;
|
||||
|
||||
// v6+ may or may not support unaligned mem access depending on the system
|
||||
// configuration.
|
||||
if (!StrictAlign && hasV6Ops() && isTargetDarwin())
|
||||
AllowsUnalignedMem = true;
|
||||
switch (Align) {
|
||||
case DefaultAlign:
|
||||
// Assume pre-ARMv6 doesn't support unaligned accesses.
|
||||
//
|
||||
// ARMv6 may or may not support unaligned accesses depending on the
|
||||
// SCTLR.U bit, which is architecture-specific. We assume ARMv6
|
||||
// Darwin targets support unaligned accesses, and others don't.
|
||||
//
|
||||
// ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
|
||||
// which raises an alignment fault on unaligned accesses. Linux
|
||||
// defaults this bit to 0 and handles it as a system-wide (not
|
||||
// per-process) setting. It is therefore safe to assume that ARMv7+
|
||||
// Linux targets support unaligned accesses. The same goes for NaCl.
|
||||
//
|
||||
// The above behavior is consistent with GCC.
|
||||
AllowsUnalignedMem = (
|
||||
(hasV7Ops() && (isTargetLinux() || isTargetNaCl())) ||
|
||||
(hasV6Ops() && isTargetDarwin()));
|
||||
break;
|
||||
case StrictAlign:
|
||||
AllowsUnalignedMem = false;
|
||||
break;
|
||||
case NoStrictAlign:
|
||||
AllowsUnalignedMem = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default.
|
||||
uint64_t Bits = getFeatureBits();
|
||||
|
||||
Reference in New Issue
Block a user