| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_PPC | 7 #if V8_TARGET_ARCH_PPC |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 __ cmpi(r3, Operand::Zero()); | 354 __ cmpi(r3, Operand::Zero()); |
| 355 // For equal we already have the right value in r3: Return zero (equal) | 355 // For equal we already have the right value in r3: Return zero (equal) |
| 356 // if all bits in mantissa are zero (it's an Infinity) and non-zero if | 356 // if all bits in mantissa are zero (it's an Infinity) and non-zero if |
| 357 // not (it's a NaN). For <= and >= we need to load r0 with the failing | 357 // not (it's a NaN). For <= and >= we need to load r0 with the failing |
| 358 // value if it's a NaN. | 358 // value if it's a NaN. |
| 359 if (cond != eq) { | 359 if (cond != eq) { |
| 360 if (CpuFeatures::IsSupported(ISELECT)) { | 360 if (CpuFeatures::IsSupported(ISELECT)) { |
| 361 __ li(r4, Operand((cond == le) ? GREATER : LESS)); | 361 __ li(r4, Operand((cond == le) ? GREATER : LESS)); |
| 362 __ isel(eq, r3, r3, r4); | 362 __ isel(eq, r3, r3, r4); |
| 363 } else { | 363 } else { |
| 364 Label not_equal; | |
| 365 __ bne(¬_equal); | |
| 366 // All-zero means Infinity means equal. | 364 // All-zero means Infinity means equal. |
| 367 __ Ret(); | 365 __ Ret(eq); |
| 368 __ bind(¬_equal); | |
| 369 if (cond == le) { | 366 if (cond == le) { |
| 370 __ li(r3, Operand(GREATER)); // NaN <= NaN should fail. | 367 __ li(r3, Operand(GREATER)); // NaN <= NaN should fail. |
| 371 } else { | 368 } else { |
| 372 __ li(r3, Operand(LESS)); // NaN >= NaN should fail. | 369 __ li(r3, Operand(LESS)); // NaN >= NaN should fail. |
| 373 } | 370 } |
| 374 } | 371 } |
| 375 } | 372 } |
| 376 __ Ret(); | 373 __ Ret(); |
| 377 } | 374 } |
| 378 // No fall through here. | 375 // No fall through here. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 389 | 386 |
| 390 Label rhs_is_smi; | 387 Label rhs_is_smi; |
| 391 __ JumpIfSmi(rhs, &rhs_is_smi); | 388 __ JumpIfSmi(rhs, &rhs_is_smi); |
| 392 | 389 |
| 393 // Lhs is a Smi. Check whether the rhs is a heap number. | 390 // Lhs is a Smi. Check whether the rhs is a heap number. |
| 394 __ CompareObjectType(rhs, r6, r7, HEAP_NUMBER_TYPE); | 391 __ CompareObjectType(rhs, r6, r7, HEAP_NUMBER_TYPE); |
| 395 if (strict) { | 392 if (strict) { |
| 396 // If rhs is not a number and lhs is a Smi then strict equality cannot | 393 // If rhs is not a number and lhs is a Smi then strict equality cannot |
| 397 // succeed. Return non-equal | 394 // succeed. Return non-equal |
| 398 // If rhs is r3 then there is already a non zero value in it. | 395 // If rhs is r3 then there is already a non zero value in it. |
| 399 Label skip; | |
| 400 __ beq(&skip); | |
| 401 if (!rhs.is(r3)) { | 396 if (!rhs.is(r3)) { |
| 397 Label skip; |
| 398 __ beq(&skip); |
| 402 __ mov(r3, Operand(NOT_EQUAL)); | 399 __ mov(r3, Operand(NOT_EQUAL)); |
| 400 __ Ret(); |
| 401 __ bind(&skip); |
| 402 } else { |
| 403 __ Ret(ne); |
| 403 } | 404 } |
| 404 __ Ret(); | |
| 405 __ bind(&skip); | |
| 406 } else { | 405 } else { |
| 407 // Smi compared non-strictly with a non-Smi non-heap-number. Call | 406 // Smi compared non-strictly with a non-Smi non-heap-number. Call |
| 408 // the runtime. | 407 // the runtime. |
| 409 __ bne(slow); | 408 __ bne(slow); |
| 410 } | 409 } |
| 411 | 410 |
| 412 // Lhs is a smi, rhs is a number. | 411 // Lhs is a smi, rhs is a number. |
| 413 // Convert lhs to a double in d7. | 412 // Convert lhs to a double in d7. |
| 414 __ SmiToDouble(d7, lhs); | 413 __ SmiToDouble(d7, lhs); |
| 415 // Load the double from rhs, tagged HeapNumber r3, to d6. | 414 // Load the double from rhs, tagged HeapNumber r3, to d6. |
| 416 __ lfd(d6, FieldMemOperand(rhs, HeapNumber::kValueOffset)); | 415 __ lfd(d6, FieldMemOperand(rhs, HeapNumber::kValueOffset)); |
| 417 | 416 |
| 418 // We now have both loaded as doubles but we can skip the lhs nan check | 417 // We now have both loaded as doubles but we can skip the lhs nan check |
| 419 // since it's a smi. | 418 // since it's a smi. |
| 420 __ b(lhs_not_nan); | 419 __ b(lhs_not_nan); |
| 421 | 420 |
| 422 __ bind(&rhs_is_smi); | 421 __ bind(&rhs_is_smi); |
| 423 // Rhs is a smi. Check whether the non-smi lhs is a heap number. | 422 // Rhs is a smi. Check whether the non-smi lhs is a heap number. |
| 424 __ CompareObjectType(lhs, r7, r7, HEAP_NUMBER_TYPE); | 423 __ CompareObjectType(lhs, r7, r7, HEAP_NUMBER_TYPE); |
| 425 if (strict) { | 424 if (strict) { |
| 426 // If lhs is not a number and rhs is a smi then strict equality cannot | 425 // If lhs is not a number and rhs is a smi then strict equality cannot |
| 427 // succeed. Return non-equal. | 426 // succeed. Return non-equal. |
| 428 // If lhs is r3 then there is already a non zero value in it. | 427 // If lhs is r3 then there is already a non zero value in it. |
| 429 Label skip; | |
| 430 __ beq(&skip); | |
| 431 if (!lhs.is(r3)) { | 428 if (!lhs.is(r3)) { |
| 429 Label skip; |
| 430 __ beq(&skip); |
| 432 __ mov(r3, Operand(NOT_EQUAL)); | 431 __ mov(r3, Operand(NOT_EQUAL)); |
| 432 __ Ret(); |
| 433 __ bind(&skip); |
| 434 } else { |
| 435 __ Ret(ne); |
| 433 } | 436 } |
| 434 __ Ret(); | |
| 435 __ bind(&skip); | |
| 436 } else { | 437 } else { |
| 437 // Smi compared non-strictly with a non-smi non-heap-number. Call | 438 // Smi compared non-strictly with a non-smi non-heap-number. Call |
| 438 // the runtime. | 439 // the runtime. |
| 439 __ bne(slow); | 440 __ bne(slow); |
| 440 } | 441 } |
| 441 | 442 |
| 442 // Rhs is a smi, lhs is a heap number. | 443 // Rhs is a smi, lhs is a heap number. |
| 443 // Load the double from lhs, tagged HeapNumber r4, to d7. | 444 // Load the double from lhs, tagged HeapNumber r4, to d7. |
| 444 __ lfd(d7, FieldMemOperand(lhs, HeapNumber::kValueOffset)); | 445 __ lfd(d7, FieldMemOperand(lhs, HeapNumber::kValueOffset)); |
| 445 // Convert rhs to a double in d6. | 446 // Convert rhs to a double in d6. |
| (...skipping 3513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3959 // Handle not identical strings. | 3960 // Handle not identical strings. |
| 3960 | 3961 |
| 3961 // Check that both strings are internalized strings. If they are, we're done | 3962 // Check that both strings are internalized strings. If they are, we're done |
| 3962 // because we already know they are not identical. We know they are both | 3963 // because we already know they are not identical. We know they are both |
| 3963 // strings. | 3964 // strings. |
| 3964 if (equality) { | 3965 if (equality) { |
| 3965 DCHECK(GetCondition() == eq); | 3966 DCHECK(GetCondition() == eq); |
| 3966 STATIC_ASSERT(kInternalizedTag == 0); | 3967 STATIC_ASSERT(kInternalizedTag == 0); |
| 3967 __ orx(tmp3, tmp1, tmp2); | 3968 __ orx(tmp3, tmp1, tmp2); |
| 3968 __ andi(r0, tmp3, Operand(kIsNotInternalizedMask)); | 3969 __ andi(r0, tmp3, Operand(kIsNotInternalizedMask)); |
| 3969 __ bne(&is_symbol, cr0); | |
| 3970 // Make sure r3 is non-zero. At this point input operands are | 3970 // Make sure r3 is non-zero. At this point input operands are |
| 3971 // guaranteed to be non-zero. | 3971 // guaranteed to be non-zero. |
| 3972 DCHECK(right.is(r3)); | 3972 DCHECK(right.is(r3)); |
| 3973 __ Ret(); | 3973 __ Ret(eq, cr0); |
| 3974 __ bind(&is_symbol); | |
| 3975 } | 3974 } |
| 3976 | 3975 |
| 3977 // Check that both strings are sequential one-byte. | 3976 // Check that both strings are sequential one-byte. |
| 3978 Label runtime; | 3977 Label runtime; |
| 3979 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(tmp1, tmp2, tmp3, tmp4, | 3978 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(tmp1, tmp2, tmp3, tmp4, |
| 3980 &runtime); | 3979 &runtime); |
| 3981 | 3980 |
| 3982 // Compare flat one-byte strings. Returns when done. | 3981 // Compare flat one-byte strings. Returns when done. |
| 3983 if (equality) { | 3982 if (equality) { |
| 3984 StringHelper::GenerateFlatOneByteStringEquals(masm, left, right, tmp1, | 3983 StringHelper::GenerateFlatOneByteStringEquals(masm, left, right, tmp1, |
| (...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5670 kStackUnwindSpace, NULL, | 5669 kStackUnwindSpace, NULL, |
| 5671 MemOperand(fp, 6 * kPointerSize), NULL); | 5670 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5672 } | 5671 } |
| 5673 | 5672 |
| 5674 | 5673 |
| 5675 #undef __ | 5674 #undef __ |
| 5676 } // namespace internal | 5675 } // namespace internal |
| 5677 } // namespace v8 | 5676 } // namespace v8 |
| 5678 | 5677 |
| 5679 #endif // V8_TARGET_ARCH_PPC | 5678 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |