aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMSubtarget.cpp
diff options
context:
space:
mode:
authorEli Bendersky <eliben@chromium.org>2013-07-16 14:34:27 -0700
committerEli Bendersky <eliben@chromium.org>2013-07-16 14:34:27 -0700
commitaf56c404f86351c203c5c14181c42553dc2215e3 (patch)
tree84c5cf00f4d8c72132a9b43d5debe918071fd9fb /lib/Target/ARM/ARMSubtarget.cpp
parent89671101b88b575278760d3dda29571e4fc5ced0 (diff)
Fixing make check errors...
Diffstat (limited to 'lib/Target/ARM/ARMSubtarget.cpp')
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp51
1 files changed, 44 insertions, 7 deletions
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index b0e2f182b9..375a0ec4be 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -48,9 +48,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)
@@ -185,10 +200,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();