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

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

Issue 14784011: Fixes for integer division on ARM hardware so that assembler tests pass. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 | « no previous file | runtime/vm/assembler_arm_test.cc » ('j') | runtime/vm/assembler_arm_test.cc » ('J')
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 // An extra check since we are assuming the existence of /proc/cpuinfo below.
9 #if !defined(__linux__)
10 #error ARM cross-compile only supported on Linux
11 #endif
regis 2013/05/07 17:14:35 Shoudn't it be #if !defined(USING_SIMULATOR) && !
zra 2013/05/07 17:50:18 Done.
12
8 #include "vm/assembler.h" 13 #include "vm/assembler.h"
9 #include "vm/simulator.h" 14 #include "vm/simulator.h"
10 #include "vm/runtime_entry.h" 15 #include "vm/runtime_entry.h"
11 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
12 17
13 namespace dart { 18 namespace dart {
14 19
15 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
16 21
17 22
18 bool CPUFeatures::integer_division_supported_ = false; 23 bool CPUFeatures::integer_division_supported_ = false;
19 #if defined(DEBUG) 24 #if defined(DEBUG)
20 bool CPUFeatures::initialized_ = false; 25 bool CPUFeatures::initialized_ = false;
21 #endif 26 #endif
22 27
23 28
24 bool CPUFeatures::integer_division_supported() { 29 bool CPUFeatures::integer_division_supported() {
25 DEBUG_ASSERT(initialized_); 30 DEBUG_ASSERT(initialized_);
26 return integer_division_supported_; 31 return integer_division_supported_;
27 } 32 }
28 33
29 34
35 // If we are using the simulator, allow tests to enable/disable support for
36 // integer division.
30 #if defined(USING_SIMULATOR) 37 #if defined(USING_SIMULATOR)
31 void CPUFeatures::set_integer_division_supported(bool supported) { 38 void CPUFeatures::set_integer_division_supported(bool supported) {
32 integer_division_supported_ = supported; 39 integer_division_supported_ = supported;
33 } 40 }
34 #endif 41 #endif
35 42
36 43
37 #define __ assembler. 44 // Probe /proc/cpuinfo for features of the ARM processor.
45 #if !defined(USING_SIMULATOR)
46 static bool CPUInfoContainsString(const char* search_string) {
47 const char* file_name = "/proc/cpuinfo";
48 // This is written as a straight shot one pass parser
49 // and not using STL string and ifstream because,
50 // on Linux, it's reading from a (non-mmap-able)
51 // character special device.
52 FILE* f = NULL;
53 const char* what = search_string;
54
55 if (NULL == (f = fopen(file_name, "r")))
56 return false;
57
58 int k;
59 while (EOF != (k = fgetc(f))) {
60 if (k == *what) {
61 ++what;
62 while ((*what != '\0') && (*what == fgetc(f))) {
63 ++what;
64 }
65 if (*what == '\0') {
66 fclose(f);
67 return true;
68 } else {
69 what = search_string;
70 }
71 }
72 }
73 fclose(f);
74
75 // Did not find string in the proc file.
76 return false;
77 }
78 #endif
38 79
39 void CPUFeatures::InitOnce() { 80 void CPUFeatures::InitOnce() {
40 #if defined(USING_SIMULATOR) 81 #if defined(USING_SIMULATOR)
41 integer_division_supported_ = true; 82 integer_division_supported_ = true;
42 #else 83 #else
43 integer_division_supported_ = false; 84 ASSERT(CPUInfoContainsString("ARMv7")); // Implements ARMv7.
85 ASSERT(CPUInfoContainsString("vfp")); // Has floating point unit.
86 // Has integer division.
87 integer_division_supported_ = CPUInfoContainsString("idiva");
44 #endif // defined(USING_SIMULATOR) 88 #endif // defined(USING_SIMULATOR)
45 #if defined(DEBUG) 89 #if defined(DEBUG)
46 initialized_ = true; 90 initialized_ = true;
47 #endif 91 #endif
48 } 92 }
49 93
50 #undef __
51
52 94
53 // Instruction encoding bits. 95 // Instruction encoding bits.
54 enum { 96 enum {
55 H = 1 << 5, // halfword (or byte) 97 H = 1 << 5, // halfword (or byte)
56 L = 1 << 20, // load (or store) 98 L = 1 << 20, // load (or store)
57 S = 1 << 20, // set condition code (or leave unchanged) 99 S = 1 << 20, // set condition code (or leave unchanged)
58 W = 1 << 21, // writeback base register (or leave unchanged) 100 W = 1 << 21, // writeback base register (or leave unchanged)
59 A = 1 << 21, // accumulate in multiply instruction (or not) 101 A = 1 << 21, // accumulate in multiply instruction (or not)
60 B = 1 << 22, // unsigned byte (or word) 102 B = 1 << 22, // unsigned byte (or word)
61 D = 1 << 22, // high/lo bit of start of s/d register range 103 D = 1 << 22, // high/lo bit of start of s/d register range
(...skipping 26 matching lines...) Expand all
88 B24 = 1 << 24, 130 B24 = 1 << 24,
89 B25 = 1 << 25, 131 B25 = 1 << 25,
90 B26 = 1 << 26, 132 B26 = 1 << 26,
91 B27 = 1 << 27, 133 B27 = 1 << 27,
92 134
93 // ldrex/strex register field encodings. 135 // ldrex/strex register field encodings.
94 kLdExRnShift = 16, 136 kLdExRnShift = 16,
95 kLdExRtShift = 12, 137 kLdExRtShift = 12,
96 kStrExRnShift = 16, 138 kStrExRnShift = 16,
97 kStrExRdShift = 12, 139 kStrExRdShift = 12,
98 kStrExRtShift = 0, 140 kStrExRtShift = 0,
regis 2013/05/07 17:14:35 Unrelated to your change, but these ldrex/strex re
zra 2013/05/07 17:50:18 Done.
99 }; 141 };
100 142
101 143
102 uint32_t Address::encoding3() const { 144 uint32_t Address::encoding3() const {
103 if (kind_ == Immediate) { 145 if (kind_ == Immediate) {
104 uint32_t offset = encoding_ & kOffset12Mask; 146 uint32_t offset = encoding_ & kOffset12Mask;
105 ASSERT(offset < 256); 147 ASSERT(offset < 256);
106 return (encoding_ & ~kOffset12Mask) | B22 | 148 return (encoding_ & ~kOffset12Mask) | B22 |
107 ((offset & 0xf0) << 4) | (offset & 0xf); 149 ((offset & 0xf0) << 4) | (offset & 0xf);
108 } 150 }
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 526
485 void Assembler::EmitDivOp(Condition cond, int32_t opcode, 527 void Assembler::EmitDivOp(Condition cond, int32_t opcode,
486 Register rd, Register rn, Register rm) { 528 Register rd, Register rn, Register rm) {
487 ASSERT(CPUFeatures::integer_division_supported()); 529 ASSERT(CPUFeatures::integer_division_supported());
488 ASSERT(rd != kNoRegister); 530 ASSERT(rd != kNoRegister);
489 ASSERT(rn != kNoRegister); 531 ASSERT(rn != kNoRegister);
490 ASSERT(rm != kNoRegister); 532 ASSERT(rm != kNoRegister);
491 ASSERT(cond != kNoCondition); 533 ASSERT(cond != kNoCondition);
492 int32_t encoding = opcode | 534 int32_t encoding = opcode |
493 (static_cast<int32_t>(cond) << kConditionShift) | 535 (static_cast<int32_t>(cond) << kConditionShift) |
494 (static_cast<int32_t>(rn) << kRnShift) | 536 (static_cast<int32_t>(rn) << kDivRnShift) |
495 (static_cast<int32_t>(rd) << kRdShift) | 537 (static_cast<int32_t>(rd) << kDivRdShift) |
496 B26 | B25 | B24 | B20 | B4 | 538 B26 | B25 | B24 | B20 | B4 |
497 (static_cast<int32_t>(rm) << kRmShift); 539 (static_cast<int32_t>(rm) << kDivRmShift);
498 Emit(encoding); 540 Emit(encoding);
499 } 541 }
500 542
501 543
502 void Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) { 544 void Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) {
503 EmitDivOp(cond, 0, rd, rn, rm); 545 EmitDivOp(cond, 0, rd, rn, rm);
504 } 546 }
505 547
506 548
507 void Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) { 549 void Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) {
(...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after
2128 2170
2129 const char* Assembler::FpuRegisterName(FpuRegister reg) { 2171 const char* Assembler::FpuRegisterName(FpuRegister reg) {
2130 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 2172 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
2131 return fpu_reg_names[reg]; 2173 return fpu_reg_names[reg];
2132 } 2174 }
2133 2175
2134 } // namespace dart 2176 } // namespace dart
2135 2177
2136 #endif // defined TARGET_ARCH_ARM 2178 #endif // defined TARGET_ARCH_ARM
2137 2179
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_arm_test.cc » ('j') | runtime/vm/assembler_arm_test.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698