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

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

Issue 6201004: ARM: Implement ClassOf in the lithium arm backend. (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 | « src/arm/lithium-arm.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 Register result = ToRegister(instr->result()); 951 Register result = ToRegister(instr->result());
952 Register array = ToRegister(instr->input()); 952 Register array = ToRegister(instr->input());
953 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset)); 953 __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
954 } 954 }
955 955
956 956
957 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { 957 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
958 Register result = ToRegister(instr->result()); 958 Register result = ToRegister(instr->result());
959 Register array = ToRegister(instr->input()); 959 Register array = ToRegister(instr->input());
960 __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset)); 960 __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset));
961 Abort("DoFixedArrayLength untested.");
962 } 961 }
963 962
964 963
965 void LCodeGen::DoValueOf(LValueOf* instr) { 964 void LCodeGen::DoValueOf(LValueOf* instr) {
966 Abort("DoValueOf unimplemented."); 965 Register input = ToRegister(instr->input());
966 Register result = ToRegister(instr->result());
967 Register map = ToRegister(instr->temporary());
968 ASSERT(input.is(result));
969 Label done;
970
971 // If the object is a smi return the object.
972 __ tst(input, Operand(kSmiTagMask));
973 __ b(eq, &done);
974
975 // If the object is not a value type, return the object.
976 __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
977 __ b(ne, &done);
978 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
979
980 __ bind(&done);
967 } 981 }
968 982
969 983
970 void LCodeGen::DoBitNotI(LBitNotI* instr) { 984 void LCodeGen::DoBitNotI(LBitNotI* instr) {
971 LOperand* input = instr->input(); 985 LOperand* input = instr->input();
972 ASSERT(input->Equals(instr->result())); 986 ASSERT(input->Equals(instr->result()));
973 __ mvn(ToRegister(input), Operand(ToRegister(input))); 987 __ mvn(ToRegister(input), Operand(ToRegister(input)));
974 Abort("DoBitNotI untested.");
975 } 988 }
976 989
977 990
978 void LCodeGen::DoThrow(LThrow* instr) { 991 void LCodeGen::DoThrow(LThrow* instr) {
979 Register input_reg = EmitLoadRegister(instr->input(), ip); 992 Register input_reg = EmitLoadRegister(instr->input(), ip);
980 __ push(input_reg); 993 __ push(input_reg);
981 CallRuntime(Runtime::kThrow, 1, instr); 994 CallRuntime(Runtime::kThrow, 1, instr);
982 995
983 if (FLAG_debug_code) { 996 if (FLAG_debug_code) {
984 __ stop("Unreachable code."); 997 __ stop("Unreachable code.");
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 Abort("DoHasCachedArrayIndex unimplemented."); 1414 Abort("DoHasCachedArrayIndex unimplemented.");
1402 } 1415 }
1403 1416
1404 1417
1405 void LCodeGen::DoHasCachedArrayIndexAndBranch( 1418 void LCodeGen::DoHasCachedArrayIndexAndBranch(
1406 LHasCachedArrayIndexAndBranch* instr) { 1419 LHasCachedArrayIndexAndBranch* instr) {
1407 Abort("DoHasCachedArrayIndexAndBranch unimplemented."); 1420 Abort("DoHasCachedArrayIndexAndBranch unimplemented.");
1408 } 1421 }
1409 1422
1410 1423
1411 // Branches to a label or falls through with the answer in the z flag. Trashes 1424 // Branches to a label or falls through with the answer in flags. Trashes
1412 // the temp registers, but not the input. Only input and temp2 may alias. 1425 // the temp registers, but not the input. Only input and temp2 may alias.
1413 void LCodeGen::EmitClassOfTest(Label* is_true, 1426 void LCodeGen::EmitClassOfTest(Label* is_true,
1414 Label* is_false, 1427 Label* is_false,
1415 Handle<String>class_name, 1428 Handle<String>class_name,
1416 Register input, 1429 Register input,
1417 Register temp, 1430 Register temp,
1418 Register temp2) { 1431 Register temp2) {
1419 Abort("EmitClassOfTest unimplemented."); 1432 ASSERT(!input.is(temp));
1433 ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register.
1434 __ tst(input, Operand(kSmiTagMask));
1435 __ b(eq, is_false);
1436 __ CompareObjectType(input, temp, temp2, FIRST_JS_OBJECT_TYPE);
1437 __ b(lt, is_false);
1438
1439 // Map is now in temp.
1440 // Functions have class 'Function'.
1441 __ CompareInstanceType(temp, temp2, JS_FUNCTION_TYPE);
1442 if (class_name->IsEqualTo(CStrVector("Function"))) {
1443 __ b(eq, is_true);
1444 } else {
1445 __ b(eq, is_false);
1446 }
1447
1448 // Check if the constructor in the map is a function.
1449 __ ldr(temp, FieldMemOperand(temp, Map::kConstructorOffset));
1450
1451 // As long as JS_FUNCTION_TYPE is the last instance type and it is
1452 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
1453 // LAST_JS_OBJECT_TYPE.
1454 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
1455 ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
1456
1457 // Objects with a non-function constructor have class 'Object'.
1458 __ CompareObjectType(temp, temp2, temp2, JS_FUNCTION_TYPE);
1459 if (class_name->IsEqualTo(CStrVector("Object"))) {
1460 __ b(ne, is_true);
1461 } else {
1462 __ b(ne, is_false);
1463 }
1464
1465 // temp now contains the constructor function. Grab the
1466 // instance class name from there.
1467 __ ldr(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset));
1468 __ ldr(temp, FieldMemOperand(temp,
1469 SharedFunctionInfo::kInstanceClassNameOffset));
1470 // The class name we are testing against is a symbol because it's a literal.
1471 // The name in the constructor is a symbol because of the way the context is
1472 // booted. This routine isn't expected to work for random API-created
1473 // classes and it doesn't have to because you can't access it with natives
1474 // syntax. Since both sides are symbols it is sufficient to use an identity
1475 // comparison.
1476 __ cmp(temp, Operand(class_name));
1477 // End with the answer in flags.
1420 } 1478 }
1421 1479
1422 1480
1423 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { 1481 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
1424 Abort("DoClassOfTest unimplemented."); 1482 Register input = ToRegister(instr->input());
1483 Register result = ToRegister(instr->result());
1484 ASSERT(input.is(result));
1485 Handle<String> class_name = instr->hydrogen()->class_name();
1486
1487 Label done, is_true, is_false;
1488
1489 EmitClassOfTest(&is_true, &is_false, class_name, input, scratch0(), input);
1490 __ b(ne, &is_false);
1491
1492 __ bind(&is_true);
1493 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1494 __ jmp(&done);
1495
1496 __ bind(&is_false);
1497 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1498 __ bind(&done);
1425 } 1499 }
1426 1500
1427 1501
1428 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1502 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1429 Abort("DoClassOfTestAndBranch unimplemented."); 1503 Register input = ToRegister(instr->input());
1504 Register temp = scratch0();
1505 Register temp2 = ToRegister(instr->temporary());
1506 Handle<String> class_name = instr->hydrogen()->class_name();
1507
1508 int true_block = chunk_->LookupDestination(instr->true_block_id());
1509 int false_block = chunk_->LookupDestination(instr->false_block_id());
1510
1511 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1512 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1513
1514 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
1515
1516 EmitBranch(true_block, false_block, eq);
1430 } 1517 }
1431 1518
1432 1519
1433 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 1520 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
1434 Register reg = ToRegister(instr->input()); 1521 Register reg = ToRegister(instr->input());
1435 Register temp = ToRegister(instr->temp()); 1522 Register temp = ToRegister(instr->temp());
1436 int true_block = instr->true_block_id(); 1523 int true_block = instr->true_block_id();
1437 int false_block = instr->false_block_id(); 1524 int false_block = instr->false_block_id();
1438 1525
1439 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 1526 __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
(...skipping 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after
2646 2733
2647 2734
2648 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 2735 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
2649 Abort("DoOsrEntry unimplemented."); 2736 Abort("DoOsrEntry unimplemented.");
2650 } 2737 }
2651 2738
2652 2739
2653 #undef __ 2740 #undef __
2654 2741
2655 } } // namespace v8::internal 2742 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698