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 |