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

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

Issue 136303012: Updates refactoring of CPU feature detection (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 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
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1887 matching lines...) Expand 10 before | Expand all | Expand 10 after
2450 tst(rn, shifter_op, cond); 2360 tst(rn, shifter_op, cond);
2451 } else { 2361 } else {
2452 LoadImmediate(IP, imm); 2362 LoadImmediate(IP, imm);
2453 tst(rn, ShifterOperand(IP), cond); 2363 tst(rn, ShifterOperand(IP), cond);
2454 } 2364 }
2455 } 2365 }
2456 2366
2457 void Assembler::IntegerDivide(Register result, Register left, Register right, 2367 void Assembler::IntegerDivide(Register result, Register left, Register right,
2458 DRegister tmpl, DRegister tmpr) { 2368 DRegister tmpl, DRegister tmpr) {
2459 ASSERT(tmpl != tmpr); 2369 ASSERT(tmpl != tmpr);
2460 if (CPUFeatures::integer_division_supported()) { 2370 if (TargetCPUFeatures::integer_division_supported()) {
2461 sdiv(result, left, right); 2371 sdiv(result, left, right);
2462 } else { 2372 } else {
2463 SRegister stmpl = static_cast<SRegister>(2 * tmpl); 2373 SRegister stmpl = static_cast<SRegister>(2 * tmpl);
2464 SRegister stmpr = static_cast<SRegister>(2 * tmpr); 2374 SRegister stmpr = static_cast<SRegister>(2 * tmpr);
2465 vmovsr(stmpl, left); 2375 vmovsr(stmpl, left);
2466 vcvtdi(tmpl, stmpl); // left is in tmpl. 2376 vcvtdi(tmpl, stmpl); // left is in tmpl.
2467 vmovsr(stmpr, right); 2377 vmovsr(stmpr, right);
2468 vcvtdi(tmpr, stmpr); // right is in tmpr. 2378 vcvtdi(tmpr, stmpr); // right is in tmpr.
2469 vdivd(tmpr, tmpl, tmpr); 2379 vdivd(tmpr, tmpl, tmpr);
2470 vcvtid(stmpr, tmpr); 2380 vcvtid(stmpr, tmpr);
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
2844 2754
2845 2755
2846 const char* Assembler::FpuRegisterName(FpuRegister reg) { 2756 const char* Assembler::FpuRegisterName(FpuRegister reg) {
2847 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 2757 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
2848 return fpu_reg_names[reg]; 2758 return fpu_reg_names[reg];
2849 } 2759 }
2850 2760
2851 } // namespace dart 2761 } // namespace dart
2852 2762
2853 #endif // defined TARGET_ARCH_ARM 2763 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698