Files
sdk/runtime/vm/cpu_arm.cc
T
zra@google.com 7c91e88e6e Adds support for ARMv6.
When we detect ARMv6, instead of using movw and
movt, this change loads each individual byte.
Although this is not the best way to achieve this,
a modification to store large constants in the
object pool would be more invasive. Further,
this change will be easier to back-out once
ARMv6 is obsolete.

R=regis@google.com

Review URL: https://codereview.chromium.org//183803024

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@33442 260f80e4-7a28-3924-810f-c04153c831b5
2014-03-07 19:17:36 +00:00

135 lines
3.4 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/globals.h"
#if defined(TARGET_ARCH_ARM)
#include "vm/cpu.h"
#include "vm/cpuinfo.h"
#include "vm/simulator.h"
#if defined(HOST_ARCH_ARM)
#include <sys/syscall.h> /* NOLINT */
#include <unistd.h> /* NOLINT */
#endif
namespace dart {
void CPU::FlushICache(uword start, uword size) {
#if defined(HOST_ARCH_ARM)
// Nothing to do. Flushing no instructions.
if (size == 0) {
return;
}
// ARM recommends using the gcc intrinsic __clear_cache on Linux, and the
// library call cacheflush from unistd.h on Android:
// blogs.arm.com/software-enablement/141-caches-and-self-modifying-code/
#if defined(__linux__) && !defined(ANDROID)
extern void __clear_cache(char*, char*);
char* beg = reinterpret_cast<char*>(start);
char* end = reinterpret_cast<char*>(start + size);
::__clear_cache(beg, end);
#elif defined(ANDROID)
cacheflush(start, start + size, 0);
#else
#error FlushICache only tested/supported on Linux and Android
#endif
#endif
}
const char* CPU::Id() {
return
#if !defined(HOST_ARCH_ARM)
"sim"
#endif // !defined(HOST_ARCH_ARM)
"arm";
}
bool HostCPUFeatures::integer_division_supported_ = false;
bool HostCPUFeatures::neon_supported_ = false;
const char* HostCPUFeatures::hardware_ = NULL;
ARMVersion HostCPUFeatures::arm_version_ = ARMvUnknown;
#if defined(DEBUG)
bool HostCPUFeatures::initialized_ = false;
#endif
#if defined(HOST_ARCH_ARM)
void HostCPUFeatures::InitOnce() {
CpuInfo::InitOnce();
hardware_ = CpuInfo::GetCpuModel();
// Check for ARMv6 or ARMv7. It can be in either the Processor or
// Model information fields.
if (CpuInfo::FieldContains(kCpuInfoProcessor, "ARMv6") ||
CpuInfo::FieldContains(kCpuInfoModel, "ARMv6")) {
arm_version_ = ARMv6;
} else {
ASSERT(CpuInfo::FieldContains(kCpuInfoProcessor, "ARMv7") ||
CpuInfo::FieldContains(kCpuInfoModel, "ARMv7"));
arm_version_ = ARMv7;
}
// Has floating point unit.
ASSERT(CpuInfo::FieldContains(kCpuInfoFeatures, "vfp"));
// Has integer division.
bool is_krait = CpuInfo::FieldContains(kCpuInfoHardware, "QCT APQ8064");
if (is_krait) {
// Special case for Qualcomm Krait CPUs in Nexus 4 and 7.
integer_division_supported_ = true;
} else {
integer_division_supported_ =
CpuInfo::FieldContains(kCpuInfoFeatures, "idiva");
}
neon_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "neon");
#if defined(DEBUG)
initialized_ = true;
#endif
}
void HostCPUFeatures::Cleanup() {
DEBUG_ASSERT(initialized_);
#if defined(DEBUG)
initialized_ = false;
#endif
ASSERT(hardware_ != NULL);
free(const_cast<char*>(hardware_));
hardware_ = NULL;
CpuInfo::Cleanup();
}
#else
void HostCPUFeatures::InitOnce() {
CpuInfo::InitOnce();
hardware_ = CpuInfo::GetCpuModel();
integer_division_supported_ = true;
neon_supported_ = true;
arm_version_ = ARMv7;
#if defined(DEBUG)
initialized_ = true;
#endif
}
void HostCPUFeatures::Cleanup() {
DEBUG_ASSERT(initialized_);
#if defined(DEBUG)
initialized_ = false;
#endif
ASSERT(hardware_ != NULL);
free(const_cast<char*>(hardware_));
hardware_ = NULL;
CpuInfo::Cleanup();
}
#endif // defined(HOST_ARCH_ARM)
} // namespace dart
#endif // defined TARGET_ARCH_ARM