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

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

Issue 16244007: Enable language tests on SIMARM and mark 14 of them as failing. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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" // 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 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 } 826 }
827 827
828 828
829 bool Intrinsifier::Integer_bitOr(Assembler* assembler) { 829 bool Intrinsifier::Integer_bitOr(Assembler* assembler) {
830 return Integer_bitOrFromInteger(assembler); 830 return Integer_bitOrFromInteger(assembler);
831 } 831 }
832 832
833 833
834 bool Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) { 834 bool Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
835 Label fall_through; 835 Label fall_through;
836 __ Untested("Intrinsifier::Integer_bitXorFromInteger");
837 836
838 TestBothArgumentsSmis(assembler, &fall_through); // checks two smis 837 TestBothArgumentsSmis(assembler, &fall_through); // checks two smis
839 __ eor(R0, R0, ShifterOperand(R1)); 838 __ eor(R0, R0, ShifterOperand(R1));
840 839
841 __ Ret(); 840 __ Ret();
842 __ Bind(&fall_through); 841 __ Bind(&fall_through);
843 return false; 842 return false;
844 } 843 }
845 844
846 845
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown 1118 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
1120 // type. Return true or false object in the register R0. Any NaN argument 1119 // type. Return true or false object in the register R0. Any NaN argument
1121 // returns false. Any non-double arg1 causes control flow to fall through to the 1120 // returns false. Any non-double arg1 causes control flow to fall through to the
1122 // slow case (compiled method body). 1121 // slow case (compiled method body).
1123 static bool CompareDoubles(Assembler* assembler, Condition true_condition) { 1122 static bool CompareDoubles(Assembler* assembler, Condition true_condition) {
1124 Label fall_through, is_smi, double_op; 1123 Label fall_through, is_smi, double_op;
1125 1124
1126 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); 1125 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
1127 // Both arguments are double, right operand is in R0. 1126 // Both arguments are double, right operand is in R0.
1128 1127
1129 __ AddImmediate(R0, Double::value_offset() - kHeapObjectTag); 1128 __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
1130 __ vldrd(D1, Address(R0));
1131 __ Bind(&double_op); 1129 __ Bind(&double_op);
1132 __ ldr(R0, Address(SP, 1 * kWordSize)); // Left argument. 1130 __ ldr(R0, Address(SP, 1 * kWordSize)); // Left argument.
1133 __ AddImmediate(R0, Double::value_offset() - kHeapObjectTag); 1131 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1134 __ vldrd(D0, Address(R0));
1135 1132
1136 __ vcmpd(D0, D1); 1133 __ vcmpd(D0, D1);
1137 __ vmstat(); 1134 __ vmstat();
1138 __ LoadObject(R0, Bool::False()); 1135 __ LoadObject(R0, Bool::False());
1139 // Return false if D0 or D1 was NaN before checking true condition. 1136 // Return false if D0 or D1 was NaN before checking true condition.
1140 __ bx(LR, VS); 1137 __ bx(LR, VS);
1141 __ LoadObject(R0, Bool::True(), true_condition); 1138 __ LoadObject(R0, Bool::True(), true_condition);
1142 __ Ret(); 1139 __ Ret();
1143 1140
1144 __ Bind(&is_smi); // Convert R0 to a double. 1141 __ Bind(&is_smi); // Convert R0 to a double.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 } 1173 }
1177 1174
1178 1175
1179 // Expects left argument to be double (receiver). Right argument is unknown. 1176 // Expects left argument to be double (receiver). Right argument is unknown.
1180 // Both arguments are on stack. 1177 // Both arguments are on stack.
1181 static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { 1178 static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
1182 Label fall_through; 1179 Label fall_through;
1183 1180
1184 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through); 1181 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through);
1185 // Both arguments are double, right operand is in R0. 1182 // Both arguments are double, right operand is in R0.
1186 // Can't use FieldAddress here. R0 is heap-object-tagged, so the offset will 1183 __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
1187 // not be 4-byte aligned.
1188 __ AddImmediate(R0, Double::value_offset() - kHeapObjectTag);
1189 __ vldrd(D1, Address(R0));
1190 __ ldr(R0, Address(SP, 1 * kWordSize)); // Left argument. 1184 __ ldr(R0, Address(SP, 1 * kWordSize)); // Left argument.
1191 __ AddImmediate(R0, Double::value_offset() - kHeapObjectTag); 1185 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1192 __ vldrd(D0, Address(R0));
1193 switch (kind) { 1186 switch (kind) {
1194 case Token::kADD: __ vaddd(D0, D0, D1); break; 1187 case Token::kADD: __ vaddd(D0, D0, D1); break;
1195 case Token::kSUB: __ vsubd(D0, D0, D1); break; 1188 case Token::kSUB: __ vsubd(D0, D0, D1); break;
1196 case Token::kMUL: __ vmuld(D0, D0, D1); break; 1189 case Token::kMUL: __ vmuld(D0, D0, D1); break;
1197 case Token::kDIV: __ vdivd(D0, D0, D1); break; 1190 case Token::kDIV: __ vdivd(D0, D0, D1); break;
1198 default: UNREACHABLE(); 1191 default: UNREACHABLE();
1199 } 1192 }
1200 const Class& double_class = Class::Handle( 1193 const Class& double_class = Class::Handle(
1201 Isolate::Current()->object_store()->double_class()); 1194 Isolate::Current()->object_store()->double_class());
1202 __ TryAllocate(double_class, &fall_through, R0); // Result register. 1195 __ TryAllocate(double_class, &fall_through, R0); // Result register.
1203 __ AddImmediate(R1, R0, Double::value_offset() - kHeapObjectTag); 1196 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1204 __ vstrd(D0, Address(R1));
1205 __ Ret(); 1197 __ Ret();
1206 __ Bind(&fall_through); 1198 __ Bind(&fall_through);
1207 return false; 1199 return false;
1208 } 1200 }
1209 1201
1210 1202
1211 bool Intrinsifier::Double_add(Assembler* assembler) { 1203 bool Intrinsifier::Double_add(Assembler* assembler) {
1212 return DoubleArithmeticOperations(assembler, Token::kADD); 1204 return DoubleArithmeticOperations(assembler, Token::kADD);
1213 } 1205 }
1214 1206
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 __ ldr(R0, Address(SP, 0 * kWordSize)); 1250 __ ldr(R0, Address(SP, 0 * kWordSize));
1259 __ tst(R0, ShifterOperand(kSmiTagMask)); 1251 __ tst(R0, ShifterOperand(kSmiTagMask));
1260 __ b(&fall_through, NE); 1252 __ b(&fall_through, NE);
1261 // Is Smi. 1253 // Is Smi.
1262 __ SmiUntag(R0); 1254 __ SmiUntag(R0);
1263 __ vmovsr(S0, R0); 1255 __ vmovsr(S0, R0);
1264 __ vcvtdi(D0, S0); 1256 __ vcvtdi(D0, S0);
1265 const Class& double_class = Class::Handle( 1257 const Class& double_class = Class::Handle(
1266 Isolate::Current()->object_store()->double_class()); 1258 Isolate::Current()->object_store()->double_class());
1267 __ TryAllocate(double_class, &fall_through, R0); // Result register. 1259 __ TryAllocate(double_class, &fall_through, R0); // Result register.
1268 __ AddImmediate(R1, R0, Double::value_offset() - kHeapObjectTag); 1260 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1269 __ vstrd(D0, Address(R1));
1270 __ Ret(); 1261 __ Ret();
1271 __ Bind(&fall_through); 1262 __ Bind(&fall_through);
1272 return false; 1263 return false;
1273 } 1264 }
1274 1265
1275 1266
1276 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) { 1267 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) {
1277 Label is_true; 1268 Label is_true;
1278 __ ldr(R0, Address(SP, 0 * kWordSize)); 1269 __ ldr(R0, Address(SP, 0 * kWordSize));
1279 __ AddImmediate(R0, Double::value_offset() - kHeapObjectTag); 1270 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1280 __ vldrd(D0, Address(R0));
1281 __ vcmpd(D0, D0); 1271 __ vcmpd(D0, D0);
1282 __ vmstat(); 1272 __ vmstat();
1283 __ LoadObject(R0, Bool::False(), VC); 1273 __ LoadObject(R0, Bool::False(), VC);
1284 __ LoadObject(R0, Bool::True(), VS); 1274 __ LoadObject(R0, Bool::True(), VS);
1285 __ Ret(); 1275 __ Ret();
1286 return true; 1276 return true;
1287 } 1277 }
1288 1278
1289 1279
1290 bool Intrinsifier::Double_getIsNegative(Assembler* assembler) { 1280 bool Intrinsifier::Double_getIsNegative(Assembler* assembler) {
1291 Label is_false, is_true, is_zero; 1281 Label is_false, is_true, is_zero;
1292 __ Untested("Intrinsifier::Double_getIsNegative");
1293 __ ldr(R0, Address(SP, 0 * kWordSize)); 1282 __ ldr(R0, Address(SP, 0 * kWordSize));
1294 __ AddImmediate(R0, Double::value_offset() - kHeapObjectTag); 1283 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1295 __ vldrd(D0, Address(R0));
1296 __ LoadDImmediate(D1, 0.0, R1); 1284 __ LoadDImmediate(D1, 0.0, R1);
1297 __ vcmpd(D0, D1); 1285 __ vcmpd(D0, D1);
1298 __ vmstat(); 1286 __ vmstat();
1299 __ b(&is_false, VS); // NaN -> false. 1287 __ b(&is_false, VS); // NaN -> false.
1300 __ b(&is_zero, EQ); // Check for negative zero. 1288 __ b(&is_zero, EQ); // Check for negative zero.
1301 __ b(&is_false, CS); // >= 0 -> false. 1289 __ b(&is_false, CS); // >= 0 -> false.
1302 1290
1303 __ Bind(&is_true); 1291 __ Bind(&is_true);
1304 __ LoadObject(R0, Bool::True()); 1292 __ LoadObject(R0, Bool::True());
1305 __ Ret(); 1293 __ Ret();
1306 1294
1307 __ Bind(&is_false); 1295 __ Bind(&is_false);
1308 __ LoadObject(R0, Bool::False()); 1296 __ LoadObject(R0, Bool::False());
1309 __ Ret(); 1297 __ Ret();
1310 1298
1311 __ Bind(&is_zero); 1299 __ Bind(&is_zero);
1312 // Check for negative zero by looking at the sign bit. 1300 // Check for negative zero by looking at the sign bit.
1313 __ vmovrrd(R0, R1, D0); // R1:R0 <- D0, so sign bit is in bit 31 of R1. 1301 __ vmovrrd(R0, R1, D0); // R1:R0 <- D0, so sign bit is in bit 31 of R1.
1314 __ mov(R1, ShifterOperand(R1, LSR, 31)); 1302 __ mov(R1, ShifterOperand(R1, LSR, 31));
1315 __ tst(R1, ShifterOperand(1)); 1303 __ tst(R1, ShifterOperand(1));
1316 __ b(&is_true, NE); // Sign bit set. 1304 __ b(&is_true, NE); // Sign bit set.
1317 __ b(&is_false); 1305 __ b(&is_false);
1318 return true; 1306 return true;
1319 } 1307 }
1320 1308
1321 1309
1322 bool Intrinsifier::Double_toInt(Assembler* assembler) { 1310 bool Intrinsifier::Double_toInt(Assembler* assembler) {
1323 __ ldr(R0, Address(SP, 0 * kWordSize)); 1311 __ ldr(R0, Address(SP, 0 * kWordSize));
1324 __ AddImmediate(R0, Double::value_offset() - kHeapObjectTag); 1312 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1325 __ vldrd(D0, Address(R0));
1326 __ vcvtid(S0, D0); 1313 __ vcvtid(S0, D0);
1327 __ vmovrs(R0, S0); 1314 __ vmovrs(R0, S0);
1328 // Overflow is signaled with minint. 1315 // Overflow is signaled with minint.
1329 Label fall_through; 1316 Label fall_through;
1330 // Check for overflow and that it fits into Smi. 1317 // Check for overflow and that it fits into Smi.
1331 __ CompareImmediate(R0, 0xC0000000); 1318 __ CompareImmediate(R0, 0xC0000000);
1332 __ b(&fall_through, MI); 1319 __ b(&fall_through, MI);
1333 __ SmiTag(R0); 1320 __ SmiTag(R0);
1334 __ Ret(); 1321 __ Ret();
1335 __ Bind(&fall_through); 1322 __ Bind(&fall_through);
1336 return false; 1323 return false;
1337 } 1324 }
1338 1325
1339 1326
1340 bool Intrinsifier::Math_sqrt(Assembler* assembler) { 1327 bool Intrinsifier::Math_sqrt(Assembler* assembler) {
1341 Label fall_through, is_smi, double_op; 1328 Label fall_through, is_smi, double_op;
1342 __ Untested("Intrinsifier::Math_sqrt");
1343 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); 1329 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
1344 // Argument is double and is in R0. 1330 // Argument is double and is in R0.
1345 __ AddImmediate(R0, Double::value_offset() - kHeapObjectTag); 1331 __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
1346 __ vldrd(D1, Address(R0));
1347 __ Bind(&double_op); 1332 __ Bind(&double_op);
1348 __ vsqrtd(D0, D1); 1333 __ vsqrtd(D0, D1);
1349 const Class& double_class = Class::Handle( 1334 const Class& double_class = Class::Handle(
1350 Isolate::Current()->object_store()->double_class()); 1335 Isolate::Current()->object_store()->double_class());
1351 __ TryAllocate(double_class, &fall_through, R0); // Result register. 1336 __ TryAllocate(double_class, &fall_through, R0); // Result register.
1352 __ AddImmediate(R1, R0, Double::value_offset() - kHeapObjectTag); 1337 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1353 __ vstrd(D0, Address(R1));
1354 __ Ret(); 1338 __ Ret();
1355 __ Bind(&is_smi); 1339 __ Bind(&is_smi);
1356 __ SmiUntag(R0); 1340 __ SmiUntag(R0);
1357 __ vmovsr(S0, R0); 1341 __ vmovsr(S0, R0);
1358 __ vcvtdi(D1, S0); 1342 __ vcvtdi(D1, S0);
1359 __ b(&double_op); 1343 __ b(&double_op);
1360 __ Bind(&fall_through); 1344 __ Bind(&fall_through);
1361 return false; 1345 return false;
1362 } 1346 }
1363 1347
(...skipping 23 matching lines...) Expand all
1387 const Field& random_A_field = Field::ZoneHandle( 1371 const Field& random_A_field = Field::ZoneHandle(
1388 random_class.LookupStaticField(Symbols::_A())); 1372 random_class.LookupStaticField(Symbols::_A()));
1389 ASSERT(!random_A_field.IsNull()); 1373 ASSERT(!random_A_field.IsNull());
1390 ASSERT(random_A_field.is_const()); 1374 ASSERT(random_A_field.is_const());
1391 const Instance& a_value = Instance::Handle(random_A_field.value()); 1375 const Instance& a_value = Instance::Handle(random_A_field.value());
1392 const int64_t a_int_value = Integer::Cast(a_value).AsInt64Value(); 1376 const int64_t a_int_value = Integer::Cast(a_value).AsInt64Value();
1393 // 'a_int_value' is a mask. 1377 // 'a_int_value' is a mask.
1394 ASSERT(Utils::IsUint(32, a_int_value)); 1378 ASSERT(Utils::IsUint(32, a_int_value));
1395 int32_t a_int32_value = static_cast<int32_t>(a_int_value); 1379 int32_t a_int32_value = static_cast<int32_t>(a_int_value);
1396 1380
1397 __ Untested("Random_nextState");
1398
1399 __ ldr(R0, Address(SP, 0 * kWordSize)); // Receiver. 1381 __ ldr(R0, Address(SP, 0 * kWordSize)); // Receiver.
1400 __ ldr(R1, FieldAddress(R0, state_field.Offset())); // Field '_state'. 1382 __ ldr(R1, FieldAddress(R0, state_field.Offset())); // Field '_state'.
1401 // Addresses of _state[0] and _state[1]. 1383 // Addresses of _state[0] and _state[1].
1402 1384
1403 const int64_t disp_0 = 1385 const int64_t disp_0 =
1404 FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid); 1386 FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid);
1405 1387
1406 const int64_t disp_1 = 1388 const int64_t disp_1 =
1407 FlowGraphCompiler::ElementSizeFor(kTypedDataUint32ArrayCid) + 1389 FlowGraphCompiler::ElementSizeFor(kTypedDataUint32ArrayCid) +
1408 FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid); 1390 FlowGraphCompiler::DataOffsetFor(kTypedDataUint32ArrayCid);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 __ Bind(&ok); 1679 __ Bind(&ok);
1698 __ Ret(); 1680 __ Ret();
1699 1681
1700 __ Bind(&fall_through); 1682 __ Bind(&fall_through);
1701 return false; 1683 return false;
1702 } 1684 }
1703 1685
1704 } // namespace dart 1686 } // namespace dart
1705 1687
1706 #endif // defined TARGET_ARCH_ARM 1688 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698