OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1562 | 1562 |
1563 CallRuntimeFromDeferred( | 1563 CallRuntimeFromDeferred( |
1564 Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); | 1564 Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); |
1565 __ StoreToSafepointRegisterSlot(x0, ToRegister(instr->result())); | 1565 __ StoreToSafepointRegisterSlot(x0, ToRegister(instr->result())); |
1566 } | 1566 } |
1567 | 1567 |
1568 | 1568 |
1569 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 1569 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
1570 Register receiver = ToRegister(instr->receiver()); | 1570 Register receiver = ToRegister(instr->receiver()); |
1571 Register function = ToRegister(instr->function()); | 1571 Register function = ToRegister(instr->function()); |
1572 Register length = ToRegister(instr->length()); | 1572 Register length = ToRegister32(instr->length()); |
| 1573 |
1573 Register elements = ToRegister(instr->elements()); | 1574 Register elements = ToRegister(instr->elements()); |
1574 Register scratch = x5; | 1575 Register scratch = x5; |
1575 ASSERT(receiver.Is(x0)); // Used for parameter count. | 1576 ASSERT(receiver.Is(x0)); // Used for parameter count. |
1576 ASSERT(function.Is(x1)); // Required by InvokeFunction. | 1577 ASSERT(function.Is(x1)); // Required by InvokeFunction. |
1577 ASSERT(ToRegister(instr->result()).Is(x0)); | 1578 ASSERT(ToRegister(instr->result()).Is(x0)); |
1578 ASSERT(instr->IsMarkedAsCall()); | 1579 ASSERT(instr->IsMarkedAsCall()); |
1579 | 1580 |
1580 // Copy the arguments to this function possibly from the | 1581 // Copy the arguments to this function possibly from the |
1581 // adaptor frame below it. | 1582 // adaptor frame below it. |
1582 const uint32_t kArgumentsLimit = 1 * KB; | 1583 const uint32_t kArgumentsLimit = 1 * KB; |
1583 __ Cmp(length, kArgumentsLimit); | 1584 __ Cmp(length, kArgumentsLimit); |
1584 DeoptimizeIf(hi, instr->environment()); | 1585 DeoptimizeIf(hi, instr->environment()); |
1585 | 1586 |
1586 // Push the receiver and use the register to keep the original | 1587 // Push the receiver and use the register to keep the original |
1587 // number of arguments. | 1588 // number of arguments. |
1588 __ Push(receiver); | 1589 __ Push(receiver); |
1589 Register argc = receiver; | 1590 Register argc = receiver; |
1590 receiver = NoReg; | 1591 receiver = NoReg; |
1591 __ Mov(argc, length); | 1592 __ Sxtw(argc, length); |
1592 // The arguments are at a one pointer size offset from elements. | 1593 // The arguments are at a one pointer size offset from elements. |
1593 __ Add(elements, elements, 1 * kPointerSize); | 1594 __ Add(elements, elements, 1 * kPointerSize); |
1594 | 1595 |
1595 // Loop through the arguments pushing them onto the execution | 1596 // Loop through the arguments pushing them onto the execution |
1596 // stack. | 1597 // stack. |
1597 Label invoke, loop; | 1598 Label invoke, loop; |
1598 // length is a small non-negative integer, due to the test above. | 1599 // length is a small non-negative integer, due to the test above. |
1599 __ Cbz(length, &invoke); | 1600 __ Cbz(length, &invoke); |
1600 __ Bind(&loop); | 1601 __ Bind(&loop); |
1601 __ Ldr(scratch, MemOperand(elements, length, LSL, kPointerSizeLog2)); | 1602 __ Ldr(scratch, MemOperand(elements, length, SXTW, kPointerSizeLog2)); |
1602 __ Push(scratch); | 1603 __ Push(scratch); |
1603 __ Subs(length, length, 1); | 1604 __ Subs(length, length, 1); |
1604 __ B(ne, &loop); | 1605 __ B(ne, &loop); |
1605 | 1606 |
1606 __ Bind(&invoke); | 1607 __ Bind(&invoke); |
1607 ASSERT(instr->HasPointerMap()); | 1608 ASSERT(instr->HasPointerMap()); |
1608 LPointerMap* pointers = instr->pointer_map(); | 1609 LPointerMap* pointers = instr->pointer_map(); |
1609 SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt); | 1610 SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt); |
1610 // The number of arguments is stored in argc (receiver) which is x0, as | 1611 // The number of arguments is stored in argc (receiver) which is x0, as |
1611 // expected by InvokeFunction. | 1612 // expected by InvokeFunction. |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 __ Assert(InvertCondition(cc), kEliminatedBoundsCheckFailed); | 1747 __ Assert(InvertCondition(cc), kEliminatedBoundsCheckFailed); |
1747 } else { | 1748 } else { |
1748 DeoptimizeIf(cc, check->environment()); | 1749 DeoptimizeIf(cc, check->environment()); |
1749 } | 1750 } |
1750 } | 1751 } |
1751 | 1752 |
1752 | 1753 |
1753 void LCodeGen::DoBoundsCheck(LBoundsCheck *instr) { | 1754 void LCodeGen::DoBoundsCheck(LBoundsCheck *instr) { |
1754 if (instr->hydrogen()->skip_check()) return; | 1755 if (instr->hydrogen()->skip_check()) return; |
1755 | 1756 |
1756 Register length = ToRegister(instr->length()); | 1757 ASSERT(instr->hydrogen()->length()->representation().IsInteger32()); |
| 1758 Register length = ToRegister32(instr->length()); |
1757 | 1759 |
1758 if (instr->index()->IsConstantOperand()) { | 1760 if (instr->index()->IsConstantOperand()) { |
1759 int constant_index = | 1761 int constant_index = |
1760 ToInteger32(LConstantOperand::cast(instr->index())); | 1762 ToInteger32(LConstantOperand::cast(instr->index())); |
1761 | 1763 |
1762 if (instr->hydrogen()->length()->representation().IsSmi()) { | 1764 if (instr->hydrogen()->length()->representation().IsSmi()) { |
1763 __ Cmp(length, Operand(Smi::FromInt(constant_index))); | 1765 __ Cmp(length, Operand(Smi::FromInt(constant_index))); |
1764 } else { | 1766 } else { |
1765 __ Cmp(length, Operand(constant_index)); | 1767 __ Cmp(length, Operand(constant_index)); |
1766 } | 1768 } |
1767 } else { | 1769 } else { |
1768 __ Cmp(length, ToRegister(instr->index())); | 1770 ASSERT(instr->hydrogen()->index()->representation().IsInteger32()); |
| 1771 __ Cmp(length, ToRegister32(instr->index())); |
1769 } | 1772 } |
1770 Condition condition = instr->hydrogen()->allow_equality() ? lo : ls; | 1773 Condition condition = instr->hydrogen()->allow_equality() ? lo : ls; |
1771 ApplyCheckIf(condition, instr); | 1774 ApplyCheckIf(condition, instr); |
1772 } | 1775 } |
1773 | 1776 |
1774 | 1777 |
1775 void LCodeGen::DoBranch(LBranch* instr) { | 1778 void LCodeGen::DoBranch(LBranch* instr) { |
1776 Representation r = instr->hydrogen()->value()->representation(); | 1779 Representation r = instr->hydrogen()->value()->representation(); |
1777 Label* true_label = instr->TrueLabel(chunk_); | 1780 Label* true_label = instr->TrueLabel(chunk_); |
1778 Label* false_label = instr->FalseLabel(chunk_); | 1781 Label* false_label = instr->FalseLabel(chunk_); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2179 __ Cmp(scratch, tag); | 2182 __ Cmp(scratch, tag); |
2180 } | 2183 } |
2181 DeoptimizeIf(ne, instr->environment()); | 2184 DeoptimizeIf(ne, instr->environment()); |
2182 } | 2185 } |
2183 } | 2186 } |
2184 } | 2187 } |
2185 | 2188 |
2186 | 2189 |
2187 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { | 2190 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { |
2188 DoubleRegister input = ToDoubleRegister(instr->unclamped()); | 2191 DoubleRegister input = ToDoubleRegister(instr->unclamped()); |
2189 Register result = ToRegister(instr->result()); | 2192 Register result = ToRegister32(instr->result()); |
2190 __ ClampDoubleToUint8(result, input, double_scratch()); | 2193 __ ClampDoubleToUint8(result, input, double_scratch()); |
2191 } | 2194 } |
2192 | 2195 |
2193 | 2196 |
2194 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { | 2197 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { |
2195 Register input = ToRegister32(instr->unclamped()); | 2198 Register input = ToRegister32(instr->unclamped()); |
2196 Register result = ToRegister32(instr->result()); | 2199 Register result = ToRegister32(instr->result()); |
2197 __ ClampInt32ToUint8(result, input); | 2200 __ ClampInt32ToUint8(result, input); |
2198 } | 2201 } |
2199 | 2202 |
2200 | 2203 |
2201 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { | 2204 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { |
2202 Register input = ToRegister(instr->unclamped()); | 2205 Register input = ToRegister(instr->unclamped()); |
2203 Register result = ToRegister(instr->result()); | 2206 Register result = ToRegister32(instr->result()); |
2204 Register scratch = ToRegister(instr->temp1()); | 2207 Register scratch = ToRegister(instr->temp1()); |
2205 Label done; | 2208 Label done; |
2206 | 2209 |
2207 // Both smi and heap number cases are handled. | 2210 // Both smi and heap number cases are handled. |
2208 Label is_not_smi; | 2211 Label is_not_smi; |
2209 __ JumpIfNotSmi(input, &is_not_smi); | 2212 __ JumpIfNotSmi(input, &is_not_smi); |
2210 __ SmiUntag(result, input); | 2213 __ SmiUntag(result.X(), input); |
2211 __ ClampInt32ToUint8(result); | 2214 __ ClampInt32ToUint8(result); |
2212 __ B(&done); | 2215 __ B(&done); |
2213 | 2216 |
2214 __ Bind(&is_not_smi); | 2217 __ Bind(&is_not_smi); |
2215 | 2218 |
2216 // Check for heap number. | 2219 // Check for heap number. |
2217 Label is_heap_number; | 2220 Label is_heap_number; |
2218 __ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 2221 __ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); |
2219 __ JumpIfRoot(scratch, Heap::kHeapNumberMapRootIndex, &is_heap_number); | 2222 __ JumpIfRoot(scratch, Heap::kHeapNumberMapRootIndex, &is_heap_number); |
2220 | 2223 |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2453 __ Fmov(result, instr->value()); | 2456 __ Fmov(result, instr->value()); |
2454 } | 2457 } |
2455 | 2458 |
2456 | 2459 |
2457 void LCodeGen::DoConstantE(LConstantE* instr) { | 2460 void LCodeGen::DoConstantE(LConstantE* instr) { |
2458 __ Mov(ToRegister(instr->result()), Operand(instr->value())); | 2461 __ Mov(ToRegister(instr->result()), Operand(instr->value())); |
2459 } | 2462 } |
2460 | 2463 |
2461 | 2464 |
2462 void LCodeGen::DoConstantI(LConstantI* instr) { | 2465 void LCodeGen::DoConstantI(LConstantI* instr) { |
2463 __ Mov(ToRegister(instr->result()), instr->value()); | 2466 ASSERT(is_int32(instr->value())); |
| 2467 // Cast the value here to ensure that the value isn't sign extended by the |
| 2468 // implicit Operand constructor. |
| 2469 __ Mov(ToRegister32(instr->result()), static_cast<uint32_t>(instr->value())); |
2464 } | 2470 } |
2465 | 2471 |
2466 | 2472 |
2467 void LCodeGen::DoConstantS(LConstantS* instr) { | 2473 void LCodeGen::DoConstantS(LConstantS* instr) { |
2468 __ Mov(ToRegister(instr->result()), Operand(instr->value())); | 2474 __ Mov(ToRegister(instr->result()), Operand(instr->value())); |
2469 } | 2475 } |
2470 | 2476 |
2471 | 2477 |
2472 void LCodeGen::DoConstantT(LConstantT* instr) { | 2478 void LCodeGen::DoConstantT(LConstantT* instr) { |
2473 Handle<Object> value = instr->value(isolate()); | 2479 Handle<Object> value = instr->value(isolate()); |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2904 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); | 2910 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); |
2905 } | 2911 } |
2906 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); | 2912 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); |
2907 EmitBranch(instr, BranchCondition(instr->hydrogen())); | 2913 EmitBranch(instr, BranchCondition(instr->hydrogen())); |
2908 } | 2914 } |
2909 | 2915 |
2910 | 2916 |
2911 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { | 2917 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
2912 Register result = ToRegister(instr->result()); | 2918 Register result = ToRegister(instr->result()); |
2913 Register base = ToRegister(instr->base_object()); | 2919 Register base = ToRegister(instr->base_object()); |
2914 __ Add(result, base, ToOperand(instr->offset())); | 2920 if (instr->offset()->IsConstantOperand()) { |
| 2921 __ Add(result, base, ToOperand32I(instr->offset())); |
| 2922 } else { |
| 2923 __ Add(result, base, Operand(ToRegister32(instr->offset()), SXTW)); |
| 2924 } |
2915 } | 2925 } |
2916 | 2926 |
2917 | 2927 |
2918 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 2928 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
2919 ASSERT(ToRegister(instr->context()).is(cp)); | 2929 ASSERT(ToRegister(instr->context()).is(cp)); |
2920 // Assert that the arguments are in the registers expected by InstanceofStub. | 2930 // Assert that the arguments are in the registers expected by InstanceofStub. |
2921 ASSERT(ToRegister(instr->left()).Is(InstanceofStub::left())); | 2931 ASSERT(ToRegister(instr->left()).Is(InstanceofStub::left())); |
2922 ASSERT(ToRegister(instr->right()).Is(InstanceofStub::right())); | 2932 ASSERT(ToRegister(instr->right()).Is(InstanceofStub::right())); |
2923 | 2933 |
2924 InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 2934 InstanceofStub stub(InstanceofStub::kArgsInRegisters); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3059 DoubleRegister result = ToDoubleRegister(instr->result()); | 3069 DoubleRegister result = ToDoubleRegister(instr->result()); |
3060 __ Scvtf(result, value); | 3070 __ Scvtf(result, value); |
3061 } | 3071 } |
3062 | 3072 |
3063 | 3073 |
3064 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { | 3074 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { |
3065 // A64 smis can represent all Integer32 values, so this cannot deoptimize. | 3075 // A64 smis can represent all Integer32 values, so this cannot deoptimize. |
3066 ASSERT(!instr->hydrogen()->value()->HasRange() || | 3076 ASSERT(!instr->hydrogen()->value()->HasRange() || |
3067 instr->hydrogen()->value()->range()->IsInSmiRange()); | 3077 instr->hydrogen()->value()->range()->IsInSmiRange()); |
3068 | 3078 |
3069 Register value = ToRegister(instr->value()); | 3079 Register value = ToRegister32(instr->value()); |
3070 Register result = ToRegister(instr->result()); | 3080 Register result = ToRegister(instr->result()); |
3071 __ SmiTag(result, value); | 3081 __ SmiTag(result, value.X()); |
3072 } | 3082 } |
3073 | 3083 |
3074 | 3084 |
3075 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3085 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
3076 ASSERT(ToRegister(instr->context()).is(cp)); | 3086 ASSERT(ToRegister(instr->context()).is(cp)); |
3077 // The function is required to be in x1. | 3087 // The function is required to be in x1. |
3078 ASSERT(ToRegister(instr->function()).is(x1)); | 3088 ASSERT(ToRegister(instr->function()).is(x1)); |
3079 ASSERT(instr->HasPointerMap()); | 3089 ASSERT(instr->HasPointerMap()); |
3080 | 3090 |
3081 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 3091 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3316 } | 3326 } |
3317 | 3327 |
3318 if (additional_index == 0) { | 3328 if (additional_index == 0) { |
3319 if (key_is_smi) { | 3329 if (key_is_smi) { |
3320 // Key is smi: untag, and scale by element size. | 3330 // Key is smi: untag, and scale by element size. |
3321 __ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift)); | 3331 __ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift)); |
3322 return MemOperand(scratch, additional_offset); | 3332 return MemOperand(scratch, additional_offset); |
3323 } else { | 3333 } else { |
3324 // Key is not smi, and element size is not byte: scale by element size. | 3334 // Key is not smi, and element size is not byte: scale by element size. |
3325 if (additional_offset == 0) { | 3335 if (additional_offset == 0) { |
3326 return MemOperand(base, key, LSL, element_size_shift); | 3336 return MemOperand(base, key, SXTW, element_size_shift); |
3327 } else { | 3337 } else { |
3328 __ Add(scratch, base, Operand(key, LSL, element_size_shift)); | 3338 __ Add(scratch, base, Operand(key, SXTW, element_size_shift)); |
3329 return MemOperand(scratch, additional_offset); | 3339 return MemOperand(scratch, additional_offset); |
3330 } | 3340 } |
3331 } | 3341 } |
3332 } else { | 3342 } else { |
3333 // TODO(all): Try to combine these cases a bit more intelligently. | 3343 // TODO(all): Try to combine these cases a bit more intelligently. |
3334 if (additional_offset == 0) { | 3344 if (additional_offset == 0) { |
3335 if (key_is_smi) { | 3345 if (key_is_smi) { |
3336 __ SmiUntag(scratch, key); | 3346 __ SmiUntag(scratch, key); |
3337 __ Add(scratch, scratch, additional_index); | 3347 __ Add(scratch.W(), scratch.W(), additional_index); |
3338 } else { | 3348 } else { |
3339 __ Add(scratch, key, additional_index); | 3349 __ Add(scratch.W(), key.W(), additional_index); |
3340 } | 3350 } |
3341 return MemOperand(base, scratch, LSL, element_size_shift); | 3351 return MemOperand(base, scratch, LSL, element_size_shift); |
3342 } else { | 3352 } else { |
3343 if (key_is_smi) { | 3353 if (key_is_smi) { |
3344 __ Add(scratch, base, | 3354 __ Add(scratch, base, |
3345 Operand::UntagSmiAndScale(key, element_size_shift)); | 3355 Operand::UntagSmiAndScale(key, element_size_shift)); |
3346 } else { | 3356 } else { |
3347 __ Add(scratch, base, Operand(key, LSL, element_size_shift)); | 3357 __ Add(scratch, base, Operand(key, SXTW, element_size_shift)); |
3348 } | 3358 } |
3349 return MemOperand( | 3359 return MemOperand( |
3350 scratch, | 3360 scratch, |
3351 (additional_index << element_size_shift) + additional_offset); | 3361 (additional_index << element_size_shift) + additional_offset); |
3352 } | 3362 } |
3353 } | 3363 } |
3354 } | 3364 } |
3355 | 3365 |
3356 | 3366 |
3357 void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) { | 3367 void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3450 ElementsKind elements_kind) { | 3460 ElementsKind elements_kind) { |
3451 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3461 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
3452 | 3462 |
3453 // Even though the HLoad/StoreKeyed instructions force the input | 3463 // Even though the HLoad/StoreKeyed instructions force the input |
3454 // representation for the key to be an integer, the input gets replaced during | 3464 // representation for the key to be an integer, the input gets replaced during |
3455 // bounds check elimination with the index argument to the bounds check, which | 3465 // bounds check elimination with the index argument to the bounds check, which |
3456 // can be tagged, so that case must be handled here, too. | 3466 // can be tagged, so that case must be handled here, too. |
3457 if (key_is_tagged) { | 3467 if (key_is_tagged) { |
3458 __ Add(base, elements, Operand::UntagSmiAndScale(key, element_size_shift)); | 3468 __ Add(base, elements, Operand::UntagSmiAndScale(key, element_size_shift)); |
3459 } else { | 3469 } else { |
3460 // Sign extend key because it could be a 32-bit negative value and the | 3470 // Sign extend key because it could be a 32-bit negative value or contain |
3461 // address computation happens in 64-bit. | 3471 // garbage in the top 32-bits. The address computation happens in 64-bit. |
3462 ASSERT((element_size_shift >= 0) && (element_size_shift <= 4)); | 3472 ASSERT((element_size_shift >= 0) && (element_size_shift <= 4)); |
3463 __ Add(base, elements, Operand(key, SXTW, element_size_shift)); | 3473 __ Add(base, elements, Operand(key, SXTW, element_size_shift)); |
3464 } | 3474 } |
3465 } | 3475 } |
3466 | 3476 |
3467 | 3477 |
3468 void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) { | 3478 void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) { |
3469 Register elements = ToRegister(instr->elements()); | 3479 Register elements = ToRegister(instr->elements()); |
3470 DoubleRegister result = ToDoubleRegister(instr->result()); | 3480 DoubleRegister result = ToDoubleRegister(instr->result()); |
3471 Register load_base; | 3481 Register load_base; |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3911 } else if (exponent_type.IsTagged()) { | 3921 } else if (exponent_type.IsTagged()) { |
3912 Label no_deopt; | 3922 Label no_deopt; |
3913 __ JumpIfSmi(x11, &no_deopt); | 3923 __ JumpIfSmi(x11, &no_deopt); |
3914 __ Ldr(x0, FieldMemOperand(x11, HeapObject::kMapOffset)); | 3924 __ Ldr(x0, FieldMemOperand(x11, HeapObject::kMapOffset)); |
3915 DeoptimizeIfNotRoot(x0, Heap::kHeapNumberMapRootIndex, | 3925 DeoptimizeIfNotRoot(x0, Heap::kHeapNumberMapRootIndex, |
3916 instr->environment()); | 3926 instr->environment()); |
3917 __ Bind(&no_deopt); | 3927 __ Bind(&no_deopt); |
3918 MathPowStub stub(MathPowStub::TAGGED); | 3928 MathPowStub stub(MathPowStub::TAGGED); |
3919 __ CallStub(&stub); | 3929 __ CallStub(&stub); |
3920 } else if (exponent_type.IsInteger32()) { | 3930 } else if (exponent_type.IsInteger32()) { |
| 3931 // Ensure integer exponent has no garbage in top 32-bits, as MathPowStub |
| 3932 // supports large integer exponents. |
| 3933 Register exponent = ToRegister(instr->right()); |
| 3934 __ Sxtw(exponent, exponent); |
3921 MathPowStub stub(MathPowStub::INTEGER); | 3935 MathPowStub stub(MathPowStub::INTEGER); |
3922 __ CallStub(&stub); | 3936 __ CallStub(&stub); |
3923 } else { | 3937 } else { |
3924 ASSERT(exponent_type.IsDouble()); | 3938 ASSERT(exponent_type.IsDouble()); |
3925 MathPowStub stub(MathPowStub::DOUBLE); | 3939 MathPowStub stub(MathPowStub::DOUBLE); |
3926 __ CallStub(&stub); | 3940 __ CallStub(&stub); |
3927 } | 3941 } |
3928 } | 3942 } |
3929 | 3943 |
3930 | 3944 |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4349 codegen()->DoDeferredNumberTagU(instr_, | 4363 codegen()->DoDeferredNumberTagU(instr_, |
4350 instr_->value(), | 4364 instr_->value(), |
4351 instr_->temp1(), | 4365 instr_->temp1(), |
4352 instr_->temp2()); | 4366 instr_->temp2()); |
4353 } | 4367 } |
4354 virtual LInstruction* instr() { return instr_; } | 4368 virtual LInstruction* instr() { return instr_; } |
4355 private: | 4369 private: |
4356 LNumberTagU* instr_; | 4370 LNumberTagU* instr_; |
4357 }; | 4371 }; |
4358 | 4372 |
4359 Register value = ToRegister(instr->value()); | 4373 Register value = ToRegister32(instr->value()); |
4360 Register result = ToRegister(instr->result()); | 4374 Register result = ToRegister(instr->result()); |
4361 | 4375 |
4362 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); | 4376 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); |
4363 __ Cmp(value, Smi::kMaxValue); | 4377 __ Cmp(value, Smi::kMaxValue); |
4364 __ B(hi, deferred->entry()); | 4378 __ B(hi, deferred->entry()); |
4365 __ SmiTag(result, value); | 4379 __ SmiTag(result, value.X()); |
4366 __ Bind(deferred->exit()); | 4380 __ Bind(deferred->exit()); |
4367 } | 4381 } |
4368 | 4382 |
4369 | 4383 |
4370 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { | 4384 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { |
4371 Register input = ToRegister(instr->value()); | 4385 Register input = ToRegister(instr->value()); |
4372 Register scratch = ToRegister(instr->temp()); | 4386 Register scratch = ToRegister(instr->temp()); |
4373 DoubleRegister result = ToDoubleRegister(instr->result()); | 4387 DoubleRegister result = ToDoubleRegister(instr->result()); |
4374 bool can_convert_undefined_to_nan = | 4388 bool can_convert_undefined_to_nan = |
4375 instr->hydrogen()->can_convert_undefined_to_nan(); | 4389 instr->hydrogen()->can_convert_undefined_to_nan(); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4499 int offset = ToInteger32(LConstantOperand::cast(index)); | 4513 int offset = ToInteger32(LConstantOperand::cast(index)); |
4500 if (encoding == String::TWO_BYTE_ENCODING) { | 4514 if (encoding == String::TWO_BYTE_ENCODING) { |
4501 offset *= kUC16Size; | 4515 offset *= kUC16Size; |
4502 } | 4516 } |
4503 STATIC_ASSERT(kCharSize == 1); | 4517 STATIC_ASSERT(kCharSize == 1); |
4504 return FieldMemOperand(string, SeqString::kHeaderSize + offset); | 4518 return FieldMemOperand(string, SeqString::kHeaderSize + offset); |
4505 } | 4519 } |
4506 ASSERT(!temp.is(string)); | 4520 ASSERT(!temp.is(string)); |
4507 ASSERT(!temp.is(ToRegister(index))); | 4521 ASSERT(!temp.is(ToRegister(index))); |
4508 if (encoding == String::ONE_BYTE_ENCODING) { | 4522 if (encoding == String::ONE_BYTE_ENCODING) { |
4509 __ Add(temp, string, Operand(ToRegister(index))); | 4523 __ Add(temp, string, Operand(ToRegister32(index), SXTW)); |
4510 } else { | 4524 } else { |
4511 STATIC_ASSERT(kUC16Size == 2); | 4525 STATIC_ASSERT(kUC16Size == 2); |
4512 __ Add(temp, string, Operand(ToRegister(index), LSL, 1)); | 4526 __ Add(temp, string, Operand(ToRegister32(index), SXTW, 1)); |
4513 } | 4527 } |
4514 return FieldMemOperand(temp, SeqString::kHeaderSize); | 4528 return FieldMemOperand(temp, SeqString::kHeaderSize); |
4515 } | 4529 } |
4516 | 4530 |
4517 | 4531 |
4518 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) { | 4532 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) { |
4519 String::Encoding encoding = instr->hydrogen()->encoding(); | 4533 String::Encoding encoding = instr->hydrogen()->encoding(); |
4520 Register string = ToRegister(instr->string()); | 4534 Register string = ToRegister(instr->string()); |
4521 Register result = ToRegister(instr->result()); | 4535 Register result = ToRegister(instr->result()); |
4522 Register temp = ToRegister(instr->temp()); | 4536 Register temp = ToRegister(instr->temp()); |
(...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5701 __ Bind(&out_of_object); | 5715 __ Bind(&out_of_object); |
5702 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5716 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
5703 // Index is equal to negated out of object property index plus 1. | 5717 // Index is equal to negated out of object property index plus 1. |
5704 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5718 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
5705 __ Ldr(result, FieldMemOperand(result, | 5719 __ Ldr(result, FieldMemOperand(result, |
5706 FixedArray::kHeaderSize - kPointerSize)); | 5720 FixedArray::kHeaderSize - kPointerSize)); |
5707 __ Bind(&done); | 5721 __ Bind(&done); |
5708 } | 5722 } |
5709 | 5723 |
5710 } } // namespace v8::internal | 5724 } } // namespace v8::internal |
OLD | NEW |