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

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 15664008: MIPS: Convert ToBooleanStub to a HydrogenStub. Currently just using the existing HBranch instructio… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
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
« no previous file with comments | « no previous file | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 169 }
170 170
171 171
172 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( 172 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
173 Isolate* isolate, 173 Isolate* isolate,
174 CodeStubInterfaceDescriptor* descriptor) { 174 CodeStubInterfaceDescriptor* descriptor) {
175 InitializeArrayConstructorDescriptor(isolate, descriptor, -1); 175 InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
176 } 176 }
177 177
178 178
179 void ToBooleanStub::InitializeInterfaceDescriptor(
180 Isolate* isolate,
181 CodeStubInterfaceDescriptor* descriptor) {
182 static Register registers[] = { a0 };
183 descriptor->register_param_count_ = 1;
184 descriptor->register_params_ = registers;
185 descriptor->deoptimization_handler_ =
186 FUNCTION_ADDR(ToBooleanIC_Miss);
187 descriptor->SetMissHandler(
188 ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate));
189 }
190
191
179 #define __ ACCESS_MASM(masm) 192 #define __ ACCESS_MASM(masm)
180 193
181 static void EmitIdenticalObjectComparison(MacroAssembler* masm, 194 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
182 Label* slow, 195 Label* slow,
183 Condition cc); 196 Condition cc);
184 static void EmitSmiNonsmiComparison(MacroAssembler* masm, 197 static void EmitSmiNonsmiComparison(MacroAssembler* masm,
185 Register lhs, 198 Register lhs,
186 Register rhs, 199 Register rhs,
187 Label* rhs_not_nan, 200 Label* rhs_not_nan,
188 Label* slow, 201 Label* slow,
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 1506
1494 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 1507 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
1495 // tagged as a small integer. 1508 // tagged as a small integer.
1496 __ InvokeBuiltin(native, JUMP_FUNCTION); 1509 __ InvokeBuiltin(native, JUMP_FUNCTION);
1497 1510
1498 __ bind(&miss); 1511 __ bind(&miss);
1499 GenerateMiss(masm); 1512 GenerateMiss(masm);
1500 } 1513 }
1501 1514
1502 1515
1503 // The stub expects its argument in the tos_ register and returns its result in
1504 // it, too: zero for false, and a non-zero value for true.
1505 void ToBooleanStub::Generate(MacroAssembler* masm) {
1506 Label patch;
1507 const Register map = t5.is(tos_) ? t3 : t5;
1508
1509 // undefined -> false.
1510 CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false);
1511
1512 // Boolean -> its value.
1513 CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false);
1514 CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true);
1515
1516 // 'null' -> false.
1517 CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false);
1518
1519 if (types_.Contains(SMI)) {
1520 // Smis: 0 -> false, all other -> true
1521 __ And(at, tos_, kSmiTagMask);
1522 // tos_ contains the correct return value already
1523 __ Ret(eq, at, Operand(zero_reg));
1524 } else if (types_.NeedsMap()) {
1525 // If we need a map later and have a Smi -> patch.
1526 __ JumpIfSmi(tos_, &patch);
1527 }
1528
1529 if (types_.NeedsMap()) {
1530 __ lw(map, FieldMemOperand(tos_, HeapObject::kMapOffset));
1531
1532 if (types_.CanBeUndetectable()) {
1533 __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
1534 __ And(at, at, Operand(1 << Map::kIsUndetectable));
1535 // Undetectable -> false.
1536 __ Movn(tos_, zero_reg, at);
1537 __ Ret(ne, at, Operand(zero_reg));
1538 }
1539 }
1540
1541 if (types_.Contains(SPEC_OBJECT)) {
1542 // Spec object -> true.
1543 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
1544 // tos_ contains the correct non-zero return value already.
1545 __ Ret(ge, at, Operand(FIRST_SPEC_OBJECT_TYPE));
1546 }
1547
1548 if (types_.Contains(STRING)) {
1549 // String value -> false iff empty.
1550 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
1551 Label skip;
1552 __ Branch(&skip, ge, at, Operand(FIRST_NONSTRING_TYPE));
1553 __ Ret(USE_DELAY_SLOT); // the string length is OK as the return value
1554 __ lw(tos_, FieldMemOperand(tos_, String::kLengthOffset));
1555 __ bind(&skip);
1556 }
1557
1558 if (types_.Contains(HEAP_NUMBER)) {
1559 // Heap number -> false iff +0, -0, or NaN.
1560 Label not_heap_number;
1561 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
1562 __ Branch(&not_heap_number, ne, map, Operand(at));
1563 Label zero_or_nan, number;
1564 __ ldc1(f2, FieldMemOperand(tos_, HeapNumber::kValueOffset));
1565 __ BranchF(&number, &zero_or_nan, ne, f2, kDoubleRegZero);
1566 // "tos_" is a register, and contains a non zero value by default.
1567 // Hence we only need to overwrite "tos_" with zero to return false for
1568 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true.
1569 __ bind(&zero_or_nan);
1570 __ mov(tos_, zero_reg);
1571 __ bind(&number);
1572 __ Ret();
1573 __ bind(&not_heap_number);
1574 }
1575
1576 __ bind(&patch);
1577 GenerateTypeTransition(masm);
1578 }
1579
1580
1581 void ToBooleanStub::CheckOddball(MacroAssembler* masm,
1582 Type type,
1583 Heap::RootListIndex value,
1584 bool result) {
1585 if (types_.Contains(type)) {
1586 // If we see an expected oddball, return its ToBoolean value tos_.
1587 __ LoadRoot(at, value);
1588 __ Subu(at, at, tos_); // This is a check for equality for the movz below.
1589 // The value of a root is never NULL, so we can avoid loading a non-null
1590 // value into tos_ when we want to return 'true'.
1591 if (!result) {
1592 __ Movz(tos_, zero_reg, at);
1593 }
1594 __ Ret(eq, at, Operand(zero_reg));
1595 }
1596 }
1597
1598
1599 void ToBooleanStub::GenerateTypeTransition(MacroAssembler* masm) {
1600 __ Move(a3, tos_);
1601 __ li(a2, Operand(Smi::FromInt(tos_.code())));
1602 __ li(a1, Operand(Smi::FromInt(types_.ToByte())));
1603 __ Push(a3, a2, a1);
1604 // Patch the caller to an appropriate specialized stub and return the
1605 // operation result to the caller of the stub.
1606 __ TailCallExternalReference(
1607 ExternalReference(IC_Utility(IC::kToBoolean_Patch), masm->isolate()),
1608 3,
1609 1);
1610 }
1611
1612
1613 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { 1516 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
1614 // We don't allow a GC during a store buffer overflow so there is no need to 1517 // We don't allow a GC during a store buffer overflow so there is no need to
1615 // store the registers in any particular way, but we do have to store and 1518 // store the registers in any particular way, but we do have to store and
1616 // restore them. 1519 // restore them.
1617 __ MultiPush(kJSCallerSaved | ra.bit()); 1520 __ MultiPush(kJSCallerSaved | ra.bit());
1618 if (save_doubles_ == kSaveFPRegs) { 1521 if (save_doubles_ == kSaveFPRegs) {
1619 __ MultiPushFPU(kCallerSavedFPU); 1522 __ MultiPushFPU(kCallerSavedFPU);
1620 } 1523 }
1621 const int argument_count = 1; 1524 const int argument_count = 1;
1622 const int fp_argument_count = 0; 1525 const int fp_argument_count = 0;
(...skipping 6224 matching lines...) Expand 10 before | Expand all | Expand 10 after
7847 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 7750 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
7848 } 7751 }
7849 } 7752 }
7850 7753
7851 7754
7852 #undef __ 7755 #undef __
7853 7756
7854 } } // namespace v8::internal 7757 } } // namespace v8::internal
7855 7758
7856 #endif // V8_TARGET_ARCH_MIPS 7759 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698