Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 12391055: Cleaned up CpuFeature scope handling. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed nits Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/lithium-gap-resolver-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
2294 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); 2294 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
2295 __ b(ge, &not_string); 2295 __ b(ge, &not_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(&not_string); 2300 __ bind(&not_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, &not_heap_number); 2309 __ b(ne, &not_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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/lithium-gap-resolver-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698