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_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 | 282 |
283 __ li(exp_mask_reg, Operand(HeapNumber::kExponentMask)); | 283 __ li(exp_mask_reg, Operand(HeapNumber::kExponentMask)); |
284 | 284 |
285 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), | 285 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), |
286 // so we do the second best thing - test it ourselves. | 286 // so we do the second best thing - test it ourselves. |
287 // They are both equal and they are not both Smis so both of them are not | 287 // They are both equal and they are not both Smis so both of them are not |
288 // Smis. If it's not a heap number, then return equal. | 288 // Smis. If it's not a heap number, then return equal. |
289 __ GetObjectType(a0, t0, t0); | 289 __ GetObjectType(a0, t0, t0); |
290 if (cc == less || cc == greater) { | 290 if (cc == less || cc == greater) { |
291 // Call runtime on identical JSObjects. | 291 // Call runtime on identical JSObjects. |
292 __ Branch(slow, greater, t0, Operand(FIRST_SPEC_OBJECT_TYPE)); | 292 __ Branch(slow, greater, t0, Operand(FIRST_JS_RECEIVER_TYPE)); |
293 // Call runtime on identical symbols since we need to throw a TypeError. | 293 // Call runtime on identical symbols since we need to throw a TypeError. |
294 __ Branch(slow, eq, t0, Operand(SYMBOL_TYPE)); | 294 __ Branch(slow, eq, t0, Operand(SYMBOL_TYPE)); |
295 // Call runtime on identical SIMD values since we must throw a TypeError. | 295 // Call runtime on identical SIMD values since we must throw a TypeError. |
296 __ Branch(slow, eq, t0, Operand(SIMD128_VALUE_TYPE)); | 296 __ Branch(slow, eq, t0, Operand(SIMD128_VALUE_TYPE)); |
297 if (is_strong(strength)) { | 297 if (is_strong(strength)) { |
298 // Call the runtime on anything that is converted in the semantics, since | 298 // Call the runtime on anything that is converted in the semantics, since |
299 // we need to throw a TypeError. Smis have already been ruled out. | 299 // we need to throw a TypeError. Smis have already been ruled out. |
300 __ Branch(&return_equal, eq, t0, Operand(HEAP_NUMBER_TYPE)); | 300 __ Branch(&return_equal, eq, t0, Operand(HEAP_NUMBER_TYPE)); |
301 __ And(t0, t0, Operand(kIsNotStringMask)); | 301 __ And(t0, t0, Operand(kIsNotStringMask)); |
302 __ Branch(slow, ne, t0, Operand(zero_reg)); | 302 __ Branch(slow, ne, t0, Operand(zero_reg)); |
303 } | 303 } |
304 } else { | 304 } else { |
305 __ Branch(&heap_number, eq, t0, Operand(HEAP_NUMBER_TYPE)); | 305 __ Branch(&heap_number, eq, t0, Operand(HEAP_NUMBER_TYPE)); |
306 // Comparing JS objects with <=, >= is complicated. | 306 // Comparing JS objects with <=, >= is complicated. |
307 if (cc != eq) { | 307 if (cc != eq) { |
308 __ Branch(slow, greater, t0, Operand(FIRST_SPEC_OBJECT_TYPE)); | 308 __ Branch(slow, greater, t0, Operand(FIRST_JS_RECEIVER_TYPE)); |
309 // Call runtime on identical symbols since we need to throw a TypeError. | 309 // Call runtime on identical symbols since we need to throw a TypeError. |
310 __ Branch(slow, eq, t0, Operand(SYMBOL_TYPE)); | 310 __ Branch(slow, eq, t0, Operand(SYMBOL_TYPE)); |
311 // Call runtime on identical SIMD values since we must throw a TypeError. | 311 // Call runtime on identical SIMD values since we must throw a TypeError. |
312 __ Branch(slow, eq, t0, Operand(SIMD128_VALUE_TYPE)); | 312 __ Branch(slow, eq, t0, Operand(SIMD128_VALUE_TYPE)); |
313 if (is_strong(strength)) { | 313 if (is_strong(strength)) { |
314 // Call the runtime on anything that is converted in the semantics, | 314 // Call the runtime on anything that is converted in the semantics, |
315 // since we need to throw a TypeError. Smis and heap numbers have | 315 // since we need to throw a TypeError. Smis and heap numbers have |
316 // already been ruled out. | 316 // already been ruled out. |
317 __ And(t0, t0, Operand(kIsNotStringMask)); | 317 __ And(t0, t0, Operand(kIsNotStringMask)); |
318 __ Branch(slow, ne, t0, Operand(zero_reg)); | 318 __ Branch(slow, ne, t0, Operand(zero_reg)); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 // Fall through to both_loaded_as_doubles. | 448 // Fall through to both_loaded_as_doubles. |
449 } | 449 } |
450 | 450 |
451 | 451 |
452 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, | 452 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, |
453 Register lhs, | 453 Register lhs, |
454 Register rhs) { | 454 Register rhs) { |
455 // If either operand is a JS object or an oddball value, then they are | 455 // If either operand is a JS object or an oddball value, then they are |
456 // not equal since their pointers are different. | 456 // not equal since their pointers are different. |
457 // There is no test for undetectability in strict equality. | 457 // There is no test for undetectability in strict equality. |
458 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | 458 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
459 Label first_non_object; | 459 Label first_non_object; |
460 // Get the type of the first operand into a2 and compare it with | 460 // Get the type of the first operand into a2 and compare it with |
461 // FIRST_SPEC_OBJECT_TYPE. | 461 // FIRST_JS_RECEIVER_TYPE. |
462 __ GetObjectType(lhs, a2, a2); | 462 __ GetObjectType(lhs, a2, a2); |
463 __ Branch(&first_non_object, less, a2, Operand(FIRST_SPEC_OBJECT_TYPE)); | 463 __ Branch(&first_non_object, less, a2, Operand(FIRST_JS_RECEIVER_TYPE)); |
464 | 464 |
465 // Return non-zero. | 465 // Return non-zero. |
466 Label return_not_equal; | 466 Label return_not_equal; |
467 __ bind(&return_not_equal); | 467 __ bind(&return_not_equal); |
468 __ Ret(USE_DELAY_SLOT); | 468 __ Ret(USE_DELAY_SLOT); |
469 __ li(v0, Operand(1)); | 469 __ li(v0, Operand(1)); |
470 | 470 |
471 __ bind(&first_non_object); | 471 __ bind(&first_non_object); |
472 // Check for oddballs: true, false, null, undefined. | 472 // Check for oddballs: true, false, null, undefined. |
473 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE)); | 473 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE)); |
474 | 474 |
475 __ GetObjectType(rhs, a3, a3); | 475 __ GetObjectType(rhs, a3, a3); |
476 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); | 476 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_JS_RECEIVER_TYPE)); |
477 | 477 |
478 // Check for oddballs: true, false, null, undefined. | 478 // Check for oddballs: true, false, null, undefined. |
479 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE)); | 479 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE)); |
480 | 480 |
481 // Now that we have the types we might as well check for | 481 // Now that we have the types we might as well check for |
482 // internalized-internalized. | 482 // internalized-internalized. |
483 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); | 483 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); |
484 __ Or(a2, a2, Operand(a3)); | 484 __ Or(a2, a2, Operand(a3)); |
485 __ And(at, a2, Operand(kIsNotStringMask | kIsNotInternalizedMask)); | 485 __ And(at, a2, Operand(kIsNotStringMask | kIsNotInternalizedMask)); |
486 __ Branch(&return_not_equal, eq, at, Operand(zero_reg)); | 486 __ Branch(&return_not_equal, eq, at, Operand(zero_reg)); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE)); | 528 __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE)); |
529 __ And(at, a3, Operand(kIsNotInternalizedMask)); | 529 __ And(at, a3, Operand(kIsNotInternalizedMask)); |
530 __ Branch(possible_strings, ne, at, Operand(zero_reg)); | 530 __ Branch(possible_strings, ne, at, Operand(zero_reg)); |
531 | 531 |
532 // Both are internalized strings. We already checked they weren't the same | 532 // Both are internalized strings. We already checked they weren't the same |
533 // pointer so they are not equal. | 533 // pointer so they are not equal. |
534 __ Ret(USE_DELAY_SLOT); | 534 __ Ret(USE_DELAY_SLOT); |
535 __ li(v0, Operand(1)); // Non-zero indicates not equal. | 535 __ li(v0, Operand(1)); // Non-zero indicates not equal. |
536 | 536 |
537 __ bind(&object_test); | 537 __ bind(&object_test); |
538 __ Branch(not_both_strings, lt, a2, Operand(FIRST_SPEC_OBJECT_TYPE)); | 538 __ Branch(not_both_strings, lt, a2, Operand(FIRST_JS_RECEIVER_TYPE)); |
539 __ GetObjectType(rhs, a2, a3); | 539 __ GetObjectType(rhs, a2, a3); |
540 __ Branch(not_both_strings, lt, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); | 540 __ Branch(not_both_strings, lt, a3, Operand(FIRST_JS_RECEIVER_TYPE)); |
541 | 541 |
542 // If both objects are undetectable, they are equal. Otherwise, they | 542 // If both objects are undetectable, they are equal. Otherwise, they |
543 // are not equal, since they are different objects and an object is not | 543 // are not equal, since they are different objects and an object is not |
544 // equal to undefined. | 544 // equal to undefined. |
545 __ ld(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); | 545 __ ld(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); |
546 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); | 546 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); |
547 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); | 547 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); |
548 __ and_(a0, a2, a3); | 548 __ and_(a0, a2, a3); |
549 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); | 549 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); |
550 __ Ret(USE_DELAY_SLOT); | 550 __ Ret(USE_DELAY_SLOT); |
(...skipping 5045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5596 MemOperand(fp, 6 * kPointerSize), NULL); | 5596 MemOperand(fp, 6 * kPointerSize), NULL); |
5597 } | 5597 } |
5598 | 5598 |
5599 | 5599 |
5600 #undef __ | 5600 #undef __ |
5601 | 5601 |
5602 } // namespace internal | 5602 } // namespace internal |
5603 } // namespace v8 | 5603 } // namespace v8 |
5604 | 5604 |
5605 #endif // V8_TARGET_ARCH_MIPS64 | 5605 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |