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