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

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

Issue 1062593003: Fixes ARM multiplication instruction version checking. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 8 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/disassembler_arm.cc ('k') | runtime/vm/simulator_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" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex)); 910 __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
911 __ b(&carry_loop, NE); 911 __ b(&carry_loop, NE);
912 912
913 __ Bind(&done); 913 __ Bind(&done);
914 // Returning Object::null() is not required, since this method is private. 914 // Returning Object::null() is not required, since this method is private.
915 __ Ret(); 915 __ Ret();
916 } 916 }
917 917
918 918
919 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) { 919 void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
920 if (TargetCPUFeatures::arm_version() != ARMv7) {
921 return;
922 }
923 // Pseudo code: 920 // Pseudo code:
924 // static int _mulAdd(Uint32List x_digits, int xi, 921 // static int _mulAdd(Uint32List x_digits, int xi,
925 // Uint32List m_digits, int i, 922 // Uint32List m_digits, int i,
926 // Uint32List a_digits, int j, int n) { 923 // Uint32List a_digits, int j, int n) {
927 // uint32_t x = x_digits[xi >> 1]; // xi is Smi. 924 // uint32_t x = x_digits[xi >> 1]; // xi is Smi.
928 // if (x == 0 || n == 0) { 925 // if (x == 0 || n == 0) {
929 // return 1; 926 // return 1;
930 // } 927 // }
931 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi. 928 // uint32_t* mip = &m_digits[i >> 1]; // i is Smi.
932 // uint32_t* ajp = &a_digits[j >> 1]; // j is Smi. 929 // uint32_t* ajp = &a_digits[j >> 1]; // j is Smi.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex)); 1012 __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
1016 __ b(&propagate_carry_loop, CS); 1013 __ b(&propagate_carry_loop, CS);
1017 1014
1018 __ Bind(&done); 1015 __ Bind(&done);
1019 __ mov(R0, Operand(Smi::RawValue(1))); // One digit processed. 1016 __ mov(R0, Operand(Smi::RawValue(1))); // One digit processed.
1020 __ Ret(); 1017 __ Ret();
1021 } 1018 }
1022 1019
1023 1020
1024 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) { 1021 void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
1025 if (TargetCPUFeatures::arm_version() != ARMv7) {
1026 return;
1027 }
1028 // Pseudo code: 1022 // Pseudo code:
1029 // static int _sqrAdd(Uint32List x_digits, int i, 1023 // static int _sqrAdd(Uint32List x_digits, int i,
1030 // Uint32List a_digits, int used) { 1024 // Uint32List a_digits, int used) {
1031 // uint32_t* xip = &x_digits[i >> 1]; // i is Smi. 1025 // uint32_t* xip = &x_digits[i >> 1]; // i is Smi.
1032 // uint32_t x = *xip++; 1026 // uint32_t x = *xip++;
1033 // if (x == 0) return 1; 1027 // if (x == 0) return 1;
1034 // uint32_t* ajp = &a_digits[i]; // j == 2*i, i is Smi. 1028 // uint32_t* ajp = &a_digits[i]; // j == 2*i, i is Smi.
1035 // uint32_t aj = *ajp; 1029 // uint32_t aj = *ajp;
1036 // uint64_t t = x*x + aj; 1030 // uint64_t t = x*x + aj;
1037 // *ajp++ = low32(t); 1031 // *ajp++ = low32(t);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 __ Ret(); 1131 __ Ret();
1138 } 1132 }
1139 1133
1140 1134
1141 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) { 1135 void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
1142 // No unsigned 64-bit / 32-bit divide instruction. 1136 // No unsigned 64-bit / 32-bit divide instruction.
1143 } 1137 }
1144 1138
1145 1139
1146 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) { 1140 void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
1147 if (TargetCPUFeatures::arm_version() != ARMv7) {
1148 return;
1149 }
1150 // Pseudo code: 1141 // Pseudo code:
1151 // static int _mulMod(Uint32List args, Uint32List digits, int i) { 1142 // static int _mulMod(Uint32List args, Uint32List digits, int i) {
1152 // uint32_t rho = args[_RHO]; // _RHO == 2. 1143 // uint32_t rho = args[_RHO]; // _RHO == 2.
1153 // uint32_t d = digits[i >> 1]; // i is Smi. 1144 // uint32_t d = digits[i >> 1]; // i is Smi.
1154 // uint64_t t = rho*d; 1145 // uint64_t t = rho*d;
1155 // args[_MU] = t mod DIGIT_BASE; // _MU == 4. 1146 // args[_MU] = t mod DIGIT_BASE; // _MU == 4.
1156 // return 1; 1147 // return 1;
1157 // } 1148 // }
1158 1149
1159 // R4 = args 1150 // R4 = args
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 __ b(&double_op); 1428 __ b(&double_op);
1438 __ Bind(&fall_through); 1429 __ Bind(&fall_through);
1439 } 1430 }
1440 } 1431 }
1441 1432
1442 1433
1443 // var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64; 1434 // var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
1444 // _state[kSTATE_LO] = state & _MASK_32; 1435 // _state[kSTATE_LO] = state & _MASK_32;
1445 // _state[kSTATE_HI] = state >> 32; 1436 // _state[kSTATE_HI] = state >> 32;
1446 void Intrinsifier::Random_nextState(Assembler* assembler) { 1437 void Intrinsifier::Random_nextState(Assembler* assembler) {
1447 // No 32x32 -> 64 bit multiply/accumulate on ARMv5 or ARMv6. 1438 const Library& math_lib = Library::Handle(Library::MathLibrary());
1448 if (TargetCPUFeatures::arm_version() == ARMv7) { 1439 ASSERT(!math_lib.IsNull());
1449 const Library& math_lib = Library::Handle(Library::MathLibrary()); 1440 const Class& random_class = Class::Handle(
1450 ASSERT(!math_lib.IsNull()); 1441 math_lib.LookupClassAllowPrivate(Symbols::_Random()));
1451 const Class& random_class = Class::Handle( 1442 ASSERT(!random_class.IsNull());
1452 math_lib.LookupClassAllowPrivate(Symbols::_Random())); 1443 const Field& state_field = Field::ZoneHandle(
1453 ASSERT(!random_class.IsNull()); 1444 random_class.LookupInstanceField(Symbols::_state()));
1454 const Field& state_field = Field::ZoneHandle( 1445 ASSERT(!state_field.IsNull());
1455 random_class.LookupInstanceField(Symbols::_state())); 1446 const Field& random_A_field = Field::ZoneHandle(
1456 ASSERT(!state_field.IsNull()); 1447 random_class.LookupStaticField(Symbols::_A()));
1457 const Field& random_A_field = Field::ZoneHandle( 1448 ASSERT(!random_A_field.IsNull());
1458 random_class.LookupStaticField(Symbols::_A())); 1449 ASSERT(random_A_field.is_const());
1459 ASSERT(!random_A_field.IsNull()); 1450 const Instance& a_value = Instance::Handle(random_A_field.value());
1460 ASSERT(random_A_field.is_const()); 1451 const int64_t a_int_value = Integer::Cast(a_value).AsInt64Value();
1461 const Instance& a_value = Instance::Handle(random_A_field.value()); 1452 // 'a_int_value' is a mask.
1462 const int64_t a_int_value = Integer::Cast(a_value).AsInt64Value(); 1453 ASSERT(Utils::IsUint(32, a_int_value));
1463 // 'a_int_value' is a mask. 1454 int32_t a_int32_value = static_cast<int32_t>(a_int_value);
1464 ASSERT(Utils::IsUint(32, a_int_value));
1465 int32_t a_int32_value = static_cast<int32_t>(a_int_value);
1466 1455
1467 __ ldr(R0, Address(SP, 0 * kWordSize)); // Receiver. 1456 __ ldr(R0, Address(SP, 0 * kWordSize)); // Receiver.
1468 __ ldr(R1, FieldAddress(R0, state_field.Offset())); // Field '_state'. 1457 __ ldr(R1, FieldAddress(R0, state_field.Offset())); // Field '_state'.
1469 // Addresses of _state[0] and _state[1]. 1458 // Addresses of _state[0] and _state[1].
1470 1459
1471 const int64_t disp_0 = Instance::DataOffsetFor(kTypedDataUint32ArrayCid); 1460 const int64_t disp_0 = Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
1472 const int64_t disp_1 = disp_0 + 1461 const int64_t disp_1 = disp_0 +
1473 Instance::ElementSizeFor(kTypedDataUint32ArrayCid); 1462 Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
1474 1463
1475 __ LoadImmediate(R0, a_int32_value); 1464 __ LoadImmediate(R0, a_int32_value);
1476 __ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag); 1465 __ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag);
1477 __ LoadFromOffset(kWord, R3, R1, disp_1 - kHeapObjectTag); 1466 __ LoadFromOffset(kWord, R3, R1, disp_1 - kHeapObjectTag);
1478 __ mov(R6, Operand(0)); // Zero extend unsigned _state[kSTATE_HI]. 1467 __ mov(R6, Operand(0)); // Zero extend unsigned _state[kSTATE_HI].
1479 // Unsigned 32-bit multiply and 64-bit accumulate into R6:R3. 1468 // Unsigned 32-bit multiply and 64-bit accumulate into R6:R3.
1480 __ umlal(R3, R6, R0, R2); // R6:R3 <- R6:R3 + R0 * R2. 1469 __ umlal(R3, R6, R0, R2); // R6:R3 <- R6:R3 + R0 * R2.
1481 __ StoreToOffset(kWord, R3, R1, disp_0 - kHeapObjectTag); 1470 __ StoreToOffset(kWord, R3, R1, disp_0 - kHeapObjectTag);
1482 __ StoreToOffset(kWord, R6, R1, disp_1 - kHeapObjectTag); 1471 __ StoreToOffset(kWord, R6, R1, disp_1 - kHeapObjectTag);
1483 __ Ret(); 1472 __ Ret();
1484 }
1485 } 1473 }
1486 1474
1487 1475
1488 void Intrinsifier::ObjectEquals(Assembler* assembler) { 1476 void Intrinsifier::ObjectEquals(Assembler* assembler) {
1489 __ ldr(R0, Address(SP, 0 * kWordSize)); 1477 __ ldr(R0, Address(SP, 0 * kWordSize));
1490 __ ldr(R1, Address(SP, 1 * kWordSize)); 1478 __ ldr(R1, Address(SP, 1 * kWordSize));
1491 __ cmp(R0, Operand(R1)); 1479 __ cmp(R0, Operand(R1));
1492 __ LoadObject(R0, Bool::False(), NE); 1480 __ LoadObject(R0, Bool::False(), NE);
1493 __ LoadObject(R0, Bool::True(), EQ); 1481 __ LoadObject(R0, Bool::True(), EQ);
1494 __ Ret(); 1482 __ Ret();
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 Isolate* isolate = Isolate::Current(); 1942 Isolate* isolate = Isolate::Current();
1955 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate)); 1943 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate));
1956 // Set return value to Isolate::current_tag_. 1944 // Set return value to Isolate::current_tag_.
1957 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); 1945 __ ldr(R0, Address(R1, Isolate::current_tag_offset()));
1958 __ Ret(); 1946 __ Ret();
1959 } 1947 }
1960 1948
1961 } // namespace dart 1949 } // namespace dart
1962 1950
1963 #endif // defined TARGET_ARCH_ARM 1951 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/disassembler_arm.cc ('k') | runtime/vm/simulator_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698