| Index: runtime/vm/assembler_arm.cc
|
| ===================================================================
|
| --- runtime/vm/assembler_arm.cc (revision 32559)
|
| +++ runtime/vm/assembler_arm.cc (working copy)
|
| @@ -6,7 +6,6 @@
|
| #if defined(TARGET_ARCH_ARM)
|
|
|
| #include "vm/assembler.h"
|
| -#include "vm/cpu.h"
|
| #include "vm/longjump.h"
|
| #include "vm/runtime_entry.h"
|
| #include "vm/simulator.h"
|
| @@ -23,7 +22,98 @@
|
| DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
|
| DECLARE_FLAG(bool, inline_alloc);
|
|
|
| +bool CPUFeatures::integer_division_supported_ = false;
|
| +bool CPUFeatures::neon_supported_ = false;
|
| +#if defined(DEBUG)
|
| +bool CPUFeatures::initialized_ = false;
|
| +#endif
|
|
|
| +
|
| +bool CPUFeatures::integer_division_supported() {
|
| + DEBUG_ASSERT(initialized_);
|
| + return integer_division_supported_;
|
| +}
|
| +
|
| +
|
| +bool CPUFeatures::neon_supported() {
|
| + DEBUG_ASSERT(initialized_);
|
| + return neon_supported_;
|
| +}
|
| +
|
| +
|
| +// If we are using the simulator, allow tests to enable/disable support for
|
| +// integer division.
|
| +#if defined(USING_SIMULATOR)
|
| +void CPUFeatures::set_integer_division_supported(bool supported) {
|
| + integer_division_supported_ = supported;
|
| +}
|
| +
|
| +
|
| +void CPUFeatures::set_neon_supported(bool supported) {
|
| + neon_supported_ = supported;
|
| +}
|
| +#endif
|
| +
|
| +
|
| +// Probe /proc/cpuinfo for features of the ARM processor.
|
| +#if !defined(USING_SIMULATOR)
|
| +static bool CPUInfoContainsString(const char* search_string) {
|
| + const char* file_name = "/proc/cpuinfo";
|
| + // This is written as a straight shot one pass parser
|
| + // and not using STL string and ifstream because,
|
| + // on Linux, it's reading from a (non-mmap-able)
|
| + // character special device.
|
| + FILE* f = NULL;
|
| + const char* what = search_string;
|
| +
|
| + if (NULL == (f = fopen(file_name, "r")))
|
| + return false;
|
| +
|
| + int k;
|
| + while (EOF != (k = fgetc(f))) {
|
| + if (k == *what) {
|
| + ++what;
|
| + while ((*what != '\0') && (*what == fgetc(f))) {
|
| + ++what;
|
| + }
|
| + if (*what == '\0') {
|
| + fclose(f);
|
| + return true;
|
| + } else {
|
| + what = search_string;
|
| + }
|
| + }
|
| + }
|
| + fclose(f);
|
| +
|
| + // Did not find string in the proc file.
|
| + return false;
|
| +}
|
| +#endif
|
| +
|
| +
|
| +void CPUFeatures::InitOnce() {
|
| +#if defined(USING_SIMULATOR)
|
| + integer_division_supported_ = true;
|
| + neon_supported_ = true;
|
| +#else
|
| + ASSERT(CPUInfoContainsString("ARMv7")); // Implements ARMv7.
|
| + ASSERT(CPUInfoContainsString("vfp")); // Has floating point unit.
|
| + // Has integer division.
|
| + if (CPUInfoContainsString("QCT APQ8064")) {
|
| + // Special case for Qualcomm Krait CPUs in Nexus 4 and 7.
|
| + integer_division_supported_ = true;
|
| + } else {
|
| + integer_division_supported_ = CPUInfoContainsString("idiva");
|
| + }
|
| + neon_supported_ = CPUInfoContainsString("neon");
|
| +#endif // defined(USING_SIMULATOR)
|
| +#if defined(DEBUG)
|
| + initialized_ = true;
|
| +#endif
|
| +}
|
| +
|
| +
|
| // Instruction encoding bits.
|
| enum {
|
| H = 1 << 5, // halfword (or byte)
|
| @@ -459,7 +549,7 @@
|
|
|
| void Assembler::EmitDivOp(Condition cond, int32_t opcode,
|
| Register rd, Register rn, Register rm) {
|
| - ASSERT(TargetCPUFeatures::integer_division_supported());
|
| + ASSERT(CPUFeatures::integer_division_supported());
|
| ASSERT(rd != kNoRegister);
|
| ASSERT(rn != kNoRegister);
|
| ASSERT(rm != kNoRegister);
|
| @@ -2367,7 +2457,7 @@
|
| void Assembler::IntegerDivide(Register result, Register left, Register right,
|
| DRegister tmpl, DRegister tmpr) {
|
| ASSERT(tmpl != tmpr);
|
| - if (TargetCPUFeatures::integer_division_supported()) {
|
| + if (CPUFeatures::integer_division_supported()) {
|
| sdiv(result, left, right);
|
| } else {
|
| SRegister stmpl = static_cast<SRegister>(2 * tmpl);
|
|
|