Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |