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 |