| 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 |