| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 __ cmp(r0, sp); | 189 __ cmp(r0, sp); |
| 190 __ b(ne, &loop); | 190 __ b(ne, &loop); |
| 191 __ pop(r1); | 191 __ pop(r1); |
| 192 __ pop(r0); | 192 __ pop(r0); |
| 193 } else { | 193 } else { |
| 194 __ sub(sp, sp, Operand(slots * kPointerSize)); | 194 __ sub(sp, sp, Operand(slots * kPointerSize)); |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 | 197 |
| 198 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(VFP2)) { | 198 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(VFP2)) { |
| 199 CpuFeatures::Scope scope(VFP2); | 199 CpuFeatureScope scope(masm(), VFP2); |
| 200 Comment(";;; Save clobbered callee double registers"); | 200 Comment(";;; Save clobbered callee double registers"); |
| 201 int count = 0; | 201 int count = 0; |
| 202 BitVector* doubles = chunk()->allocated_double_registers(); | 202 BitVector* doubles = chunk()->allocated_double_registers(); |
| 203 BitVector::Iterator save_iterator(doubles); | 203 BitVector::Iterator save_iterator(doubles); |
| 204 while (!save_iterator.Done()) { | 204 while (!save_iterator.Done()) { |
| 205 __ vstr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()), | 205 __ vstr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()), |
| 206 MemOperand(sp, count * kDoubleSize)); | 206 MemOperand(sp, count * kDoubleSize)); |
| 207 save_iterator.Advance(); | 207 save_iterator.Advance(); |
| 208 count++; | 208 count++; |
| 209 } | 209 } |
| (...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 return; | 1155 return; |
| 1156 } | 1156 } |
| 1157 | 1157 |
| 1158 // These registers hold untagged 32 bit values. | 1158 // These registers hold untagged 32 bit values. |
| 1159 Register left = ToRegister(instr->left()); | 1159 Register left = ToRegister(instr->left()); |
| 1160 Register right = ToRegister(instr->right()); | 1160 Register right = ToRegister(instr->right()); |
| 1161 Register result = ToRegister(instr->result()); | 1161 Register result = ToRegister(instr->result()); |
| 1162 Label done; | 1162 Label done; |
| 1163 | 1163 |
| 1164 if (CpuFeatures::IsSupported(SUDIV)) { | 1164 if (CpuFeatures::IsSupported(SUDIV)) { |
| 1165 CpuFeatures::Scope scope(SUDIV); | 1165 CpuFeatureScope scope(masm(), SUDIV); |
| 1166 // Check for x % 0. | 1166 // Check for x % 0. |
| 1167 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | 1167 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1168 __ cmp(right, Operand::Zero()); | 1168 __ cmp(right, Operand::Zero()); |
| 1169 DeoptimizeIf(eq, instr->environment()); | 1169 DeoptimizeIf(eq, instr->environment()); |
| 1170 } | 1170 } |
| 1171 | 1171 |
| 1172 // Check for (kMinInt % -1). | 1172 // Check for (kMinInt % -1). |
| 1173 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1173 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 1174 Label left_not_min_int; | 1174 Label left_not_min_int; |
| 1175 __ cmp(left, Operand(kMinInt)); | 1175 __ cmp(left, Operand(kMinInt)); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1201 | 1201 |
| 1202 ASSERT(!dividend.is(divisor)); | 1202 ASSERT(!dividend.is(divisor)); |
| 1203 ASSERT(!dividend.is(quotient)); | 1203 ASSERT(!dividend.is(quotient)); |
| 1204 ASSERT(!divisor.is(quotient)); | 1204 ASSERT(!divisor.is(quotient)); |
| 1205 ASSERT(!scratch.is(left)); | 1205 ASSERT(!scratch.is(left)); |
| 1206 ASSERT(!scratch.is(right)); | 1206 ASSERT(!scratch.is(right)); |
| 1207 ASSERT(!scratch.is(result)); | 1207 ASSERT(!scratch.is(result)); |
| 1208 | 1208 |
| 1209 Label vfp_modulo, both_positive, right_negative; | 1209 Label vfp_modulo, both_positive, right_negative; |
| 1210 | 1210 |
| 1211 CpuFeatures::Scope scope(VFP2); | 1211 CpuFeatureScope scope(masm(), VFP2); |
| 1212 | 1212 |
| 1213 // Check for x % 0. | 1213 // Check for x % 0. |
| 1214 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | 1214 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1215 __ cmp(right, Operand::Zero()); | 1215 __ cmp(right, Operand::Zero()); |
| 1216 DeoptimizeIf(eq, instr->environment()); | 1216 DeoptimizeIf(eq, instr->environment()); |
| 1217 } | 1217 } |
| 1218 | 1218 |
| 1219 __ Move(result, left); | 1219 __ Move(result, left); |
| 1220 | 1220 |
| 1221 // (0 % x) must yield 0 (if x is finite, which is the case here). | 1221 // (0 % x) must yield 0 (if x is finite, which is the case here). |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1560 left, | 1560 left, |
| 1561 divisor, | 1561 divisor, |
| 1562 remainder, | 1562 remainder, |
| 1563 scratch, | 1563 scratch, |
| 1564 instr->environment()); | 1564 instr->environment()); |
| 1565 // We performed a truncating division. Correct the result if necessary. | 1565 // We performed a truncating division. Correct the result if necessary. |
| 1566 __ cmp(remainder, Operand::Zero()); | 1566 __ cmp(remainder, Operand::Zero()); |
| 1567 __ teq(remainder, Operand(divisor), ne); | 1567 __ teq(remainder, Operand(divisor), ne); |
| 1568 __ sub(result, result, Operand(1), LeaveCC, mi); | 1568 __ sub(result, result, Operand(1), LeaveCC, mi); |
| 1569 } else { | 1569 } else { |
| 1570 CpuFeatures::Scope scope(SUDIV); | 1570 CpuFeatureScope scope(masm(), SUDIV); |
| 1571 const Register right = ToRegister(instr->right()); | 1571 const Register right = ToRegister(instr->right()); |
| 1572 | 1572 |
| 1573 // Check for x / 0. | 1573 // Check for x / 0. |
| 1574 __ cmp(right, Operand::Zero()); | 1574 __ cmp(right, Operand::Zero()); |
| 1575 DeoptimizeIf(eq, instr->environment()); | 1575 DeoptimizeIf(eq, instr->environment()); |
| 1576 | 1576 |
| 1577 // Check for (kMinInt / -1). | 1577 // Check for (kMinInt / -1). |
| 1578 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1578 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 1579 Label left_not_min_int; | 1579 Label left_not_min_int; |
| 1580 __ cmp(left, Operand(kMinInt)); | 1580 __ cmp(left, Operand(kMinInt)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1607 | 1607 |
| 1608 __ bind(&done); | 1608 __ bind(&done); |
| 1609 } | 1609 } |
| 1610 } | 1610 } |
| 1611 | 1611 |
| 1612 | 1612 |
| 1613 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, | 1613 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, |
| 1614 LOperand* left_argument, | 1614 LOperand* left_argument, |
| 1615 LOperand* right_argument, | 1615 LOperand* right_argument, |
| 1616 Token::Value op) { | 1616 Token::Value op) { |
| 1617 CpuFeatures::Scope vfp_scope(VFP2); | 1617 CpuFeatureScope vfp_scope(masm(), VFP2); |
| 1618 Register left = ToRegister(left_argument); | 1618 Register left = ToRegister(left_argument); |
| 1619 Register right = ToRegister(right_argument); | 1619 Register right = ToRegister(right_argument); |
| 1620 | 1620 |
| 1621 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); | 1621 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); |
| 1622 // Move left to r1 and right to r0 for the stub call. | 1622 // Move left to r1 and right to r0 for the stub call. |
| 1623 if (left.is(r1)) { | 1623 if (left.is(r1)) { |
| 1624 __ Move(r0, right); | 1624 __ Move(r0, right); |
| 1625 } else if (left.is(r0) && right.is(r1)) { | 1625 } else if (left.is(r0) && right.is(r1)) { |
| 1626 __ Swap(r0, r1, r2); | 1626 __ Swap(r0, r1, r2); |
| 1627 } else if (left.is(r0)) { | 1627 } else if (left.is(r0)) { |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1893 | 1893 |
| 1894 void LCodeGen::DoConstantI(LConstantI* instr) { | 1894 void LCodeGen::DoConstantI(LConstantI* instr) { |
| 1895 ASSERT(instr->result()->IsRegister()); | 1895 ASSERT(instr->result()->IsRegister()); |
| 1896 __ mov(ToRegister(instr->result()), Operand(instr->value())); | 1896 __ mov(ToRegister(instr->result()), Operand(instr->value())); |
| 1897 } | 1897 } |
| 1898 | 1898 |
| 1899 | 1899 |
| 1900 void LCodeGen::DoConstantD(LConstantD* instr) { | 1900 void LCodeGen::DoConstantD(LConstantD* instr) { |
| 1901 ASSERT(instr->result()->IsDoubleRegister()); | 1901 ASSERT(instr->result()->IsDoubleRegister()); |
| 1902 DwVfpRegister result = ToDoubleRegister(instr->result()); | 1902 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 1903 CpuFeatures::Scope scope(VFP2); | 1903 CpuFeatureScope scope(masm(), VFP2); |
| 1904 double v = instr->value(); | 1904 double v = instr->value(); |
| 1905 __ Vmov(result, v, scratch0()); | 1905 __ Vmov(result, v, scratch0()); |
| 1906 } | 1906 } |
| 1907 | 1907 |
| 1908 | 1908 |
| 1909 void LCodeGen::DoConstantT(LConstantT* instr) { | 1909 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 1910 Handle<Object> value = instr->value(); | 1910 Handle<Object> value = instr->value(); |
| 1911 if (value->IsSmi()) { | 1911 if (value->IsSmi()) { |
| 1912 __ mov(ToRegister(instr->result()), Operand(value)); | 1912 __ mov(ToRegister(instr->result()), Operand(value)); |
| 1913 } else { | 1913 } else { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2071 ? ToOperand(right) | 2071 ? ToOperand(right) |
| 2072 : Operand(EmitLoadRegister(right, ip)); | 2072 : Operand(EmitLoadRegister(right, ip)); |
| 2073 Register result_reg = ToRegister(instr->result()); | 2073 Register result_reg = ToRegister(instr->result()); |
| 2074 __ cmp(left_reg, right_op); | 2074 __ cmp(left_reg, right_op); |
| 2075 if (!result_reg.is(left_reg)) { | 2075 if (!result_reg.is(left_reg)) { |
| 2076 __ mov(result_reg, left_reg, LeaveCC, condition); | 2076 __ mov(result_reg, left_reg, LeaveCC, condition); |
| 2077 } | 2077 } |
| 2078 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); | 2078 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); |
| 2079 } else { | 2079 } else { |
| 2080 ASSERT(instr->hydrogen()->representation().IsDouble()); | 2080 ASSERT(instr->hydrogen()->representation().IsDouble()); |
| 2081 CpuFeatures::Scope scope(VFP2); | 2081 CpuFeatureScope scope(masm(), VFP2); |
| 2082 DwVfpRegister left_reg = ToDoubleRegister(left); | 2082 DwVfpRegister left_reg = ToDoubleRegister(left); |
| 2083 DwVfpRegister right_reg = ToDoubleRegister(right); | 2083 DwVfpRegister right_reg = ToDoubleRegister(right); |
| 2084 DwVfpRegister result_reg = ToDoubleRegister(instr->result()); | 2084 DwVfpRegister result_reg = ToDoubleRegister(instr->result()); |
| 2085 Label check_nan_left, check_zero, return_left, return_right, done; | 2085 Label check_nan_left, check_zero, return_left, return_right, done; |
| 2086 __ VFPCompareAndSetFlags(left_reg, right_reg); | 2086 __ VFPCompareAndSetFlags(left_reg, right_reg); |
| 2087 __ b(vs, &check_nan_left); | 2087 __ b(vs, &check_nan_left); |
| 2088 __ b(eq, &check_zero); | 2088 __ b(eq, &check_zero); |
| 2089 __ b(condition, &return_left); | 2089 __ b(condition, &return_left); |
| 2090 __ b(al, &return_right); | 2090 __ b(al, &return_right); |
| 2091 | 2091 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2117 __ bind(&return_left); | 2117 __ bind(&return_left); |
| 2118 if (!left_reg.is(result_reg)) { | 2118 if (!left_reg.is(result_reg)) { |
| 2119 __ vmov(result_reg, left_reg); | 2119 __ vmov(result_reg, left_reg); |
| 2120 } | 2120 } |
| 2121 __ bind(&done); | 2121 __ bind(&done); |
| 2122 } | 2122 } |
| 2123 } | 2123 } |
| 2124 | 2124 |
| 2125 | 2125 |
| 2126 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 2126 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
| 2127 CpuFeatures::Scope scope(VFP2); | 2127 CpuFeatureScope scope(masm(), VFP2); |
| 2128 DwVfpRegister left = ToDoubleRegister(instr->left()); | 2128 DwVfpRegister left = ToDoubleRegister(instr->left()); |
| 2129 DwVfpRegister right = ToDoubleRegister(instr->right()); | 2129 DwVfpRegister right = ToDoubleRegister(instr->right()); |
| 2130 DwVfpRegister result = ToDoubleRegister(instr->result()); | 2130 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 2131 switch (instr->op()) { | 2131 switch (instr->op()) { |
| 2132 case Token::ADD: | 2132 case Token::ADD: |
| 2133 __ vadd(result, left, right); | 2133 __ vadd(result, left, right); |
| 2134 break; | 2134 break; |
| 2135 case Token::SUB: | 2135 case Token::SUB: |
| 2136 __ vsub(result, left, right); | 2136 __ vsub(result, left, right); |
| 2137 break; | 2137 break; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2208 void LCodeGen::DoBranch(LBranch* instr) { | 2208 void LCodeGen::DoBranch(LBranch* instr) { |
| 2209 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 2209 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 2210 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 2210 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 2211 | 2211 |
| 2212 Representation r = instr->hydrogen()->value()->representation(); | 2212 Representation r = instr->hydrogen()->value()->representation(); |
| 2213 if (r.IsInteger32()) { | 2213 if (r.IsInteger32()) { |
| 2214 Register reg = ToRegister(instr->value()); | 2214 Register reg = ToRegister(instr->value()); |
| 2215 __ cmp(reg, Operand::Zero()); | 2215 __ cmp(reg, Operand::Zero()); |
| 2216 EmitBranch(true_block, false_block, ne); | 2216 EmitBranch(true_block, false_block, ne); |
| 2217 } else if (r.IsDouble()) { | 2217 } else if (r.IsDouble()) { |
| 2218 CpuFeatures::Scope scope(VFP2); | 2218 CpuFeatureScope scope(masm(), VFP2); |
| 2219 DwVfpRegister reg = ToDoubleRegister(instr->value()); | 2219 DwVfpRegister reg = ToDoubleRegister(instr->value()); |
| 2220 Register scratch = scratch0(); | 2220 Register scratch = scratch0(); |
| 2221 | 2221 |
| 2222 // Test the double value. Zero and NaN are false. | 2222 // Test the double value. Zero and NaN are false. |
| 2223 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); | 2223 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); |
| 2224 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); | 2224 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); |
| 2225 EmitBranch(true_block, false_block, eq); | 2225 EmitBranch(true_block, false_block, eq); |
| 2226 } else { | 2226 } else { |
| 2227 ASSERT(r.IsTagged()); | 2227 ASSERT(r.IsTagged()); |
| 2228 Register reg = ToRegister(instr->value()); | 2228 Register reg = ToRegister(instr->value()); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2294 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); | 2294 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); |
| 2295 __ b(ge, ¬_string); | 2295 __ b(ge, ¬_string); |
| 2296 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); | 2296 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); |
| 2297 __ cmp(ip, Operand::Zero()); | 2297 __ cmp(ip, Operand::Zero()); |
| 2298 __ b(ne, true_label); | 2298 __ b(ne, true_label); |
| 2299 __ b(false_label); | 2299 __ b(false_label); |
| 2300 __ bind(¬_string); | 2300 __ bind(¬_string); |
| 2301 } | 2301 } |
| 2302 | 2302 |
| 2303 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2303 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
| 2304 CpuFeatures::Scope scope(VFP2); | 2304 CpuFeatureScope scope(masm(), VFP2); |
| 2305 // heap number -> false iff +0, -0, or NaN. | 2305 // heap number -> false iff +0, -0, or NaN. |
| 2306 DwVfpRegister dbl_scratch = double_scratch0(); | 2306 DwVfpRegister dbl_scratch = double_scratch0(); |
| 2307 Label not_heap_number; | 2307 Label not_heap_number; |
| 2308 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 2308 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
| 2309 __ b(ne, ¬_heap_number); | 2309 __ b(ne, ¬_heap_number); |
| 2310 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 2310 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
| 2311 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); | 2311 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); |
| 2312 __ b(vs, false_label); // NaN -> false. | 2312 __ b(vs, false_label); // NaN -> false. |
| 2313 __ b(eq, false_label); // +0, -0 -> false. | 2313 __ b(eq, false_label); // +0, -0 -> false. |
| 2314 __ b(true_label); | 2314 __ b(true_label); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2374 if (left->IsConstantOperand() && right->IsConstantOperand()) { | 2374 if (left->IsConstantOperand() && right->IsConstantOperand()) { |
| 2375 // We can statically evaluate the comparison. | 2375 // We can statically evaluate the comparison. |
| 2376 double left_val = ToDouble(LConstantOperand::cast(left)); | 2376 double left_val = ToDouble(LConstantOperand::cast(left)); |
| 2377 double right_val = ToDouble(LConstantOperand::cast(right)); | 2377 double right_val = ToDouble(LConstantOperand::cast(right)); |
| 2378 int next_block = | 2378 int next_block = |
| 2379 EvalComparison(instr->op(), left_val, right_val) ? true_block | 2379 EvalComparison(instr->op(), left_val, right_val) ? true_block |
| 2380 : false_block; | 2380 : false_block; |
| 2381 EmitGoto(next_block); | 2381 EmitGoto(next_block); |
| 2382 } else { | 2382 } else { |
| 2383 if (instr->is_double()) { | 2383 if (instr->is_double()) { |
| 2384 CpuFeatures::Scope scope(VFP2); | 2384 CpuFeatureScope scope(masm(), VFP2); |
| 2385 // Compare left and right operands as doubles and load the | 2385 // Compare left and right operands as doubles and load the |
| 2386 // resulting flags into the normal status register. | 2386 // resulting flags into the normal status register. |
| 2387 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); | 2387 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); |
| 2388 // If a NaN is involved, i.e. the result is unordered (V set), | 2388 // If a NaN is involved, i.e. the result is unordered (V set), |
| 2389 // jump to false block label. | 2389 // jump to false block label. |
| 2390 __ b(vs, chunk_->GetAssemblyLabel(false_block)); | 2390 __ b(vs, chunk_->GetAssemblyLabel(false_block)); |
| 2391 } else { | 2391 } else { |
| 2392 if (right->IsConstantOperand()) { | 2392 if (right->IsConstantOperand()) { |
| 2393 __ cmp(ToRegister(left), | 2393 __ cmp(ToRegister(left), |
| 2394 Operand(ToInteger32(LConstantOperand::cast(right)))); | 2394 Operand(ToInteger32(LConstantOperand::cast(right)))); |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2930 | 2930 |
| 2931 | 2931 |
| 2932 void LCodeGen::DoReturn(LReturn* instr) { | 2932 void LCodeGen::DoReturn(LReturn* instr) { |
| 2933 if (FLAG_trace && info()->IsOptimizing()) { | 2933 if (FLAG_trace && info()->IsOptimizing()) { |
| 2934 // Push the return value on the stack as the parameter. | 2934 // Push the return value on the stack as the parameter. |
| 2935 // Runtime::TraceExit returns its parameter in r0. | 2935 // Runtime::TraceExit returns its parameter in r0. |
| 2936 __ push(r0); | 2936 __ push(r0); |
| 2937 __ CallRuntime(Runtime::kTraceExit, 1); | 2937 __ CallRuntime(Runtime::kTraceExit, 1); |
| 2938 } | 2938 } |
| 2939 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(VFP2)) { | 2939 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(VFP2)) { |
| 2940 CpuFeatures::Scope scope(VFP2); | 2940 CpuFeatureScope scope(masm(), VFP2); |
| 2941 ASSERT(NeedsEagerFrame()); | 2941 ASSERT(NeedsEagerFrame()); |
| 2942 BitVector* doubles = chunk()->allocated_double_registers(); | 2942 BitVector* doubles = chunk()->allocated_double_registers(); |
| 2943 BitVector::Iterator save_iterator(doubles); | 2943 BitVector::Iterator save_iterator(doubles); |
| 2944 int count = 0; | 2944 int count = 0; |
| 2945 while (!save_iterator.Done()) { | 2945 while (!save_iterator.Done()) { |
| 2946 __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()), | 2946 __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()), |
| 2947 MemOperand(sp, count * kDoubleSize)); | 2947 MemOperand(sp, count * kDoubleSize)); |
| 2948 save_iterator.Advance(); | 2948 save_iterator.Advance(); |
| 2949 count++; | 2949 count++; |
| 2950 } | 2950 } |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3305 int additional_offset = instr->additional_index() << element_size_shift; | 3305 int additional_offset = instr->additional_index() << element_size_shift; |
| 3306 | 3306 |
| 3307 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3307 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 3308 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3308 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 3309 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3309 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3310 Operand operand = key_is_constant | 3310 Operand operand = key_is_constant |
| 3311 ? Operand(constant_key << element_size_shift) | 3311 ? Operand(constant_key << element_size_shift) |
| 3312 : Operand(key, LSL, shift_size); | 3312 : Operand(key, LSL, shift_size); |
| 3313 __ add(scratch0(), external_pointer, operand); | 3313 __ add(scratch0(), external_pointer, operand); |
| 3314 if (CpuFeatures::IsSupported(VFP2)) { | 3314 if (CpuFeatures::IsSupported(VFP2)) { |
| 3315 CpuFeatures::Scope scope(VFP2); | 3315 CpuFeatureScope scope(masm(), VFP2); |
| 3316 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3316 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 3317 __ vldr(kScratchDoubleReg.low(), scratch0(), additional_offset); | 3317 __ vldr(kScratchDoubleReg.low(), scratch0(), additional_offset); |
| 3318 __ vcvt_f64_f32(result, kScratchDoubleReg.low()); | 3318 __ vcvt_f64_f32(result, kScratchDoubleReg.low()); |
| 3319 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3319 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 3320 __ vldr(result, scratch0(), additional_offset); | 3320 __ vldr(result, scratch0(), additional_offset); |
| 3321 } | 3321 } |
| 3322 } else { | 3322 } else { |
| 3323 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3323 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 3324 Register value = external_pointer; | 3324 Register value = external_pointer; |
| 3325 __ ldr(value, MemOperand(scratch0(), additional_offset)); | 3325 __ ldr(value, MemOperand(scratch0(), additional_offset)); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3430 } else { | 3430 } else { |
| 3431 key = ToRegister(instr->key()); | 3431 key = ToRegister(instr->key()); |
| 3432 } | 3432 } |
| 3433 | 3433 |
| 3434 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | 3434 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
| 3435 ((constant_key + instr->additional_index()) << element_size_shift); | 3435 ((constant_key + instr->additional_index()) << element_size_shift); |
| 3436 if (!key_is_constant) { | 3436 if (!key_is_constant) { |
| 3437 __ add(elements, elements, Operand(key, LSL, shift_size)); | 3437 __ add(elements, elements, Operand(key, LSL, shift_size)); |
| 3438 } | 3438 } |
| 3439 if (CpuFeatures::IsSupported(VFP2)) { | 3439 if (CpuFeatures::IsSupported(VFP2)) { |
| 3440 CpuFeatures::Scope scope(VFP2); | 3440 CpuFeatureScope scope(masm(), VFP2); |
| 3441 __ add(elements, elements, Operand(base_offset)); | 3441 __ add(elements, elements, Operand(base_offset)); |
| 3442 __ vldr(result, elements, 0); | 3442 __ vldr(result, elements, 0); |
| 3443 if (instr->hydrogen()->RequiresHoleCheck()) { | 3443 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3444 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | 3444 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
| 3445 __ cmp(scratch, Operand(kHoleNanUpper32)); | 3445 __ cmp(scratch, Operand(kHoleNanUpper32)); |
| 3446 DeoptimizeIf(eq, instr->environment()); | 3446 DeoptimizeIf(eq, instr->environment()); |
| 3447 } | 3447 } |
| 3448 } else { | 3448 } else { |
| 3449 __ ldr(sfpd_hi, MemOperand(elements, base_offset + kPointerSize)); | 3449 __ ldr(sfpd_hi, MemOperand(elements, base_offset + kPointerSize)); |
| 3450 __ ldr(sfpd_lo, MemOperand(elements, base_offset)); | 3450 __ ldr(sfpd_lo, MemOperand(elements, base_offset)); |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3887 // We can make rsb conditional because the previous cmp instruction | 3887 // We can make rsb conditional because the previous cmp instruction |
| 3888 // will clear the V (overflow) flag and rsb won't set this flag | 3888 // will clear the V (overflow) flag and rsb won't set this flag |
| 3889 // if input is positive. | 3889 // if input is positive. |
| 3890 __ rsb(result, input, Operand::Zero(), SetCC, mi); | 3890 __ rsb(result, input, Operand::Zero(), SetCC, mi); |
| 3891 // Deoptimize on overflow. | 3891 // Deoptimize on overflow. |
| 3892 DeoptimizeIf(vs, instr->environment()); | 3892 DeoptimizeIf(vs, instr->environment()); |
| 3893 } | 3893 } |
| 3894 | 3894 |
| 3895 | 3895 |
| 3896 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 3896 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
| 3897 CpuFeatures::Scope scope(VFP2); | 3897 CpuFeatureScope scope(masm(), VFP2); |
| 3898 // Class for deferred case. | 3898 // Class for deferred case. |
| 3899 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3899 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 3900 public: | 3900 public: |
| 3901 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 3901 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
| 3902 LUnaryMathOperation* instr) | 3902 LUnaryMathOperation* instr) |
| 3903 : LDeferredCode(codegen), instr_(instr) { } | 3903 : LDeferredCode(codegen), instr_(instr) { } |
| 3904 virtual void Generate() { | 3904 virtual void Generate() { |
| 3905 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3905 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
| 3906 } | 3906 } |
| 3907 virtual LInstruction* instr() { return instr_; } | 3907 virtual LInstruction* instr() { return instr_; } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3924 // Smi check. | 3924 // Smi check. |
| 3925 __ JumpIfNotSmi(input, deferred->entry()); | 3925 __ JumpIfNotSmi(input, deferred->entry()); |
| 3926 // If smi, handle it directly. | 3926 // If smi, handle it directly. |
| 3927 EmitIntegerMathAbs(instr); | 3927 EmitIntegerMathAbs(instr); |
| 3928 __ bind(deferred->exit()); | 3928 __ bind(deferred->exit()); |
| 3929 } | 3929 } |
| 3930 } | 3930 } |
| 3931 | 3931 |
| 3932 | 3932 |
| 3933 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3933 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
| 3934 CpuFeatures::Scope scope(VFP2); | 3934 CpuFeatureScope scope(masm(), VFP2); |
| 3935 DwVfpRegister input = ToDoubleRegister(instr->value()); | 3935 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 3936 Register result = ToRegister(instr->result()); | 3936 Register result = ToRegister(instr->result()); |
| 3937 Register scratch = scratch0(); | 3937 Register scratch = scratch0(); |
| 3938 | 3938 |
| 3939 __ EmitVFPTruncate(kRoundToMinusInf, | 3939 __ EmitVFPTruncate(kRoundToMinusInf, |
| 3940 result, | 3940 result, |
| 3941 input, | 3941 input, |
| 3942 scratch, | 3942 scratch, |
| 3943 double_scratch0()); | 3943 double_scratch0()); |
| 3944 DeoptimizeIf(ne, instr->environment()); | 3944 DeoptimizeIf(ne, instr->environment()); |
| 3945 | 3945 |
| 3946 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3946 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3947 // Test for -0. | 3947 // Test for -0. |
| 3948 Label done; | 3948 Label done; |
| 3949 __ cmp(result, Operand::Zero()); | 3949 __ cmp(result, Operand::Zero()); |
| 3950 __ b(ne, &done); | 3950 __ b(ne, &done); |
| 3951 __ vmov(scratch, input.high()); | 3951 __ vmov(scratch, input.high()); |
| 3952 __ tst(scratch, Operand(HeapNumber::kSignMask)); | 3952 __ tst(scratch, Operand(HeapNumber::kSignMask)); |
| 3953 DeoptimizeIf(ne, instr->environment()); | 3953 DeoptimizeIf(ne, instr->environment()); |
| 3954 __ bind(&done); | 3954 __ bind(&done); |
| 3955 } | 3955 } |
| 3956 } | 3956 } |
| 3957 | 3957 |
| 3958 | 3958 |
| 3959 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 3959 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
| 3960 CpuFeatures::Scope scope(VFP2); | 3960 CpuFeatureScope scope(masm(), VFP2); |
| 3961 DwVfpRegister input = ToDoubleRegister(instr->value()); | 3961 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 3962 Register result = ToRegister(instr->result()); | 3962 Register result = ToRegister(instr->result()); |
| 3963 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 3963 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); |
| 3964 Register scratch = scratch0(); | 3964 Register scratch = scratch0(); |
| 3965 Label done, check_sign_on_zero; | 3965 Label done, check_sign_on_zero; |
| 3966 | 3966 |
| 3967 // Extract exponent bits. | 3967 // Extract exponent bits. |
| 3968 __ vmov(result, input.high()); | 3968 __ vmov(result, input.high()); |
| 3969 __ ubfx(scratch, | 3969 __ ubfx(scratch, |
| 3970 result, | 3970 result, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4016 __ bind(&check_sign_on_zero); | 4016 __ bind(&check_sign_on_zero); |
| 4017 __ vmov(scratch, input.high()); | 4017 __ vmov(scratch, input.high()); |
| 4018 __ tst(scratch, Operand(HeapNumber::kSignMask)); | 4018 __ tst(scratch, Operand(HeapNumber::kSignMask)); |
| 4019 DeoptimizeIf(ne, instr->environment()); | 4019 DeoptimizeIf(ne, instr->environment()); |
| 4020 } | 4020 } |
| 4021 __ bind(&done); | 4021 __ bind(&done); |
| 4022 } | 4022 } |
| 4023 | 4023 |
| 4024 | 4024 |
| 4025 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 4025 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { |
| 4026 CpuFeatures::Scope scope(VFP2); | 4026 CpuFeatureScope scope(masm(), VFP2); |
| 4027 DwVfpRegister input = ToDoubleRegister(instr->value()); | 4027 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 4028 DwVfpRegister result = ToDoubleRegister(instr->result()); | 4028 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 4029 __ vsqrt(result, input); | 4029 __ vsqrt(result, input); |
| 4030 } | 4030 } |
| 4031 | 4031 |
| 4032 | 4032 |
| 4033 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { | 4033 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { |
| 4034 CpuFeatures::Scope scope(VFP2); | 4034 CpuFeatureScope scope(masm(), VFP2); |
| 4035 DwVfpRegister input = ToDoubleRegister(instr->value()); | 4035 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 4036 DwVfpRegister result = ToDoubleRegister(instr->result()); | 4036 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 4037 DwVfpRegister temp = ToDoubleRegister(instr->temp()); | 4037 DwVfpRegister temp = ToDoubleRegister(instr->temp()); |
| 4038 | 4038 |
| 4039 // Note that according to ECMA-262 15.8.2.13: | 4039 // Note that according to ECMA-262 15.8.2.13: |
| 4040 // Math.pow(-Infinity, 0.5) == Infinity | 4040 // Math.pow(-Infinity, 0.5) == Infinity |
| 4041 // Math.sqrt(-Infinity) == NaN | 4041 // Math.sqrt(-Infinity) == NaN |
| 4042 Label done; | 4042 Label done; |
| 4043 __ vmov(temp, -V8_INFINITY, scratch0()); | 4043 __ vmov(temp, -V8_INFINITY, scratch0()); |
| 4044 __ VFPCompareAndSetFlags(input, temp); | 4044 __ VFPCompareAndSetFlags(input, temp); |
| 4045 __ vneg(result, temp, eq); | 4045 __ vneg(result, temp, eq); |
| 4046 __ b(&done, eq); | 4046 __ b(&done, eq); |
| 4047 | 4047 |
| 4048 // Add +0 to convert -0 to +0. | 4048 // Add +0 to convert -0 to +0. |
| 4049 __ vadd(result, input, kDoubleRegZero); | 4049 __ vadd(result, input, kDoubleRegZero); |
| 4050 __ vsqrt(result, result); | 4050 __ vsqrt(result, result); |
| 4051 __ bind(&done); | 4051 __ bind(&done); |
| 4052 } | 4052 } |
| 4053 | 4053 |
| 4054 | 4054 |
| 4055 void LCodeGen::DoPower(LPower* instr) { | 4055 void LCodeGen::DoPower(LPower* instr) { |
| 4056 CpuFeatures::Scope scope(VFP2); | 4056 CpuFeatureScope scope(masm(), VFP2); |
| 4057 Representation exponent_type = instr->hydrogen()->right()->representation(); | 4057 Representation exponent_type = instr->hydrogen()->right()->representation(); |
| 4058 // Having marked this as a call, we can use any registers. | 4058 // Having marked this as a call, we can use any registers. |
| 4059 // Just make sure that the input/output registers are the expected ones. | 4059 // Just make sure that the input/output registers are the expected ones. |
| 4060 ASSERT(!instr->right()->IsDoubleRegister() || | 4060 ASSERT(!instr->right()->IsDoubleRegister() || |
| 4061 ToDoubleRegister(instr->right()).is(d2)); | 4061 ToDoubleRegister(instr->right()).is(d2)); |
| 4062 ASSERT(!instr->right()->IsRegister() || | 4062 ASSERT(!instr->right()->IsRegister() || |
| 4063 ToRegister(instr->right()).is(r2)); | 4063 ToRegister(instr->right()).is(r2)); |
| 4064 ASSERT(ToDoubleRegister(instr->left()).is(d1)); | 4064 ASSERT(ToDoubleRegister(instr->left()).is(d1)); |
| 4065 ASSERT(ToDoubleRegister(instr->result()).is(d3)); | 4065 ASSERT(ToDoubleRegister(instr->result()).is(d3)); |
| 4066 | 4066 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4079 __ CallStub(&stub); | 4079 __ CallStub(&stub); |
| 4080 } else { | 4080 } else { |
| 4081 ASSERT(exponent_type.IsDouble()); | 4081 ASSERT(exponent_type.IsDouble()); |
| 4082 MathPowStub stub(MathPowStub::DOUBLE); | 4082 MathPowStub stub(MathPowStub::DOUBLE); |
| 4083 __ CallStub(&stub); | 4083 __ CallStub(&stub); |
| 4084 } | 4084 } |
| 4085 } | 4085 } |
| 4086 | 4086 |
| 4087 | 4087 |
| 4088 void LCodeGen::DoRandom(LRandom* instr) { | 4088 void LCodeGen::DoRandom(LRandom* instr) { |
| 4089 CpuFeatures::Scope scope(VFP2); | 4089 CpuFeatureScope scope(masm(), VFP2); |
| 4090 class DeferredDoRandom: public LDeferredCode { | 4090 class DeferredDoRandom: public LDeferredCode { |
| 4091 public: | 4091 public: |
| 4092 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) | 4092 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) |
| 4093 : LDeferredCode(codegen), instr_(instr) { } | 4093 : LDeferredCode(codegen), instr_(instr) { } |
| 4094 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } | 4094 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } |
| 4095 virtual LInstruction* instr() { return instr_; } | 4095 virtual LInstruction* instr() { return instr_; } |
| 4096 private: | 4096 private: |
| 4097 LRandom* instr_; | 4097 LRandom* instr_; |
| 4098 }; | 4098 }; |
| 4099 | 4099 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4158 | 4158 |
| 4159 | 4159 |
| 4160 void LCodeGen::DoDeferredRandom(LRandom* instr) { | 4160 void LCodeGen::DoDeferredRandom(LRandom* instr) { |
| 4161 __ PrepareCallCFunction(1, scratch0()); | 4161 __ PrepareCallCFunction(1, scratch0()); |
| 4162 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 4162 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
| 4163 // Return value is in r0. | 4163 // Return value is in r0. |
| 4164 } | 4164 } |
| 4165 | 4165 |
| 4166 | 4166 |
| 4167 void LCodeGen::DoMathExp(LMathExp* instr) { | 4167 void LCodeGen::DoMathExp(LMathExp* instr) { |
| 4168 CpuFeatures::Scope scope(VFP2); | 4168 CpuFeatureScope scope(masm(), VFP2); |
| 4169 DwVfpRegister input = ToDoubleRegister(instr->value()); | 4169 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 4170 DwVfpRegister result = ToDoubleRegister(instr->result()); | 4170 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 4171 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); | 4171 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); |
| 4172 DwVfpRegister double_scratch2 = double_scratch0(); | 4172 DwVfpRegister double_scratch2 = double_scratch0(); |
| 4173 Register temp1 = ToRegister(instr->temp1()); | 4173 Register temp1 = ToRegister(instr->temp1()); |
| 4174 Register temp2 = ToRegister(instr->temp2()); | 4174 Register temp2 = ToRegister(instr->temp2()); |
| 4175 | 4175 |
| 4176 MathExpGenerator::EmitMathExp( | 4176 MathExpGenerator::EmitMathExp( |
| 4177 masm(), input, result, double_scratch1, double_scratch2, | 4177 masm(), input, result, double_scratch1, double_scratch2, |
| 4178 temp1, temp2, scratch0()); | 4178 temp1, temp2, scratch0()); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4449 } | 4449 } |
| 4450 __ cmp(ip, ToRegister(instr->length())); | 4450 __ cmp(ip, ToRegister(instr->length())); |
| 4451 } else { | 4451 } else { |
| 4452 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); | 4452 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); |
| 4453 } | 4453 } |
| 4454 DeoptimizeIf(hs, instr->environment()); | 4454 DeoptimizeIf(hs, instr->environment()); |
| 4455 } | 4455 } |
| 4456 | 4456 |
| 4457 | 4457 |
| 4458 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4458 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 4459 CpuFeatures::Scope scope(VFP2); | 4459 CpuFeatureScope scope(masm(), VFP2); |
| 4460 Register external_pointer = ToRegister(instr->elements()); | 4460 Register external_pointer = ToRegister(instr->elements()); |
| 4461 Register key = no_reg; | 4461 Register key = no_reg; |
| 4462 ElementsKind elements_kind = instr->elements_kind(); | 4462 ElementsKind elements_kind = instr->elements_kind(); |
| 4463 bool key_is_constant = instr->key()->IsConstantOperand(); | 4463 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4464 int constant_key = 0; | 4464 int constant_key = 0; |
| 4465 if (key_is_constant) { | 4465 if (key_is_constant) { |
| 4466 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4466 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4467 if (constant_key & 0xF0000000) { | 4467 if (constant_key & 0xF0000000) { |
| 4468 Abort("array index constant value too big."); | 4468 Abort("array index constant value too big."); |
| 4469 } | 4469 } |
| 4470 } else { | 4470 } else { |
| 4471 key = ToRegister(instr->key()); | 4471 key = ToRegister(instr->key()); |
| 4472 } | 4472 } |
| 4473 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4473 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4474 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) | 4474 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) |
| 4475 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4475 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4476 int additional_offset = instr->additional_index() << element_size_shift; | 4476 int additional_offset = instr->additional_index() << element_size_shift; |
| 4477 | 4477 |
| 4478 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4478 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 4479 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4479 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 4480 CpuFeatures::Scope scope(VFP3); | 4480 CpuFeatureScope scope(masm(), VFP3); |
| 4481 DwVfpRegister value(ToDoubleRegister(instr->value())); | 4481 DwVfpRegister value(ToDoubleRegister(instr->value())); |
| 4482 Operand operand(key_is_constant | 4482 Operand operand(key_is_constant |
| 4483 ? Operand(constant_key << element_size_shift) | 4483 ? Operand(constant_key << element_size_shift) |
| 4484 : Operand(key, LSL, shift_size)); | 4484 : Operand(key, LSL, shift_size)); |
| 4485 __ add(scratch0(), external_pointer, operand); | 4485 __ add(scratch0(), external_pointer, operand); |
| 4486 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4486 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 4487 __ vcvt_f32_f64(double_scratch0().low(), value); | 4487 __ vcvt_f32_f64(double_scratch0().low(), value); |
| 4488 __ vstr(double_scratch0().low(), scratch0(), additional_offset); | 4488 __ vstr(double_scratch0().low(), scratch0(), additional_offset); |
| 4489 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 4489 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 4490 __ vstr(value, scratch0(), additional_offset); | 4490 __ vstr(value, scratch0(), additional_offset); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4520 case DICTIONARY_ELEMENTS: | 4520 case DICTIONARY_ELEMENTS: |
| 4521 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4521 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 4522 UNREACHABLE(); | 4522 UNREACHABLE(); |
| 4523 break; | 4523 break; |
| 4524 } | 4524 } |
| 4525 } | 4525 } |
| 4526 } | 4526 } |
| 4527 | 4527 |
| 4528 | 4528 |
| 4529 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4529 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 4530 CpuFeatures::Scope scope(VFP2); | 4530 CpuFeatureScope scope(masm(), VFP2); |
| 4531 DwVfpRegister value = ToDoubleRegister(instr->value()); | 4531 DwVfpRegister value = ToDoubleRegister(instr->value()); |
| 4532 Register elements = ToRegister(instr->elements()); | 4532 Register elements = ToRegister(instr->elements()); |
| 4533 Register key = no_reg; | 4533 Register key = no_reg; |
| 4534 Register scratch = scratch0(); | 4534 Register scratch = scratch0(); |
| 4535 bool key_is_constant = instr->key()->IsConstantOperand(); | 4535 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4536 int constant_key = 0; | 4536 int constant_key = 0; |
| 4537 | 4537 |
| 4538 // Calculate the effective address of the slot in the array to store the | 4538 // Calculate the effective address of the slot in the array to store the |
| 4539 // double value. | 4539 // double value. |
| 4540 if (key_is_constant) { | 4540 if (key_is_constant) { |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4821 | 4821 |
| 4822 | 4822 |
| 4823 void LCodeGen::DoStringLength(LStringLength* instr) { | 4823 void LCodeGen::DoStringLength(LStringLength* instr) { |
| 4824 Register string = ToRegister(instr->string()); | 4824 Register string = ToRegister(instr->string()); |
| 4825 Register result = ToRegister(instr->result()); | 4825 Register result = ToRegister(instr->result()); |
| 4826 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); | 4826 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); |
| 4827 } | 4827 } |
| 4828 | 4828 |
| 4829 | 4829 |
| 4830 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 4830 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 4831 CpuFeatures::Scope scope(VFP2); | 4831 CpuFeatureScope scope(masm(), VFP2); |
| 4832 LOperand* input = instr->value(); | 4832 LOperand* input = instr->value(); |
| 4833 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4833 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 4834 LOperand* output = instr->result(); | 4834 LOperand* output = instr->result(); |
| 4835 ASSERT(output->IsDoubleRegister()); | 4835 ASSERT(output->IsDoubleRegister()); |
| 4836 SwVfpRegister single_scratch = double_scratch0().low(); | 4836 SwVfpRegister single_scratch = double_scratch0().low(); |
| 4837 if (input->IsStackSlot()) { | 4837 if (input->IsStackSlot()) { |
| 4838 Register scratch = scratch0(); | 4838 Register scratch = scratch0(); |
| 4839 __ ldr(scratch, ToMemOperand(input)); | 4839 __ ldr(scratch, ToMemOperand(input)); |
| 4840 __ vmov(single_scratch, scratch); | 4840 __ vmov(single_scratch, scratch); |
| 4841 } else { | 4841 } else { |
| 4842 __ vmov(single_scratch, ToRegister(input)); | 4842 __ vmov(single_scratch, ToRegister(input)); |
| 4843 } | 4843 } |
| 4844 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); | 4844 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); |
| 4845 } | 4845 } |
| 4846 | 4846 |
| 4847 | 4847 |
| 4848 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4848 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
| 4849 CpuFeatures::Scope scope(VFP2); | 4849 CpuFeatureScope scope(masm(), VFP2); |
| 4850 LOperand* input = instr->value(); | 4850 LOperand* input = instr->value(); |
| 4851 LOperand* output = instr->result(); | 4851 LOperand* output = instr->result(); |
| 4852 | 4852 |
| 4853 SwVfpRegister flt_scratch = double_scratch0().low(); | 4853 SwVfpRegister flt_scratch = double_scratch0().low(); |
| 4854 __ vmov(flt_scratch, ToRegister(input)); | 4854 __ vmov(flt_scratch, ToRegister(input)); |
| 4855 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); | 4855 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); |
| 4856 } | 4856 } |
| 4857 | 4857 |
| 4858 | 4858 |
| 4859 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4859 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4959 Label done; | 4959 Label done; |
| 4960 if (signedness == SIGNED_INT32) { | 4960 if (signedness == SIGNED_INT32) { |
| 4961 // There was overflow, so bits 30 and 31 of the original integer | 4961 // There was overflow, so bits 30 and 31 of the original integer |
| 4962 // disagree. Try to allocate a heap number in new space and store | 4962 // disagree. Try to allocate a heap number in new space and store |
| 4963 // the value in there. If that fails, call the runtime system. | 4963 // the value in there. If that fails, call the runtime system. |
| 4964 if (dst.is(src)) { | 4964 if (dst.is(src)) { |
| 4965 __ SmiUntag(src, dst); | 4965 __ SmiUntag(src, dst); |
| 4966 __ eor(src, src, Operand(0x80000000)); | 4966 __ eor(src, src, Operand(0x80000000)); |
| 4967 } | 4967 } |
| 4968 if (CpuFeatures::IsSupported(VFP2)) { | 4968 if (CpuFeatures::IsSupported(VFP2)) { |
| 4969 CpuFeatures::Scope scope(VFP2); | 4969 CpuFeatureScope scope(masm(), VFP2); |
| 4970 __ vmov(flt_scratch, src); | 4970 __ vmov(flt_scratch, src); |
| 4971 __ vcvt_f64_s32(dbl_scratch, flt_scratch); | 4971 __ vcvt_f64_s32(dbl_scratch, flt_scratch); |
| 4972 } else { | 4972 } else { |
| 4973 FloatingPointHelper::Destination dest = | 4973 FloatingPointHelper::Destination dest = |
| 4974 FloatingPointHelper::kCoreRegisters; | 4974 FloatingPointHelper::kCoreRegisters; |
| 4975 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, d0, | 4975 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, d0, |
| 4976 sfpd_lo, sfpd_hi, | 4976 sfpd_lo, sfpd_hi, |
| 4977 scratch0(), s0); | 4977 scratch0(), s0); |
| 4978 } | 4978 } |
| 4979 } else { | 4979 } else { |
| 4980 if (CpuFeatures::IsSupported(VFP2)) { | 4980 if (CpuFeatures::IsSupported(VFP2)) { |
| 4981 CpuFeatures::Scope scope(VFP2); | 4981 CpuFeatureScope scope(masm(), VFP2); |
| 4982 __ vmov(flt_scratch, src); | 4982 __ vmov(flt_scratch, src); |
| 4983 __ vcvt_f64_u32(dbl_scratch, flt_scratch); | 4983 __ vcvt_f64_u32(dbl_scratch, flt_scratch); |
| 4984 } else { | 4984 } else { |
| 4985 Label no_leading_zero, done; | 4985 Label no_leading_zero, done; |
| 4986 __ tst(src, Operand(0x80000000)); | 4986 __ tst(src, Operand(0x80000000)); |
| 4987 __ b(ne, &no_leading_zero); | 4987 __ b(ne, &no_leading_zero); |
| 4988 | 4988 |
| 4989 // Integer has one leading zeros. | 4989 // Integer has one leading zeros. |
| 4990 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1); | 4990 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1); |
| 4991 __ b(&done); | 4991 __ b(&done); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 5012 __ mov(ip, Operand::Zero()); | 5012 __ mov(ip, Operand::Zero()); |
| 5013 __ StoreToSafepointRegisterSlot(ip, dst); | 5013 __ StoreToSafepointRegisterSlot(ip, dst); |
| 5014 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 5014 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
| 5015 __ Move(dst, r0); | 5015 __ Move(dst, r0); |
| 5016 __ sub(dst, dst, Operand(kHeapObjectTag)); | 5016 __ sub(dst, dst, Operand(kHeapObjectTag)); |
| 5017 | 5017 |
| 5018 // Done. Put the value in dbl_scratch into the value of the allocated heap | 5018 // Done. Put the value in dbl_scratch into the value of the allocated heap |
| 5019 // number. | 5019 // number. |
| 5020 __ bind(&done); | 5020 __ bind(&done); |
| 5021 if (CpuFeatures::IsSupported(VFP2)) { | 5021 if (CpuFeatures::IsSupported(VFP2)) { |
| 5022 CpuFeatures::Scope scope(VFP2); | 5022 CpuFeatureScope scope(masm(), VFP2); |
| 5023 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); | 5023 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); |
| 5024 } else { | 5024 } else { |
| 5025 __ str(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); | 5025 __ str(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); |
| 5026 __ str(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset)); | 5026 __ str(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset)); |
| 5027 } | 5027 } |
| 5028 __ add(dst, dst, Operand(kHeapObjectTag)); | 5028 __ add(dst, dst, Operand(kHeapObjectTag)); |
| 5029 __ StoreToSafepointRegisterSlot(dst, dst); | 5029 __ StoreToSafepointRegisterSlot(dst, dst); |
| 5030 } | 5030 } |
| 5031 | 5031 |
| 5032 | 5032 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5051 HValue* change_input = instr->hydrogen()->value(); | 5051 HValue* change_input = instr->hydrogen()->value(); |
| 5052 if (change_input->IsLoadKeyed()) { | 5052 if (change_input->IsLoadKeyed()) { |
| 5053 HLoadKeyed* load = HLoadKeyed::cast(change_input); | 5053 HLoadKeyed* load = HLoadKeyed::cast(change_input); |
| 5054 convert_hole = load->UsesMustHandleHole(); | 5054 convert_hole = load->UsesMustHandleHole(); |
| 5055 } | 5055 } |
| 5056 | 5056 |
| 5057 Label no_special_nan_handling; | 5057 Label no_special_nan_handling; |
| 5058 Label done; | 5058 Label done; |
| 5059 if (convert_hole) { | 5059 if (convert_hole) { |
| 5060 if (CpuFeatures::IsSupported(VFP2)) { | 5060 if (CpuFeatures::IsSupported(VFP2)) { |
| 5061 CpuFeatures::Scope scope(VFP2); | 5061 CpuFeatureScope scope(masm(), VFP2); |
| 5062 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); | 5062 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); |
| 5063 __ VFPCompareAndSetFlags(input_reg, input_reg); | 5063 __ VFPCompareAndSetFlags(input_reg, input_reg); |
| 5064 __ b(vc, &no_special_nan_handling); | 5064 __ b(vc, &no_special_nan_handling); |
| 5065 __ vmov(reg, scratch0(), input_reg); | 5065 __ vmov(reg, scratch0(), input_reg); |
| 5066 __ cmp(scratch0(), Operand(kHoleNanUpper32)); | 5066 __ cmp(scratch0(), Operand(kHoleNanUpper32)); |
| 5067 Label canonicalize; | 5067 Label canonicalize; |
| 5068 __ b(ne, &canonicalize); | 5068 __ b(ne, &canonicalize); |
| 5069 __ Move(reg, factory()->the_hole_value()); | 5069 __ Move(reg, factory()->the_hole_value()); |
| 5070 __ b(&done); | 5070 __ b(&done); |
| 5071 __ bind(&canonicalize); | 5071 __ bind(&canonicalize); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5103 if (FLAG_inline_new) { | 5103 if (FLAG_inline_new) { |
| 5104 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); | 5104 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); |
| 5105 // We want the untagged address first for performance | 5105 // We want the untagged address first for performance |
| 5106 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), | 5106 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), |
| 5107 DONT_TAG_RESULT); | 5107 DONT_TAG_RESULT); |
| 5108 } else { | 5108 } else { |
| 5109 __ jmp(deferred->entry()); | 5109 __ jmp(deferred->entry()); |
| 5110 } | 5110 } |
| 5111 __ bind(deferred->exit()); | 5111 __ bind(deferred->exit()); |
| 5112 if (CpuFeatures::IsSupported(VFP2)) { | 5112 if (CpuFeatures::IsSupported(VFP2)) { |
| 5113 CpuFeatures::Scope scope(VFP2); | 5113 CpuFeatureScope scope(masm(), VFP2); |
| 5114 __ vstr(input_reg, reg, HeapNumber::kValueOffset); | 5114 __ vstr(input_reg, reg, HeapNumber::kValueOffset); |
| 5115 } else { | 5115 } else { |
| 5116 __ str(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset)); | 5116 __ str(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset)); |
| 5117 __ str(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize)); | 5117 __ str(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize)); |
| 5118 } | 5118 } |
| 5119 // Now that we have finished with the object's real address tag it | 5119 // Now that we have finished with the object's real address tag it |
| 5120 __ add(reg, reg, Operand(kHeapObjectTag)); | 5120 __ add(reg, reg, Operand(kHeapObjectTag)); |
| 5121 __ bind(&done); | 5121 __ bind(&done); |
| 5122 } | 5122 } |
| 5123 | 5123 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5158 | 5158 |
| 5159 void LCodeGen::EmitNumberUntagD(Register input_reg, | 5159 void LCodeGen::EmitNumberUntagD(Register input_reg, |
| 5160 DwVfpRegister result_reg, | 5160 DwVfpRegister result_reg, |
| 5161 bool deoptimize_on_undefined, | 5161 bool deoptimize_on_undefined, |
| 5162 bool deoptimize_on_minus_zero, | 5162 bool deoptimize_on_minus_zero, |
| 5163 LEnvironment* env, | 5163 LEnvironment* env, |
| 5164 NumberUntagDMode mode) { | 5164 NumberUntagDMode mode) { |
| 5165 Register scratch = scratch0(); | 5165 Register scratch = scratch0(); |
| 5166 SwVfpRegister flt_scratch = double_scratch0().low(); | 5166 SwVfpRegister flt_scratch = double_scratch0().low(); |
| 5167 ASSERT(!result_reg.is(double_scratch0())); | 5167 ASSERT(!result_reg.is(double_scratch0())); |
| 5168 CpuFeatures::Scope scope(VFP2); | 5168 CpuFeatureScope scope(masm(), VFP2); |
| 5169 | 5169 |
| 5170 Label load_smi, heap_number, done; | 5170 Label load_smi, heap_number, done; |
| 5171 | 5171 |
| 5172 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 5172 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
| 5173 // Smi check. | 5173 // Smi check. |
| 5174 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | 5174 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); |
| 5175 | 5175 |
| 5176 // Heap number map check. | 5176 // Heap number map check. |
| 5177 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 5177 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
| 5178 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 5178 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5247 // SmiUntag(heap_object, SetCC) | 5247 // SmiUntag(heap_object, SetCC) |
| 5248 STATIC_ASSERT(kHeapObjectTag == 1); | 5248 STATIC_ASSERT(kHeapObjectTag == 1); |
| 5249 __ adc(input_reg, input_reg, Operand(input_reg)); | 5249 __ adc(input_reg, input_reg, Operand(input_reg)); |
| 5250 | 5250 |
| 5251 // Heap number map check. | 5251 // Heap number map check. |
| 5252 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 5252 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
| 5253 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 5253 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| 5254 __ cmp(scratch1, Operand(ip)); | 5254 __ cmp(scratch1, Operand(ip)); |
| 5255 | 5255 |
| 5256 if (instr->truncating()) { | 5256 if (instr->truncating()) { |
| 5257 CpuFeatures::Scope scope(VFP2); | 5257 CpuFeatureScope scope(masm(), VFP2); |
| 5258 Register scratch3 = ToRegister(instr->temp2()); | 5258 Register scratch3 = ToRegister(instr->temp2()); |
| 5259 ASSERT(!scratch3.is(input_reg) && | 5259 ASSERT(!scratch3.is(input_reg) && |
| 5260 !scratch3.is(scratch1) && | 5260 !scratch3.is(scratch1) && |
| 5261 !scratch3.is(scratch2)); | 5261 !scratch3.is(scratch2)); |
| 5262 // Performs a truncating conversion of a floating point number as used by | 5262 // Performs a truncating conversion of a floating point number as used by |
| 5263 // the JS bitwise operations. | 5263 // the JS bitwise operations. |
| 5264 Label heap_number; | 5264 Label heap_number; |
| 5265 __ b(eq, &heap_number); | 5265 __ b(eq, &heap_number); |
| 5266 // Check for undefined. Undefined is converted to zero for truncating | 5266 // Check for undefined. Undefined is converted to zero for truncating |
| 5267 // conversions. | 5267 // conversions. |
| 5268 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 5268 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 5269 __ cmp(input_reg, Operand(ip)); | 5269 __ cmp(input_reg, Operand(ip)); |
| 5270 DeoptimizeIf(ne, instr->environment()); | 5270 DeoptimizeIf(ne, instr->environment()); |
| 5271 __ mov(input_reg, Operand::Zero()); | 5271 __ mov(input_reg, Operand::Zero()); |
| 5272 __ b(&done); | 5272 __ b(&done); |
| 5273 | 5273 |
| 5274 __ bind(&heap_number); | 5274 __ bind(&heap_number); |
| 5275 __ sub(scratch1, input_reg, Operand(kHeapObjectTag)); | 5275 __ sub(scratch1, input_reg, Operand(kHeapObjectTag)); |
| 5276 __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset); | 5276 __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset); |
| 5277 | 5277 |
| 5278 __ EmitECMATruncate(input_reg, | 5278 __ EmitECMATruncate(input_reg, |
| 5279 double_scratch2, | 5279 double_scratch2, |
| 5280 double_scratch, | 5280 double_scratch, |
| 5281 scratch1, | 5281 scratch1, |
| 5282 scratch2, | 5282 scratch2, |
| 5283 scratch3); | 5283 scratch3); |
| 5284 | 5284 |
| 5285 } else { | 5285 } else { |
| 5286 CpuFeatures::Scope scope(VFP3); | 5286 CpuFeatureScope scope(masm(), VFP3); |
| 5287 // Deoptimize if we don't have a heap number. | 5287 // Deoptimize if we don't have a heap number. |
| 5288 DeoptimizeIf(ne, instr->environment()); | 5288 DeoptimizeIf(ne, instr->environment()); |
| 5289 | 5289 |
| 5290 __ sub(ip, input_reg, Operand(kHeapObjectTag)); | 5290 __ sub(ip, input_reg, Operand(kHeapObjectTag)); |
| 5291 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); | 5291 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); |
| 5292 __ EmitVFPTruncate(kRoundToZero, | 5292 __ EmitVFPTruncate(kRoundToZero, |
| 5293 input_reg, | 5293 input_reg, |
| 5294 double_scratch, | 5294 double_scratch, |
| 5295 scratch1, | 5295 scratch1, |
| 5296 double_scratch2, | 5296 double_scratch2, |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5504 __ CompareMap(map_reg, map, &success, REQUIRE_EXACT_MAP); | 5504 __ CompareMap(map_reg, map, &success, REQUIRE_EXACT_MAP); |
| 5505 __ b(eq, &success); | 5505 __ b(eq, &success); |
| 5506 } | 5506 } |
| 5507 Handle<Map> map = map_set->last(); | 5507 Handle<Map> map = map_set->last(); |
| 5508 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); | 5508 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); |
| 5509 __ bind(&success); | 5509 __ bind(&success); |
| 5510 } | 5510 } |
| 5511 | 5511 |
| 5512 | 5512 |
| 5513 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { | 5513 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { |
| 5514 CpuFeatures::Scope vfp_scope(VFP2); | 5514 CpuFeatureScope vfp_scope(masm(), VFP2); |
| 5515 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped()); | 5515 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped()); |
| 5516 Register result_reg = ToRegister(instr->result()); | 5516 Register result_reg = ToRegister(instr->result()); |
| 5517 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); | 5517 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); |
| 5518 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); | 5518 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); |
| 5519 } | 5519 } |
| 5520 | 5520 |
| 5521 | 5521 |
| 5522 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { | 5522 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { |
| 5523 CpuFeatures::Scope scope(VFP2); | 5523 CpuFeatureScope scope(masm(), VFP2); |
| 5524 Register unclamped_reg = ToRegister(instr->unclamped()); | 5524 Register unclamped_reg = ToRegister(instr->unclamped()); |
| 5525 Register result_reg = ToRegister(instr->result()); | 5525 Register result_reg = ToRegister(instr->result()); |
| 5526 __ ClampUint8(result_reg, unclamped_reg); | 5526 __ ClampUint8(result_reg, unclamped_reg); |
| 5527 } | 5527 } |
| 5528 | 5528 |
| 5529 | 5529 |
| 5530 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { | 5530 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { |
| 5531 CpuFeatures::Scope scope(VFP2); | 5531 CpuFeatureScope scope(masm(), VFP2); |
| 5532 Register scratch = scratch0(); | 5532 Register scratch = scratch0(); |
| 5533 Register input_reg = ToRegister(instr->unclamped()); | 5533 Register input_reg = ToRegister(instr->unclamped()); |
| 5534 Register result_reg = ToRegister(instr->result()); | 5534 Register result_reg = ToRegister(instr->result()); |
| 5535 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); | 5535 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); |
| 5536 Label is_smi, done, heap_number; | 5536 Label is_smi, done, heap_number; |
| 5537 | 5537 |
| 5538 // Both smi and heap number cases are handled. | 5538 // Both smi and heap number cases are handled. |
| 5539 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); | 5539 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); |
| 5540 | 5540 |
| 5541 // Check for heap number | 5541 // Check for heap number |
| (...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6432 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6432 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 6433 __ ldr(result, FieldMemOperand(scratch, | 6433 __ ldr(result, FieldMemOperand(scratch, |
| 6434 FixedArray::kHeaderSize - kPointerSize)); | 6434 FixedArray::kHeaderSize - kPointerSize)); |
| 6435 __ bind(&done); | 6435 __ bind(&done); |
| 6436 } | 6436 } |
| 6437 | 6437 |
| 6438 | 6438 |
| 6439 #undef __ | 6439 #undef __ |
| 6440 | 6440 |
| 6441 } } // namespace v8::internal | 6441 } } // namespace v8::internal |
| OLD | NEW |