OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 | 284 |
285 __ li(exp_mask_reg, Operand(HeapNumber::kExponentMask)); | 285 __ li(exp_mask_reg, Operand(HeapNumber::kExponentMask)); |
286 | 286 |
287 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), | 287 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), |
288 // so we do the second best thing - test it ourselves. | 288 // so we do the second best thing - test it ourselves. |
289 // They are both equal and they are not both Smis so both of them are not | 289 // They are both equal and they are not both Smis so both of them are not |
290 // Smis. If it's not a heap number, then return equal. | 290 // Smis. If it's not a heap number, then return equal. |
291 __ GetObjectType(a0, t4, t4); | 291 __ GetObjectType(a0, t4, t4); |
292 if (cc == less || cc == greater) { | 292 if (cc == less || cc == greater) { |
293 // Call runtime on identical JSObjects. | 293 // Call runtime on identical JSObjects. |
294 __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE)); | 294 __ Branch(slow, greater, t4, Operand(FIRST_JS_RECEIVER_TYPE)); |
295 // Call runtime on identical symbols since we need to throw a TypeError. | 295 // Call runtime on identical symbols since we need to throw a TypeError. |
296 __ Branch(slow, eq, t4, Operand(SYMBOL_TYPE)); | 296 __ Branch(slow, eq, t4, Operand(SYMBOL_TYPE)); |
297 // Call runtime on identical SIMD values since we must throw a TypeError. | 297 // Call runtime on identical SIMD values since we must throw a TypeError. |
298 __ Branch(slow, eq, t4, Operand(SIMD128_VALUE_TYPE)); | 298 __ Branch(slow, eq, t4, Operand(SIMD128_VALUE_TYPE)); |
299 if (is_strong(strength)) { | 299 if (is_strong(strength)) { |
300 // Call the runtime on anything that is converted in the semantics, since | 300 // Call the runtime on anything that is converted in the semantics, since |
301 // we need to throw a TypeError. Smis have already been ruled out. | 301 // we need to throw a TypeError. Smis have already been ruled out. |
302 __ Branch(&return_equal, eq, t4, Operand(HEAP_NUMBER_TYPE)); | 302 __ Branch(&return_equal, eq, t4, Operand(HEAP_NUMBER_TYPE)); |
303 __ And(t4, t4, Operand(kIsNotStringMask)); | 303 __ And(t4, t4, Operand(kIsNotStringMask)); |
304 __ Branch(slow, ne, t4, Operand(zero_reg)); | 304 __ Branch(slow, ne, t4, Operand(zero_reg)); |
305 } | 305 } |
306 } else { | 306 } else { |
307 __ Branch(&heap_number, eq, t4, Operand(HEAP_NUMBER_TYPE)); | 307 __ Branch(&heap_number, eq, t4, Operand(HEAP_NUMBER_TYPE)); |
308 // Comparing JS objects with <=, >= is complicated. | 308 // Comparing JS objects with <=, >= is complicated. |
309 if (cc != eq) { | 309 if (cc != eq) { |
310 __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE)); | 310 __ Branch(slow, greater, t4, Operand(FIRST_JS_RECEIVER_TYPE)); |
311 // Call runtime on identical symbols since we need to throw a TypeError. | 311 // Call runtime on identical symbols since we need to throw a TypeError. |
312 __ Branch(slow, eq, t4, Operand(SYMBOL_TYPE)); | 312 __ Branch(slow, eq, t4, Operand(SYMBOL_TYPE)); |
313 // Call runtime on identical SIMD values since we must throw a TypeError. | 313 // Call runtime on identical SIMD values since we must throw a TypeError. |
314 __ Branch(slow, eq, t4, Operand(SIMD128_VALUE_TYPE)); | 314 __ Branch(slow, eq, t4, Operand(SIMD128_VALUE_TYPE)); |
315 if (is_strong(strength)) { | 315 if (is_strong(strength)) { |
316 // Call the runtime on anything that is converted in the semantics, | 316 // Call the runtime on anything that is converted in the semantics, |
317 // since we need to throw a TypeError. Smis and heap numbers have | 317 // since we need to throw a TypeError. Smis and heap numbers have |
318 // already been ruled out. | 318 // already been ruled out. |
319 __ And(t4, t4, Operand(kIsNotStringMask)); | 319 __ And(t4, t4, Operand(kIsNotStringMask)); |
320 __ Branch(slow, ne, t4, Operand(zero_reg)); | 320 __ Branch(slow, ne, t4, Operand(zero_reg)); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 // Fall through to both_loaded_as_doubles. | 452 // Fall through to both_loaded_as_doubles. |
453 } | 453 } |
454 | 454 |
455 | 455 |
456 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, | 456 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, |
457 Register lhs, | 457 Register lhs, |
458 Register rhs) { | 458 Register rhs) { |
459 // If either operand is a JS object or an oddball value, then they are | 459 // If either operand is a JS object or an oddball value, then they are |
460 // not equal since their pointers are different. | 460 // not equal since their pointers are different. |
461 // There is no test for undetectability in strict equality. | 461 // There is no test for undetectability in strict equality. |
462 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | 462 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
463 Label first_non_object; | 463 Label first_non_object; |
464 // Get the type of the first operand into a2 and compare it with | 464 // Get the type of the first operand into a2 and compare it with |
465 // FIRST_SPEC_OBJECT_TYPE. | 465 // FIRST_JS_RECEIVER_TYPE. |
466 __ GetObjectType(lhs, a2, a2); | 466 __ GetObjectType(lhs, a2, a2); |
467 __ Branch(&first_non_object, less, a2, Operand(FIRST_SPEC_OBJECT_TYPE)); | 467 __ Branch(&first_non_object, less, a2, Operand(FIRST_JS_RECEIVER_TYPE)); |
468 | 468 |
469 // Return non-zero. | 469 // Return non-zero. |
470 Label return_not_equal; | 470 Label return_not_equal; |
471 __ bind(&return_not_equal); | 471 __ bind(&return_not_equal); |
472 __ Ret(USE_DELAY_SLOT); | 472 __ Ret(USE_DELAY_SLOT); |
473 __ li(v0, Operand(1)); | 473 __ li(v0, Operand(1)); |
474 | 474 |
475 __ bind(&first_non_object); | 475 __ bind(&first_non_object); |
476 // Check for oddballs: true, false, null, undefined. | 476 // Check for oddballs: true, false, null, undefined. |
477 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE)); | 477 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE)); |
478 | 478 |
479 __ GetObjectType(rhs, a3, a3); | 479 __ GetObjectType(rhs, a3, a3); |
480 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); | 480 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_JS_RECEIVER_TYPE)); |
481 | 481 |
482 // Check for oddballs: true, false, null, undefined. | 482 // Check for oddballs: true, false, null, undefined. |
483 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE)); | 483 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE)); |
484 | 484 |
485 // Now that we have the types we might as well check for | 485 // Now that we have the types we might as well check for |
486 // internalized-internalized. | 486 // internalized-internalized. |
487 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); | 487 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); |
488 __ Or(a2, a2, Operand(a3)); | 488 __ Or(a2, a2, Operand(a3)); |
489 __ And(at, a2, Operand(kIsNotStringMask | kIsNotInternalizedMask)); | 489 __ And(at, a2, Operand(kIsNotStringMask | kIsNotInternalizedMask)); |
490 __ Branch(&return_not_equal, eq, at, Operand(zero_reg)); | 490 __ Branch(&return_not_equal, eq, at, Operand(zero_reg)); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE)); | 532 __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE)); |
533 __ And(at, a3, Operand(kIsNotInternalizedMask)); | 533 __ And(at, a3, Operand(kIsNotInternalizedMask)); |
534 __ Branch(possible_strings, ne, at, Operand(zero_reg)); | 534 __ Branch(possible_strings, ne, at, Operand(zero_reg)); |
535 | 535 |
536 // Both are internalized strings. We already checked they weren't the same | 536 // Both are internalized strings. We already checked they weren't the same |
537 // pointer so they are not equal. | 537 // pointer so they are not equal. |
538 __ Ret(USE_DELAY_SLOT); | 538 __ Ret(USE_DELAY_SLOT); |
539 __ li(v0, Operand(1)); // Non-zero indicates not equal. | 539 __ li(v0, Operand(1)); // Non-zero indicates not equal. |
540 | 540 |
541 __ bind(&object_test); | 541 __ bind(&object_test); |
542 __ Branch(not_both_strings, lt, a2, Operand(FIRST_SPEC_OBJECT_TYPE)); | 542 __ Branch(not_both_strings, lt, a2, Operand(FIRST_JS_RECEIVER_TYPE)); |
543 __ GetObjectType(rhs, a2, a3); | 543 __ GetObjectType(rhs, a2, a3); |
544 __ Branch(not_both_strings, lt, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); | 544 __ Branch(not_both_strings, lt, a3, Operand(FIRST_JS_RECEIVER_TYPE)); |
545 | 545 |
546 // If both objects are undetectable, they are equal. Otherwise, they | 546 // If both objects are undetectable, they are equal. Otherwise, they |
547 // are not equal, since they are different objects and an object is not | 547 // are not equal, since they are different objects and an object is not |
548 // equal to undefined. | 548 // equal to undefined. |
549 __ lw(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); | 549 __ lw(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); |
550 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); | 550 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); |
551 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); | 551 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); |
552 __ and_(a0, a2, a3); | 552 __ and_(a0, a2, a3); |
553 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); | 553 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); |
554 __ Ret(USE_DELAY_SLOT); | 554 __ Ret(USE_DELAY_SLOT); |
(...skipping 5011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5566 MemOperand(fp, 6 * kPointerSize), NULL); | 5566 MemOperand(fp, 6 * kPointerSize), NULL); |
5567 } | 5567 } |
5568 | 5568 |
5569 | 5569 |
5570 #undef __ | 5570 #undef __ |
5571 | 5571 |
5572 } // namespace internal | 5572 } // namespace internal |
5573 } // namespace v8 | 5573 } // namespace v8 |
5574 | 5574 |
5575 #endif // V8_TARGET_ARCH_MIPS | 5575 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |