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

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
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(); return kByte;
2063 case kTypedDataFloat32ArrayCid:
2064 return kSWord;
2065 case kTypedDataFloat64ArrayCid:
2066 return kDWord;
2067 case kTypedDataFloat32x4ArrayCid:
2068 case kTypedDataInt32x4ArrayCid:
2069 case kTypedDataFloat64x2ArrayCid:
2070 return kRegList;
2071 case kTypedDataInt8ArrayViewCid:
2072 UNREACHABLE(); return kByte;
zra 2014/05/23 20:03:24 newline?
regis 2014/05/23 20:21:35 Done.
2073 default:
2074 UNREACHABLE(); return kByte;
zra 2014/05/23 20:03:24 newline?
regis 2014/05/23 20:21:35 Done.
2075 }
2076 }
2077
2078
2079 bool Address::CanHoldLoadOffset(OperandSize size,
2037 int32_t offset, 2080 int32_t offset,
2038 int32_t* offset_mask) { 2081 int32_t* offset_mask) {
2039 switch (type) { 2082 switch (size) {
2040 case kByte: 2083 case kByte:
2041 case kHalfword: 2084 case kHalfword:
2042 case kUnsignedHalfword: 2085 case kUnsignedHalfword:
2043 case kWordPair: { 2086 case kWordPair: {
2044 *offset_mask = 0xff; 2087 *offset_mask = 0xff;
2045 return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3. 2088 return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3.
2046 } 2089 }
2047 case kUnsignedByte: 2090 case kUnsignedByte:
2048 case kWord: { 2091 case kWord:
2092 case kUnsignedWord: {
2049 *offset_mask = 0xfff; 2093 *offset_mask = 0xfff;
2050 return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2. 2094 return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2.
2051 } 2095 }
2052 case kSWord: 2096 case kSWord:
2053 case kDWord: { 2097 case kDWord: {
2054 *offset_mask = 0x3fc; // Multiple of 4. 2098 *offset_mask = 0x3fc; // Multiple of 4.
2055 // VFP addressing mode. 2099 // VFP addressing mode.
2056 return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4)); 2100 return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4));
2057 } 2101 }
2102 case kRegList: {
2103 *offset_mask = 0x0;
2104 return offset == 0;
2105 }
2058 default: { 2106 default: {
2059 UNREACHABLE(); 2107 UNREACHABLE();
2060 return false; 2108 return false;
2061 } 2109 }
2062 } 2110 }
2063 } 2111 }
2064 2112
2065 2113
2066 bool Address::CanHoldStoreOffset(OperandSize type, 2114 bool Address::CanHoldStoreOffset(OperandSize size,
2067 int32_t offset, 2115 int32_t offset,
2068 int32_t* offset_mask) { 2116 int32_t* offset_mask) {
2069 switch (type) { 2117 switch (size) {
2070 case kHalfword: 2118 case kHalfword:
2119 case kUnsignedHalfword:
2071 case kWordPair: { 2120 case kWordPair: {
2072 *offset_mask = 0xff; 2121 *offset_mask = 0xff;
2073 return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3. 2122 return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3.
2074 } 2123 }
2075 case kByte: 2124 case kByte:
2076 case kWord: { 2125 case kUnsignedByte:
2126 case kWord:
2127 case kUnsignedWord: {
2077 *offset_mask = 0xfff; 2128 *offset_mask = 0xfff;
2078 return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2. 2129 return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2.
2079 } 2130 }
2080 case kSWord: 2131 case kSWord:
2081 case kDWord: { 2132 case kDWord: {
2082 *offset_mask = 0x3fc; // Multiple of 4. 2133 *offset_mask = 0x3fc; // Multiple of 4.
2083 // VFP addressing mode. 2134 // VFP addressing mode.
2084 return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4)); 2135 return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4));
2085 } 2136 }
2137 case kRegList: {
2138 *offset_mask = 0x0;
2139 return offset == 0;
2140 }
2086 default: { 2141 default: {
2087 UNREACHABLE(); 2142 UNREACHABLE();
2088 return false; 2143 return false;
2089 } 2144 }
2090 } 2145 }
2091 } 2146 }
2092 2147
2093 2148
2094 void Assembler::Push(Register rd, Condition cond) { 2149 void Assembler::Push(Register rd, Condition cond) {
2095 str(rd, Address(SP, -kWordSize, Address::PreIndex), cond); 2150 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. 2402 // A scratch register and IP are needed to load an arbitrary double.
2348 ASSERT(scratch != kNoRegister); 2403 ASSERT(scratch != kNoRegister);
2349 int64_t imm64 = bit_cast<int64_t, double>(value); 2404 int64_t imm64 = bit_cast<int64_t, double>(value);
2350 LoadImmediate(IP, Utils::Low32Bits(imm64), cond); 2405 LoadImmediate(IP, Utils::Low32Bits(imm64), cond);
2351 LoadImmediate(scratch, Utils::High32Bits(imm64), cond); 2406 LoadImmediate(scratch, Utils::High32Bits(imm64), cond);
2352 vmovdrr(dd, IP, scratch, cond); 2407 vmovdrr(dd, IP, scratch, cond);
2353 } 2408 }
2354 } 2409 }
2355 2410
2356 2411
2357 void Assembler::LoadFromOffset(OperandSize type, 2412 void Assembler::LoadFromOffset(OperandSize size,
2358 Register reg, 2413 Register reg,
2359 Register base, 2414 Register base,
2360 int32_t offset, 2415 int32_t offset,
2361 Condition cond) { 2416 Condition cond) {
2362 int32_t offset_mask = 0; 2417 int32_t offset_mask = 0;
2363 if (!Address::CanHoldLoadOffset(type, offset, &offset_mask)) { 2418 if (!Address::CanHoldLoadOffset(size, offset, &offset_mask)) {
2364 ASSERT(base != IP); 2419 ASSERT(base != IP);
2365 AddImmediate(IP, base, offset & ~offset_mask, cond); 2420 AddImmediate(IP, base, offset & ~offset_mask, cond);
2366 base = IP; 2421 base = IP;
2367 offset = offset & offset_mask; 2422 offset = offset & offset_mask;
2368 } 2423 }
2369 switch (type) { 2424 switch (size) {
2370 case kByte: 2425 case kByte:
2371 ldrsb(reg, Address(base, offset), cond); 2426 ldrsb(reg, Address(base, offset), cond);
2372 break; 2427 break;
2373 case kUnsignedByte: 2428 case kUnsignedByte:
2374 ldrb(reg, Address(base, offset), cond); 2429 ldrb(reg, Address(base, offset), cond);
2375 break; 2430 break;
2376 case kHalfword: 2431 case kHalfword:
2377 ldrsh(reg, Address(base, offset), cond); 2432 ldrsh(reg, Address(base, offset), cond);
2378 break; 2433 break;
2379 case kUnsignedHalfword: 2434 case kUnsignedHalfword:
2380 ldrh(reg, Address(base, offset), cond); 2435 ldrh(reg, Address(base, offset), cond);
2381 break; 2436 break;
2382 case kWord: 2437 case kWord:
2383 ldr(reg, Address(base, offset), cond); 2438 ldr(reg, Address(base, offset), cond);
2384 break; 2439 break;
2385 case kWordPair: 2440 case kWordPair:
2386 ldrd(reg, Address(base, offset), cond); 2441 ldrd(reg, Address(base, offset), cond);
2387 break; 2442 break;
2388 default: 2443 default:
2389 UNREACHABLE(); 2444 UNREACHABLE();
2390 } 2445 }
2391 } 2446 }
2392 2447
2393 2448
2394 void Assembler::StoreToOffset(OperandSize type, 2449 void Assembler::StoreToOffset(OperandSize size,
2395 Register reg, 2450 Register reg,
2396 Register base, 2451 Register base,
2397 int32_t offset, 2452 int32_t offset,
2398 Condition cond) { 2453 Condition cond) {
2399 int32_t offset_mask = 0; 2454 int32_t offset_mask = 0;
2400 if (!Address::CanHoldStoreOffset(type, offset, &offset_mask)) { 2455 if (!Address::CanHoldStoreOffset(size, offset, &offset_mask)) {
2401 ASSERT(reg != IP); 2456 ASSERT(reg != IP);
2402 ASSERT(base != IP); 2457 ASSERT(base != IP);
2403 AddImmediate(IP, base, offset & ~offset_mask, cond); 2458 AddImmediate(IP, base, offset & ~offset_mask, cond);
2404 base = IP; 2459 base = IP;
2405 offset = offset & offset_mask; 2460 offset = offset & offset_mask;
2406 } 2461 }
2407 switch (type) { 2462 switch (size) {
2408 case kByte: 2463 case kByte:
2409 strb(reg, Address(base, offset), cond); 2464 strb(reg, Address(base, offset), cond);
2410 break; 2465 break;
2411 case kHalfword: 2466 case kHalfword:
2412 strh(reg, Address(base, offset), cond); 2467 strh(reg, Address(base, offset), cond);
2413 break; 2468 break;
2414 case kWord: 2469 case kWord:
2415 str(reg, Address(base, offset), cond); 2470 str(reg, Address(base, offset), cond);
2416 break; 2471 break;
2417 case kWordPair: 2472 case kWordPair:
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
3152 3207
3153 3208
3154 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3209 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3155 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 3210 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
3156 return fpu_reg_names[reg]; 3211 return fpu_reg_names[reg];
3157 } 3212 }
3158 3213
3159 } // namespace dart 3214 } // namespace dart
3160 3215
3161 #endif // defined TARGET_ARCH_ARM 3216 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698