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

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 6124005: Implementing a few more missing stubs on ARM:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 11 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 Abort("DoHasCachedArrayIndex unimplemented."); 1373 Abort("DoHasCachedArrayIndex unimplemented.");
1374 } 1374 }
1375 1375
1376 1376
1377 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1377 void LCodeGen::DoHasCachedArrayIndexAndBranch(
1378 LHasCachedArrayIndexAndBranch* instr) { 1378 LHasCachedArrayIndexAndBranch* instr) {
1379 Abort("DoHasCachedArrayIndexAndBranch unimplemented."); 1379 Abort("DoHasCachedArrayIndexAndBranch unimplemented.");
1380 } 1380 }
1381 1381
1382 1382
1383 // Branches to a label or falls through with the answer in the z flag. Trashes 1383 // Branches to a label or falls through with the answer in the z flag. Trashes
1384 // the temp registers, but not the input. Only input and temp2 may alias. 1384 // the temp registers, but not the input. Only input and temp2 may alias.
Søren Thygesen Gjesse 2011/01/10 09:56:08 input is trashed if temp2 aliases it.
Alexandre 2011/01/10 10:48:27 Indeed. Changed the code to have input and temp2 a
1385 void LCodeGen::EmitClassOfTest(Label* is_true, 1385 void LCodeGen::EmitClassOfTest(Label* is_true,
1386 Label* is_false, 1386 Label* is_false,
1387 Handle<String>class_name, 1387 Handle<String>class_name,
1388 Register input, 1388 Register input,
1389 Register temp, 1389 Register temp,
1390 Register temp2) { 1390 Register temp2) {
1391 Abort("EmitClassOfTest unimplemented."); 1391 ASSERT(!input.is(temp));
1392 ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register.
1393
1394 __ BranchOnSmi(input, is_false);
1395
1396 __ CompareObjectType(input, temp, temp2, FIRST_JS_OBJECT_TYPE);
1397 __ b(lt, is_false);
1398
Søren Thygesen Gjesse 2011/01/10 09:56:08 How about just // temp: map of input // temp2: o
Alexandre 2011/01/10 10:48:27 Done.
1399 // After CompareObjectType:
1400 // - Input's map is in temp.
1401 // - Input's type is in temp2.
1402
1403 // Functions have class 'Function'.
1404 __ cmp(temp2, Operand(JS_FUNCTION_TYPE));
1405 if (class_name->IsEqualTo(CStrVector("Function"))) {
1406 __ b(eq, is_true);
1407 } else {
1408 __ b(eq, is_false);
1409 }
1410
1411 // Check if the constructor in the map is a function.
1412 __ ldr(temp, FieldMemOperand(temp, Map::kConstructorOffset));
Søren Thygesen Gjesse 2011/01/10 09:56:08 After this // temp: constructor
Alexandre 2011/01/10 10:48:27 Done.
1413
1414 // As long as JS_FUNCTION_TYPE is the last instance type and it is
1415 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
1416 // LAST_JS_OBJECT_TYPE.
1417 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
1418 ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
1419
1420 // Objects with a non-function constructor have class 'Object'.
1421 __ CompareObjectType(temp, temp2, temp2, JS_FUNCTION_TYPE);
1422 if (class_name->IsEqualTo(CStrVector("Object"))) {
1423 __ b(ne, is_true);
1424 } else {
1425 __ b(ne, is_false);
1426 }
1427
Søren Thygesen Gjesse 2011/01/10 09:56:08 Change comment to // Get the instance class name
Alexandre 2011/01/10 10:48:27 Done.
1428 // temp now contains the constructor function. Grab the
1429 // instance class name from there.
1430 __ ldr(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset));
1431 __ ldr(temp, FieldMemOperand(temp,
1432 SharedFunctionInfo::kInstanceClassNameOffset));
1433 // The class name we are testing against is a symbol because it's a literal.
1434 // The name in the constructor is a symbol because of the way the context is
1435 // booted. This routine isn't expected to work for random API-created
1436 // classes and it doesn't have to because you can't access it with natives
1437 // syntax. Since both sides are symbols it is sufficient to use an identity
1438 // comparison.
1439 __ cmp(temp, Operand(class_name));
1440 // End with the answer in the z flag.
1392 } 1441 }
1393 1442
1394 1443
1395 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { 1444 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
Søren Thygesen Gjesse 2011/01/10 09:56:08 Maybe implement this now you have done EmitClassOf
Alexandre 2011/01/10 10:48:27 Implemented. On 2011/01/10 09:56:08, Søren Gjesse
1396 Abort("DoClassOfTest unimplemented."); 1445 Abort("DoClassOfTest unimplemented.");
1397 } 1446 }
1398 1447
1399 1448
1400 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1449 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1401 Abort("DoClassOfTestAndBranch unimplemented."); 1450 Register input = ToRegister(instr->input());
1451 Register temp = ToRegister(instr->temporary());
1452 Register temp2 = ToRegister(instr->temporary2());
1453 if (input.is(temp)) {
1454 // Swap.
Søren Thygesen Gjesse 2011/01/10 09:56:08 There is a Swap instruction in the macro assembler
Alexandre 2011/01/10 10:48:27 Removed. Not needed anymore, as all these register
1455 Register swapper = temp;
1456 temp = temp2;
1457 temp2 = swapper;
1458 }
1459 Handle<String> class_name = instr->hydrogen()->class_name();
1460
1461 int true_block = chunk_->LookupDestination(instr->true_block_id());
1462 int false_block = chunk_->LookupDestination(instr->false_block_id());
1463
1464 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1465 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1466
1467 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
1468
1469 EmitBranch(true_block, false_block, eq);
1402 } 1470 }
1403 1471
1404 1472
1405 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 1473 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
1406 Register reg = ToRegister(instr->input()); 1474 Register reg = ToRegister(instr->input());
1407 Register temp = ToRegister(instr->temp()); 1475 Register temp = ToRegister(instr->temp());
1408 int true_block = instr->true_block_id(); 1476 int true_block = instr->true_block_id();
1409 int false_block = instr->false_block_id(); 1477 int false_block = instr->false_block_id();
1410 1478
1411 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 1479 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1777 Abort("DoDeferredMathAbsTaggedHeapNumber unimplemented."); 1845 Abort("DoDeferredMathAbsTaggedHeapNumber unimplemented.");
1778 } 1846 }
1779 1847
1780 1848
1781 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 1849 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
1782 Abort("DoMathAbs unimplemented."); 1850 Abort("DoMathAbs unimplemented.");
1783 } 1851 }
1784 1852
1785 1853
1786 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 1854 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
1787 Abort("DoMathFloor unimplemented."); 1855 DoubleRegister input_reg = ToDoubleRegister(instr->input());
Søren Thygesen Gjesse 2011/01/10 09:56:08 input_reg -> input?
1856 SwVfpRegister single_precision_scratch = s0;
Søren Thygesen Gjesse 2011/01/10 09:56:08 Please add double_scratch0() and single_scratch0()
1857 Register result = ToRegister(instr->result());
1858 Register scratch = scratch0();
1859
1860 // Set custom FPCSR:
1861 // - Set rounding mode to "Round towards Minus Infinity"
Søren Thygesen Gjesse 2011/01/10 09:56:08 No need to refer to specific bit numbers in the co
1862 // (ie bits [23:22] = 0b10).
1863 // - Clear vfp cumulative exception flags (bits [3:0]).
1864 // - Make sure Flush-to-zero mode control bit is unset (bit 22).
1865 __ vmrs(scratch);
Søren Thygesen Gjesse 2011/01/10 09:56:08 Don't we need to backup and restore FPSCR here? Th
1866 __ bic(scratch, scratch,
1867 Operand(kVFPExceptionMask | kVFPRoundingModeMask | kVFPFlushToZeroMask));
1868 __ orr(scratch, scratch, Operand(kVFPRoundToMinusInfinityBits));
1869 __ vmsr(scratch);
1870
1871 // Convert the argument to an integer.
1872 __ vcvt_s32_f64(single_precision_scratch,
1873 input_reg,
1874 Assembler::FPSCRRounding,
1875 al);
1876
1877 // Retrieve FPSCR and check for vfp exceptions.
1878 __ vmrs(scratch);
1879 __ tst(scratch, Operand(kVFPExceptionMask));
1880 DeoptimizeIf(ne, instr->environment());
1881
1882 // Move the result back to general purpose register r0.
1883 __ vmov(result, single_precision_scratch);
1788 } 1884 }
1789 1885
1790 1886
1791 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 1887 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
1792 Abort("DoMathSqrt unimplemented."); 1888 DoubleRegister input_reg = ToDoubleRegister(instr->input());
Søren Thygesen Gjesse 2011/01/10 09:56:08 input_reg -> input?
Alexandre 2011/01/10 10:48:27 Done.
1889 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
1890 __ vsqrt(input_reg, input_reg);
1793 } 1891 }
1794 1892
1795 1893
1796 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { 1894 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
1797 switch (instr->op()) { 1895 switch (instr->op()) {
1798 case kMathAbs: 1896 case kMathAbs:
1799 DoMathAbs(instr); 1897 DoMathAbs(instr);
1800 break; 1898 break;
1801 case kMathFloor: 1899 case kMathFloor:
1802 DoMathFloor(instr); 1900 DoMathFloor(instr);
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
2623 2721
2624 2722
2625 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 2723 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
2626 Abort("DoOsrEntry unimplemented."); 2724 Abort("DoOsrEntry unimplemented.");
2627 } 2725 }
2628 2726
2629 2727
2630 #undef __ 2728 #undef __
2631 2729
2632 } } // namespace v8::internal 2730 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698