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

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

Issue 300513002: Generate better ARM code for indexed loads and stores. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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 | « runtime/vm/assembler_arm.h ('k') | runtime/vm/intermediate_language_arm.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/cpu.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 2015 matching lines...) Expand 10 before | Expand all | Expand 10 after
2026 const ARMVersion version = TargetCPUFeatures::arm_version(); 2026 const ARMVersion version = TargetCPUFeatures::arm_version();
2027 if ((version == ARMv5TE) || (version == ARMv6)) { 2027 if ((version == ARMv5TE) || (version == ARMv6)) {
2028 BindARMv6(label); 2028 BindARMv6(label);
2029 } else { 2029 } else {
2030 ASSERT(version == ARMv7); 2030 ASSERT(version == ARMv7);
2031 BindARMv7(label); 2031 BindARMv7(label);
2032 } 2032 }
2033 } 2033 }
2034 2034
2035 2035
2036 bool Address::CanHoldLoadOffset(OperandSize type, 2036 OperandSize Address::OperandSizeFor(intptr_t cid) {
2037 switch (cid) {
2038 case kArrayCid:
2039 case kImmutableArrayCid:
2040 return kWord;
2041 case kOneByteStringCid:
2042 return kByte;
2043 case kTwoByteStringCid:
2044 return kHalfword;
2045 case kTypedDataInt8ArrayCid:
2046 return kByte;
2047 case kTypedDataUint8ArrayCid:
2048 case kTypedDataUint8ClampedArrayCid:
2049 case kExternalTypedDataUint8ArrayCid:
2050 case kExternalTypedDataUint8ClampedArrayCid:
2051 return kUnsignedByte;
2052 case kTypedDataInt16ArrayCid:
2053 return kHalfword;
2054 case kTypedDataUint16ArrayCid:
2055 return kUnsignedHalfword;
2056 case kTypedDataInt32ArrayCid:
2057 return kWord;
2058 case kTypedDataUint32ArrayCid:
2059 return kUnsignedWord;
2060 case kTypedDataInt64ArrayCid:
2061 case kTypedDataUint64ArrayCid:
2062 UNREACHABLE();
2063 return kByte;
2064 case kTypedDataFloat32ArrayCid:
2065 return kSWord;
2066 case kTypedDataFloat64ArrayCid:
2067 return kDWord;
2068 case kTypedDataFloat32x4ArrayCid:
2069 case kTypedDataInt32x4ArrayCid:
2070 case kTypedDataFloat64x2ArrayCid:
2071 return kRegList;
2072 case kTypedDataInt8ArrayViewCid:
2073 UNREACHABLE();
2074 return kByte;
2075 default:
2076 UNREACHABLE();
2077 return kByte;
2078 }
2079 }
2080
2081
2082 bool Address::CanHoldLoadOffset(OperandSize size,
2037 int32_t offset, 2083 int32_t offset,
2038 int32_t* offset_mask) { 2084 int32_t* offset_mask) {
2039 switch (type) { 2085 switch (size) {
2040 case kByte: 2086 case kByte:
2041 case kHalfword: 2087 case kHalfword:
2042 case kUnsignedHalfword: 2088 case kUnsignedHalfword:
2043 case kWordPair: { 2089 case kWordPair: {
2044 *offset_mask = 0xff; 2090 *offset_mask = 0xff;
2045 return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3. 2091 return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3.
2046 } 2092 }
2047 case kUnsignedByte: 2093 case kUnsignedByte:
2048 case kWord: { 2094 case kWord:
2095 case kUnsignedWord: {
2049 *offset_mask = 0xfff; 2096 *offset_mask = 0xfff;
2050 return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2. 2097 return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2.
2051 } 2098 }
2052 case kSWord: 2099 case kSWord:
2053 case kDWord: { 2100 case kDWord: {
2054 *offset_mask = 0x3fc; // Multiple of 4. 2101 *offset_mask = 0x3fc; // Multiple of 4.
2055 // VFP addressing mode. 2102 // VFP addressing mode.
2056 return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4)); 2103 return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4));
2057 } 2104 }
2105 case kRegList: {
2106 *offset_mask = 0x0;
2107 return offset == 0;
2108 }
2058 default: { 2109 default: {
2059 UNREACHABLE(); 2110 UNREACHABLE();
2060 return false; 2111 return false;
2061 } 2112 }
2062 } 2113 }
2063 } 2114 }
2064 2115
2065 2116
2066 bool Address::CanHoldStoreOffset(OperandSize type, 2117 bool Address::CanHoldStoreOffset(OperandSize size,
2067 int32_t offset, 2118 int32_t offset,
2068 int32_t* offset_mask) { 2119 int32_t* offset_mask) {
2069 switch (type) { 2120 switch (size) {
2070 case kHalfword: 2121 case kHalfword:
2122 case kUnsignedHalfword:
2071 case kWordPair: { 2123 case kWordPair: {
2072 *offset_mask = 0xff; 2124 *offset_mask = 0xff;
2073 return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3. 2125 return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3.
2074 } 2126 }
2075 case kByte: 2127 case kByte:
2076 case kWord: { 2128 case kUnsignedByte:
2129 case kWord:
2130 case kUnsignedWord: {
2077 *offset_mask = 0xfff; 2131 *offset_mask = 0xfff;
2078 return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2. 2132 return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2.
2079 } 2133 }
2080 case kSWord: 2134 case kSWord:
2081 case kDWord: { 2135 case kDWord: {
2082 *offset_mask = 0x3fc; // Multiple of 4. 2136 *offset_mask = 0x3fc; // Multiple of 4.
2083 // VFP addressing mode. 2137 // VFP addressing mode.
2084 return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4)); 2138 return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4));
2085 } 2139 }
2140 case kRegList: {
2141 *offset_mask = 0x0;
2142 return offset == 0;
2143 }
2086 default: { 2144 default: {
2087 UNREACHABLE(); 2145 UNREACHABLE();
2088 return false; 2146 return false;
2089 } 2147 }
2090 } 2148 }
2091 } 2149 }
2092 2150
2093 2151
2094 void Assembler::Push(Register rd, Condition cond) { 2152 void Assembler::Push(Register rd, Condition cond) {
2095 str(rd, Address(SP, -kWordSize, Address::PreIndex), cond); 2153 str(rd, Address(SP, -kWordSize, Address::PreIndex), cond);
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2347 // A scratch register and IP are needed to load an arbitrary double. 2405 // A scratch register and IP are needed to load an arbitrary double.
2348 ASSERT(scratch != kNoRegister); 2406 ASSERT(scratch != kNoRegister);
2349 int64_t imm64 = bit_cast<int64_t, double>(value); 2407 int64_t imm64 = bit_cast<int64_t, double>(value);
2350 LoadImmediate(IP, Utils::Low32Bits(imm64), cond); 2408 LoadImmediate(IP, Utils::Low32Bits(imm64), cond);
2351 LoadImmediate(scratch, Utils::High32Bits(imm64), cond); 2409 LoadImmediate(scratch, Utils::High32Bits(imm64), cond);
2352 vmovdrr(dd, IP, scratch, cond); 2410 vmovdrr(dd, IP, scratch, cond);
2353 } 2411 }
2354 } 2412 }
2355 2413
2356 2414
2357 void Assembler::LoadFromOffset(OperandSize type, 2415 void Assembler::LoadFromOffset(OperandSize size,
2358 Register reg, 2416 Register reg,
2359 Register base, 2417 Register base,
2360 int32_t offset, 2418 int32_t offset,
2361 Condition cond) { 2419 Condition cond) {
2362 int32_t offset_mask = 0; 2420 int32_t offset_mask = 0;
2363 if (!Address::CanHoldLoadOffset(type, offset, &offset_mask)) { 2421 if (!Address::CanHoldLoadOffset(size, offset, &offset_mask)) {
2364 ASSERT(base != IP); 2422 ASSERT(base != IP);
2365 AddImmediate(IP, base, offset & ~offset_mask, cond); 2423 AddImmediate(IP, base, offset & ~offset_mask, cond);
2366 base = IP; 2424 base = IP;
2367 offset = offset & offset_mask; 2425 offset = offset & offset_mask;
2368 } 2426 }
2369 switch (type) { 2427 switch (size) {
2370 case kByte: 2428 case kByte:
2371 ldrsb(reg, Address(base, offset), cond); 2429 ldrsb(reg, Address(base, offset), cond);
2372 break; 2430 break;
2373 case kUnsignedByte: 2431 case kUnsignedByte:
2374 ldrb(reg, Address(base, offset), cond); 2432 ldrb(reg, Address(base, offset), cond);
2375 break; 2433 break;
2376 case kHalfword: 2434 case kHalfword:
2377 ldrsh(reg, Address(base, offset), cond); 2435 ldrsh(reg, Address(base, offset), cond);
2378 break; 2436 break;
2379 case kUnsignedHalfword: 2437 case kUnsignedHalfword:
2380 ldrh(reg, Address(base, offset), cond); 2438 ldrh(reg, Address(base, offset), cond);
2381 break; 2439 break;
2382 case kWord: 2440 case kWord:
2383 ldr(reg, Address(base, offset), cond); 2441 ldr(reg, Address(base, offset), cond);
2384 break; 2442 break;
2385 case kWordPair: 2443 case kWordPair:
2386 ldrd(reg, Address(base, offset), cond); 2444 ldrd(reg, Address(base, offset), cond);
2387 break; 2445 break;
2388 default: 2446 default:
2389 UNREACHABLE(); 2447 UNREACHABLE();
2390 } 2448 }
2391 } 2449 }
2392 2450
2393 2451
2394 void Assembler::StoreToOffset(OperandSize type, 2452 void Assembler::StoreToOffset(OperandSize size,
2395 Register reg, 2453 Register reg,
2396 Register base, 2454 Register base,
2397 int32_t offset, 2455 int32_t offset,
2398 Condition cond) { 2456 Condition cond) {
2399 int32_t offset_mask = 0; 2457 int32_t offset_mask = 0;
2400 if (!Address::CanHoldStoreOffset(type, offset, &offset_mask)) { 2458 if (!Address::CanHoldStoreOffset(size, offset, &offset_mask)) {
2401 ASSERT(reg != IP); 2459 ASSERT(reg != IP);
2402 ASSERT(base != IP); 2460 ASSERT(base != IP);
2403 AddImmediate(IP, base, offset & ~offset_mask, cond); 2461 AddImmediate(IP, base, offset & ~offset_mask, cond);
2404 base = IP; 2462 base = IP;
2405 offset = offset & offset_mask; 2463 offset = offset & offset_mask;
2406 } 2464 }
2407 switch (type) { 2465 switch (size) {
2408 case kByte: 2466 case kByte:
2409 strb(reg, Address(base, offset), cond); 2467 strb(reg, Address(base, offset), cond);
2410 break; 2468 break;
2411 case kHalfword: 2469 case kHalfword:
2412 strh(reg, Address(base, offset), cond); 2470 strh(reg, Address(base, offset), cond);
2413 break; 2471 break;
2414 case kWord: 2472 case kWord:
2415 str(reg, Address(base, offset), cond); 2473 str(reg, Address(base, offset), cond);
2416 break; 2474 break;
2417 case kWordPair: 2475 case kWordPair:
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
3152 3210
3153 3211
3154 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3212 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3155 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 3213 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
3156 return fpu_reg_names[reg]; 3214 return fpu_reg_names[reg];
3157 } 3215 }
3158 3216
3159 } // namespace dart 3217 } // namespace dart
3160 3218
3161 #endif // defined TARGET_ARCH_ARM 3219 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698