| 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 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1524 left, | 1524 left, |
| 1525 divisor, | 1525 divisor, |
| 1526 remainder, | 1526 remainder, |
| 1527 scratch, | 1527 scratch, |
| 1528 instr->environment()); | 1528 instr->environment()); |
| 1529 // We performed a truncating division. Correct the result if necessary. | 1529 // We performed a truncating division. Correct the result if necessary. |
| 1530 __ cmp(remainder, Operand::Zero()); | 1530 __ cmp(remainder, Operand::Zero()); |
| 1531 __ teq(remainder, Operand(divisor), ne); | 1531 __ teq(remainder, Operand(divisor), ne); |
| 1532 __ sub(result, result, Operand(1), LeaveCC, mi); | 1532 __ sub(result, result, Operand(1), LeaveCC, mi); |
| 1533 } else { | 1533 } else { |
| 1534 CpuFeatures::Scope scope(SUDIV); | 1534 CpuFeatureScope scope(masm(), SUDIV); |
| 1535 const Register right = ToRegister(instr->right()); | 1535 const Register right = ToRegister(instr->right()); |
| 1536 | 1536 |
| 1537 // Check for x / 0. | 1537 // Check for x / 0. |
| 1538 __ cmp(right, Operand::Zero()); | 1538 __ cmp(right, Operand::Zero()); |
| 1539 DeoptimizeIf(eq, instr->environment()); | 1539 DeoptimizeIf(eq, instr->environment()); |
| 1540 | 1540 |
| 1541 // Check for (kMinInt / -1). | 1541 // Check for (kMinInt / -1). |
| 1542 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1542 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 1543 Label left_not_min_int; | 1543 Label left_not_min_int; |
| 1544 __ cmp(left, Operand(kMinInt)); | 1544 __ cmp(left, Operand(kMinInt)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1571 | 1571 |
| 1572 __ bind(&done); | 1572 __ bind(&done); |
| 1573 } | 1573 } |
| 1574 } | 1574 } |
| 1575 | 1575 |
| 1576 | 1576 |
| 1577 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, | 1577 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, |
| 1578 LOperand* left_argument, | 1578 LOperand* left_argument, |
| 1579 LOperand* right_argument, | 1579 LOperand* right_argument, |
| 1580 Token::Value op) { | 1580 Token::Value op) { |
| 1581 CpuFeatures::Scope vfp_scope(VFP2); | 1581 CpuFeatureScope vfp_scope(masm(), VFP2); |
| 1582 Register left = ToRegister(left_argument); | 1582 Register left = ToRegister(left_argument); |
| 1583 Register right = ToRegister(right_argument); | 1583 Register right = ToRegister(right_argument); |
| 1584 | 1584 |
| 1585 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); | 1585 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); |
| 1586 // Move left to r1 and right to r0 for the stub call. | 1586 // Move left to r1 and right to r0 for the stub call. |
| 1587 if (left.is(r1)) { | 1587 if (left.is(r1)) { |
| 1588 __ Move(r0, right); | 1588 __ Move(r0, right); |
| 1589 } else if (left.is(r0) && right.is(r1)) { | 1589 } else if (left.is(r0) && right.is(r1)) { |
| 1590 __ Swap(r0, r1, r2); | 1590 __ Swap(r0, r1, r2); |
| 1591 } else if (left.is(r0)) { | 1591 } else if (left.is(r0)) { |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1857 | 1857 |
| 1858 void LCodeGen::DoConstantI(LConstantI* instr) { | 1858 void LCodeGen::DoConstantI(LConstantI* instr) { |
| 1859 ASSERT(instr->result()->IsRegister()); | 1859 ASSERT(instr->result()->IsRegister()); |
| 1860 __ mov(ToRegister(instr->result()), Operand(instr->value())); | 1860 __ mov(ToRegister(instr->result()), Operand(instr->value())); |
| 1861 } | 1861 } |
| 1862 | 1862 |
| 1863 | 1863 |
| 1864 void LCodeGen::DoConstantD(LConstantD* instr) { | 1864 void LCodeGen::DoConstantD(LConstantD* instr) { |
| 1865 ASSERT(instr->result()->IsDoubleRegister()); | 1865 ASSERT(instr->result()->IsDoubleRegister()); |
| 1866 DwVfpRegister result = ToDoubleRegister(instr->result()); | 1866 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 1867 CpuFeatures::Scope scope(VFP2); | 1867 CpuFeatureScope scope(masm(), VFP2); |
| 1868 double v = instr->value(); | 1868 double v = instr->value(); |
| 1869 __ Vmov(result, v, scratch0()); | 1869 __ Vmov(result, v, scratch0()); |
| 1870 } | 1870 } |
| 1871 | 1871 |
| 1872 | 1872 |
| 1873 void LCodeGen::DoConstantT(LConstantT* instr) { | 1873 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 1874 Handle<Object> value = instr->value(); | 1874 Handle<Object> value = instr->value(); |
| 1875 if (value->IsSmi()) { | 1875 if (value->IsSmi()) { |
| 1876 __ mov(ToRegister(instr->result()), Operand(value)); | 1876 __ mov(ToRegister(instr->result()), Operand(value)); |
| 1877 } else { | 1877 } else { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2035 ? ToOperand(right) | 2035 ? ToOperand(right) |
| 2036 : Operand(EmitLoadRegister(right, ip)); | 2036 : Operand(EmitLoadRegister(right, ip)); |
| 2037 Register result_reg = ToRegister(instr->result()); | 2037 Register result_reg = ToRegister(instr->result()); |
| 2038 __ cmp(left_reg, right_op); | 2038 __ cmp(left_reg, right_op); |
| 2039 if (!result_reg.is(left_reg)) { | 2039 if (!result_reg.is(left_reg)) { |
| 2040 __ mov(result_reg, left_reg, LeaveCC, condition); | 2040 __ mov(result_reg, left_reg, LeaveCC, condition); |
| 2041 } | 2041 } |
| 2042 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); | 2042 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); |
| 2043 } else { | 2043 } else { |
| 2044 ASSERT(instr->hydrogen()->representation().IsDouble()); | 2044 ASSERT(instr->hydrogen()->representation().IsDouble()); |
| 2045 CpuFeatures::Scope scope(VFP2); | 2045 CpuFeatureScope scope(masm(), VFP2); |
| 2046 DwVfpRegister left_reg = ToDoubleRegister(left); | 2046 DwVfpRegister left_reg = ToDoubleRegister(left); |
| 2047 DwVfpRegister right_reg = ToDoubleRegister(right); | 2047 DwVfpRegister right_reg = ToDoubleRegister(right); |
| 2048 DwVfpRegister result_reg = ToDoubleRegister(instr->result()); | 2048 DwVfpRegister result_reg = ToDoubleRegister(instr->result()); |
| 2049 Label check_nan_left, check_zero, return_left, return_right, done; | 2049 Label check_nan_left, check_zero, return_left, return_right, done; |
| 2050 __ VFPCompareAndSetFlags(left_reg, right_reg); | 2050 __ VFPCompareAndSetFlags(left_reg, right_reg); |
| 2051 __ b(vs, &check_nan_left); | 2051 __ b(vs, &check_nan_left); |
| 2052 __ b(eq, &check_zero); | 2052 __ b(eq, &check_zero); |
| 2053 __ b(condition, &return_left); | 2053 __ b(condition, &return_left); |
| 2054 __ b(al, &return_right); | 2054 __ b(al, &return_right); |
| 2055 | 2055 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2081 __ bind(&return_left); | 2081 __ bind(&return_left); |
| 2082 if (!left_reg.is(result_reg)) { | 2082 if (!left_reg.is(result_reg)) { |
| 2083 __ vmov(result_reg, left_reg); | 2083 __ vmov(result_reg, left_reg); |
| 2084 } | 2084 } |
| 2085 __ bind(&done); | 2085 __ bind(&done); |
| 2086 } | 2086 } |
| 2087 } | 2087 } |
| 2088 | 2088 |
| 2089 | 2089 |
| 2090 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 2090 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
| 2091 CpuFeatures::Scope scope(VFP2); | 2091 CpuFeatureScope scope(masm(), VFP2); |
| 2092 DwVfpRegister left = ToDoubleRegister(instr->left()); | 2092 DwVfpRegister left = ToDoubleRegister(instr->left()); |
| 2093 DwVfpRegister right = ToDoubleRegister(instr->right()); | 2093 DwVfpRegister right = ToDoubleRegister(instr->right()); |
| 2094 DwVfpRegister result = ToDoubleRegister(instr->result()); | 2094 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 2095 switch (instr->op()) { | 2095 switch (instr->op()) { |
| 2096 case Token::ADD: | 2096 case Token::ADD: |
| 2097 __ vadd(result, left, right); | 2097 __ vadd(result, left, right); |
| 2098 break; | 2098 break; |
| 2099 case Token::SUB: | 2099 case Token::SUB: |
| 2100 __ vsub(result, left, right); | 2100 __ vsub(result, left, right); |
| 2101 break; | 2101 break; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2172 void LCodeGen::DoBranch(LBranch* instr) { | 2172 void LCodeGen::DoBranch(LBranch* instr) { |
| 2173 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 2173 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 2174 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 2174 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 2175 | 2175 |
| 2176 Representation r = instr->hydrogen()->value()->representation(); | 2176 Representation r = instr->hydrogen()->value()->representation(); |
| 2177 if (r.IsInteger32()) { | 2177 if (r.IsInteger32()) { |
| 2178 Register reg = ToRegister(instr->value()); | 2178 Register reg = ToRegister(instr->value()); |
| 2179 __ cmp(reg, Operand::Zero()); | 2179 __ cmp(reg, Operand::Zero()); |
| 2180 EmitBranch(true_block, false_block, ne); | 2180 EmitBranch(true_block, false_block, ne); |
| 2181 } else if (r.IsDouble()) { | 2181 } else if (r.IsDouble()) { |
| 2182 CpuFeatures::Scope scope(VFP2); | 2182 CpuFeatureScope scope(masm(), VFP2); |
| 2183 DwVfpRegister reg = ToDoubleRegister(instr->value()); | 2183 DwVfpRegister reg = ToDoubleRegister(instr->value()); |
| 2184 Register scratch = scratch0(); | 2184 Register scratch = scratch0(); |
| 2185 | 2185 |
| 2186 // Test the double value. Zero and NaN are false. | 2186 // Test the double value. Zero and NaN are false. |
| 2187 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); | 2187 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); |
| 2188 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); | 2188 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); |
| 2189 EmitBranch(true_block, false_block, eq); | 2189 EmitBranch(true_block, false_block, eq); |
| 2190 } else { | 2190 } else { |
| 2191 ASSERT(r.IsTagged()); | 2191 ASSERT(r.IsTagged()); |
| 2192 Register reg = ToRegister(instr->value()); | 2192 Register reg = ToRegister(instr->value()); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2258 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); | 2258 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); |
| 2259 __ b(ge, ¬_string); | 2259 __ b(ge, ¬_string); |
| 2260 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); | 2260 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); |
| 2261 __ cmp(ip, Operand::Zero()); | 2261 __ cmp(ip, Operand::Zero()); |
| 2262 __ b(ne, true_label); | 2262 __ b(ne, true_label); |
| 2263 __ b(false_label); | 2263 __ b(false_label); |
| 2264 __ bind(¬_string); | 2264 __ bind(¬_string); |
| 2265 } | 2265 } |
| 2266 | 2266 |
| 2267 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2267 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
| 2268 CpuFeatures::Scope scope(VFP2); | 2268 CpuFeatureScope scope(masm(), VFP2); |
| 2269 // heap number -> false iff +0, -0, or NaN. | 2269 // heap number -> false iff +0, -0, or NaN. |
| 2270 DwVfpRegister dbl_scratch = double_scratch0(); | 2270 DwVfpRegister dbl_scratch = double_scratch0(); |
| 2271 Label not_heap_number; | 2271 Label not_heap_number; |
| 2272 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 2272 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
| 2273 __ b(ne, ¬_heap_number); | 2273 __ b(ne, ¬_heap_number); |
| 2274 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 2274 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
| 2275 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); | 2275 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); |
| 2276 __ b(vs, false_label); // NaN -> false. | 2276 __ b(vs, false_label); // NaN -> false. |
| 2277 __ b(eq, false_label); // +0, -0 -> false. | 2277 __ b(eq, false_label); // +0, -0 -> false. |
| 2278 __ b(true_label); | 2278 __ b(true_label); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2338 if (left->IsConstantOperand() && right->IsConstantOperand()) { | 2338 if (left->IsConstantOperand() && right->IsConstantOperand()) { |
| 2339 // We can statically evaluate the comparison. | 2339 // We can statically evaluate the comparison. |
| 2340 double left_val = ToDouble(LConstantOperand::cast(left)); | 2340 double left_val = ToDouble(LConstantOperand::cast(left)); |
| 2341 double right_val = ToDouble(LConstantOperand::cast(right)); | 2341 double right_val = ToDouble(LConstantOperand::cast(right)); |
| 2342 int next_block = | 2342 int next_block = |
| 2343 EvalComparison(instr->op(), left_val, right_val) ? true_block | 2343 EvalComparison(instr->op(), left_val, right_val) ? true_block |
| 2344 : false_block; | 2344 : false_block; |
| 2345 EmitGoto(next_block); | 2345 EmitGoto(next_block); |
| 2346 } else { | 2346 } else { |
| 2347 if (instr->is_double()) { | 2347 if (instr->is_double()) { |
| 2348 CpuFeatures::Scope scope(VFP2); | 2348 CpuFeatureScope scope(masm(), VFP2); |
| 2349 // Compare left and right operands as doubles and load the | 2349 // Compare left and right operands as doubles and load the |
| 2350 // resulting flags into the normal status register. | 2350 // resulting flags into the normal status register. |
| 2351 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); | 2351 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); |
| 2352 // If a NaN is involved, i.e. the result is unordered (V set), | 2352 // If a NaN is involved, i.e. the result is unordered (V set), |
| 2353 // jump to false block label. | 2353 // jump to false block label. |
| 2354 __ b(vs, chunk_->GetAssemblyLabel(false_block)); | 2354 __ b(vs, chunk_->GetAssemblyLabel(false_block)); |
| 2355 } else { | 2355 } else { |
| 2356 if (right->IsConstantOperand()) { | 2356 if (right->IsConstantOperand()) { |
| 2357 __ cmp(ToRegister(left), | 2357 __ cmp(ToRegister(left), |
| 2358 Operand(ToInteger32(LConstantOperand::cast(right)))); | 2358 Operand(ToInteger32(LConstantOperand::cast(right)))); |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2894 | 2894 |
| 2895 | 2895 |
| 2896 void LCodeGen::DoReturn(LReturn* instr) { | 2896 void LCodeGen::DoReturn(LReturn* instr) { |
| 2897 if (FLAG_trace && info()->IsOptimizing()) { | 2897 if (FLAG_trace && info()->IsOptimizing()) { |
| 2898 // Push the return value on the stack as the parameter. | 2898 // Push the return value on the stack as the parameter. |
| 2899 // Runtime::TraceExit returns its parameter in r0. | 2899 // Runtime::TraceExit returns its parameter in r0. |
| 2900 __ push(r0); | 2900 __ push(r0); |
| 2901 __ CallRuntime(Runtime::kTraceExit, 1); | 2901 __ CallRuntime(Runtime::kTraceExit, 1); |
| 2902 } | 2902 } |
| 2903 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(VFP2)) { | 2903 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(VFP2)) { |
| 2904 CpuFeatures::Scope scope(VFP2); | 2904 CpuFeatureScope scope(masm(), VFP2); |
| 2905 ASSERT(NeedsEagerFrame()); | 2905 ASSERT(NeedsEagerFrame()); |
| 2906 BitVector* doubles = chunk()->allocated_double_registers(); | 2906 BitVector* doubles = chunk()->allocated_double_registers(); |
| 2907 BitVector::Iterator save_iterator(doubles); | 2907 BitVector::Iterator save_iterator(doubles); |
| 2908 int count = 0; | 2908 int count = 0; |
| 2909 while (!save_iterator.Done()) { | 2909 while (!save_iterator.Done()) { |
| 2910 __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()), | 2910 __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()), |
| 2911 MemOperand(sp, count * kDoubleSize)); | 2911 MemOperand(sp, count * kDoubleSize)); |
| 2912 save_iterator.Advance(); | 2912 save_iterator.Advance(); |
| 2913 count++; | 2913 count++; |
| 2914 } | 2914 } |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3269 int additional_offset = instr->additional_index() << element_size_shift; | 3269 int additional_offset = instr->additional_index() << element_size_shift; |
| 3270 | 3270 |
| 3271 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3271 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 3272 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3272 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 3273 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3273 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3274 Operand operand = key_is_constant | 3274 Operand operand = key_is_constant |
| 3275 ? Operand(constant_key << element_size_shift) | 3275 ? Operand(constant_key << element_size_shift) |
| 3276 : Operand(key, LSL, shift_size); | 3276 : Operand(key, LSL, shift_size); |
| 3277 __ add(scratch0(), external_pointer, operand); | 3277 __ add(scratch0(), external_pointer, operand); |
| 3278 if (CpuFeatures::IsSupported(VFP2)) { | 3278 if (CpuFeatures::IsSupported(VFP2)) { |
| 3279 CpuFeatures::Scope scope(VFP2); | 3279 CpuFeatureScope scope(masm(), VFP2); |
| 3280 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3280 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 3281 __ vldr(kScratchDoubleReg.low(), scratch0(), additional_offset); | 3281 __ vldr(kScratchDoubleReg.low(), scratch0(), additional_offset); |
| 3282 __ vcvt_f64_f32(result, kScratchDoubleReg.low()); | 3282 __ vcvt_f64_f32(result, kScratchDoubleReg.low()); |
| 3283 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3283 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 3284 __ vldr(result, scratch0(), additional_offset); | 3284 __ vldr(result, scratch0(), additional_offset); |
| 3285 } | 3285 } |
| 3286 } else { | 3286 } else { |
| 3287 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3287 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 3288 Register value = external_pointer; | 3288 Register value = external_pointer; |
| 3289 __ ldr(value, MemOperand(scratch0(), additional_offset)); | 3289 __ ldr(value, MemOperand(scratch0(), additional_offset)); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3394 } else { | 3394 } else { |
| 3395 key = ToRegister(instr->key()); | 3395 key = ToRegister(instr->key()); |
| 3396 } | 3396 } |
| 3397 | 3397 |
| 3398 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | 3398 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
| 3399 ((constant_key + instr->additional_index()) << element_size_shift); | 3399 ((constant_key + instr->additional_index()) << element_size_shift); |
| 3400 if (!key_is_constant) { | 3400 if (!key_is_constant) { |
| 3401 __ add(elements, elements, Operand(key, LSL, shift_size)); | 3401 __ add(elements, elements, Operand(key, LSL, shift_size)); |
| 3402 } | 3402 } |
| 3403 if (CpuFeatures::IsSupported(VFP2)) { | 3403 if (CpuFeatures::IsSupported(VFP2)) { |
| 3404 CpuFeatures::Scope scope(VFP2); | 3404 CpuFeatureScope scope(masm(), VFP2); |
| 3405 __ add(elements, elements, Operand(base_offset)); | 3405 __ add(elements, elements, Operand(base_offset)); |
| 3406 __ vldr(result, elements, 0); | 3406 __ vldr(result, elements, 0); |
| 3407 if (instr->hydrogen()->RequiresHoleCheck()) { | 3407 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3408 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | 3408 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
| 3409 __ cmp(scratch, Operand(kHoleNanUpper32)); | 3409 __ cmp(scratch, Operand(kHoleNanUpper32)); |
| 3410 DeoptimizeIf(eq, instr->environment()); | 3410 DeoptimizeIf(eq, instr->environment()); |
| 3411 } | 3411 } |
| 3412 } else { | 3412 } else { |
| 3413 __ ldr(sfpd_hi, MemOperand(elements, base_offset + kPointerSize)); | 3413 __ ldr(sfpd_hi, MemOperand(elements, base_offset + kPointerSize)); |
| 3414 __ ldr(sfpd_lo, MemOperand(elements, base_offset)); | 3414 __ ldr(sfpd_lo, MemOperand(elements, base_offset)); |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3851 // We can make rsb conditional because the previous cmp instruction | 3851 // We can make rsb conditional because the previous cmp instruction |
| 3852 // will clear the V (overflow) flag and rsb won't set this flag | 3852 // will clear the V (overflow) flag and rsb won't set this flag |
| 3853 // if input is positive. | 3853 // if input is positive. |
| 3854 __ rsb(result, input, Operand::Zero(), SetCC, mi); | 3854 __ rsb(result, input, Operand::Zero(), SetCC, mi); |
| 3855 // Deoptimize on overflow. | 3855 // Deoptimize on overflow. |
| 3856 DeoptimizeIf(vs, instr->environment()); | 3856 DeoptimizeIf(vs, instr->environment()); |
| 3857 } | 3857 } |
| 3858 | 3858 |
| 3859 | 3859 |
| 3860 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 3860 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
| 3861 CpuFeatures::Scope scope(VFP2); | 3861 CpuFeatureScope scope(masm(), VFP2); |
| 3862 // Class for deferred case. | 3862 // Class for deferred case. |
| 3863 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3863 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 3864 public: | 3864 public: |
| 3865 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 3865 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
| 3866 LUnaryMathOperation* instr) | 3866 LUnaryMathOperation* instr) |
| 3867 : LDeferredCode(codegen), instr_(instr) { } | 3867 : LDeferredCode(codegen), instr_(instr) { } |
| 3868 virtual void Generate() { | 3868 virtual void Generate() { |
| 3869 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3869 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
| 3870 } | 3870 } |
| 3871 virtual LInstruction* instr() { return instr_; } | 3871 virtual LInstruction* instr() { return instr_; } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3888 // Smi check. | 3888 // Smi check. |
| 3889 __ JumpIfNotSmi(input, deferred->entry()); | 3889 __ JumpIfNotSmi(input, deferred->entry()); |
| 3890 // If smi, handle it directly. | 3890 // If smi, handle it directly. |
| 3891 EmitIntegerMathAbs(instr); | 3891 EmitIntegerMathAbs(instr); |
| 3892 __ bind(deferred->exit()); | 3892 __ bind(deferred->exit()); |
| 3893 } | 3893 } |
| 3894 } | 3894 } |
| 3895 | 3895 |
| 3896 | 3896 |
| 3897 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3897 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
| 3898 CpuFeatures::Scope scope(VFP2); | 3898 CpuFeatureScope scope(masm(), VFP2); |
| 3899 DwVfpRegister input = ToDoubleRegister(instr->value()); | 3899 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 3900 Register result = ToRegister(instr->result()); | 3900 Register result = ToRegister(instr->result()); |
| 3901 Register scratch = scratch0(); | 3901 Register scratch = scratch0(); |
| 3902 | 3902 |
| 3903 __ EmitVFPTruncate(kRoundToMinusInf, | 3903 __ EmitVFPTruncate(kRoundToMinusInf, |
| 3904 result, | 3904 result, |
| 3905 input, | 3905 input, |
| 3906 scratch, | 3906 scratch, |
| 3907 double_scratch0()); | 3907 double_scratch0()); |
| 3908 DeoptimizeIf(ne, instr->environment()); | 3908 DeoptimizeIf(ne, instr->environment()); |
| 3909 | 3909 |
| 3910 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3910 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3911 // Test for -0. | 3911 // Test for -0. |
| 3912 Label done; | 3912 Label done; |
| 3913 __ cmp(result, Operand::Zero()); | 3913 __ cmp(result, Operand::Zero()); |
| 3914 __ b(ne, &done); | 3914 __ b(ne, &done); |
| 3915 __ vmov(scratch, input.high()); | 3915 __ vmov(scratch, input.high()); |
| 3916 __ tst(scratch, Operand(HeapNumber::kSignMask)); | 3916 __ tst(scratch, Operand(HeapNumber::kSignMask)); |
| 3917 DeoptimizeIf(ne, instr->environment()); | 3917 DeoptimizeIf(ne, instr->environment()); |
| 3918 __ bind(&done); | 3918 __ bind(&done); |
| 3919 } | 3919 } |
| 3920 } | 3920 } |
| 3921 | 3921 |
| 3922 | 3922 |
| 3923 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 3923 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
| 3924 CpuFeatures::Scope scope(VFP2); | 3924 CpuFeatureScope scope(masm(), VFP2); |
| 3925 DwVfpRegister input = ToDoubleRegister(instr->value()); | 3925 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 3926 Register result = ToRegister(instr->result()); | 3926 Register result = ToRegister(instr->result()); |
| 3927 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 3927 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); |
| 3928 Register scratch = scratch0(); | 3928 Register scratch = scratch0(); |
| 3929 Label done, check_sign_on_zero; | 3929 Label done, check_sign_on_zero; |
| 3930 | 3930 |
| 3931 // Extract exponent bits. | 3931 // Extract exponent bits. |
| 3932 __ vmov(result, input.high()); | 3932 __ vmov(result, input.high()); |
| 3933 __ ubfx(scratch, | 3933 __ ubfx(scratch, |
| 3934 result, | 3934 result, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3980 __ bind(&check_sign_on_zero); | 3980 __ bind(&check_sign_on_zero); |
| 3981 __ vmov(scratch, input.high()); | 3981 __ vmov(scratch, input.high()); |
| 3982 __ tst(scratch, Operand(HeapNumber::kSignMask)); | 3982 __ tst(scratch, Operand(HeapNumber::kSignMask)); |
| 3983 DeoptimizeIf(ne, instr->environment()); | 3983 DeoptimizeIf(ne, instr->environment()); |
| 3984 } | 3984 } |
| 3985 __ bind(&done); | 3985 __ bind(&done); |
| 3986 } | 3986 } |
| 3987 | 3987 |
| 3988 | 3988 |
| 3989 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 3989 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { |
| 3990 CpuFeatures::Scope scope(VFP2); | 3990 CpuFeatureScope scope(masm(), VFP2); |
| 3991 DwVfpRegister input = ToDoubleRegister(instr->value()); | 3991 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 3992 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3992 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3993 __ vsqrt(result, input); | 3993 __ vsqrt(result, input); |
| 3994 } | 3994 } |
| 3995 | 3995 |
| 3996 | 3996 |
| 3997 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { | 3997 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { |
| 3998 CpuFeatures::Scope scope(VFP2); | 3998 CpuFeatureScope scope(masm(), VFP2); |
| 3999 DwVfpRegister input = ToDoubleRegister(instr->value()); | 3999 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 4000 DwVfpRegister result = ToDoubleRegister(instr->result()); | 4000 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 4001 DwVfpRegister temp = ToDoubleRegister(instr->temp()); | 4001 DwVfpRegister temp = ToDoubleRegister(instr->temp()); |
| 4002 | 4002 |
| 4003 // Note that according to ECMA-262 15.8.2.13: | 4003 // Note that according to ECMA-262 15.8.2.13: |
| 4004 // Math.pow(-Infinity, 0.5) == Infinity | 4004 // Math.pow(-Infinity, 0.5) == Infinity |
| 4005 // Math.sqrt(-Infinity) == NaN | 4005 // Math.sqrt(-Infinity) == NaN |
| 4006 Label done; | 4006 Label done; |
| 4007 __ vmov(temp, -V8_INFINITY, scratch0()); | 4007 __ vmov(temp, -V8_INFINITY, scratch0()); |
| 4008 __ VFPCompareAndSetFlags(input, temp); | 4008 __ VFPCompareAndSetFlags(input, temp); |
| 4009 __ vneg(result, temp, eq); | 4009 __ vneg(result, temp, eq); |
| 4010 __ b(&done, eq); | 4010 __ b(&done, eq); |
| 4011 | 4011 |
| 4012 // Add +0 to convert -0 to +0. | 4012 // Add +0 to convert -0 to +0. |
| 4013 __ vadd(result, input, kDoubleRegZero); | 4013 __ vadd(result, input, kDoubleRegZero); |
| 4014 __ vsqrt(result, result); | 4014 __ vsqrt(result, result); |
| 4015 __ bind(&done); | 4015 __ bind(&done); |
| 4016 } | 4016 } |
| 4017 | 4017 |
| 4018 | 4018 |
| 4019 void LCodeGen::DoPower(LPower* instr) { | 4019 void LCodeGen::DoPower(LPower* instr) { |
| 4020 CpuFeatures::Scope scope(VFP2); | 4020 CpuFeatureScope scope(masm(), VFP2); |
| 4021 Representation exponent_type = instr->hydrogen()->right()->representation(); | 4021 Representation exponent_type = instr->hydrogen()->right()->representation(); |
| 4022 // Having marked this as a call, we can use any registers. | 4022 // Having marked this as a call, we can use any registers. |
| 4023 // Just make sure that the input/output registers are the expected ones. | 4023 // Just make sure that the input/output registers are the expected ones. |
| 4024 ASSERT(!instr->right()->IsDoubleRegister() || | 4024 ASSERT(!instr->right()->IsDoubleRegister() || |
| 4025 ToDoubleRegister(instr->right()).is(d2)); | 4025 ToDoubleRegister(instr->right()).is(d2)); |
| 4026 ASSERT(!instr->right()->IsRegister() || | 4026 ASSERT(!instr->right()->IsRegister() || |
| 4027 ToRegister(instr->right()).is(r2)); | 4027 ToRegister(instr->right()).is(r2)); |
| 4028 ASSERT(ToDoubleRegister(instr->left()).is(d1)); | 4028 ASSERT(ToDoubleRegister(instr->left()).is(d1)); |
| 4029 ASSERT(ToDoubleRegister(instr->result()).is(d3)); | 4029 ASSERT(ToDoubleRegister(instr->result()).is(d3)); |
| 4030 | 4030 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4043 __ CallStub(&stub); | 4043 __ CallStub(&stub); |
| 4044 } else { | 4044 } else { |
| 4045 ASSERT(exponent_type.IsDouble()); | 4045 ASSERT(exponent_type.IsDouble()); |
| 4046 MathPowStub stub(MathPowStub::DOUBLE); | 4046 MathPowStub stub(MathPowStub::DOUBLE); |
| 4047 __ CallStub(&stub); | 4047 __ CallStub(&stub); |
| 4048 } | 4048 } |
| 4049 } | 4049 } |
| 4050 | 4050 |
| 4051 | 4051 |
| 4052 void LCodeGen::DoRandom(LRandom* instr) { | 4052 void LCodeGen::DoRandom(LRandom* instr) { |
| 4053 CpuFeatures::Scope scope(VFP2); | 4053 CpuFeatureScope scope(masm(), VFP2); |
| 4054 class DeferredDoRandom: public LDeferredCode { | 4054 class DeferredDoRandom: public LDeferredCode { |
| 4055 public: | 4055 public: |
| 4056 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) | 4056 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) |
| 4057 : LDeferredCode(codegen), instr_(instr) { } | 4057 : LDeferredCode(codegen), instr_(instr) { } |
| 4058 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } | 4058 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } |
| 4059 virtual LInstruction* instr() { return instr_; } | 4059 virtual LInstruction* instr() { return instr_; } |
| 4060 private: | 4060 private: |
| 4061 LRandom* instr_; | 4061 LRandom* instr_; |
| 4062 }; | 4062 }; |
| 4063 | 4063 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4122 | 4122 |
| 4123 | 4123 |
| 4124 void LCodeGen::DoDeferredRandom(LRandom* instr) { | 4124 void LCodeGen::DoDeferredRandom(LRandom* instr) { |
| 4125 __ PrepareCallCFunction(1, scratch0()); | 4125 __ PrepareCallCFunction(1, scratch0()); |
| 4126 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 4126 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
| 4127 // Return value is in r0. | 4127 // Return value is in r0. |
| 4128 } | 4128 } |
| 4129 | 4129 |
| 4130 | 4130 |
| 4131 void LCodeGen::DoMathExp(LMathExp* instr) { | 4131 void LCodeGen::DoMathExp(LMathExp* instr) { |
| 4132 CpuFeatures::Scope scope(VFP2); | 4132 CpuFeatureScope scope(masm(), VFP2); |
| 4133 DwVfpRegister input = ToDoubleRegister(instr->value()); | 4133 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 4134 DwVfpRegister result = ToDoubleRegister(instr->result()); | 4134 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 4135 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); | 4135 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); |
| 4136 DwVfpRegister double_scratch2 = double_scratch0(); | 4136 DwVfpRegister double_scratch2 = double_scratch0(); |
| 4137 Register temp1 = ToRegister(instr->temp1()); | 4137 Register temp1 = ToRegister(instr->temp1()); |
| 4138 Register temp2 = ToRegister(instr->temp2()); | 4138 Register temp2 = ToRegister(instr->temp2()); |
| 4139 | 4139 |
| 4140 MathExpGenerator::EmitMathExp( | 4140 MathExpGenerator::EmitMathExp( |
| 4141 masm(), input, result, double_scratch1, double_scratch2, | 4141 masm(), input, result, double_scratch1, double_scratch2, |
| 4142 temp1, temp2, scratch0()); | 4142 temp1, temp2, scratch0()); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4413 } | 4413 } |
| 4414 __ cmp(ip, ToRegister(instr->length())); | 4414 __ cmp(ip, ToRegister(instr->length())); |
| 4415 } else { | 4415 } else { |
| 4416 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); | 4416 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); |
| 4417 } | 4417 } |
| 4418 DeoptimizeIf(hs, instr->environment()); | 4418 DeoptimizeIf(hs, instr->environment()); |
| 4419 } | 4419 } |
| 4420 | 4420 |
| 4421 | 4421 |
| 4422 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4422 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 4423 CpuFeatures::Scope scope(VFP2); | 4423 CpuFeatureScope scope(masm(), VFP2); |
| 4424 Register external_pointer = ToRegister(instr->elements()); | 4424 Register external_pointer = ToRegister(instr->elements()); |
| 4425 Register key = no_reg; | 4425 Register key = no_reg; |
| 4426 ElementsKind elements_kind = instr->elements_kind(); | 4426 ElementsKind elements_kind = instr->elements_kind(); |
| 4427 bool key_is_constant = instr->key()->IsConstantOperand(); | 4427 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4428 int constant_key = 0; | 4428 int constant_key = 0; |
| 4429 if (key_is_constant) { | 4429 if (key_is_constant) { |
| 4430 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4430 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4431 if (constant_key & 0xF0000000) { | 4431 if (constant_key & 0xF0000000) { |
| 4432 Abort("array index constant value too big."); | 4432 Abort("array index constant value too big."); |
| 4433 } | 4433 } |
| 4434 } else { | 4434 } else { |
| 4435 key = ToRegister(instr->key()); | 4435 key = ToRegister(instr->key()); |
| 4436 } | 4436 } |
| 4437 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4437 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4438 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) | 4438 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) |
| 4439 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4439 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4440 int additional_offset = instr->additional_index() << element_size_shift; | 4440 int additional_offset = instr->additional_index() << element_size_shift; |
| 4441 | 4441 |
| 4442 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4442 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 4443 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4443 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 4444 CpuFeatures::Scope scope(VFP3); | 4444 CpuFeatureScope scope(masm(), VFP3); |
| 4445 DwVfpRegister value(ToDoubleRegister(instr->value())); | 4445 DwVfpRegister value(ToDoubleRegister(instr->value())); |
| 4446 Operand operand(key_is_constant | 4446 Operand operand(key_is_constant |
| 4447 ? Operand(constant_key << element_size_shift) | 4447 ? Operand(constant_key << element_size_shift) |
| 4448 : Operand(key, LSL, shift_size)); | 4448 : Operand(key, LSL, shift_size)); |
| 4449 __ add(scratch0(), external_pointer, operand); | 4449 __ add(scratch0(), external_pointer, operand); |
| 4450 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4450 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 4451 __ vcvt_f32_f64(double_scratch0().low(), value); | 4451 __ vcvt_f32_f64(double_scratch0().low(), value); |
| 4452 __ vstr(double_scratch0().low(), scratch0(), additional_offset); | 4452 __ vstr(double_scratch0().low(), scratch0(), additional_offset); |
| 4453 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 4453 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 4454 __ vstr(value, scratch0(), additional_offset); | 4454 __ vstr(value, scratch0(), additional_offset); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4484 case DICTIONARY_ELEMENTS: | 4484 case DICTIONARY_ELEMENTS: |
| 4485 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4485 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 4486 UNREACHABLE(); | 4486 UNREACHABLE(); |
| 4487 break; | 4487 break; |
| 4488 } | 4488 } |
| 4489 } | 4489 } |
| 4490 } | 4490 } |
| 4491 | 4491 |
| 4492 | 4492 |
| 4493 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4493 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 4494 CpuFeatures::Scope scope(VFP2); | 4494 CpuFeatureScope scope(masm(), VFP2); |
| 4495 DwVfpRegister value = ToDoubleRegister(instr->value()); | 4495 DwVfpRegister value = ToDoubleRegister(instr->value()); |
| 4496 Register elements = ToRegister(instr->elements()); | 4496 Register elements = ToRegister(instr->elements()); |
| 4497 Register key = no_reg; | 4497 Register key = no_reg; |
| 4498 Register scratch = scratch0(); | 4498 Register scratch = scratch0(); |
| 4499 bool key_is_constant = instr->key()->IsConstantOperand(); | 4499 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4500 int constant_key = 0; | 4500 int constant_key = 0; |
| 4501 | 4501 |
| 4502 // Calculate the effective address of the slot in the array to store the | 4502 // Calculate the effective address of the slot in the array to store the |
| 4503 // double value. | 4503 // double value. |
| 4504 if (key_is_constant) { | 4504 if (key_is_constant) { |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4785 | 4785 |
| 4786 | 4786 |
| 4787 void LCodeGen::DoStringLength(LStringLength* instr) { | 4787 void LCodeGen::DoStringLength(LStringLength* instr) { |
| 4788 Register string = ToRegister(instr->string()); | 4788 Register string = ToRegister(instr->string()); |
| 4789 Register result = ToRegister(instr->result()); | 4789 Register result = ToRegister(instr->result()); |
| 4790 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); | 4790 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); |
| 4791 } | 4791 } |
| 4792 | 4792 |
| 4793 | 4793 |
| 4794 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 4794 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 4795 CpuFeatures::Scope scope(VFP2); | 4795 CpuFeatureScope scope(masm(), VFP2); |
| 4796 LOperand* input = instr->value(); | 4796 LOperand* input = instr->value(); |
| 4797 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4797 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 4798 LOperand* output = instr->result(); | 4798 LOperand* output = instr->result(); |
| 4799 ASSERT(output->IsDoubleRegister()); | 4799 ASSERT(output->IsDoubleRegister()); |
| 4800 SwVfpRegister single_scratch = double_scratch0().low(); | 4800 SwVfpRegister single_scratch = double_scratch0().low(); |
| 4801 if (input->IsStackSlot()) { | 4801 if (input->IsStackSlot()) { |
| 4802 Register scratch = scratch0(); | 4802 Register scratch = scratch0(); |
| 4803 __ ldr(scratch, ToMemOperand(input)); | 4803 __ ldr(scratch, ToMemOperand(input)); |
| 4804 __ vmov(single_scratch, scratch); | 4804 __ vmov(single_scratch, scratch); |
| 4805 } else { | 4805 } else { |
| 4806 __ vmov(single_scratch, ToRegister(input)); | 4806 __ vmov(single_scratch, ToRegister(input)); |
| 4807 } | 4807 } |
| 4808 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); | 4808 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); |
| 4809 } | 4809 } |
| 4810 | 4810 |
| 4811 | 4811 |
| 4812 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4812 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
| 4813 CpuFeatures::Scope scope(VFP2); | 4813 CpuFeatureScope scope(masm(), VFP2); |
| 4814 LOperand* input = instr->value(); | 4814 LOperand* input = instr->value(); |
| 4815 LOperand* output = instr->result(); | 4815 LOperand* output = instr->result(); |
| 4816 | 4816 |
| 4817 SwVfpRegister flt_scratch = double_scratch0().low(); | 4817 SwVfpRegister flt_scratch = double_scratch0().low(); |
| 4818 __ vmov(flt_scratch, ToRegister(input)); | 4818 __ vmov(flt_scratch, ToRegister(input)); |
| 4819 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); | 4819 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); |
| 4820 } | 4820 } |
| 4821 | 4821 |
| 4822 | 4822 |
| 4823 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4823 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4923 Label done; | 4923 Label done; |
| 4924 if (signedness == SIGNED_INT32) { | 4924 if (signedness == SIGNED_INT32) { |
| 4925 // There was overflow, so bits 30 and 31 of the original integer | 4925 // There was overflow, so bits 30 and 31 of the original integer |
| 4926 // disagree. Try to allocate a heap number in new space and store | 4926 // disagree. Try to allocate a heap number in new space and store |
| 4927 // the value in there. If that fails, call the runtime system. | 4927 // the value in there. If that fails, call the runtime system. |
| 4928 if (dst.is(src)) { | 4928 if (dst.is(src)) { |
| 4929 __ SmiUntag(src, dst); | 4929 __ SmiUntag(src, dst); |
| 4930 __ eor(src, src, Operand(0x80000000)); | 4930 __ eor(src, src, Operand(0x80000000)); |
| 4931 } | 4931 } |
| 4932 if (CpuFeatures::IsSupported(VFP2)) { | 4932 if (CpuFeatures::IsSupported(VFP2)) { |
| 4933 CpuFeatures::Scope scope(VFP2); | 4933 CpuFeatureScope scope(masm(), VFP2); |
| 4934 __ vmov(flt_scratch, src); | 4934 __ vmov(flt_scratch, src); |
| 4935 __ vcvt_f64_s32(dbl_scratch, flt_scratch); | 4935 __ vcvt_f64_s32(dbl_scratch, flt_scratch); |
| 4936 } else { | 4936 } else { |
| 4937 FloatingPointHelper::Destination dest = | 4937 FloatingPointHelper::Destination dest = |
| 4938 FloatingPointHelper::kCoreRegisters; | 4938 FloatingPointHelper::kCoreRegisters; |
| 4939 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, d0, | 4939 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, d0, |
| 4940 sfpd_lo, sfpd_hi, | 4940 sfpd_lo, sfpd_hi, |
| 4941 scratch0(), s0); | 4941 scratch0(), s0); |
| 4942 } | 4942 } |
| 4943 } else { | 4943 } else { |
| 4944 if (CpuFeatures::IsSupported(VFP2)) { | 4944 if (CpuFeatures::IsSupported(VFP2)) { |
| 4945 CpuFeatures::Scope scope(VFP2); | 4945 CpuFeatureScope scope(masm(), VFP2); |
| 4946 __ vmov(flt_scratch, src); | 4946 __ vmov(flt_scratch, src); |
| 4947 __ vcvt_f64_u32(dbl_scratch, flt_scratch); | 4947 __ vcvt_f64_u32(dbl_scratch, flt_scratch); |
| 4948 } else { | 4948 } else { |
| 4949 Label no_leading_zero, done; | 4949 Label no_leading_zero, done; |
| 4950 __ tst(src, Operand(0x80000000)); | 4950 __ tst(src, Operand(0x80000000)); |
| 4951 __ b(ne, &no_leading_zero); | 4951 __ b(ne, &no_leading_zero); |
| 4952 | 4952 |
| 4953 // Integer has one leading zeros. | 4953 // Integer has one leading zeros. |
| 4954 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1); | 4954 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1); |
| 4955 __ b(&done); | 4955 __ b(&done); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4976 __ mov(ip, Operand::Zero()); | 4976 __ mov(ip, Operand::Zero()); |
| 4977 __ StoreToSafepointRegisterSlot(ip, dst); | 4977 __ StoreToSafepointRegisterSlot(ip, dst); |
| 4978 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 4978 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
| 4979 __ Move(dst, r0); | 4979 __ Move(dst, r0); |
| 4980 __ sub(dst, dst, Operand(kHeapObjectTag)); | 4980 __ sub(dst, dst, Operand(kHeapObjectTag)); |
| 4981 | 4981 |
| 4982 // Done. Put the value in dbl_scratch into the value of the allocated heap | 4982 // Done. Put the value in dbl_scratch into the value of the allocated heap |
| 4983 // number. | 4983 // number. |
| 4984 __ bind(&done); | 4984 __ bind(&done); |
| 4985 if (CpuFeatures::IsSupported(VFP2)) { | 4985 if (CpuFeatures::IsSupported(VFP2)) { |
| 4986 CpuFeatures::Scope scope(VFP2); | 4986 CpuFeatureScope scope(masm(), VFP2); |
| 4987 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); | 4987 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); |
| 4988 } else { | 4988 } else { |
| 4989 __ str(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); | 4989 __ str(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); |
| 4990 __ str(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset)); | 4990 __ str(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset)); |
| 4991 } | 4991 } |
| 4992 __ add(dst, dst, Operand(kHeapObjectTag)); | 4992 __ add(dst, dst, Operand(kHeapObjectTag)); |
| 4993 __ StoreToSafepointRegisterSlot(dst, dst); | 4993 __ StoreToSafepointRegisterSlot(dst, dst); |
| 4994 } | 4994 } |
| 4995 | 4995 |
| 4996 | 4996 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5015 HValue* change_input = instr->hydrogen()->value(); | 5015 HValue* change_input = instr->hydrogen()->value(); |
| 5016 if (change_input->IsLoadKeyed()) { | 5016 if (change_input->IsLoadKeyed()) { |
| 5017 HLoadKeyed* load = HLoadKeyed::cast(change_input); | 5017 HLoadKeyed* load = HLoadKeyed::cast(change_input); |
| 5018 convert_hole = load->UsesMustHandleHole(); | 5018 convert_hole = load->UsesMustHandleHole(); |
| 5019 } | 5019 } |
| 5020 | 5020 |
| 5021 Label no_special_nan_handling; | 5021 Label no_special_nan_handling; |
| 5022 Label done; | 5022 Label done; |
| 5023 if (convert_hole) { | 5023 if (convert_hole) { |
| 5024 if (CpuFeatures::IsSupported(VFP2)) { | 5024 if (CpuFeatures::IsSupported(VFP2)) { |
| 5025 CpuFeatures::Scope scope(VFP2); | 5025 CpuFeatureScope scope(masm(), VFP2); |
| 5026 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); | 5026 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); |
| 5027 __ VFPCompareAndSetFlags(input_reg, input_reg); | 5027 __ VFPCompareAndSetFlags(input_reg, input_reg); |
| 5028 __ b(vc, &no_special_nan_handling); | 5028 __ b(vc, &no_special_nan_handling); |
| 5029 __ vmov(reg, scratch0(), input_reg); | 5029 __ vmov(reg, scratch0(), input_reg); |
| 5030 __ cmp(scratch0(), Operand(kHoleNanUpper32)); | 5030 __ cmp(scratch0(), Operand(kHoleNanUpper32)); |
| 5031 Label canonicalize; | 5031 Label canonicalize; |
| 5032 __ b(ne, &canonicalize); | 5032 __ b(ne, &canonicalize); |
| 5033 __ Move(reg, factory()->the_hole_value()); | 5033 __ Move(reg, factory()->the_hole_value()); |
| 5034 __ b(&done); | 5034 __ b(&done); |
| 5035 __ bind(&canonicalize); | 5035 __ bind(&canonicalize); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5067 if (FLAG_inline_new) { | 5067 if (FLAG_inline_new) { |
| 5068 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); | 5068 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); |
| 5069 // We want the untagged address first for performance | 5069 // We want the untagged address first for performance |
| 5070 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), | 5070 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), |
| 5071 DONT_TAG_RESULT); | 5071 DONT_TAG_RESULT); |
| 5072 } else { | 5072 } else { |
| 5073 __ jmp(deferred->entry()); | 5073 __ jmp(deferred->entry()); |
| 5074 } | 5074 } |
| 5075 __ bind(deferred->exit()); | 5075 __ bind(deferred->exit()); |
| 5076 if (CpuFeatures::IsSupported(VFP2)) { | 5076 if (CpuFeatures::IsSupported(VFP2)) { |
| 5077 CpuFeatures::Scope scope(VFP2); | 5077 CpuFeatureScope scope(masm(), VFP2); |
| 5078 __ vstr(input_reg, reg, HeapNumber::kValueOffset); | 5078 __ vstr(input_reg, reg, HeapNumber::kValueOffset); |
| 5079 } else { | 5079 } else { |
| 5080 __ str(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset)); | 5080 __ str(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset)); |
| 5081 __ str(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize)); | 5081 __ str(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize)); |
| 5082 } | 5082 } |
| 5083 // Now that we have finished with the object's real address tag it | 5083 // Now that we have finished with the object's real address tag it |
| 5084 __ add(reg, reg, Operand(kHeapObjectTag)); | 5084 __ add(reg, reg, Operand(kHeapObjectTag)); |
| 5085 __ bind(&done); | 5085 __ bind(&done); |
| 5086 } | 5086 } |
| 5087 | 5087 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5122 | 5122 |
| 5123 void LCodeGen::EmitNumberUntagD(Register input_reg, | 5123 void LCodeGen::EmitNumberUntagD(Register input_reg, |
| 5124 DwVfpRegister result_reg, | 5124 DwVfpRegister result_reg, |
| 5125 bool deoptimize_on_undefined, | 5125 bool deoptimize_on_undefined, |
| 5126 bool deoptimize_on_minus_zero, | 5126 bool deoptimize_on_minus_zero, |
| 5127 LEnvironment* env, | 5127 LEnvironment* env, |
| 5128 NumberUntagDMode mode) { | 5128 NumberUntagDMode mode) { |
| 5129 Register scratch = scratch0(); | 5129 Register scratch = scratch0(); |
| 5130 SwVfpRegister flt_scratch = double_scratch0().low(); | 5130 SwVfpRegister flt_scratch = double_scratch0().low(); |
| 5131 ASSERT(!result_reg.is(double_scratch0())); | 5131 ASSERT(!result_reg.is(double_scratch0())); |
| 5132 CpuFeatures::Scope scope(VFP2); | 5132 CpuFeatureScope scope(masm(), VFP2); |
| 5133 | 5133 |
| 5134 Label load_smi, heap_number, done; | 5134 Label load_smi, heap_number, done; |
| 5135 | 5135 |
| 5136 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 5136 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
| 5137 // Smi check. | 5137 // Smi check. |
| 5138 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | 5138 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); |
| 5139 | 5139 |
| 5140 // Heap number map check. | 5140 // Heap number map check. |
| 5141 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 5141 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
| 5142 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 5142 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5211 // SmiUntag(heap_object, SetCC) | 5211 // SmiUntag(heap_object, SetCC) |
| 5212 STATIC_ASSERT(kHeapObjectTag == 1); | 5212 STATIC_ASSERT(kHeapObjectTag == 1); |
| 5213 __ adc(input_reg, input_reg, Operand(input_reg)); | 5213 __ adc(input_reg, input_reg, Operand(input_reg)); |
| 5214 | 5214 |
| 5215 // Heap number map check. | 5215 // Heap number map check. |
| 5216 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 5216 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
| 5217 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 5217 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| 5218 __ cmp(scratch1, Operand(ip)); | 5218 __ cmp(scratch1, Operand(ip)); |
| 5219 | 5219 |
| 5220 if (instr->truncating()) { | 5220 if (instr->truncating()) { |
| 5221 CpuFeatures::Scope scope(VFP2); | 5221 CpuFeatureScope scope(masm(), VFP2); |
| 5222 Register scratch3 = ToRegister(instr->temp2()); | 5222 Register scratch3 = ToRegister(instr->temp2()); |
| 5223 ASSERT(!scratch3.is(input_reg) && | 5223 ASSERT(!scratch3.is(input_reg) && |
| 5224 !scratch3.is(scratch1) && | 5224 !scratch3.is(scratch1) && |
| 5225 !scratch3.is(scratch2)); | 5225 !scratch3.is(scratch2)); |
| 5226 // Performs a truncating conversion of a floating point number as used by | 5226 // Performs a truncating conversion of a floating point number as used by |
| 5227 // the JS bitwise operations. | 5227 // the JS bitwise operations. |
| 5228 Label heap_number; | 5228 Label heap_number; |
| 5229 __ b(eq, &heap_number); | 5229 __ b(eq, &heap_number); |
| 5230 // Check for undefined. Undefined is converted to zero for truncating | 5230 // Check for undefined. Undefined is converted to zero for truncating |
| 5231 // conversions. | 5231 // conversions. |
| 5232 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 5232 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 5233 __ cmp(input_reg, Operand(ip)); | 5233 __ cmp(input_reg, Operand(ip)); |
| 5234 DeoptimizeIf(ne, instr->environment()); | 5234 DeoptimizeIf(ne, instr->environment()); |
| 5235 __ mov(input_reg, Operand::Zero()); | 5235 __ mov(input_reg, Operand::Zero()); |
| 5236 __ b(&done); | 5236 __ b(&done); |
| 5237 | 5237 |
| 5238 __ bind(&heap_number); | 5238 __ bind(&heap_number); |
| 5239 __ sub(scratch1, input_reg, Operand(kHeapObjectTag)); | 5239 __ sub(scratch1, input_reg, Operand(kHeapObjectTag)); |
| 5240 __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset); | 5240 __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset); |
| 5241 | 5241 |
| 5242 __ EmitECMATruncate(input_reg, | 5242 __ EmitECMATruncate(input_reg, |
| 5243 double_scratch2, | 5243 double_scratch2, |
| 5244 double_scratch, | 5244 double_scratch, |
| 5245 scratch1, | 5245 scratch1, |
| 5246 scratch2, | 5246 scratch2, |
| 5247 scratch3); | 5247 scratch3); |
| 5248 | 5248 |
| 5249 } else { | 5249 } else { |
| 5250 CpuFeatures::Scope scope(VFP3); | 5250 CpuFeatureScope scope(masm(), VFP3); |
| 5251 // Deoptimize if we don't have a heap number. | 5251 // Deoptimize if we don't have a heap number. |
| 5252 DeoptimizeIf(ne, instr->environment()); | 5252 DeoptimizeIf(ne, instr->environment()); |
| 5253 | 5253 |
| 5254 __ sub(ip, input_reg, Operand(kHeapObjectTag)); | 5254 __ sub(ip, input_reg, Operand(kHeapObjectTag)); |
| 5255 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); | 5255 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); |
| 5256 __ EmitVFPTruncate(kRoundToZero, | 5256 __ EmitVFPTruncate(kRoundToZero, |
| 5257 input_reg, | 5257 input_reg, |
| 5258 double_scratch, | 5258 double_scratch, |
| 5259 scratch1, | 5259 scratch1, |
| 5260 double_scratch2, | 5260 double_scratch2, |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5468 __ CompareMap(map_reg, map, &success, REQUIRE_EXACT_MAP); | 5468 __ CompareMap(map_reg, map, &success, REQUIRE_EXACT_MAP); |
| 5469 __ b(eq, &success); | 5469 __ b(eq, &success); |
| 5470 } | 5470 } |
| 5471 Handle<Map> map = map_set->last(); | 5471 Handle<Map> map = map_set->last(); |
| 5472 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); | 5472 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); |
| 5473 __ bind(&success); | 5473 __ bind(&success); |
| 5474 } | 5474 } |
| 5475 | 5475 |
| 5476 | 5476 |
| 5477 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { | 5477 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { |
| 5478 CpuFeatures::Scope vfp_scope(VFP2); | 5478 CpuFeatureScope vfp_scope(masm(), VFP2); |
| 5479 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped()); | 5479 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped()); |
| 5480 Register result_reg = ToRegister(instr->result()); | 5480 Register result_reg = ToRegister(instr->result()); |
| 5481 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); | 5481 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); |
| 5482 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); | 5482 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); |
| 5483 } | 5483 } |
| 5484 | 5484 |
| 5485 | 5485 |
| 5486 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { | 5486 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { |
| 5487 CpuFeatures::Scope scope(VFP2); | 5487 CpuFeatureScope scope(masm(), VFP2); |
| 5488 Register unclamped_reg = ToRegister(instr->unclamped()); | 5488 Register unclamped_reg = ToRegister(instr->unclamped()); |
| 5489 Register result_reg = ToRegister(instr->result()); | 5489 Register result_reg = ToRegister(instr->result()); |
| 5490 __ ClampUint8(result_reg, unclamped_reg); | 5490 __ ClampUint8(result_reg, unclamped_reg); |
| 5491 } | 5491 } |
| 5492 | 5492 |
| 5493 | 5493 |
| 5494 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { | 5494 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { |
| 5495 CpuFeatures::Scope scope(VFP2); | 5495 CpuFeatureScope scope(masm(), VFP2); |
| 5496 Register scratch = scratch0(); | 5496 Register scratch = scratch0(); |
| 5497 Register input_reg = ToRegister(instr->unclamped()); | 5497 Register input_reg = ToRegister(instr->unclamped()); |
| 5498 Register result_reg = ToRegister(instr->result()); | 5498 Register result_reg = ToRegister(instr->result()); |
| 5499 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); | 5499 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); |
| 5500 Label is_smi, done, heap_number; | 5500 Label is_smi, done, heap_number; |
| 5501 | 5501 |
| 5502 // Both smi and heap number cases are handled. | 5502 // Both smi and heap number cases are handled. |
| 5503 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); | 5503 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); |
| 5504 | 5504 |
| 5505 // Check for heap number | 5505 // Check for heap number |
| (...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6396 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6396 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 6397 __ ldr(result, FieldMemOperand(scratch, | 6397 __ ldr(result, FieldMemOperand(scratch, |
| 6398 FixedArray::kHeaderSize - kPointerSize)); | 6398 FixedArray::kHeaderSize - kPointerSize)); |
| 6399 __ bind(&done); | 6399 __ bind(&done); |
| 6400 } | 6400 } |
| 6401 | 6401 |
| 6402 | 6402 |
| 6403 #undef __ | 6403 #undef __ |
| 6404 | 6404 |
| 6405 } } // namespace v8::internal | 6405 } } // namespace v8::internal |
| OLD | NEW |