| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1613 Register left = ToRegister(instr->InputAt(0)); | 1613 Register left = ToRegister(instr->InputAt(0)); |
| 1614 Register right = ToRegister(instr->InputAt(1)); | 1614 Register right = ToRegister(instr->InputAt(1)); |
| 1615 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1615 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1616 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1616 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1617 | 1617 |
| 1618 __ cmp(left, Operand(right)); | 1618 __ cmp(left, Operand(right)); |
| 1619 EmitBranch(true_block, false_block, eq); | 1619 EmitBranch(true_block, false_block, eq); |
| 1620 } | 1620 } |
| 1621 | 1621 |
| 1622 | 1622 |
| 1623 void LCodeGen::DoCmpSymbolEq(LCmpSymbolEq* instr) { |
| 1624 Register left = ToRegister(instr->InputAt(0)); |
| 1625 Register right = ToRegister(instr->InputAt(1)); |
| 1626 Register result = ToRegister(instr->result()); |
| 1627 |
| 1628 __ cmp(left, Operand(right)); |
| 1629 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); |
| 1630 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); |
| 1631 } |
| 1632 |
| 1633 |
| 1634 void LCodeGen::DoCmpSymbolEqAndBranch(LCmpSymbolEqAndBranch* instr) { |
| 1635 Register left = ToRegister(instr->InputAt(0)); |
| 1636 Register right = ToRegister(instr->InputAt(1)); |
| 1637 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1638 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1639 |
| 1640 __ cmp(left, Operand(right)); |
| 1641 EmitBranch(true_block, false_block, eq); |
| 1642 } |
| 1643 |
| 1644 |
| 1623 void LCodeGen::DoIsNull(LIsNull* instr) { | 1645 void LCodeGen::DoIsNull(LIsNull* instr) { |
| 1624 Register reg = ToRegister(instr->InputAt(0)); | 1646 Register reg = ToRegister(instr->InputAt(0)); |
| 1625 Register result = ToRegister(instr->result()); | 1647 Register result = ToRegister(instr->result()); |
| 1626 | 1648 |
| 1627 __ LoadRoot(ip, Heap::kNullValueRootIndex); | 1649 __ LoadRoot(ip, Heap::kNullValueRootIndex); |
| 1628 __ cmp(reg, ip); | 1650 __ cmp(reg, ip); |
| 1629 if (instr->is_strict()) { | 1651 if (instr->is_strict()) { |
| 1630 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); | 1652 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); |
| 1631 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); | 1653 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); |
| 1632 } else { | 1654 } else { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1767 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 1789 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { |
| 1768 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1790 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1769 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1791 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1770 | 1792 |
| 1771 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); | 1793 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); |
| 1772 __ tst(input_reg, Operand(kSmiTagMask)); | 1794 __ tst(input_reg, Operand(kSmiTagMask)); |
| 1773 EmitBranch(true_block, false_block, eq); | 1795 EmitBranch(true_block, false_block, eq); |
| 1774 } | 1796 } |
| 1775 | 1797 |
| 1776 | 1798 |
| 1799 void LCodeGen::DoIsUndetectable(LIsUndetectable* instr) { |
| 1800 Register input = ToRegister(instr->InputAt(0)); |
| 1801 Register result = ToRegister(instr->result()); |
| 1802 |
| 1803 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
| 1804 Label false_label, done; |
| 1805 __ JumpIfSmi(input, &false_label); |
| 1806 __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 1807 __ ldrb(result, FieldMemOperand(result, Map::kBitFieldOffset)); |
| 1808 __ tst(result, Operand(1 << Map::kIsUndetectable)); |
| 1809 __ b(eq, &false_label); |
| 1810 __ LoadRoot(result, Heap::kTrueValueRootIndex); |
| 1811 __ jmp(&done); |
| 1812 __ bind(&false_label); |
| 1813 __ LoadRoot(result, Heap::kFalseValueRootIndex); |
| 1814 __ bind(&done); |
| 1815 } |
| 1816 |
| 1817 |
| 1818 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { |
| 1819 Register input = ToRegister(instr->InputAt(0)); |
| 1820 Register temp = ToRegister(instr->TempAt(0)); |
| 1821 |
| 1822 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1823 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1824 |
| 1825 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); |
| 1826 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 1827 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); |
| 1828 __ tst(temp, Operand(1 << Map::kIsUndetectable)); |
| 1829 EmitBranch(true_block, false_block, ne); |
| 1830 } |
| 1831 |
| 1832 |
| 1777 static InstanceType TestType(HHasInstanceType* instr) { | 1833 static InstanceType TestType(HHasInstanceType* instr) { |
| 1778 InstanceType from = instr->from(); | 1834 InstanceType from = instr->from(); |
| 1779 InstanceType to = instr->to(); | 1835 InstanceType to = instr->to(); |
| 1780 if (from == FIRST_TYPE) return to; | 1836 if (from == FIRST_TYPE) return to; |
| 1781 ASSERT(from == to || to == LAST_TYPE); | 1837 ASSERT(from == to || to == LAST_TYPE); |
| 1782 return from; | 1838 return from; |
| 1783 } | 1839 } |
| 1784 | 1840 |
| 1785 | 1841 |
| 1786 static Condition BranchCondition(HHasInstanceType* instr) { | 1842 static Condition BranchCondition(HHasInstanceType* instr) { |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2466 Register key = EmitLoadRegister(instr->key(), scratch0()); | 2522 Register key = EmitLoadRegister(instr->key(), scratch0()); |
| 2467 Register result = ToRegister(instr->result()); | 2523 Register result = ToRegister(instr->result()); |
| 2468 Register scratch = scratch0(); | 2524 Register scratch = scratch0(); |
| 2469 ASSERT(result.is(elements)); | 2525 ASSERT(result.is(elements)); |
| 2470 | 2526 |
| 2471 // Load the result. | 2527 // Load the result. |
| 2472 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 2528 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
| 2473 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 2529 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
| 2474 | 2530 |
| 2475 // Check for the hole value. | 2531 // Check for the hole value. |
| 2476 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 2532 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2477 __ cmp(result, scratch); | 2533 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
| 2478 DeoptimizeIf(eq, instr->environment()); | 2534 __ cmp(result, scratch); |
| 2535 DeoptimizeIf(eq, instr->environment()); |
| 2536 } |
| 2479 } | 2537 } |
| 2480 | 2538 |
| 2481 | 2539 |
| 2482 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | 2540 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
| 2483 LLoadKeyedSpecializedArrayElement* instr) { | 2541 LLoadKeyedSpecializedArrayElement* instr) { |
| 2484 Register external_pointer = ToRegister(instr->external_pointer()); | 2542 Register external_pointer = ToRegister(instr->external_pointer()); |
| 2485 Register key = ToRegister(instr->key()); | 2543 Register key = no_reg; |
| 2486 ExternalArrayType array_type = instr->array_type(); | 2544 ExternalArrayType array_type = instr->array_type(); |
| 2487 if (array_type == kExternalFloatArray) { | 2545 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 2546 int constant_key = 0; |
| 2547 if (key_is_constant) { |
| 2548 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 2549 if (constant_key & 0xF0000000) { |
| 2550 Abort("array index constant value too big."); |
| 2551 } |
| 2552 } else { |
| 2553 key = ToRegister(instr->key()); |
| 2554 } |
| 2555 int shift_size = ExternalArrayTypeToShiftSize(array_type); |
| 2556 |
| 2557 if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) { |
| 2488 CpuFeatures::Scope scope(VFP3); | 2558 CpuFeatures::Scope scope(VFP3); |
| 2489 DwVfpRegister result(ToDoubleRegister(instr->result())); | 2559 DwVfpRegister result(ToDoubleRegister(instr->result())); |
| 2490 __ add(scratch0(), external_pointer, Operand(key, LSL, 2)); | 2560 Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) |
| 2491 __ vldr(result.low(), scratch0(), 0); | 2561 : Operand(key, LSL, shift_size)); |
| 2492 __ vcvt_f64_f32(result, result.low()); | 2562 __ add(scratch0(), external_pointer, operand); |
| 2493 } else if (array_type == kExternalDoubleArray) { | 2563 if (array_type == kExternalFloatArray) { |
| 2494 CpuFeatures::Scope scope(VFP3); | 2564 __ vldr(result.low(), scratch0(), 0); |
| 2495 DwVfpRegister result(ToDoubleRegister(instr->result())); | 2565 __ vcvt_f64_f32(result, result.low()); |
| 2496 __ add(scratch0(), external_pointer, Operand(key, LSL, 3)); | 2566 } else { // i.e. array_type == kExternalDoubleArray |
| 2497 __ vldr(result, scratch0(), 0); | 2567 __ vldr(result, scratch0(), 0); |
| 2568 } |
| 2498 } else { | 2569 } else { |
| 2499 Register result(ToRegister(instr->result())); | 2570 Register result(ToRegister(instr->result())); |
| 2571 MemOperand mem_operand(key_is_constant |
| 2572 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) |
| 2573 : MemOperand(external_pointer, key, LSL, shift_size)); |
| 2500 switch (array_type) { | 2574 switch (array_type) { |
| 2501 case kExternalByteArray: | 2575 case kExternalByteArray: |
| 2502 __ ldrsb(result, MemOperand(external_pointer, key)); | 2576 __ ldrsb(result, mem_operand); |
| 2503 break; | 2577 break; |
| 2504 case kExternalUnsignedByteArray: | 2578 case kExternalUnsignedByteArray: |
| 2505 case kExternalPixelArray: | 2579 case kExternalPixelArray: |
| 2506 __ ldrb(result, MemOperand(external_pointer, key)); | 2580 __ ldrb(result, mem_operand); |
| 2507 break; | 2581 break; |
| 2508 case kExternalShortArray: | 2582 case kExternalShortArray: |
| 2509 __ ldrsh(result, MemOperand(external_pointer, key, LSL, 1)); | 2583 __ ldrsh(result, mem_operand); |
| 2510 break; | 2584 break; |
| 2511 case kExternalUnsignedShortArray: | 2585 case kExternalUnsignedShortArray: |
| 2512 __ ldrh(result, MemOperand(external_pointer, key, LSL, 1)); | 2586 __ ldrh(result, mem_operand); |
| 2513 break; | 2587 break; |
| 2514 case kExternalIntArray: | 2588 case kExternalIntArray: |
| 2515 __ ldr(result, MemOperand(external_pointer, key, LSL, 2)); | 2589 __ ldr(result, mem_operand); |
| 2516 break; | 2590 break; |
| 2517 case kExternalUnsignedIntArray: | 2591 case kExternalUnsignedIntArray: |
| 2518 __ ldr(result, MemOperand(external_pointer, key, LSL, 2)); | 2592 __ ldr(result, mem_operand); |
| 2519 __ cmp(result, Operand(0x80000000)); | 2593 __ cmp(result, Operand(0x80000000)); |
| 2520 // TODO(danno): we could be more clever here, perhaps having a special | 2594 // TODO(danno): we could be more clever here, perhaps having a special |
| 2521 // version of the stub that detects if the overflow case actually | 2595 // version of the stub that detects if the overflow case actually |
| 2522 // happens, and generate code that returns a double rather than int. | 2596 // happens, and generate code that returns a double rather than int. |
| 2523 DeoptimizeIf(cs, instr->environment()); | 2597 DeoptimizeIf(cs, instr->environment()); |
| 2524 break; | 2598 break; |
| 2525 case kExternalFloatArray: | 2599 case kExternalFloatArray: |
| 2526 case kExternalDoubleArray: | 2600 case kExternalDoubleArray: |
| 2527 UNREACHABLE(); | 2601 UNREACHABLE(); |
| 2528 break; | 2602 break; |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3238 __ add(key, scratch, Operand(FixedArray::kHeaderSize)); | 3312 __ add(key, scratch, Operand(FixedArray::kHeaderSize)); |
| 3239 __ RecordWrite(elements, key, value); | 3313 __ RecordWrite(elements, key, value); |
| 3240 } | 3314 } |
| 3241 } | 3315 } |
| 3242 | 3316 |
| 3243 | 3317 |
| 3244 void LCodeGen::DoStoreKeyedSpecializedArrayElement( | 3318 void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
| 3245 LStoreKeyedSpecializedArrayElement* instr) { | 3319 LStoreKeyedSpecializedArrayElement* instr) { |
| 3246 | 3320 |
| 3247 Register external_pointer = ToRegister(instr->external_pointer()); | 3321 Register external_pointer = ToRegister(instr->external_pointer()); |
| 3248 Register key = ToRegister(instr->key()); | 3322 Register key = no_reg; |
| 3249 ExternalArrayType array_type = instr->array_type(); | 3323 ExternalArrayType array_type = instr->array_type(); |
| 3324 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 3325 int constant_key = 0; |
| 3326 if (key_is_constant) { |
| 3327 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3328 if (constant_key & 0xF0000000) { |
| 3329 Abort("array index constant value too big."); |
| 3330 } |
| 3331 } else { |
| 3332 key = ToRegister(instr->key()); |
| 3333 } |
| 3334 int shift_size = ExternalArrayTypeToShiftSize(array_type); |
| 3250 | 3335 |
| 3251 if (array_type == kExternalFloatArray) { | 3336 if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) { |
| 3252 CpuFeatures::Scope scope(VFP3); | 3337 CpuFeatures::Scope scope(VFP3); |
| 3253 DwVfpRegister value(ToDoubleRegister(instr->value())); | 3338 DwVfpRegister value(ToDoubleRegister(instr->value())); |
| 3254 __ add(scratch0(), external_pointer, Operand(key, LSL, 2)); | 3339 Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) |
| 3255 __ vcvt_f32_f64(double_scratch0().low(), value); | 3340 : Operand(key, LSL, shift_size)); |
| 3256 __ vstr(double_scratch0().low(), scratch0(), 0); | 3341 __ add(scratch0(), external_pointer, operand); |
| 3257 } else if (array_type == kExternalDoubleArray) { | 3342 if (array_type == kExternalFloatArray) { |
| 3258 CpuFeatures::Scope scope(VFP3); | 3343 __ vcvt_f32_f64(double_scratch0().low(), value); |
| 3259 DwVfpRegister value(ToDoubleRegister(instr->value())); | 3344 __ vstr(double_scratch0().low(), scratch0(), 0); |
| 3260 __ add(scratch0(), external_pointer, Operand(key, LSL, 3)); | 3345 } else { // i.e. array_type == kExternalDoubleArray |
| 3261 __ vstr(value, scratch0(), 0); | 3346 __ vstr(value, scratch0(), 0); |
| 3347 } |
| 3262 } else { | 3348 } else { |
| 3263 Register value(ToRegister(instr->value())); | 3349 Register value(ToRegister(instr->value())); |
| 3350 MemOperand mem_operand(key_is_constant |
| 3351 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) |
| 3352 : MemOperand(external_pointer, key, LSL, shift_size)); |
| 3264 switch (array_type) { | 3353 switch (array_type) { |
| 3265 case kExternalPixelArray: | 3354 case kExternalPixelArray: |
| 3266 // Clamp the value to [0..255]. | |
| 3267 __ Usat(value, 8, Operand(value)); | |
| 3268 __ strb(value, MemOperand(external_pointer, key)); | |
| 3269 break; | |
| 3270 case kExternalByteArray: | 3355 case kExternalByteArray: |
| 3271 case kExternalUnsignedByteArray: | 3356 case kExternalUnsignedByteArray: |
| 3272 __ strb(value, MemOperand(external_pointer, key)); | 3357 __ strb(value, mem_operand); |
| 3273 break; | 3358 break; |
| 3274 case kExternalShortArray: | 3359 case kExternalShortArray: |
| 3275 case kExternalUnsignedShortArray: | 3360 case kExternalUnsignedShortArray: |
| 3276 __ strh(value, MemOperand(external_pointer, key, LSL, 1)); | 3361 __ strh(value, mem_operand); |
| 3277 break; | 3362 break; |
| 3278 case kExternalIntArray: | 3363 case kExternalIntArray: |
| 3279 case kExternalUnsignedIntArray: | 3364 case kExternalUnsignedIntArray: |
| 3280 __ str(value, MemOperand(external_pointer, key, LSL, 2)); | 3365 __ str(value, mem_operand); |
| 3281 break; | 3366 break; |
| 3282 case kExternalFloatArray: | 3367 case kExternalFloatArray: |
| 3283 case kExternalDoubleArray: | 3368 case kExternalDoubleArray: |
| 3284 UNREACHABLE(); | 3369 UNREACHABLE(); |
| 3285 break; | 3370 break; |
| 3286 } | 3371 } |
| 3287 } | 3372 } |
| 3288 } | 3373 } |
| 3289 | 3374 |
| 3290 | 3375 |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3860 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { | 3945 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { |
| 3861 LOperand* input = instr->InputAt(0); | 3946 LOperand* input = instr->InputAt(0); |
| 3862 __ tst(ToRegister(input), Operand(kSmiTagMask)); | 3947 __ tst(ToRegister(input), Operand(kSmiTagMask)); |
| 3863 DeoptimizeIf(eq, instr->environment()); | 3948 DeoptimizeIf(eq, instr->environment()); |
| 3864 } | 3949 } |
| 3865 | 3950 |
| 3866 | 3951 |
| 3867 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 3952 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
| 3868 Register input = ToRegister(instr->InputAt(0)); | 3953 Register input = ToRegister(instr->InputAt(0)); |
| 3869 Register scratch = scratch0(); | 3954 Register scratch = scratch0(); |
| 3870 InstanceType first = instr->hydrogen()->first(); | |
| 3871 InstanceType last = instr->hydrogen()->last(); | |
| 3872 | 3955 |
| 3873 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 3956 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 3874 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); | 3957 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); |
| 3875 __ cmp(scratch, Operand(first)); | |
| 3876 | 3958 |
| 3877 // If there is only one type in the interval check for equality. | 3959 if (instr->hydrogen()->is_interval_check()) { |
| 3878 if (first == last) { | 3960 InstanceType first; |
| 3879 DeoptimizeIf(ne, instr->environment()); | 3961 InstanceType last; |
| 3962 instr->hydrogen()->GetCheckInterval(&first, &last); |
| 3963 |
| 3964 __ cmp(scratch, Operand(first)); |
| 3965 |
| 3966 // If there is only one type in the interval check for equality. |
| 3967 if (first == last) { |
| 3968 DeoptimizeIf(ne, instr->environment()); |
| 3969 } else { |
| 3970 DeoptimizeIf(lo, instr->environment()); |
| 3971 // Omit check for the last type. |
| 3972 if (last != LAST_TYPE) { |
| 3973 __ cmp(scratch, Operand(last)); |
| 3974 DeoptimizeIf(hi, instr->environment()); |
| 3975 } |
| 3976 } |
| 3880 } else { | 3977 } else { |
| 3881 DeoptimizeIf(lo, instr->environment()); | 3978 uint8_t mask; |
| 3882 // Omit check for the last type. | 3979 uint8_t tag; |
| 3883 if (last != LAST_TYPE) { | 3980 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); |
| 3884 __ cmp(scratch, Operand(last)); | 3981 |
| 3885 DeoptimizeIf(hi, instr->environment()); | 3982 if (IsPowerOf2(mask)) { |
| 3983 ASSERT(tag == 0 || IsPowerOf2(tag)); |
| 3984 __ tst(scratch, Operand(mask)); |
| 3985 DeoptimizeIf(tag == 0 ? ne : eq, instr->environment()); |
| 3986 } else { |
| 3987 __ and_(scratch, scratch, Operand(mask)); |
| 3988 __ cmp(scratch, Operand(tag)); |
| 3989 DeoptimizeIf(ne, instr->environment()); |
| 3886 } | 3990 } |
| 3887 } | 3991 } |
| 3888 } | 3992 } |
| 3889 | 3993 |
| 3890 | 3994 |
| 3891 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 3995 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
| 3892 ASSERT(instr->InputAt(0)->IsRegister()); | 3996 ASSERT(instr->InputAt(0)->IsRegister()); |
| 3893 Register reg = ToRegister(instr->InputAt(0)); | 3997 Register reg = ToRegister(instr->InputAt(0)); |
| 3894 __ cmp(reg, Operand(instr->hydrogen()->target())); | 3998 __ cmp(reg, Operand(instr->hydrogen()->target())); |
| 3895 DeoptimizeIf(ne, instr->environment()); | 3999 DeoptimizeIf(ne, instr->environment()); |
| 3896 } | 4000 } |
| 3897 | 4001 |
| 3898 | 4002 |
| 3899 void LCodeGen::DoCheckMap(LCheckMap* instr) { | 4003 void LCodeGen::DoCheckMap(LCheckMap* instr) { |
| 3900 Register scratch = scratch0(); | 4004 Register scratch = scratch0(); |
| 3901 LOperand* input = instr->InputAt(0); | 4005 LOperand* input = instr->InputAt(0); |
| 3902 ASSERT(input->IsRegister()); | 4006 ASSERT(input->IsRegister()); |
| 3903 Register reg = ToRegister(input); | 4007 Register reg = ToRegister(input); |
| 3904 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 4008 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 3905 __ cmp(scratch, Operand(instr->hydrogen()->map())); | 4009 __ cmp(scratch, Operand(instr->hydrogen()->map())); |
| 3906 DeoptimizeIf(ne, instr->environment()); | 4010 DeoptimizeIf(ne, instr->environment()); |
| 3907 } | 4011 } |
| 3908 | 4012 |
| 3909 | 4013 |
| 4014 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { |
| 4015 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); |
| 4016 Register result_reg = ToRegister(instr->result()); |
| 4017 DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0)); |
| 4018 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); |
| 4019 } |
| 4020 |
| 4021 |
| 4022 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { |
| 4023 Register unclamped_reg = ToRegister(instr->unclamped()); |
| 4024 Register result_reg = ToRegister(instr->result()); |
| 4025 __ ClampUint8(result_reg, unclamped_reg); |
| 4026 } |
| 4027 |
| 4028 |
| 4029 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { |
| 4030 Register scratch = scratch0(); |
| 4031 Register input_reg = ToRegister(instr->unclamped()); |
| 4032 Register result_reg = ToRegister(instr->result()); |
| 4033 DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0)); |
| 4034 Label is_smi, done, heap_number; |
| 4035 |
| 4036 // Both smi and heap number cases are handled. |
| 4037 __ JumpIfSmi(input_reg, &is_smi); |
| 4038 |
| 4039 // Check for heap number |
| 4040 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
| 4041 __ cmp(scratch, Operand(factory()->heap_number_map())); |
| 4042 __ b(eq, &heap_number); |
| 4043 |
| 4044 // Check for undefined. Undefined is converted to zero for clamping |
| 4045 // conversions. |
| 4046 __ cmp(input_reg, Operand(factory()->undefined_value())); |
| 4047 DeoptimizeIf(ne, instr->environment()); |
| 4048 __ movt(input_reg, 0); |
| 4049 __ jmp(&done); |
| 4050 |
| 4051 // Heap number |
| 4052 __ bind(&heap_number); |
| 4053 __ vldr(double_scratch0(), FieldMemOperand(input_reg, |
| 4054 HeapNumber::kValueOffset)); |
| 4055 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg); |
| 4056 __ jmp(&done); |
| 4057 |
| 4058 // smi |
| 4059 __ bind(&is_smi); |
| 4060 __ SmiUntag(result_reg, input_reg); |
| 4061 __ ClampUint8(result_reg, result_reg); |
| 4062 |
| 4063 __ bind(&done); |
| 4064 } |
| 4065 |
| 4066 |
| 3910 void LCodeGen::LoadHeapObject(Register result, | 4067 void LCodeGen::LoadHeapObject(Register result, |
| 3911 Handle<HeapObject> object) { | 4068 Handle<HeapObject> object) { |
| 3912 if (heap()->InNewSpace(*object)) { | 4069 if (heap()->InNewSpace(*object)) { |
| 3913 Handle<JSGlobalPropertyCell> cell = | 4070 Handle<JSGlobalPropertyCell> cell = |
| 3914 factory()->NewJSGlobalPropertyCell(object); | 4071 factory()->NewJSGlobalPropertyCell(object); |
| 3915 __ mov(result, Operand(cell)); | 4072 __ mov(result, Operand(cell)); |
| 3916 __ ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset)); | 4073 __ ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset)); |
| 3917 } else { | 4074 } else { |
| 3918 __ mov(result, Operand(object)); | 4075 __ mov(result, Operand(object)); |
| 3919 } | 4076 } |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4309 ASSERT(osr_pc_offset_ == -1); | 4466 ASSERT(osr_pc_offset_ == -1); |
| 4310 osr_pc_offset_ = masm()->pc_offset(); | 4467 osr_pc_offset_ = masm()->pc_offset(); |
| 4311 } | 4468 } |
| 4312 | 4469 |
| 4313 | 4470 |
| 4314 | 4471 |
| 4315 | 4472 |
| 4316 #undef __ | 4473 #undef __ |
| 4317 | 4474 |
| 4318 } } // namespace v8::internal | 4475 } } // namespace v8::internal |
| OLD | NEW |