Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(579)

Side by Side Diff: runtime/vm/assembler_arm.cc

Issue 120723003: Refactors CPU feature detection. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Fixed cpu service field names. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/cpu.h"
9 #include "vm/longjump.h" 10 #include "vm/longjump.h"
10 #include "vm/runtime_entry.h" 11 #include "vm/runtime_entry.h"
11 #include "vm/simulator.h" 12 #include "vm/simulator.h"
12 #include "vm/stack_frame.h" 13 #include "vm/stack_frame.h"
13 #include "vm/stub_code.h" 14 #include "vm/stub_code.h"
14 15
15 // An extra check since we are assuming the existence of /proc/cpuinfo below. 16 // An extra check since we are assuming the existence of /proc/cpuinfo below.
16 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) 17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID)
17 #error ARM cross-compile only supported on Linux 18 #error ARM cross-compile only supported on Linux
18 #endif 19 #endif
19 20
20 namespace dart { 21 namespace dart {
21 22
22 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); 23 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
23 DECLARE_FLAG(bool, inline_alloc); 24 DECLARE_FLAG(bool, inline_alloc);
24 25
25 bool CPUFeatures::integer_division_supported_ = false;
26 bool CPUFeatures::neon_supported_ = false;
27 #if defined(DEBUG)
28 bool CPUFeatures::initialized_ = false;
29 #endif
30
31
32 bool CPUFeatures::integer_division_supported() {
33 DEBUG_ASSERT(initialized_);
34 return integer_division_supported_;
35 }
36
37
38 bool CPUFeatures::neon_supported() {
39 DEBUG_ASSERT(initialized_);
40 return neon_supported_;
41 }
42
43
44 // If we are using the simulator, allow tests to enable/disable support for
45 // integer division.
46 #if defined(USING_SIMULATOR)
47 void CPUFeatures::set_integer_division_supported(bool supported) {
48 integer_division_supported_ = supported;
49 }
50
51
52 void CPUFeatures::set_neon_supported(bool supported) {
53 neon_supported_ = supported;
54 }
55 #endif
56
57
58 // Probe /proc/cpuinfo for features of the ARM processor.
59 #if !defined(USING_SIMULATOR)
60 static bool CPUInfoContainsString(const char* search_string) {
61 const char* file_name = "/proc/cpuinfo";
62 // This is written as a straight shot one pass parser
63 // and not using STL string and ifstream because,
64 // on Linux, it's reading from a (non-mmap-able)
65 // character special device.
66 FILE* f = NULL;
67 const char* what = search_string;
68
69 if (NULL == (f = fopen(file_name, "r")))
70 return false;
71
72 int k;
73 while (EOF != (k = fgetc(f))) {
74 if (k == *what) {
75 ++what;
76 while ((*what != '\0') && (*what == fgetc(f))) {
77 ++what;
78 }
79 if (*what == '\0') {
80 fclose(f);
81 return true;
82 } else {
83 what = search_string;
84 }
85 }
86 }
87 fclose(f);
88
89 // Did not find string in the proc file.
90 return false;
91 }
92 #endif
93
94
95 void CPUFeatures::InitOnce() {
96 #if defined(USING_SIMULATOR)
97 integer_division_supported_ = true;
98 neon_supported_ = true;
99 #else
100 ASSERT(CPUInfoContainsString("ARMv7")); // Implements ARMv7.
101 ASSERT(CPUInfoContainsString("vfp")); // Has floating point unit.
102 // Has integer division.
103 if (CPUInfoContainsString("QCT APQ8064")) {
104 // Special case for Qualcomm Krait CPUs in Nexus 4 and 7.
105 integer_division_supported_ = true;
106 } else {
107 integer_division_supported_ = CPUInfoContainsString("idiva");
108 }
109 neon_supported_ = CPUInfoContainsString("neon");
110 #endif // defined(USING_SIMULATOR)
111 #if defined(DEBUG)
112 initialized_ = true;
113 #endif
114 }
115
116 26
117 // Instruction encoding bits. 27 // Instruction encoding bits.
118 enum { 28 enum {
119 H = 1 << 5, // halfword (or byte) 29 H = 1 << 5, // halfword (or byte)
120 L = 1 << 20, // load (or store) 30 L = 1 << 20, // load (or store)
121 S = 1 << 20, // set condition code (or leave unchanged) 31 S = 1 << 20, // set condition code (or leave unchanged)
122 W = 1 << 21, // writeback base register (or leave unchanged) 32 W = 1 << 21, // writeback base register (or leave unchanged)
123 A = 1 << 21, // accumulate in multiply instruction (or not) 33 A = 1 << 21, // accumulate in multiply instruction (or not)
124 B = 1 << 22, // unsigned byte (or word) 34 B = 1 << 22, // unsigned byte (or word)
125 D = 1 << 22, // high/lo bit of start of s/d register range 35 D = 1 << 22, // high/lo bit of start of s/d register range
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 452
543 void Assembler::umlal(Register rd_lo, Register rd_hi, 453 void Assembler::umlal(Register rd_lo, Register rd_hi,
544 Register rn, Register rm, Condition cond) { 454 Register rn, Register rm, Condition cond) {
545 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 455 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
546 EmitMulOp(cond, B23 | B21, rd_lo, rd_hi, rn, rm); 456 EmitMulOp(cond, B23 | B21, rd_lo, rd_hi, rn, rm);
547 } 457 }
548 458
549 459
550 void Assembler::EmitDivOp(Condition cond, int32_t opcode, 460 void Assembler::EmitDivOp(Condition cond, int32_t opcode,
551 Register rd, Register rn, Register rm) { 461 Register rd, Register rn, Register rm) {
552 ASSERT(CPUFeatures::integer_division_supported()); 462 ASSERT(TargetCPUFeatures::integer_division_supported());
553 ASSERT(rd != kNoRegister); 463 ASSERT(rd != kNoRegister);
554 ASSERT(rn != kNoRegister); 464 ASSERT(rn != kNoRegister);
555 ASSERT(rm != kNoRegister); 465 ASSERT(rm != kNoRegister);
556 ASSERT(cond != kNoCondition); 466 ASSERT(cond != kNoCondition);
557 int32_t encoding = opcode | 467 int32_t encoding = opcode |
558 (static_cast<int32_t>(cond) << kConditionShift) | 468 (static_cast<int32_t>(cond) << kConditionShift) |
559 (static_cast<int32_t>(rn) << kDivRnShift) | 469 (static_cast<int32_t>(rn) << kDivRnShift) |
560 (static_cast<int32_t>(rd) << kDivRdShift) | 470 (static_cast<int32_t>(rd) << kDivRdShift) |
561 B26 | B25 | B24 | B20 | B4 | 471 B26 | B25 | B24 | B20 | B4 |
562 (static_cast<int32_t>(rm) << kDivRmShift); 472 (static_cast<int32_t>(rm) << kDivRmShift);
(...skipping 1885 matching lines...) Expand 10 before | Expand all | Expand 10 after
2448 tst(rn, shifter_op, cond); 2358 tst(rn, shifter_op, cond);
2449 } else { 2359 } else {
2450 LoadImmediate(IP, imm); 2360 LoadImmediate(IP, imm);
2451 tst(rn, ShifterOperand(IP), cond); 2361 tst(rn, ShifterOperand(IP), cond);
2452 } 2362 }
2453 } 2363 }
2454 2364
2455 void Assembler::IntegerDivide(Register result, Register left, Register right, 2365 void Assembler::IntegerDivide(Register result, Register left, Register right,
2456 DRegister tmpl, DRegister tmpr) { 2366 DRegister tmpl, DRegister tmpr) {
2457 ASSERT(tmpl != tmpr); 2367 ASSERT(tmpl != tmpr);
2458 if (CPUFeatures::integer_division_supported()) { 2368 if (TargetCPUFeatures::integer_division_supported()) {
2459 sdiv(result, left, right); 2369 sdiv(result, left, right);
2460 } else { 2370 } else {
2461 SRegister stmpl = static_cast<SRegister>(2 * tmpl); 2371 SRegister stmpl = static_cast<SRegister>(2 * tmpl);
2462 SRegister stmpr = static_cast<SRegister>(2 * tmpr); 2372 SRegister stmpr = static_cast<SRegister>(2 * tmpr);
2463 vmovsr(stmpl, left); 2373 vmovsr(stmpl, left);
2464 vcvtdi(tmpl, stmpl); // left is in tmpl. 2374 vcvtdi(tmpl, stmpl); // left is in tmpl.
2465 vmovsr(stmpr, right); 2375 vmovsr(stmpr, right);
2466 vcvtdi(tmpr, stmpr); // right is in tmpr. 2376 vcvtdi(tmpr, stmpr); // right is in tmpr.
2467 vdivd(tmpr, tmpl, tmpr); 2377 vdivd(tmpr, tmpl, tmpr);
2468 vcvtid(stmpr, tmpr); 2378 vcvtid(stmpr, tmpr);
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
2754 2664
2755 2665
2756 const char* Assembler::FpuRegisterName(FpuRegister reg) { 2666 const char* Assembler::FpuRegisterName(FpuRegister reg) {
2757 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 2667 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
2758 return fpu_reg_names[reg]; 2668 return fpu_reg_names[reg];
2759 } 2669 }
2760 2670
2761 } // namespace dart 2671 } // namespace dart
2762 2672
2763 #endif // defined TARGET_ARCH_ARM 2673 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698