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 |