Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright | 
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. | 
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above | 
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following | 
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided | 
| (...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1322 Label target; | 1322 Label target; | 
| 1323 __ beq(v0, v1, &target); | 1323 __ beq(v0, v1, &target); | 
| 1324 __ nop(); | 1324 __ nop(); | 
| 1325 __ bne(v0, v1, &target); | 1325 __ bne(v0, v1, &target); | 
| 1326 __ nop(); | 1326 __ nop(); | 
| 1327 __ bind(&target); | 1327 __ bind(&target); | 
| 1328 __ nop(); | 1328 __ nop(); | 
| 1329 } | 1329 } | 
| 1330 | 1330 | 
| 1331 | 1331 | 
| 1332 TEST(MIPS16) { | 1332 TEST(MIPS16) { | 
| 
 
paul.l...
2015/05/05 02:56:08
I've not been a fan of these numeric test names. I
 
Djordje.Pesic
2015/05/06 08:10:39
Done.
 
 | |
| 1333 if (IsMipsArchVariant(kMips32r6)) { | 1333 if (IsMipsArchVariant(kMips32r6)) { | 
| 
 
paul.l...
2015/05/05 02:56:09
I see 3 basic categories of tests, generic for all
 
Djordje.Pesic
2015/05/06 08:10:39
Done.
 
 | |
| 1334 CcTest::InitializeVM(); | 1334 CcTest::InitializeVM(); | 
| 1335 Isolate* isolate = CcTest::i_isolate(); | 1335 Isolate* isolate = CcTest::i_isolate(); | 
| 1336 HandleScope scope(isolate); | 1336 HandleScope scope(isolate); | 
| 1337 MacroAssembler assm(isolate, NULL, 0); | 1337 MacroAssembler assm(isolate, NULL, 0); | 
| 1338 | 1338 | 
| 1339 typedef struct test { | 1339 typedef struct test { | 
| 1340 int a; | 1340 int a; | 
| 1341 int b; | 1341 int b; | 
| 1342 int c; | 1342 int c; | 
| 1343 int d; | 1343 int d; | 
| 1344 double e; | 1344 double e; | 
| 1345 double f; | 1345 double f; | 
| 1346 double g; | 1346 double g; | 
| 1347 double h; | 1347 double h; | 
| 1348 float i; | |
| 1349 float j; | |
| 1350 float k; | |
| 1351 float l; | |
| 1348 } Test; | 1352 } Test; | 
| 1349 | 1353 | 
| 1350 Test test; | 1354 Test test; | 
| 1351 // Integer part of test. | 1355 // Integer part of test. | 
| 1352 __ addiu(t1, zero_reg, 1); // t1 = 1 | 1356 __ addiu(t1, zero_reg, 1); // t1 = 1 | 
| 1353 __ seleqz(t3, t1, zero_reg); // t3 = 1 | 1357 __ seleqz(t3, t1, zero_reg); // t3 = 1 | 
| 1354 __ sw(t3, MemOperand(a0, OFFSET_OF(Test, a))); // a = 1 | 1358 __ sw(t3, MemOperand(a0, OFFSET_OF(Test, a))); // a = 1 | 
| 1355 __ seleqz(t2, t1, t1); // t2 = 0 | 1359 __ seleqz(t2, t1, t1); // t2 = 0 | 
| 1356 __ sw(t2, MemOperand(a0, OFFSET_OF(Test, b))); // b = 0 | 1360 __ sw(t2, MemOperand(a0, OFFSET_OF(Test, b))); // b = 0 | 
| 1357 __ selnez(t3, t1, zero_reg); // t3 = 1; | 1361 __ selnez(t3, t1, zero_reg); // t3 = 1; | 
| 1358 __ sw(t3, MemOperand(a0, OFFSET_OF(Test, c))); // c = 0 | 1362 __ sw(t3, MemOperand(a0, OFFSET_OF(Test, c))); // c = 0 | 
| 1359 __ selnez(t3, t1, t1); // t3 = 1 | 1363 __ selnez(t3, t1, t1); // t3 = 1 | 
| 1360 __ sw(t3, MemOperand(a0, OFFSET_OF(Test, d))); // d = 1 | 1364 __ sw(t3, MemOperand(a0, OFFSET_OF(Test, d))); // d = 1 | 
| 1361 // Floating point part of test. | 1365 // Floating point part of test. | 
| 1362 __ ldc1(f0, MemOperand(a0, OFFSET_OF(Test, e)) ); // src | 1366 __ ldc1(f0, MemOperand(a0, OFFSET_OF(Test, e)) ); // src | 
| 1363 __ ldc1(f2, MemOperand(a0, OFFSET_OF(Test, f)) ); // test | 1367 __ ldc1(f2, MemOperand(a0, OFFSET_OF(Test, f)) ); // test | 
| 1368 __ lwc1(f8, MemOperand(a0, OFFSET_OF(Test, i)) ); // src | |
| 1369 __ lwc1(f10, MemOperand(a0, OFFSET_OF(Test, j)) ); // test | |
| 1364 __ seleqz(D, f4, f0, f2); | 1370 __ seleqz(D, f4, f0, f2); | 
| 
 
paul.l...
2015/05/05 02:56:08
The seleqz functions should have assembler aliases
 
Djordje.Pesic
2015/05/06 08:10:39
Done.
 
 | |
| 1365 __ selnez(D, f6, f0, f2); | 1371 __ selnez(D, f6, f0, f2); | 
| 1372 __ seleqz(S, f12, f8, f10); | |
| 1373 __ selnez(S, f14, f8, f10); | |
| 1366 __ sdc1(f4, MemOperand(a0, OFFSET_OF(Test, g)) ); // src | 1374 __ sdc1(f4, MemOperand(a0, OFFSET_OF(Test, g)) ); // src | 
| 1367 __ sdc1(f6, MemOperand(a0, OFFSET_OF(Test, h)) ); // src | 1375 __ sdc1(f6, MemOperand(a0, OFFSET_OF(Test, h)) ); // src | 
| 1376 __ swc1(f12, MemOperand(a0, OFFSET_OF(Test, k)) ); // src | |
| 1377 __ swc1(f14, MemOperand(a0, OFFSET_OF(Test, l)) ); // src | |
| 1368 __ jr(ra); | 1378 __ jr(ra); | 
| 1369 __ nop(); | 1379 __ nop(); | 
| 1370 CodeDesc desc; | 1380 CodeDesc desc; | 
| 1371 assm.GetCode(&desc); | 1381 assm.GetCode(&desc); | 
| 1372 Handle<Code> code = isolate->factory()->NewCode( | 1382 Handle<Code> code = isolate->factory()->NewCode( | 
| 1373 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 1383 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 
| 1374 F3 f = FUNCTION_CAST<F3>(code->entry()); | 1384 F3 f = FUNCTION_CAST<F3>(code->entry()); | 
| 1375 | 1385 | 
| 1376 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 1386 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 
| 1377 | 1387 | 
| 1378 CHECK_EQ(test.a, 1); | 1388 CHECK_EQ(test.a, 1); | 
| 1379 CHECK_EQ(test.b, 0); | 1389 CHECK_EQ(test.b, 0); | 
| 1380 CHECK_EQ(test.c, 0); | 1390 CHECK_EQ(test.c, 0); | 
| 1381 CHECK_EQ(test.d, 1); | 1391 CHECK_EQ(test.d, 1); | 
| 1382 | 1392 | 
| 1383 const int test_size = 3; | 1393 const int test_size = 3; | 
| 1384 const int input_size = 5; | 1394 const int input_size = 5; | 
| 1385 | 1395 | 
| 1386 double inputs[input_size] = {0.0, 65.2, -70.32, | 1396 double inputs_D[input_size] = {0.0, 65.2, -70.32, | 
| 1387 18446744073709551621.0, -18446744073709551621.0}; | 1397 18446744073709551621.0, -18446744073709551621.0}; | 
| 1388 double outputs[input_size] = {0.0, 65.2, -70.32, | 1398 double outputs_D[input_size] = {0.0, 65.2, -70.32, | 
| 1389 18446744073709551621.0, -18446744073709551621.0}; | 1399 18446744073709551621.0, -18446744073709551621.0}; | 
| 1390 double tests[test_size*2] = {2.8, 2.9, -2.8, -2.9, | 1400 double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9, | 
| 1391 18446744073709551616.0, 18446744073709555712.0}; | 1401 18446744073709551616.0, 18446744073709555712.0}; | 
| 1402 float inputs_S[input_size] = {0.0, 65.2, -70.32, | |
| 1403 18446744073709551621.0, -18446744073709551621.0}; | |
| 1404 float outputs_S[input_size] = {0.0, 65.2, -70.32, | |
| 1405 18446744073709551621.0, -18446744073709551621.0}; | |
| 1406 float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8, | |
| 1407 18446744073709551616.0, 18446746272732807168.0}; | |
| 1392 for (int j=0; j < test_size; j+=2) { | 1408 for (int j=0; j < test_size; j+=2) { | 
| 1393 for (int i=0; i < input_size; i++) { | 1409 for (int i=0; i < input_size; i++) { | 
| 1394 test.e = inputs[i]; | 1410 test.e = inputs_D[i]; | 
| 1395 test.f = tests[j]; | 1411 test.f = tests_D[j]; | 
| 1412 test.i = inputs_S[i]; | |
| 1413 test.j = tests_S[j]; | |
| 1396 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 1414 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 
| 1397 CHECK_EQ(test.g, outputs[i]); | 1415 CHECK_EQ(test.g, outputs_D[i]); | 
| 1398 CHECK_EQ(test.h, 0); | 1416 CHECK_EQ(test.h, 0); | 
| 1417 CHECK_EQ(test.k, outputs_S[i]); | |
| 1418 CHECK_EQ(test.l, 0); | |
| 1399 | 1419 | 
| 1400 test.f = tests[j+1]; | 1420 test.f = tests_D[j+1]; | 
| 1421 test.j = tests_S[j+1]; | |
| 1401 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 1422 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 
| 1402 CHECK_EQ(test.g, 0); | 1423 CHECK_EQ(test.g, 0); | 
| 1403 CHECK_EQ(test.h, outputs[i]); | 1424 CHECK_EQ(test.h, outputs_D[i]); | 
| 1425 CHECK_EQ(test.k, 0); | |
| 1426 CHECK_EQ(test.l, outputs_S[i]); | |
| 1404 } | 1427 } | 
| 1405 } | 1428 } | 
| 1406 } | 1429 } | 
| 1407 } | 1430 } | 
| 1408 | 1431 | 
| 1409 | 1432 | 
| 1410 TEST(MIPS17) { | 1433 TEST(MIPS17) { | 
| 1411 if (IsMipsArchVariant(kMips32r6)) { | 1434 if (IsMipsArchVariant(kMips32r6)) { | 
| 1412 CcTest::InitializeVM(); | 1435 CcTest::InitializeVM(); | 
| 1413 Isolate* isolate = CcTest::i_isolate(); | 1436 Isolate* isolate = CcTest::i_isolate(); | 
| 1414 HandleScope scope(isolate); | 1437 HandleScope scope(isolate); | 
| 1415 MacroAssembler assm(isolate, NULL, 0); | 1438 MacroAssembler assm(isolate, NULL, 0); | 
| 1416 | 1439 | 
| 1417 typedef struct test_float { | 1440 typedef struct test_float { | 
| 1418 double a; | 1441 double a; | 
| 1419 double b; | 1442 double b; | 
| 1420 double c; | 1443 double c; | 
| 1421 double d; | 1444 double d; | 
| 1445 float e; | |
| 1446 float f; | |
| 1447 float g; | |
| 1448 float h; | |
| 1422 } TestFloat; | 1449 } TestFloat; | 
| 1423 | 1450 | 
| 1424 TestFloat test; | 1451 TestFloat test; | 
| 1452 const double dblNaN = std::numeric_limits<double>::quiet_NaN(); | |
| 1453 const float fltNaN = std::numeric_limits<float>::quiet_NaN(); | |
| 1454 const int tableLength = 5; | |
| 1455 double inputsa[tableLength] = {2.0, 3.0, dblNaN, 3.0, dblNaN}; | |
| 1456 double inputsb[tableLength] = {3.0, 2.0, 3.0, dblNaN, dblNaN}; | |
| 1457 double outputsdmin[tableLength] = {2.0, 2.0, 3.0, 3.0, dblNaN}; | |
| 1458 double outputsdmax[tableLength] = {3.0, 3.0, 3.0, 3.0, dblNaN}; | |
| 1459 | |
| 1460 float inputse[tableLength] = {2.0, 3.0, fltNaN, 3.0, fltNaN}; | |
| 1461 float inputsf[tableLength] = {3.0, 2.0, 3.0, fltNaN, fltNaN}; | |
| 1462 float outputsfmin[tableLength] = {2.0, 2.0, 3.0, 3.0, fltNaN}; | |
| 1463 float outputsfmax[tableLength] = {3.0, 3.0, 3.0, 3.0, fltNaN}; | |
| 1425 | 1464 | 
| 1426 __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a))); | 1465 __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a))); | 
| 1427 __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b))); | 1466 __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b))); | 
| 1467 __ lwc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, e))); | |
| 1468 __ lwc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, f))); | |
| 1428 __ min_d(f10, f4, f8); | 1469 __ min_d(f10, f4, f8); | 
| 1429 __ max_d(f12, f4, f8); | 1470 __ max_d(f12, f4, f8); | 
| 1471 __ min_s(f14, f2, f6); | |
| 1472 __ max_s(f16, f2, f6); | |
| 1430 __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, c))); | 1473 __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, c))); | 
| 1431 __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, d))); | 1474 __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, d))); | 
| 1475 __ swc1(f14, MemOperand(a0, OFFSET_OF(TestFloat, g))); | |
| 1476 __ swc1(f16, MemOperand(a0, OFFSET_OF(TestFloat, h))); | |
| 1432 __ jr(ra); | 1477 __ jr(ra); | 
| 1433 __ nop(); | 1478 __ nop(); | 
| 1434 | 1479 | 
| 1435 CodeDesc desc; | 1480 CodeDesc desc; | 
| 1436 assm.GetCode(&desc); | 1481 assm.GetCode(&desc); | 
| 1437 Handle<Code> code = isolate->factory()->NewCode( | 1482 Handle<Code> code = isolate->factory()->NewCode( | 
| 1438 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 1483 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 
| 1439 F3 f = FUNCTION_CAST<F3>(code->entry()); | 1484 F3 f = FUNCTION_CAST<F3>(code->entry()); | 
| 1440 test.a = 2.0; // a goes to fs | 1485 for (int i = 0; i < tableLength; i++) { | 
| 1441 test.b = 3.0; // b goes to ft | 1486 test.a = inputsa[i]; | 
| 1442 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 1487 test.b = inputsb[i]; | 
| 1443 CHECK_EQ(test.c, 2.0); | 1488 test.e = inputse[i]; | 
| 1444 CHECK_EQ(test.d, 3.0); | 1489 test.f = inputsf[i]; | 
| 1445 | 1490 | 
| 1446 test.a = 3.0; // a goes to fs | 1491 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 
| 1447 test.b = 2.0; // b goes to ft | |
| 1448 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 1449 CHECK_EQ(test.c, 2.0); | |
| 1450 CHECK_EQ(test.d, 3.0); | |
| 1451 | 1492 | 
| 1452 test.a = std::numeric_limits<double>::quiet_NaN(); | 1493 if (i < tableLength - 1) { | 
| 1453 test.b = 3.0; // b goes to ft | 1494 CHECK_EQ(test.c, outputsdmin[i]); | 
| 1454 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 1495 CHECK_EQ(test.d, outputsdmax[i]); | 
| 1455 CHECK_EQ(test.c, 3.0); | 1496 CHECK_EQ(test.g, outputsfmin[i]); | 
| 1456 CHECK_EQ(test.d, 3.0); | 1497 CHECK_EQ(test.h, outputsfmax[i]); | 
| 1457 | 1498 } else { | 
| 1458 test.b = std::numeric_limits<double>::quiet_NaN(); | 1499 DCHECK(std::isnan(test.c)); | 
| 1459 test.a = 3.0; // b goes to ft | 1500 DCHECK(std::isnan(test.d)); | 
| 1460 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 1501 DCHECK(std::isnan(test.g)); | 
| 1461 CHECK_EQ(test.c, 3.0); | 1502 DCHECK(std::isnan(test.h)); | 
| 1462 CHECK_EQ(test.d, 3.0); | 1503 } | 
| 1463 | 1504 } | 
| 1464 test.a = std::numeric_limits<double>::quiet_NaN(); | |
| 1465 test.b = std::numeric_limits<double>::quiet_NaN(); | |
| 1466 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 1467 DCHECK(std::isnan(test.c)); | |
| 1468 DCHECK(std::isnan(test.d)); | |
| 1469 } | 1505 } | 
| 1470 } | 1506 } | 
| 1471 | 1507 | 
| 1472 | 1508 | 
| 1473 TEST(MIPS18) { | 1509 TEST(MIPS18) { | 
| 1474 if (IsMipsArchVariant(kMips32r6)) { | 1510 if (IsMipsArchVariant(kMips32r6)) { | 
| 1475 const int tableLength = 30; | 1511 const int tableLength = 30; | 
| 1476 CcTest::InitializeVM(); | 1512 CcTest::InitializeVM(); | 
| 1477 Isolate* isolate = CcTest::i_isolate(); | 1513 Isolate* isolate = CcTest::i_isolate(); | 
| 1478 HandleScope scope(isolate); | 1514 HandleScope scope(isolate); | 
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1561 CodeDesc desc; | 1597 CodeDesc desc; | 
| 1562 assm.GetCode(&desc); | 1598 assm.GetCode(&desc); | 
| 1563 Handle<Code> code = isolate->factory()->NewCode( | 1599 Handle<Code> code = isolate->factory()->NewCode( | 
| 1564 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 1600 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 
| 1565 F3 f = FUNCTION_CAST<F3>(code->entry()); | 1601 F3 f = FUNCTION_CAST<F3>(code->entry()); | 
| 1566 | 1602 | 
| 1567 for (int j = 0; j < 4; j++) { | 1603 for (int j = 0; j < 4; j++) { | 
| 1568 test.fcsr = fcsr_inputs[j]; | 1604 test.fcsr = fcsr_inputs[j]; | 
| 1569 for (int i = 0; i < tableLength; i++) { | 1605 for (int i = 0; i < tableLength; i++) { | 
| 1570 test.a = inputs[i]; | 1606 test.a = inputs[i]; | 
| 1571 std::cout << j << " " << i << "\n"; | |
| 1572 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 1607 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 
| 1573 CHECK_EQ(test.b, outputs[j][i]); | 1608 CHECK_EQ(test.b, outputs[j][i]); | 
| 1574 } | 1609 } | 
| 1575 } | 1610 } | 
| 1576 } | 1611 } | 
| 1577 } | 1612 } | 
| 1578 | 1613 | 
| 1579 | 1614 | 
| 1580 TEST(MIPS19) { | 1615 TEST(MIPS19) { | 
| 1581 CcTest::InitializeVM(); | 1616 CcTest::InitializeVM(); | 
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1640 Test test; | 1675 Test test; | 
| 1641 CodeDesc desc; | 1676 CodeDesc desc; | 
| 1642 assm.GetCode(&desc); | 1677 assm.GetCode(&desc); | 
| 1643 Handle<Code> code = isolate->factory()->NewCode( | 1678 Handle<Code> code = isolate->factory()->NewCode( | 
| 1644 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 1679 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 
| 1645 F3 f = FUNCTION_CAST<F3>(code->entry()); | 1680 F3 f = FUNCTION_CAST<F3>(code->entry()); | 
| 1646 for (int j = 0; j < 4; j++) { | 1681 for (int j = 0; j < 4; j++) { | 
| 1647 test.fcsr = fcsr_inputs[j]; | 1682 test.fcsr = fcsr_inputs[j]; | 
| 1648 for (int i = 0; i < tableLength; i++) { | 1683 for (int i = 0; i < tableLength; i++) { | 
| 1649 test.a = inputs[i]; | 1684 test.a = inputs[i]; | 
| 1650 std::cout << i << " " << j << "\n"; | |
| 1651 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 1685 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 
| 1652 CHECK_EQ(test.b, outputs[j][i]); | 1686 CHECK_EQ(test.b, outputs[j][i]); | 
| 1653 } | 1687 } | 
| 1654 } | 1688 } | 
| 1655 } | 1689 } | 
| 1656 | 1690 | 
| 1657 | 1691 | 
| 1692 TEST(MIPS20) { | |
| 1693 CcTest::InitializeVM(); | |
| 1694 Isolate* isolate = CcTest::i_isolate(); | |
| 1695 HandleScope scope(isolate); | |
| 1696 MacroAssembler assm(isolate, NULL, 0); | |
| 1697 | |
| 1698 typedef struct test_float { | |
| 1699 double a; | |
| 1700 float b; | |
| 1701 int32_t c; // a trunc result | |
| 1702 int32_t d; // b trunc result | |
| 1703 }Test; | |
| 1704 const int tableLength = 15; | |
| 1705 double inputs_D[tableLength] = { | |
| 1706 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 1707 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 1708 2147483648.0, | |
| 1709 std::numeric_limits<double>::quiet_NaN(), | |
| 1710 std::numeric_limits<double>::infinity() | |
| 1711 }; | |
| 1712 float inputs_S[tableLength] = { | |
| 1713 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 1714 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 1715 2147483648.0, | |
| 1716 std::numeric_limits<float>::quiet_NaN(), | |
| 1717 std::numeric_limits<float>::infinity() | |
| 1718 }; | |
| 1719 double outputs[tableLength] = { | |
| 1720 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, | |
| 1721 -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, | |
| 1722 kFPUInvalidResult, kFPUInvalidResult, | |
| 1723 kFPUInvalidResult}; | |
| 1724 | |
| 1725 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) ); | |
| 1726 __ lwc1(f6, MemOperand(a0, OFFSET_OF(Test, b)) ); | |
| 1727 __ trunc_w_d(f8, f4); | |
| 1728 __ trunc_w_s(f10, f6); | |
| 1729 __ swc1(f8, MemOperand(a0, OFFSET_OF(Test, c)) ); | |
| 1730 __ swc1(f10, MemOperand(a0, OFFSET_OF(Test, d)) ); | |
| 1731 __ jr(ra); | |
| 1732 __ nop(); | |
| 1733 Test test; | |
| 1734 CodeDesc desc; | |
| 1735 assm.GetCode(&desc); | |
| 1736 Handle<Code> code = isolate->factory()->NewCode( | |
| 1737 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 1738 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 1739 for (int i = 0; i < tableLength; i++) { | |
| 1740 test.a = inputs_D[i]; | |
| 1741 test.b = inputs_S[i]; | |
| 1742 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 1743 CHECK_EQ(test.c, outputs[i]); | |
| 1744 CHECK_EQ(test.d, test.c); | |
| 1745 } | |
| 1746 } | |
| 1747 | |
| 1748 | |
| 1749 TEST(MIPS21) { | |
| 1750 if (IsMipsArchVariant(kMips32r2)) { | |
| 1751 CcTest::InitializeVM(); | |
| 1752 Isolate* isolate = CcTest::i_isolate(); | |
| 1753 HandleScope scope(isolate); | |
| 1754 MacroAssembler assm(isolate, NULL, 0); | |
| 1755 const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); | |
| 1756 typedef struct test_float { | |
| 1757 double a; | |
| 1758 float b; | |
| 1759 int64_t c; // a trunc result | |
| 1760 int64_t d; // b trunc result | |
| 1761 }Test; | |
| 1762 const int tableLength = 16; | |
| 1763 double inputs_D[tableLength] = { | |
| 1764 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 1765 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 1766 2147483648.0, | |
| 1767 std::numeric_limits<double>::quiet_NaN(), | |
| 1768 std::numeric_limits<double>::infinity(), | |
| 1769 9223372036854775808.0 | |
| 1770 }; | |
| 1771 float inputs_S[tableLength] = { | |
| 1772 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 1773 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 1774 2147483648.0, | |
| 1775 std::numeric_limits<float>::quiet_NaN(), | |
| 1776 std::numeric_limits<float>::infinity(), | |
| 1777 9223372036854775808.0 | |
| 1778 }; | |
| 1779 double outputs[tableLength] = { | |
| 1780 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, | |
| 1781 -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, | |
| 1782 2147483648.0, dFPU64InvalidResult, | |
| 1783 dFPU64InvalidResult, dFPU64InvalidResult}; | |
| 1784 | |
| 1785 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) ); | |
| 1786 __ lwc1(f6, MemOperand(a0, OFFSET_OF(Test, b)) ); | |
| 1787 __ trunc_l_d(f8, f4); | |
| 1788 __ trunc_l_s(f10, f6); | |
| 1789 __ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, c)) ); | |
| 1790 __ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, d)) ); | |
| 1791 __ jr(ra); | |
| 1792 __ nop(); | |
| 1793 Test test; | |
| 1794 CodeDesc desc; | |
| 1795 assm.GetCode(&desc); | |
| 1796 Handle<Code> code = isolate->factory()->NewCode( | |
| 1797 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 1798 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 1799 for (int i = 0; i < tableLength; i++) { | |
| 1800 test.a = inputs_D[i]; | |
| 1801 test.b = inputs_S[i]; | |
| 1802 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 1803 CHECK_EQ(test.c, outputs[i]); | |
| 1804 CHECK_EQ(test.d, test.c); | |
| 1805 } | |
| 1806 } | |
| 1807 } | |
| 1808 | |
| 1809 | |
| 1810 TEST(MIPS22) { | |
| 1811 if (IsMipsArchVariant(kMips32r6)) { | |
| 1812 CcTest::InitializeVM(); | |
| 1813 Isolate* isolate = CcTest::i_isolate(); | |
| 1814 HandleScope scope(isolate); | |
| 1815 MacroAssembler assm(isolate, NULL, 0); | |
| 1816 | |
| 1817 typedef struct test { | |
| 1818 double dd; | |
| 1819 double ds; | |
| 1820 double dt; | |
| 1821 float fd; | |
| 1822 float fs; | |
| 1823 float ft; | |
| 1824 } Test; | |
| 1825 | |
| 1826 Test test; | |
| 1827 __ ldc1(f0, MemOperand(a0, OFFSET_OF(Test, dd)) ); // test | |
| 1828 __ ldc1(f2, MemOperand(a0, OFFSET_OF(Test, ds)) ); // src1 | |
| 1829 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, dt)) ); // src2 | |
| 1830 __ lwc1(f6, MemOperand(a0, OFFSET_OF(Test, fd)) ); // test | |
| 1831 __ lwc1(f8, MemOperand(a0, OFFSET_OF(Test, fs)) ); // src1 | |
| 1832 __ lwc1(f10, MemOperand(a0, OFFSET_OF(Test, ft)) ); // src2 | |
| 1833 __ sel(D, f0, f2, f4); | |
| 1834 __ sel(S, f6, f8, f10); | |
| 1835 __ sdc1(f0, MemOperand(a0, OFFSET_OF(Test, dd)) ); | |
| 1836 __ swc1(f6, MemOperand(a0, OFFSET_OF(Test, fd)) ); | |
| 1837 __ jr(ra); | |
| 1838 __ nop(); | |
| 1839 CodeDesc desc; | |
| 1840 assm.GetCode(&desc); | |
| 1841 Handle<Code> code = isolate->factory()->NewCode( | |
| 1842 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 1843 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 1844 | |
| 1845 const int test_size = 3; | |
| 1846 const int input_size = 5; | |
| 1847 | |
| 1848 double inputs_dt[input_size] = {0.0, 65.2, -70.32, | |
| 1849 18446744073709551621.0, -18446744073709551621.0}; | |
| 1850 double inputs_ds[input_size] = {0.1, 69.88, -91.325, | |
| 1851 18446744073709551625.0, -18446744073709551625.0}; | |
| 1852 float inputs_ft[input_size] = {0.0, 65.2, -70.32, | |
| 1853 18446744073709551621.0, -18446744073709551621.0}; | |
| 1854 float inputs_fs[input_size] = {0.1, 69.88, -91.325, | |
| 1855 18446744073709551625.0, -18446744073709551625.0}; | |
| 1856 double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9, | |
| 1857 18446744073709551616.0, 18446744073709555712.0}; | |
| 1858 float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8, | |
| 1859 18446744073709551616.0, 18446746272732807168.0}; | |
| 1860 for (int j=0; j < test_size; j+=2) { | |
| 1861 for (int i=0; i < input_size; i++) { | |
| 1862 test.dt = inputs_dt[i]; | |
| 1863 test.dd = tests_D[j]; | |
| 1864 test.ds = inputs_ds[i]; | |
| 1865 test.ft = inputs_ft[i]; | |
| 1866 test.fd = tests_S[j]; | |
| 1867 test.fs = inputs_fs[i]; | |
| 1868 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 1869 CHECK_EQ(test.dd, inputs_ds[i]); | |
| 1870 CHECK_EQ(test.fd, inputs_fs[i]); | |
| 1871 | |
| 1872 test.dd = tests_D[j+1]; | |
| 1873 test.fd = tests_S[j+1]; | |
| 1874 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 1875 CHECK_EQ(test.dd, inputs_dt[i]); | |
| 1876 CHECK_EQ(test.fd, inputs_ft[i]); | |
| 1877 } | |
| 1878 } | |
| 1879 } | |
| 1880 } | |
| 1881 | |
| 1882 | |
| 1883 TEST(MIPS23) { | |
| 1884 CcTest::InitializeVM(); | |
| 1885 Isolate* isolate = CcTest::i_isolate(); | |
| 1886 HandleScope scope(isolate); | |
| 1887 MacroAssembler assm(isolate, NULL, 0); | |
| 1888 | |
| 1889 typedef struct test_float { | |
| 1890 double a; | |
| 1891 float b; | |
| 1892 int32_t c; // a trunc result | |
| 1893 int32_t d; // b trunc result | |
| 1894 }Test; | |
| 1895 const int tableLength = 15; | |
| 1896 double inputs_D[tableLength] = { | |
| 1897 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 1898 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 1899 2147483648.0, | |
| 1900 std::numeric_limits<double>::quiet_NaN(), | |
| 1901 std::numeric_limits<double>::infinity() | |
| 1902 }; | |
| 1903 float inputs_S[tableLength] = { | |
| 1904 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 1905 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 1906 2147483648.0, | |
| 1907 std::numeric_limits<float>::quiet_NaN(), | |
| 1908 std::numeric_limits<float>::infinity() | |
| 1909 }; | |
| 1910 double outputs[tableLength] = { | |
| 1911 2.0, 3.0, 2.0, 3.0, 4.0, 4.0, | |
| 1912 -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, | |
| 1913 kFPUInvalidResult, kFPUInvalidResult, | |
| 1914 kFPUInvalidResult}; | |
| 1915 | |
| 1916 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) ); | |
| 1917 __ lwc1(f6, MemOperand(a0, OFFSET_OF(Test, b)) ); | |
| 1918 __ round_w_d(f8, f4); | |
| 1919 __ round_w_s(f10, f6); | |
| 1920 __ swc1(f8, MemOperand(a0, OFFSET_OF(Test, c)) ); | |
| 1921 __ swc1(f10, MemOperand(a0, OFFSET_OF(Test, d)) ); | |
| 1922 __ jr(ra); | |
| 1923 __ nop(); | |
| 1924 Test test; | |
| 1925 CodeDesc desc; | |
| 1926 assm.GetCode(&desc); | |
| 1927 Handle<Code> code = isolate->factory()->NewCode( | |
| 1928 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 1929 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 1930 for (int i = 0; i < tableLength; i++) { | |
| 1931 test.a = inputs_D[i]; | |
| 1932 test.b = inputs_S[i]; | |
| 1933 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 1934 CHECK_EQ(test.c, outputs[i]); | |
| 1935 CHECK_EQ(test.d, test.c); | |
| 1936 } | |
| 1937 } | |
| 1938 | |
| 1939 | |
| 1940 TEST(MIPS24) { | |
| 1941 CcTest::InitializeVM(); | |
| 1942 Isolate* isolate = CcTest::i_isolate(); | |
| 1943 HandleScope scope(isolate); | |
| 1944 MacroAssembler assm(isolate, NULL, 0); | |
| 1945 const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); | |
| 1946 typedef struct test_float { | |
| 1947 double a; | |
| 1948 float b; | |
| 1949 int64_t c; | |
| 1950 int64_t d; | |
| 1951 }Test; | |
| 1952 const int tableLength = 16; | |
| 1953 double inputs_D[tableLength] = { | |
| 1954 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 1955 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 1956 2147483648.0, | |
| 1957 std::numeric_limits<double>::quiet_NaN(), | |
| 1958 std::numeric_limits<double>::infinity(), | |
| 1959 9223372036854775808.0 | |
| 1960 }; | |
| 1961 float inputs_S[tableLength] = { | |
| 1962 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 1963 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 1964 2147483648.0, | |
| 1965 std::numeric_limits<float>::quiet_NaN(), | |
| 1966 std::numeric_limits<float>::infinity(), | |
| 1967 9223372036854775808.0 | |
| 1968 }; | |
| 1969 double outputs[tableLength] = { | |
| 1970 2.0, 3.0, 2.0, 3.0, 4.0, 4.0, | |
| 1971 -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, | |
| 1972 2147483648.0, dFPU64InvalidResult, | |
| 1973 dFPU64InvalidResult, dFPU64InvalidResult}; | |
| 1974 | |
| 1975 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) ); | |
| 1976 __ lwc1(f6, MemOperand(a0, OFFSET_OF(Test, b)) ); | |
| 1977 __ round_l_d(f8, f4); | |
| 1978 __ round_l_s(f10, f6); | |
| 1979 __ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, c)) ); | |
| 1980 __ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, d)) ); | |
| 1981 __ jr(ra); | |
| 1982 __ nop(); | |
| 1983 Test test; | |
| 1984 CodeDesc desc; | |
| 1985 assm.GetCode(&desc); | |
| 1986 Handle<Code> code = isolate->factory()->NewCode( | |
| 1987 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 1988 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 1989 for (int i = 0; i < tableLength; i++) { | |
| 1990 test.a = inputs_D[i]; | |
| 1991 test.b = inputs_S[i]; | |
| 1992 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 1993 CHECK_EQ(test.c, outputs[i]); | |
| 1994 CHECK_EQ(test.d, test.c); | |
| 1995 } | |
| 1996 } | |
| 1997 | |
| 1998 | |
| 1999 TEST(MIPS25) { | |
| 2000 if (IsMipsArchVariant(kMips32r6)) { | |
| 2001 const int tableLength = 30; | |
| 2002 CcTest::InitializeVM(); | |
| 2003 Isolate* isolate = CcTest::i_isolate(); | |
| 2004 HandleScope scope(isolate); | |
| 2005 MacroAssembler assm(isolate, NULL, 0); | |
| 2006 | |
| 2007 typedef struct test_float { | |
| 2008 float a; | |
| 2009 float b; | |
| 2010 int fcsr; | |
| 2011 }TestFloat; | |
| 2012 | |
| 2013 TestFloat test; | |
| 2014 float inputs[tableLength] = {18446744073709551617.0, | |
| 2015 4503599627370496.0, -4503599627370496.0, | |
| 2016 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, | |
| 2017 1.7976931348623157E+38, 6.27463370218383111104242366943E-37, | |
| 2018 309485009821345068724781056.89, | |
| 2019 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 2020 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 2021 37778931862957161709568.0, 37778931862957161709569.0, | |
| 2022 37778931862957161709580.0, 37778931862957161709581.0, | |
| 2023 37778931862957161709582.0, 37778931862957161709583.0, | |
| 2024 37778931862957161709584.0, 37778931862957161709585.0, | |
| 2025 37778931862957161709586.0, 37778931862957161709587.0}; | |
| 2026 float outputs_RN[tableLength] = {18446744073709551617.0, | |
| 2027 4503599627370496.0, -4503599627370496.0, | |
| 2028 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, | |
| 2029 1.7976931348623157E38, 0, | |
| 2030 309485009821345068724781057.0, | |
| 2031 2.0, 3.0, 2.0, 3.0, 4.0, 4.0, | |
| 2032 -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, | |
| 2033 37778931862957161709568.0, 37778931862957161709569.0, | |
| 2034 37778931862957161709580.0, 37778931862957161709581.0, | |
| 2035 37778931862957161709582.0, 37778931862957161709583.0, | |
| 2036 37778931862957161709584.0, 37778931862957161709585.0, | |
| 2037 37778931862957161709586.0, 37778931862957161709587.0}; | |
| 2038 float outputs_RZ[tableLength] = {18446744073709551617.0, | |
| 2039 4503599627370496.0, -4503599627370496.0, | |
| 2040 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, | |
| 2041 1.7976931348623157E38, 0, | |
| 2042 309485009821345068724781057.0, | |
| 2043 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, | |
| 2044 -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, | |
| 2045 37778931862957161709568.0, 37778931862957161709569.0, | |
| 2046 37778931862957161709580.0, 37778931862957161709581.0, | |
| 2047 37778931862957161709582.0, 37778931862957161709583.0, | |
| 2048 37778931862957161709584.0, 37778931862957161709585.0, | |
| 2049 37778931862957161709586.0, 37778931862957161709587.0}; | |
| 2050 float outputs_RP[tableLength] = {18446744073709551617.0, | |
| 2051 4503599627370496.0, -4503599627370496.0, | |
| 2052 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, | |
| 2053 1.7976931348623157E38, 1, | |
| 2054 309485009821345068724781057.0, | |
| 2055 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, | |
| 2056 -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, | |
| 2057 37778931862957161709568.0, 37778931862957161709569.0, | |
| 2058 37778931862957161709580.0, 37778931862957161709581.0, | |
| 2059 37778931862957161709582.0, 37778931862957161709583.0, | |
| 2060 37778931862957161709584.0, 37778931862957161709585.0, | |
| 2061 37778931862957161709586.0, 37778931862957161709587.0}; | |
| 2062 float outputs_RM[tableLength] = {18446744073709551617.0, | |
| 2063 4503599627370496.0, -4503599627370496.0, | |
| 2064 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, | |
| 2065 1.7976931348623157E38, 0, | |
| 2066 309485009821345068724781057.0, | |
| 2067 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, | |
| 2068 -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, | |
| 2069 37778931862957161709568.0, 37778931862957161709569.0, | |
| 2070 37778931862957161709580.0, 37778931862957161709581.0, | |
| 2071 37778931862957161709582.0, 37778931862957161709583.0, | |
| 2072 37778931862957161709584.0, 37778931862957161709585.0, | |
| 2073 37778931862957161709586.0, 37778931862957161709587.0}; | |
| 2074 int fcsr_inputs[4] = | |
| 2075 {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf}; | |
| 2076 float* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM}; | |
| 2077 __ lwc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)) ); | |
| 2078 __ lw(t0, MemOperand(a0, OFFSET_OF(TestFloat, fcsr)) ); | |
| 2079 __ cfc1(t1, FCSR); | |
| 2080 __ ctc1(t0, FCSR); | |
| 2081 __ rint(S, f8, f4); | |
| 2082 __ swc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)) ); | |
| 2083 __ ctc1(t1, FCSR); | |
| 2084 __ jr(ra); | |
| 2085 __ nop(); | |
| 2086 | |
| 2087 CodeDesc desc; | |
| 2088 assm.GetCode(&desc); | |
| 2089 Handle<Code> code = isolate->factory()->NewCode( | |
| 2090 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2091 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2092 | |
| 2093 for (int j = 0; j < 4; j++) { | |
| 2094 test.fcsr = fcsr_inputs[j]; | |
| 2095 for (int i = 0; i < tableLength; i++) { | |
| 2096 test.a = inputs[i]; | |
| 2097 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2098 CHECK_EQ(test.b, outputs[j][i]); | |
| 2099 } | |
| 2100 } | |
| 2101 } | |
| 2102 } | |
| 2103 | |
| 2104 | |
| 2105 TEST(MIPS26) { | |
| 2106 const int tableLength = 12; | |
| 2107 CcTest::InitializeVM(); | |
| 2108 Isolate* isolate = CcTest::i_isolate(); | |
| 2109 HandleScope scope(isolate); | |
| 2110 MacroAssembler assm(isolate, NULL, 0); | |
| 2111 | |
| 2112 typedef struct test_float { | |
| 2113 float a; | |
| 2114 float b; | |
| 2115 float resultS; | |
| 2116 double c; | |
| 2117 double d; | |
| 2118 double resultD; | |
| 2119 }TestFloat; | |
| 2120 | |
| 2121 TestFloat test; | |
| 2122 double inputfs_D[tableLength] = { | |
| 2123 5.3, 4.8, 2.9, -5.3, -4.8, -2.9, | |
| 2124 5.3, 4.8, 2.9, -5.3, -4.8, -2.9 | |
| 2125 }; | |
| 2126 double inputft_D[tableLength] = { | |
| 2127 4.8, 5.3, 2.9, 4.8, 5.3, 2.9, | |
| 2128 -4.8, -5.3, -2.9, -4.8, -5.3, -2.9 | |
| 2129 }; | |
| 2130 double outputs_D[tableLength] = { | |
| 2131 0.5, -0.5, 0.0, -10.1, -10.1, -5.8, | |
| 2132 10.1, 10.1, 5.8, -0.5, 0.5, 0.0 | |
| 2133 }; | |
| 2134 float inputfs_S[tableLength] = { | |
| 2135 5.3, 4.8, 2.9, -5.3, -4.8, -2.9, | |
| 2136 5.3, 4.8, 2.9, -5.3, -4.8, -2.9 | |
| 2137 }; | |
| 2138 float inputft_S[tableLength] = { | |
| 2139 4.8, 5.3, 2.9, 4.8, 5.3, 2.9, | |
| 2140 -4.8, -5.3, -2.9, -4.8, -5.3, -2.9 | |
| 2141 }; | |
| 2142 float outputs_S[tableLength] = { | |
| 2143 0.5, -0.5, 0.0, -10.1, -10.1, -5.8, | |
| 2144 10.1, 10.1, 5.8, -0.5, 0.5, 0.0 | |
| 2145 }; | |
| 2146 __ lwc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, a)) ); | |
| 2147 __ lwc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, b)) ); | |
| 2148 __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, c)) ); | |
| 2149 __ ldc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, d)) ); | |
| 2150 __ sub_s(f6, f2, f4); | |
| 2151 __ sub_d(f12, f8, f10); | |
| 2152 __ swc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, resultS)) ); | |
| 2153 __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, resultD)) ); | |
| 2154 __ jr(ra); | |
| 2155 __ nop(); | |
| 2156 | |
| 2157 CodeDesc desc; | |
| 2158 assm.GetCode(&desc); | |
| 2159 Handle<Code> code = isolate->factory()->NewCode( | |
| 2160 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2161 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2162 for (int i = 0; i < tableLength; i++) { | |
| 2163 test.a = inputfs_S[i]; | |
| 2164 test.b = inputft_S[i]; | |
| 2165 test.c = inputfs_D[i]; | |
| 2166 test.d = inputft_D[i]; | |
| 2167 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2168 CHECK_EQ(test.resultS, outputs_S[i]); | |
| 2169 CHECK_EQ(test.resultD, outputs_D[i]); | |
| 2170 } | |
| 2171 } | |
| 2172 | |
| 2173 | |
| 2174 TEST(MIPS27) { | |
| 2175 const int tableLength = 4; | |
| 2176 const double deltaDouble = 2E-15; | |
| 2177 const float deltaFloat = 2E-7; | |
| 2178 const float sqrt2_s = sqrt(2); | |
| 2179 const double sqrt2_d = sqrt(2); | |
| 2180 CcTest::InitializeVM(); | |
| 2181 Isolate* isolate = CcTest::i_isolate(); | |
| 2182 HandleScope scope(isolate); | |
| 2183 MacroAssembler assm(isolate, NULL, 0); | |
| 2184 | |
| 2185 typedef struct test_float { | |
| 2186 float a; | |
| 2187 float resultS; | |
| 2188 float resultS1; | |
| 2189 float resultS2; | |
| 2190 double c; | |
| 2191 double resultD; | |
| 2192 double resultD1; | |
| 2193 double resultD2; | |
| 2194 }TestFloat; | |
| 2195 TestFloat test; | |
| 2196 | |
| 2197 double inputs_D[tableLength] = { | |
| 2198 0.0L, 4.0L, 2.0L, 4e-28L | |
| 2199 }; | |
| 2200 | |
| 2201 double outputs_D[tableLength] = { | |
| 2202 0.0L, 2.0L, sqrt2_d, 2e-14L | |
| 2203 }; | |
| 2204 float inputs_S[tableLength] = { | |
| 2205 0.0, 4.0, 2.0, 4e-28 | |
| 2206 }; | |
| 2207 | |
| 2208 float outputs_S[tableLength] = { | |
| 2209 0.0, 2.0, sqrt2_s, 2e-14 | |
| 2210 }; | |
| 2211 | |
| 2212 | |
| 2213 __ lwc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, a)) ); | |
| 2214 __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, c)) ); | |
| 2215 __ sqrt_s(f6, f2); | |
| 2216 __ sqrt_d(f12, f8); | |
| 2217 __ rsqrt_d(f14, f8); | |
| 2218 __ rsqrt_s(f16, f2); | |
| 2219 __ recip_d(f18, f8); | |
| 2220 __ recip_s(f20, f2); | |
| 2221 __ swc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, resultS)) ); | |
| 2222 __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, resultD)) ); | |
| 2223 __ swc1(f16, MemOperand(a0, OFFSET_OF(TestFloat, resultS1)) ); | |
| 2224 __ sdc1(f14, MemOperand(a0, OFFSET_OF(TestFloat, resultD1)) ); | |
| 2225 __ swc1(f20, MemOperand(a0, OFFSET_OF(TestFloat, resultS2)) ); | |
| 2226 __ sdc1(f18, MemOperand(a0, OFFSET_OF(TestFloat, resultD2)) ); | |
| 2227 __ jr(ra); | |
| 2228 __ nop(); | |
| 2229 | |
| 2230 CodeDesc desc; | |
| 2231 assm.GetCode(&desc); | |
| 2232 Handle<Code> code = isolate->factory()->NewCode( | |
| 2233 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2234 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2235 | |
| 2236 for (int i = 0; i < tableLength; i++) { | |
| 2237 float f1; | |
| 2238 double d1; | |
| 2239 test.a = inputs_S[i]; | |
| 2240 test.c = inputs_D[i]; | |
| 2241 | |
| 2242 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2243 | |
| 2244 CHECK_EQ(test.resultS, outputs_S[i]); | |
| 2245 CHECK_EQ(test.resultD, outputs_D[i]); | |
| 2246 | |
| 2247 if (i != 0) { | |
| 2248 f1 = test.resultS1 - 1.0F/outputs_S[i]; | |
| 2249 f1 = (f1 < 0) ? f1 : -f1; | |
| 2250 CHECK(f1 <= deltaFloat); | |
| 2251 d1 = test.resultD1 - 1.0L/outputs_D[i]; | |
| 2252 d1 = (d1 < 0) ? d1 : -d1; | |
| 2253 CHECK(d1 <= deltaDouble); | |
| 2254 f1 = test.resultS2 - 1.0F/inputs_S[i]; | |
| 2255 f1 = (f1 < 0) ? f1 : -f1; | |
| 2256 CHECK(f1 <= deltaFloat); | |
| 2257 d1 = test.resultD2 - 1.0L/inputs_D[i]; | |
| 2258 d1 = (d1 < 0) ? d1 : -d1; | |
| 2259 CHECK(d1 <= deltaDouble); | |
| 2260 } else { | |
| 2261 CHECK_EQ(test.resultS1, 1.0F/outputs_S[i]); | |
| 2262 CHECK_EQ(test.resultD1, 1.0L/outputs_D[i]); | |
| 2263 CHECK_EQ(test.resultS2, 1.0F/inputs_S[i]); | |
| 2264 CHECK_EQ(test.resultD2, 1.0L/inputs_D[i]); | |
| 2265 } | |
| 2266 } | |
| 2267 } | |
| 2268 | |
| 2269 | |
| 2270 TEST(MIPS28) { | |
| 2271 const int tableLength = 3; | |
| 2272 CcTest::InitializeVM(); | |
| 2273 Isolate* isolate = CcTest::i_isolate(); | |
| 2274 HandleScope scope(isolate); | |
| 2275 MacroAssembler assm(isolate, NULL, 0); | |
| 2276 | |
| 2277 typedef struct test_float { | |
| 2278 float a; | |
| 2279 float resultS; | |
| 2280 double c; | |
| 2281 double resultD; | |
| 2282 }TestFloat; | |
| 2283 | |
| 2284 TestFloat test; | |
| 2285 double inputs_D[tableLength] = { | |
| 2286 0.0, 4.0, -2.0 | |
| 2287 }; | |
| 2288 | |
| 2289 double outputs_D[tableLength] = { | |
| 2290 0.0, -4.0, 2.0 | |
| 2291 }; | |
| 2292 float inputs_S[tableLength] = { | |
| 2293 0.0, 4.0, -2.0 | |
| 2294 }; | |
| 2295 | |
| 2296 float outputs_S[tableLength] = { | |
| 2297 0.0, -4.0, 2.0 | |
| 2298 }; | |
| 2299 __ lwc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, a)) ); | |
| 2300 __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, c)) ); | |
| 2301 __ neg_s(f6, f2); | |
| 2302 __ neg_d(f12, f8); | |
| 2303 __ swc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, resultS)) ); | |
| 2304 __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, resultD)) ); | |
| 2305 __ jr(ra); | |
| 2306 __ nop(); | |
| 2307 | |
| 2308 CodeDesc desc; | |
| 2309 assm.GetCode(&desc); | |
| 2310 Handle<Code> code = isolate->factory()->NewCode( | |
| 2311 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2312 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2313 for (int i = 0; i < tableLength; i++) { | |
| 2314 test.a = inputs_S[i]; | |
| 2315 test.c = inputs_D[i]; | |
| 2316 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2317 CHECK_EQ(test.resultS, outputs_S[i]); | |
| 2318 CHECK_EQ(test.resultD, outputs_D[i]); | |
| 2319 } | |
| 2320 } | |
| 2321 | |
| 2322 | |
| 2323 TEST(MIPS29) { | |
| 2324 const int tableLength = 4; | |
| 2325 CcTest::InitializeVM(); | |
| 2326 Isolate* isolate = CcTest::i_isolate(); | |
| 2327 HandleScope scope(isolate); | |
| 2328 MacroAssembler assm(isolate, NULL, 0); | |
| 2329 | |
| 2330 typedef struct test_float { | |
| 2331 float a; | |
| 2332 float b; | |
| 2333 float resultS; | |
| 2334 double c; | |
| 2335 double d; | |
| 2336 double resultD; | |
| 2337 }TestFloat; | |
| 2338 | |
| 2339 TestFloat test; | |
| 2340 double inputfs_D[tableLength] = { | |
| 2341 5.3, -5.3, 5.3, -2.9 | |
| 2342 }; | |
| 2343 double inputft_D[tableLength] = { | |
| 2344 4.8, 4.8, -4.8, -0.29 | |
| 2345 }; | |
| 2346 | |
| 2347 float inputfs_S[tableLength] = { | |
| 2348 5.3, -5.3, 5.3, -2.9 | |
| 2349 }; | |
| 2350 float inputft_S[tableLength] = { | |
| 2351 4.8, 4.8, -4.8, -0.29 | |
| 2352 }; | |
| 2353 | |
| 2354 __ lwc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, a)) ); | |
| 2355 __ lwc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, b)) ); | |
| 2356 __ ldc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, c)) ); | |
| 2357 __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, d)) ); | |
| 2358 __ mul_s(f10, f2, f4); | |
| 2359 __ mul_d(f12, f6, f8); | |
| 2360 __ swc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, resultS)) ); | |
| 2361 __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, resultD)) ); | |
| 2362 __ jr(ra); | |
| 2363 __ nop(); | |
| 2364 | |
| 2365 CodeDesc desc; | |
| 2366 assm.GetCode(&desc); | |
| 2367 Handle<Code> code = isolate->factory()->NewCode( | |
| 2368 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2369 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2370 for (int i = 0; i < tableLength; i++) { | |
| 2371 test.a = inputfs_S[i]; | |
| 2372 test.b = inputft_S[i]; | |
| 2373 test.c = inputfs_D[i]; | |
| 2374 test.d = inputft_D[i]; | |
| 2375 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2376 CHECK_EQ(test.resultS, inputfs_S[i]*inputft_S[i]); | |
| 2377 CHECK_EQ(test.resultD, inputfs_D[i]*inputft_D[i]); | |
| 2378 } | |
| 2379 } | |
| 2380 | |
| 2381 | |
| 2382 TEST(MIPS30) { | |
| 2383 if (IsMipsArchVariant(kMips32r2)) { | |
| 2384 const int tableLength = 4; | |
| 2385 CcTest::InitializeVM(); | |
| 2386 Isolate* isolate = CcTest::i_isolate(); | |
| 2387 HandleScope scope(isolate); | |
| 2388 MacroAssembler assm(isolate, NULL, 0); | |
| 2389 | |
| 2390 typedef struct test_float { | |
| 2391 int64_t rt; | |
| 2392 double a; | |
| 2393 double b; | |
| 2394 double bold; | |
| 2395 double b1; | |
| 2396 double bold1; | |
| 2397 float c; | |
| 2398 float d; | |
| 2399 float dold; | |
| 2400 float d1; | |
| 2401 float dold1; | |
| 2402 }TestFloat; | |
| 2403 | |
| 2404 TestFloat test; | |
| 2405 double inputs_D[tableLength] = { | |
| 2406 5.3, -5.3, 5.3, -2.9 | |
| 2407 }; | |
| 2408 double inputs_S[tableLength] = { | |
| 2409 4.8, 4.8, -4.8, -0.29 | |
| 2410 }; | |
| 2411 | |
| 2412 float outputs_S[tableLength] = { | |
| 2413 4.8, 4.8, -4.8, -0.29 | |
| 2414 }; | |
| 2415 double outputs_D[tableLength] = { | |
| 2416 5.3, -5.3, 5.3, -2.9 | |
| 2417 }; | |
| 2418 | |
| 2419 __ ldc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, a)) ); | |
| 2420 __ lwc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, c)) ); | |
| 2421 __ lw(t0, MemOperand(a0, OFFSET_OF(TestFloat, rt)) ); | |
| 2422 __ li(t1, 0x0); | |
| 2423 __ mtc1(t1, f12); | |
| 2424 __ mtc1(t1, f10); | |
| 2425 __ mtc1(t1, f16); | |
| 2426 __ mtc1(t1, f14); | |
| 2427 __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, bold)) ); | |
| 2428 __ swc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, dold)) ); | |
| 2429 __ sdc1(f16, MemOperand(a0, OFFSET_OF(TestFloat, bold1)) ); | |
| 2430 __ swc1(f14, MemOperand(a0, OFFSET_OF(TestFloat, dold1)) ); | |
| 2431 __ movz_s(f10, f6, t0); | |
| 2432 __ movz_d(f12, f2, t0); | |
| 2433 __ movn_s(f14, f6, t0); | |
| 2434 __ movn_d(f16, f2, t0); | |
| 2435 __ swc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, d)) ); | |
| 2436 __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, b)) ); | |
| 2437 __ swc1(f14, MemOperand(a0, OFFSET_OF(TestFloat, d1)) ); | |
| 2438 __ sdc1(f16, MemOperand(a0, OFFSET_OF(TestFloat, b1)) ); | |
| 2439 __ jr(ra); | |
| 2440 __ nop(); | |
| 2441 | |
| 2442 CodeDesc desc; | |
| 2443 assm.GetCode(&desc); | |
| 2444 Handle<Code> code = isolate->factory()->NewCode( | |
| 2445 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2446 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2447 for (int i = 0; i < tableLength; i++) { | |
| 2448 test.a = inputs_D[i]; | |
| 2449 test.c = inputs_S[i]; | |
| 2450 | |
| 2451 test.rt = 1; | |
| 2452 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2453 CHECK_EQ(test.b, test.bold); | |
| 2454 CHECK_EQ(test.d, test.dold); | |
| 2455 CHECK_EQ(test.b1, outputs_D[i]); | |
| 2456 CHECK_EQ(test.d1, outputs_S[i]); | |
| 2457 | |
| 2458 test.rt = 0; | |
| 2459 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2460 CHECK_EQ(test.b, outputs_D[i]); | |
| 2461 CHECK_EQ(test.d, outputs_S[i]); | |
| 2462 CHECK_EQ(test.b1, test.bold1); | |
| 2463 CHECK_EQ(test.d1, test.dold1); | |
| 2464 } | |
| 2465 } | |
| 2466 } | |
| 2467 | |
| 2468 | |
| 2469 TEST(MIPS31) { | |
| 2470 if (IsMipsArchVariant(kMips32r2)) { | |
| 2471 const int tableLength = 4; | |
| 2472 CcTest::InitializeVM(); | |
| 2473 Isolate* isolate = CcTest::i_isolate(); | |
| 2474 // HandleScope scope(isolate);HandleScope scope(isolate); | |
| 2475 // MacroAssembler assm(isolate, NULL, 0); | |
| 2476 | |
| 2477 typedef struct test_float { | |
| 2478 double srcd; | |
| 2479 double dstd; | |
| 2480 double dstdold; | |
| 2481 double dstd1; | |
| 2482 double dstdold1; | |
| 2483 float srcf; | |
| 2484 float dstf; | |
| 2485 float dstfold; | |
| 2486 float dstf1; | |
| 2487 float dstfold1; | |
| 2488 int32_t cc; | |
| 2489 int32_t fcsr; | |
| 2490 }TestFloat; | |
| 2491 | |
| 2492 TestFloat test; | |
| 2493 double inputs_D[tableLength] = { | |
| 2494 5.3, -5.3, 20.8, -2.9 | |
| 2495 }; | |
| 2496 double inputs_S[tableLength] = { | |
| 2497 4.88, 4.8, -4.8, -0.29 | |
| 2498 }; | |
| 2499 | |
| 2500 float outputs_S[tableLength] = { | |
| 2501 4.88, 4.8, -4.8, -0.29 | |
| 2502 }; | |
| 2503 double outputs_D[tableLength] = { | |
| 2504 5.3, -5.3, 20.8, -2.9 | |
| 2505 }; | |
| 2506 int condition_flags[8] = {0, 1, 2, 3, 4, 5, 6, 7}; | |
| 2507 | |
| 2508 for (int i = 0; i < tableLength; i++) { | |
| 2509 test.srcd = inputs_D[i]; | |
| 2510 test.srcf = inputs_S[i]; | |
| 2511 | |
| 2512 for (int j = 0; j< 8; j++) { | |
| 2513 test.cc = condition_flags[j]; | |
| 2514 if (test.cc == 0) { | |
| 2515 test.fcsr = 1 << 23; | |
| 2516 } else { | |
| 2517 test.fcsr = 1 << (24+condition_flags[j]); | |
| 2518 } | |
| 2519 HandleScope scope(isolate); | |
| 2520 MacroAssembler assm(isolate, NULL, 0); | |
| 2521 __ ldc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, srcd)) ); | |
| 2522 __ lwc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, srcf)) ); | |
| 2523 __ lw(t1, MemOperand(a0, OFFSET_OF(TestFloat, fcsr)) ); | |
| 2524 __ cfc1(t0, FCSR); | |
| 2525 __ ctc1(t1, FCSR); | |
| 2526 __ li(t2, 0x0); | |
| 2527 __ mtc1(t2, f12); | |
| 2528 __ mtc1(t2, f10); | |
| 2529 __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, dstdold)) ); | |
| 2530 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, dstfold)) ); | |
| 2531 __ movt_s(f12, f4, test.cc); | |
| 2532 __ movt_d(f10, f2, test.cc); | |
| 2533 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, dstf)) ); | |
| 2534 __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, dstd)) ); | |
| 2535 __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, dstdold1)) ); | |
| 2536 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, dstfold1)) ); | |
| 2537 __ movf_s(f12, f4, test.cc); | |
| 2538 __ movf_d(f10, f2, test.cc); | |
| 2539 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, dstf1)) ); | |
| 2540 __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, dstd1)) ); | |
| 2541 __ ctc1(t0, FCSR); | |
| 2542 __ jr(ra); | |
| 2543 __ nop(); | |
| 2544 | |
| 2545 CodeDesc desc; | |
| 2546 assm.GetCode(&desc); | |
| 2547 Handle<Code> code = isolate->factory()->NewCode( | |
| 2548 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2549 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2550 | |
| 2551 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2552 CHECK_EQ(test.dstf, outputs_S[i]); | |
| 2553 CHECK_EQ(test.dstd, outputs_D[i]); | |
| 2554 CHECK_EQ(test.dstf1, test.dstfold1); | |
| 2555 CHECK_EQ(test.dstd1, test.dstdold1); | |
| 2556 test.fcsr = 0; | |
| 2557 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2558 CHECK_EQ(test.dstf, test.dstfold); | |
| 2559 CHECK_EQ(test.dstd, test.dstdold); | |
| 2560 CHECK_EQ(test.dstf1, outputs_S[i]); | |
| 2561 CHECK_EQ(test.dstd1, outputs_D[i]); | |
| 2562 } | |
| 2563 } | |
| 2564 } | |
| 2565 } | |
| 2566 | |
| 2567 | |
| 2568 TEST(MIPS32) { | |
| 2569 const int tableLength = 4; | |
| 2570 CcTest::InitializeVM(); | |
| 2571 Isolate* isolate = CcTest::i_isolate(); | |
| 2572 HandleScope scope(isolate); | |
| 2573 MacroAssembler assm(isolate, NULL, 0); | |
| 2574 | |
| 2575 typedef struct test_float { | |
| 2576 double a; | |
| 2577 double b; | |
| 2578 float c; | |
| 2579 float d; | |
| 2580 }TestFloat; | |
| 2581 | |
| 2582 TestFloat test; | |
| 2583 double inputs_D[tableLength] = { | |
| 2584 5.3, -5.3, 5.3, -2.9 | |
| 2585 }; | |
| 2586 double inputs_S[tableLength] = { | |
| 2587 4.8, 4.8, -4.8, -0.29 | |
| 2588 }; | |
| 2589 | |
| 2590 float outputs_S[tableLength] = { | |
| 2591 4.8, 4.8, -4.8, -0.29 | |
| 2592 }; | |
| 2593 double outputs_D[tableLength] = { | |
| 2594 5.3, -5.3, 5.3, -2.9 | |
| 2595 }; | |
| 2596 | |
| 2597 __ ldc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, a)) ); | |
| 2598 __ lwc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, c)) ); | |
| 2599 __ mov_s(f18, f6); | |
| 2600 __ mov_d(f20, f2); | |
| 2601 __ swc1(f18, MemOperand(a0, OFFSET_OF(TestFloat, d)) ); | |
| 2602 __ sdc1(f20, MemOperand(a0, OFFSET_OF(TestFloat, b)) ); | |
| 2603 __ jr(ra); | |
| 2604 __ nop(); | |
| 2605 | |
| 2606 CodeDesc desc; | |
| 2607 assm.GetCode(&desc); | |
| 2608 Handle<Code> code = isolate->factory()->NewCode( | |
| 2609 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2610 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2611 for (int i = 0; i < tableLength; i++) { | |
| 2612 test.a = inputs_D[i]; | |
| 2613 test.c = inputs_S[i]; | |
| 2614 | |
| 2615 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2616 CHECK_EQ(test.b, outputs_D[i]); | |
| 2617 CHECK_EQ(test.d, outputs_S[i]); | |
| 2618 } | |
| 2619 } | |
| 2620 | |
| 2621 | |
| 2622 TEST(MIPS33) { | |
| 2623 if (IsMipsArchVariant(kMips32r6)) { | |
| 2624 const int tableLength = 12; | |
| 2625 CcTest::InitializeVM(); | |
| 2626 Isolate* isolate = CcTest::i_isolate(); | |
| 2627 HandleScope scope(isolate); | |
| 2628 MacroAssembler assm(isolate, NULL, 0); | |
| 2629 | |
| 2630 typedef struct test_float { | |
| 2631 double a; | |
| 2632 double b; | |
| 2633 double resd; | |
| 2634 double resd1; | |
| 2635 float c; | |
| 2636 float d; | |
| 2637 float resf; | |
| 2638 float resf1; | |
| 2639 }TestFloat; | |
| 2640 | |
| 2641 TestFloat test; | |
| 2642 double inputsa[tableLength] = { | |
| 2643 5.3, 4.8, 6.1, | |
| 2644 9.8, 9.8, 9.8, | |
| 2645 -10.0, -8.9, -9.8, | |
| 2646 -10.0, -8.9, -9.8 | |
| 2647 }; | |
| 2648 double inputsb[tableLength] = { | |
| 2649 4.8, 5.3, 6.1, | |
| 2650 -10.0, -8.9, -9.8, | |
| 2651 9.8, 9.8, 9.8, | |
| 2652 -9.8, -11.2, -9.8 | |
| 2653 }; | |
| 2654 double resd[tableLength] = { | |
| 2655 4.8, 4.8, 6.1, | |
| 2656 9.8, -8.9, 9.8, | |
| 2657 9.8, -8.9, 9.8, | |
| 2658 -9.8, -8.9, -9.8 | |
| 2659 }; | |
| 2660 double resd1[tableLength] = { | |
| 2661 5.3, 5.3, 6.1, | |
| 2662 -10.0, 9.8, 9.8, | |
| 2663 -10.0, 9.8, 9.8, | |
| 2664 -10.0, -11.2, -9.8 | |
| 2665 }; | |
| 2666 float inputsc[tableLength] = { | |
| 2667 5.3, 4.8, 6.1, | |
| 2668 9.8, 9.8, 9.8, | |
| 2669 -10.0, -8.9, -9.8, | |
| 2670 -10.0, -8.9, -9.8 | |
| 2671 }; | |
| 2672 float inputsd[tableLength] = { | |
| 2673 4.8, 5.3, 6.1, | |
| 2674 -10.0, -8.9, -9.8, | |
| 2675 9.8, 9.8, 9.8, | |
| 2676 -9.8, -11.2, -9.8 | |
| 2677 }; | |
| 2678 float resf[tableLength] = { | |
| 2679 4.8, 4.8, 6.1, | |
| 2680 9.8, -8.9, 9.8, | |
| 2681 9.8, -8.9, 9.8, | |
| 2682 -9.8, -8.9, -9.8 | |
| 2683 }; | |
| 2684 float resf1[tableLength] = { | |
| 2685 5.3, 5.3, 6.1, | |
| 2686 -10.0, 9.8, 9.8, | |
| 2687 -10.0, 9.8, 9.8, | |
| 2688 -10.0, -11.2, -9.8 | |
| 2689 }; | |
| 2690 | |
| 2691 __ ldc1(f2, MemOperand(a0, OFFSET_OF(TestFloat, a)) ); | |
| 2692 __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, b)) ); | |
| 2693 __ lwc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, c)) ); | |
| 2694 __ lwc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, d)) ); | |
| 2695 __ mina_d(f6, f2, f4); | |
| 2696 __ mina_s(f12, f8, f10); | |
| 2697 __ maxa_d(f14, f2, f4); | |
| 2698 __ maxa_s(f16, f8, f10); | |
| 2699 __ swc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, resf)) ); | |
| 2700 __ sdc1(f6, MemOperand(a0, OFFSET_OF(TestFloat, resd)) ); | |
| 2701 __ swc1(f16, MemOperand(a0, OFFSET_OF(TestFloat, resf1)) ); | |
| 2702 __ sdc1(f14, MemOperand(a0, OFFSET_OF(TestFloat, resd1)) ); | |
| 2703 __ jr(ra); | |
| 2704 __ nop(); | |
| 2705 | |
| 2706 CodeDesc desc; | |
| 2707 assm.GetCode(&desc); | |
| 2708 Handle<Code> code = isolate->factory()->NewCode( | |
| 2709 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2710 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2711 for (int i = 0; i < tableLength; i++) { | |
| 2712 test.a = inputsa[i]; | |
| 2713 test.b = inputsb[i]; | |
| 2714 test.c = inputsc[i]; | |
| 2715 test.d = inputsd[i]; | |
| 2716 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2717 CHECK_EQ(test.resd, resd[i]); | |
| 2718 CHECK_EQ(test.resf, resf[i]); | |
| 2719 CHECK_EQ(test.resd1, resd1[i]); | |
| 2720 CHECK_EQ(test.resf1, resf1[i]); | |
| 2721 } | |
| 2722 } | |
| 2723 } | |
| 2724 | |
| 2725 | |
| 2726 TEST(MIPS34) { | |
| 2727 CcTest::InitializeVM(); | |
| 2728 Isolate* isolate = CcTest::i_isolate(); | |
| 2729 HandleScope scope(isolate); | |
| 2730 MacroAssembler assm(isolate, NULL, 0); | |
| 2731 | |
| 2732 typedef struct test_float { | |
| 2733 double a; | |
| 2734 float b; | |
| 2735 int32_t c; // a floor result | |
| 2736 int32_t d; // b floor result | |
| 2737 }Test; | |
| 2738 const int tableLength = 15; | |
| 2739 double inputs_D[tableLength] = { | |
| 2740 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 2741 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 2742 2147483648.0, | |
| 2743 std::numeric_limits<double>::quiet_NaN(), | |
| 2744 std::numeric_limits<double>::infinity() | |
| 2745 }; | |
| 2746 float inputs_S[tableLength] = { | |
| 2747 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 2748 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 2749 2147483648.0, | |
| 2750 std::numeric_limits<float>::quiet_NaN(), | |
| 2751 std::numeric_limits<float>::infinity() | |
| 2752 }; | |
| 2753 double outputs[tableLength] = { | |
| 2754 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, | |
| 2755 -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, | |
| 2756 kFPUInvalidResult, kFPUInvalidResult, | |
| 2757 kFPUInvalidResult}; | |
| 2758 | |
| 2759 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) ); | |
| 2760 __ lwc1(f6, MemOperand(a0, OFFSET_OF(Test, b)) ); | |
| 2761 __ floor_w_d(f8, f4); | |
| 2762 __ floor_w_s(f10, f6); | |
| 2763 __ swc1(f8, MemOperand(a0, OFFSET_OF(Test, c)) ); | |
| 2764 __ swc1(f10, MemOperand(a0, OFFSET_OF(Test, d)) ); | |
| 2765 __ jr(ra); | |
| 2766 __ nop(); | |
| 2767 Test test; | |
| 2768 CodeDesc desc; | |
| 2769 assm.GetCode(&desc); | |
| 2770 Handle<Code> code = isolate->factory()->NewCode( | |
| 2771 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2772 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2773 for (int i = 0; i < tableLength; i++) { | |
| 2774 test.a = inputs_D[i]; | |
| 2775 test.b = inputs_S[i]; | |
| 2776 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2777 CHECK_EQ(test.c, outputs[i]); | |
| 2778 CHECK_EQ(test.d, test.c); | |
| 2779 } | |
| 2780 } | |
| 2781 | |
| 2782 | |
| 2783 TEST(MIPS35) { | |
| 2784 CcTest::InitializeVM(); | |
| 2785 Isolate* isolate = CcTest::i_isolate(); | |
| 2786 HandleScope scope(isolate); | |
| 2787 MacroAssembler assm(isolate, NULL, 0); | |
| 2788 const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); | |
| 2789 typedef struct test_float { | |
| 2790 double a; | |
| 2791 float b; | |
| 2792 int64_t c; | |
| 2793 int64_t d; | |
| 2794 }Test; | |
| 2795 const int tableLength = 16; | |
| 2796 double inputs_D[tableLength] = { | |
| 2797 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 2798 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 2799 2147483648.0, | |
| 2800 std::numeric_limits<double>::quiet_NaN(), | |
| 2801 std::numeric_limits<double>::infinity(), | |
| 2802 9223372036854775808.0 | |
| 2803 }; | |
| 2804 float inputs_S[tableLength] = { | |
| 2805 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 2806 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 2807 2147483648.0, | |
| 2808 std::numeric_limits<float>::quiet_NaN(), | |
| 2809 std::numeric_limits<float>::infinity(), | |
| 2810 9223372036854775808.0 | |
| 2811 }; | |
| 2812 double outputs[tableLength] = { | |
| 2813 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, | |
| 2814 -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, | |
| 2815 2147483648.0, dFPU64InvalidResult, | |
| 2816 dFPU64InvalidResult, dFPU64InvalidResult}; | |
| 2817 | |
| 2818 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) ); | |
| 2819 __ lwc1(f6, MemOperand(a0, OFFSET_OF(Test, b)) ); | |
| 2820 __ floor_l_d(f8, f4); | |
| 2821 __ floor_l_s(f10, f6); | |
| 
 
paul.l...
2015/05/05 02:56:08
As we just learned in gh issue 115 we cannot use t
 
 | |
| 2822 __ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, c)) ); | |
| 2823 __ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, d)) ); | |
| 2824 __ jr(ra); | |
| 2825 __ nop(); | |
| 2826 Test test; | |
| 2827 CodeDesc desc; | |
| 2828 assm.GetCode(&desc); | |
| 2829 Handle<Code> code = isolate->factory()->NewCode( | |
| 2830 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2831 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2832 for (int i = 0; i < tableLength; i++) { | |
| 2833 test.a = inputs_D[i]; | |
| 2834 test.b = inputs_S[i]; | |
| 2835 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2836 CHECK_EQ(test.c, outputs[i]); | |
| 2837 CHECK_EQ(test.d, test.c); | |
| 2838 } | |
| 2839 } | |
| 2840 | |
| 2841 | |
| 2842 TEST(MIPS36) { | |
| 2843 CcTest::InitializeVM(); | |
| 2844 Isolate* isolate = CcTest::i_isolate(); | |
| 2845 HandleScope scope(isolate); | |
| 2846 MacroAssembler assm(isolate, NULL, 0); | |
| 2847 | |
| 2848 typedef struct test_float { | |
| 2849 double a; | |
| 2850 float b; | |
| 2851 int32_t c; // a floor result | |
| 2852 int32_t d; // b floor result | |
| 2853 }Test; | |
| 2854 const int tableLength = 15; | |
| 2855 double inputs_D[tableLength] = { | |
| 2856 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 2857 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 2858 2147483648.0, | |
| 2859 std::numeric_limits<double>::quiet_NaN(), | |
| 2860 std::numeric_limits<double>::infinity() | |
| 2861 }; | |
| 2862 float inputs_S[tableLength] = { | |
| 2863 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 2864 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 2865 2147483648.0, | |
| 2866 std::numeric_limits<float>::quiet_NaN(), | |
| 2867 std::numeric_limits<float>::infinity() | |
| 2868 }; | |
| 2869 double outputs[tableLength] = { | |
| 2870 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, | |
| 2871 -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, | |
| 2872 kFPUInvalidResult, kFPUInvalidResult, | |
| 2873 kFPUInvalidResult}; | |
| 2874 | |
| 2875 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) ); | |
| 2876 __ lwc1(f6, MemOperand(a0, OFFSET_OF(Test, b)) ); | |
| 2877 __ ceil_w_d(f8, f4); | |
| 2878 __ ceil_w_s(f10, f6); | |
| 2879 __ swc1(f8, MemOperand(a0, OFFSET_OF(Test, c)) ); | |
| 2880 __ swc1(f10, MemOperand(a0, OFFSET_OF(Test, d)) ); | |
| 2881 __ jr(ra); | |
| 2882 __ nop(); | |
| 2883 Test test; | |
| 2884 CodeDesc desc; | |
| 2885 assm.GetCode(&desc); | |
| 2886 Handle<Code> code = isolate->factory()->NewCode( | |
| 2887 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2888 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2889 for (int i = 0; i < tableLength; i++) { | |
| 2890 test.a = inputs_D[i]; | |
| 2891 test.b = inputs_S[i]; | |
| 2892 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2893 CHECK_EQ(test.c, outputs[i]); | |
| 2894 CHECK_EQ(test.d, test.c); | |
| 2895 } | |
| 2896 } | |
| 2897 | |
| 2898 | |
| 2899 TEST(MIPS37) { | |
| 2900 CcTest::InitializeVM(); | |
| 2901 Isolate* isolate = CcTest::i_isolate(); | |
| 2902 HandleScope scope(isolate); | |
| 2903 MacroAssembler assm(isolate, NULL, 0); | |
| 2904 const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); | |
| 2905 typedef struct test_float { | |
| 2906 double a; | |
| 2907 float b; | |
| 2908 int64_t c; | |
| 2909 int64_t d; | |
| 2910 }Test; | |
| 2911 const int tableLength = 16; | |
| 2912 double inputs_D[tableLength] = { | |
| 2913 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 2914 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 2915 2147483648.0, | |
| 2916 std::numeric_limits<double>::quiet_NaN(), | |
| 2917 std::numeric_limits<double>::infinity(), | |
| 2918 9223372036854775808.0 | |
| 2919 }; | |
| 2920 float inputs_S[tableLength] = { | |
| 2921 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, | |
| 2922 -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, | |
| 2923 2147483648.0, | |
| 2924 std::numeric_limits<float>::quiet_NaN(), | |
| 2925 std::numeric_limits<float>::infinity(), | |
| 2926 9223372036854775808.0 | |
| 2927 }; | |
| 2928 double outputs[tableLength] = { | |
| 2929 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, | |
| 2930 -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, | |
| 2931 2147483648.0, dFPU64InvalidResult, | |
| 2932 dFPU64InvalidResult, dFPU64InvalidResult}; | |
| 2933 | |
| 2934 __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) ); | |
| 2935 __ lwc1(f6, MemOperand(a0, OFFSET_OF(Test, b)) ); | |
| 2936 __ ceil_l_d(f8, f4); | |
| 2937 __ ceil_l_s(f10, f6); | |
| 
 
paul.l...
2015/05/05 02:56:08
Same as above floor, re: long variants. Maybe in o
 
 | |
| 2938 __ sdc1(f8, MemOperand(a0, OFFSET_OF(Test, c)) ); | |
| 2939 __ sdc1(f10, MemOperand(a0, OFFSET_OF(Test, d)) ); | |
| 2940 __ jr(ra); | |
| 2941 __ nop(); | |
| 2942 Test test; | |
| 2943 CodeDesc desc; | |
| 2944 assm.GetCode(&desc); | |
| 2945 Handle<Code> code = isolate->factory()->NewCode( | |
| 2946 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 2947 F3 f = FUNCTION_CAST<F3>(code->entry()); | |
| 2948 for (int i = 0; i < tableLength; i++) { | |
| 2949 test.a = inputs_D[i]; | |
| 2950 test.b = inputs_S[i]; | |
| 2951 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | |
| 2952 CHECK_EQ(test.c, outputs[i]); | |
| 2953 CHECK_EQ(test.d, test.c); | |
| 2954 } | |
| 2955 } | |
| 2956 | |
| 2957 | |
| 1658 TEST(jump_tables1) { | 2958 TEST(jump_tables1) { | 
| 1659 // Test jump tables with forward jumps. | 2959 // Test jump tables with forward jumps. | 
| 1660 CcTest::InitializeVM(); | 2960 CcTest::InitializeVM(); | 
| 1661 Isolate* isolate = CcTest::i_isolate(); | 2961 Isolate* isolate = CcTest::i_isolate(); | 
| 1662 HandleScope scope(isolate); | 2962 HandleScope scope(isolate); | 
| 1663 Assembler assm(isolate, nullptr, 0); | 2963 Assembler assm(isolate, nullptr, 0); | 
| 1664 | 2964 | 
| 1665 const int kNumCases = 512; | 2965 const int kNumCases = 512; | 
| 1666 int values[kNumCases]; | 2966 int values[kNumCases]; | 
| 1667 isolate->random_number_generator()->NextBytes(values, sizeof(values)); | 2967 isolate->random_number_generator()->NextBytes(values, sizeof(values)); | 
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1860 ::printf("f(%d) = ", i); | 3160 ::printf("f(%d) = ", i); | 
| 1861 result->Print(std::cout); | 3161 result->Print(std::cout); | 
| 1862 ::printf("\n"); | 3162 ::printf("\n"); | 
| 1863 #endif | 3163 #endif | 
| 1864 CHECK(values[i].is_identical_to(result)); | 3164 CHECK(values[i].is_identical_to(result)); | 
| 1865 } | 3165 } | 
| 1866 } | 3166 } | 
| 1867 | 3167 | 
| 1868 | 3168 | 
| 1869 #undef __ | 3169 #undef __ | 
| OLD | NEW |