aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2012-06-26 21:36:32 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2012-06-26 21:36:32 +0000
commit4750c1d804a793edc1f00d4f8b9777352bb0a761 (patch)
tree3fca3e1c609667032f9962cd085c8ca98654939b /lib/Support
parent275c85f1a7d04cf1dc6c166211dc2d72fea43c0d (diff)
downloadexternal_llvm-4750c1d804a793edc1f00d4f8b9777352bb0a761.zip
external_llvm-4750c1d804a793edc1f00d4f8b9777352bb0a761.tar.gz
external_llvm-4750c1d804a793edc1f00d4f8b9777352bb0a761.tar.bz2
Implement getHostCPUName for ARM/linux. This will be used to implement -march=native in clang.
The cpuid registers are only available in privileged mode so we don't have an OS-independent way of implementing this. ARM doesn't provide a list of processor IDs so the list is somewhat incomplete. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159228 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/Host.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp
index 677da5c..550fa57 100644
--- a/lib/Support/Host.cpp
+++ b/lib/Support/Host.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/DataStream.h"
@@ -450,6 +451,60 @@ std::string sys::getHostCPUName() {
.Case("POWER7", "pwr7")
.Default(generic);
}
+#elif defined(__linux__) && defined(__arm__)
+std::string sys::getHostCPUName() {
+ // The cpuid register on arm is not accessible from user space. On Linux,
+ // it is exposed through the /proc/cpuinfo file.
+ // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
+ // memory buffer because the 'file' has 0 size (it can be read from only
+ // as a stream).
+
+ std::string Err;
+ DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
+ if (!DS) {
+ DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
+ return "generic";
+ }
+
+ // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
+ // in all cases.
+ char buffer[1024];
+ size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
+ delete DS;
+
+ StringRef Str(buffer, CPUInfoSize);
+
+ SmallVector<StringRef, 32> Lines;
+ Str.split(Lines, "\n");
+
+ // Look for the CPU implementer line.
+ StringRef Implementer;
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+ if (Lines[I].startswith("CPU implementer"))
+ Implementer = Lines[I].substr(15).ltrim("\t :");
+
+ if (Implementer == "0x41") // ARM Ltd.
+ // Look for the CPU part line.
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+ if (Lines[I].startswith("CPU part"))
+ // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
+ // values correspond to the "Part number" in the CP15/c0 register. The
+ // contents are specified in the various processor manuals.
+ return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
+ .Case("0x926", "arm926ej-s")
+ .Case("0xb02", "mpcore")
+ .Case("0xb36", "arm1136j-s")
+ .Case("0xb56", "arm1156t2-s")
+ .Case("0xb76", "arm1176jz-s")
+ .Case("0xc08", "cortex-a8")
+ .Case("0xc09", "cortex-a9")
+ .Case("0xc20", "cortex-m0")
+ .Case("0xc23", "cortex-m3")
+ .Case("0xc24", "cortex-m4")
+ .Default("generic");
+
+ return "generic";
+}
#else
std::string sys::getHostCPUName() {
return "generic";