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

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

Issue 13560007: Remove ARM support for soft float (pre-VFP2) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 7 years, 8 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/lithium-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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 __ str(r1, MemOperand(r0, 2 * kPointerSize)); 188 __ str(r1, MemOperand(r0, 2 * kPointerSize));
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()) {
199 CpuFeatureScope scope(masm(), VFP2);
200 Comment(";;; Save clobbered callee double registers"); 199 Comment(";;; Save clobbered callee double registers");
201 int count = 0; 200 int count = 0;
202 BitVector* doubles = chunk()->allocated_double_registers(); 201 BitVector* doubles = chunk()->allocated_double_registers();
203 BitVector::Iterator save_iterator(doubles); 202 BitVector::Iterator save_iterator(doubles);
204 while (!save_iterator.Done()) { 203 while (!save_iterator.Done()) {
205 __ vstr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()), 204 __ vstr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()),
206 MemOperand(sp, count * kDoubleSize)); 205 MemOperand(sp, count * kDoubleSize));
207 save_iterator.Advance(); 206 save_iterator.Advance();
208 count++; 207 count++;
209 } 208 }
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 1201
1203 ASSERT(!dividend.is(divisor)); 1202 ASSERT(!dividend.is(divisor));
1204 ASSERT(!dividend.is(quotient)); 1203 ASSERT(!dividend.is(quotient));
1205 ASSERT(!divisor.is(quotient)); 1204 ASSERT(!divisor.is(quotient));
1206 ASSERT(!scratch.is(left)); 1205 ASSERT(!scratch.is(left));
1207 ASSERT(!scratch.is(right)); 1206 ASSERT(!scratch.is(right));
1208 ASSERT(!scratch.is(result)); 1207 ASSERT(!scratch.is(result));
1209 1208
1210 Label vfp_modulo, both_positive, right_negative; 1209 Label vfp_modulo, both_positive, right_negative;
1211 1210
1212 CpuFeatureScope scope(masm(), VFP2);
1213
1214 // Check for x % 0. 1211 // Check for x % 0.
1215 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1212 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1216 __ cmp(right, Operand::Zero()); 1213 __ cmp(right, Operand::Zero());
1217 DeoptimizeIf(eq, instr->environment()); 1214 DeoptimizeIf(eq, instr->environment());
1218 } 1215 }
1219 1216
1220 __ Move(result, left); 1217 __ Move(result, left);
1221 1218
1222 // (0 % x) must yield 0 (if x is finite, which is the case here). 1219 // (0 % x) must yield 0 (if x is finite, which is the case here).
1223 __ cmp(left, Operand::Zero()); 1220 __ cmp(left, Operand::Zero());
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 1605
1609 __ bind(&done); 1606 __ bind(&done);
1610 } 1607 }
1611 } 1608 }
1612 1609
1613 1610
1614 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, 1611 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map,
1615 LOperand* left_argument, 1612 LOperand* left_argument,
1616 LOperand* right_argument, 1613 LOperand* right_argument,
1617 Token::Value op) { 1614 Token::Value op) {
1618 CpuFeatureScope vfp_scope(masm(), VFP2);
1619 Register left = ToRegister(left_argument); 1615 Register left = ToRegister(left_argument);
1620 Register right = ToRegister(right_argument); 1616 Register right = ToRegister(right_argument);
1621 1617
1622 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); 1618 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles);
1623 // Move left to r1 and right to r0 for the stub call. 1619 // Move left to r1 and right to r0 for the stub call.
1624 if (left.is(r1)) { 1620 if (left.is(r1)) {
1625 __ Move(r0, right); 1621 __ Move(r0, right);
1626 } else if (left.is(r0) && right.is(r1)) { 1622 } else if (left.is(r0) && right.is(r1)) {
1627 __ Swap(r0, r1, r2); 1623 __ Swap(r0, r1, r2);
1628 } else if (left.is(r0)) { 1624 } else if (left.is(r0)) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1894 1890
1895 void LCodeGen::DoConstantI(LConstantI* instr) { 1891 void LCodeGen::DoConstantI(LConstantI* instr) {
1896 ASSERT(instr->result()->IsRegister()); 1892 ASSERT(instr->result()->IsRegister());
1897 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1893 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1898 } 1894 }
1899 1895
1900 1896
1901 void LCodeGen::DoConstantD(LConstantD* instr) { 1897 void LCodeGen::DoConstantD(LConstantD* instr) {
1902 ASSERT(instr->result()->IsDoubleRegister()); 1898 ASSERT(instr->result()->IsDoubleRegister());
1903 DwVfpRegister result = ToDoubleRegister(instr->result()); 1899 DwVfpRegister result = ToDoubleRegister(instr->result());
1904 CpuFeatureScope scope(masm(), VFP2);
1905 double v = instr->value(); 1900 double v = instr->value();
1906 __ Vmov(result, v, scratch0()); 1901 __ Vmov(result, v, scratch0());
1907 } 1902 }
1908 1903
1909 1904
1910 void LCodeGen::DoConstantT(LConstantT* instr) { 1905 void LCodeGen::DoConstantT(LConstantT* instr) {
1911 Handle<Object> value = instr->value(); 1906 Handle<Object> value = instr->value();
1912 if (value->IsSmi()) { 1907 if (value->IsSmi()) {
1913 __ mov(ToRegister(instr->result()), Operand(value)); 1908 __ mov(ToRegister(instr->result()), Operand(value));
1914 } else { 1909 } else {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
2065 ? ToOperand(right) 2060 ? ToOperand(right)
2066 : Operand(EmitLoadRegister(right, ip)); 2061 : Operand(EmitLoadRegister(right, ip));
2067 Register result_reg = ToRegister(instr->result()); 2062 Register result_reg = ToRegister(instr->result());
2068 __ cmp(left_reg, right_op); 2063 __ cmp(left_reg, right_op);
2069 if (!result_reg.is(left_reg)) { 2064 if (!result_reg.is(left_reg)) {
2070 __ mov(result_reg, left_reg, LeaveCC, condition); 2065 __ mov(result_reg, left_reg, LeaveCC, condition);
2071 } 2066 }
2072 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); 2067 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition));
2073 } else { 2068 } else {
2074 ASSERT(instr->hydrogen()->representation().IsDouble()); 2069 ASSERT(instr->hydrogen()->representation().IsDouble());
2075 CpuFeatureScope scope(masm(), VFP2);
2076 DwVfpRegister left_reg = ToDoubleRegister(left); 2070 DwVfpRegister left_reg = ToDoubleRegister(left);
2077 DwVfpRegister right_reg = ToDoubleRegister(right); 2071 DwVfpRegister right_reg = ToDoubleRegister(right);
2078 DwVfpRegister result_reg = ToDoubleRegister(instr->result()); 2072 DwVfpRegister result_reg = ToDoubleRegister(instr->result());
2079 Label check_nan_left, check_zero, return_left, return_right, done; 2073 Label check_nan_left, check_zero, return_left, return_right, done;
2080 __ VFPCompareAndSetFlags(left_reg, right_reg); 2074 __ VFPCompareAndSetFlags(left_reg, right_reg);
2081 __ b(vs, &check_nan_left); 2075 __ b(vs, &check_nan_left);
2082 __ b(eq, &check_zero); 2076 __ b(eq, &check_zero);
2083 __ b(condition, &return_left); 2077 __ b(condition, &return_left);
2084 __ b(al, &return_right); 2078 __ b(al, &return_right);
2085 2079
(...skipping 25 matching lines...) Expand all
2111 __ bind(&return_left); 2105 __ bind(&return_left);
2112 if (!left_reg.is(result_reg)) { 2106 if (!left_reg.is(result_reg)) {
2113 __ vmov(result_reg, left_reg); 2107 __ vmov(result_reg, left_reg);
2114 } 2108 }
2115 __ bind(&done); 2109 __ bind(&done);
2116 } 2110 }
2117 } 2111 }
2118 2112
2119 2113
2120 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 2114 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
2121 CpuFeatureScope scope(masm(), VFP2);
2122 DwVfpRegister left = ToDoubleRegister(instr->left()); 2115 DwVfpRegister left = ToDoubleRegister(instr->left());
2123 DwVfpRegister right = ToDoubleRegister(instr->right()); 2116 DwVfpRegister right = ToDoubleRegister(instr->right());
2124 DwVfpRegister result = ToDoubleRegister(instr->result()); 2117 DwVfpRegister result = ToDoubleRegister(instr->result());
2125 switch (instr->op()) { 2118 switch (instr->op()) {
2126 case Token::ADD: 2119 case Token::ADD:
2127 __ vadd(result, left, right); 2120 __ vadd(result, left, right);
2128 break; 2121 break;
2129 case Token::SUB: 2122 case Token::SUB:
2130 __ vsub(result, left, right); 2123 __ vsub(result, left, right);
2131 break; 2124 break;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2202 void LCodeGen::DoBranch(LBranch* instr) { 2195 void LCodeGen::DoBranch(LBranch* instr) {
2203 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2196 int true_block = chunk_->LookupDestination(instr->true_block_id());
2204 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2197 int false_block = chunk_->LookupDestination(instr->false_block_id());
2205 2198
2206 Representation r = instr->hydrogen()->value()->representation(); 2199 Representation r = instr->hydrogen()->value()->representation();
2207 if (r.IsInteger32()) { 2200 if (r.IsInteger32()) {
2208 Register reg = ToRegister(instr->value()); 2201 Register reg = ToRegister(instr->value());
2209 __ cmp(reg, Operand::Zero()); 2202 __ cmp(reg, Operand::Zero());
2210 EmitBranch(true_block, false_block, ne); 2203 EmitBranch(true_block, false_block, ne);
2211 } else if (r.IsDouble()) { 2204 } else if (r.IsDouble()) {
2212 CpuFeatureScope scope(masm(), VFP2);
2213 DwVfpRegister reg = ToDoubleRegister(instr->value()); 2205 DwVfpRegister reg = ToDoubleRegister(instr->value());
2214 Register scratch = scratch0(); 2206 Register scratch = scratch0();
2215 2207
2216 // Test the double value. Zero and NaN are false. 2208 // Test the double value. Zero and NaN are false.
2217 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); 2209 __ VFPCompareAndLoadFlags(reg, 0.0, scratch);
2218 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); 2210 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
2219 EmitBranch(true_block, false_block, eq); 2211 EmitBranch(true_block, false_block, eq);
2220 } else { 2212 } else {
2221 ASSERT(r.IsTagged()); 2213 ASSERT(r.IsTagged());
2222 Register reg = ToRegister(instr->value()); 2214 Register reg = ToRegister(instr->value());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2294 __ bind(&not_string); 2286 __ bind(&not_string);
2295 } 2287 }
2296 2288
2297 if (expected.Contains(ToBooleanStub::SYMBOL)) { 2289 if (expected.Contains(ToBooleanStub::SYMBOL)) {
2298 // Symbol value -> true. 2290 // Symbol value -> true.
2299 __ CompareInstanceType(map, ip, SYMBOL_TYPE); 2291 __ CompareInstanceType(map, ip, SYMBOL_TYPE);
2300 __ b(eq, true_label); 2292 __ b(eq, true_label);
2301 } 2293 }
2302 2294
2303 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2295 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
2304 CpuFeatureScope scope(masm(), VFP2);
2305 // heap number -> false iff +0, -0, or NaN. 2296 // heap number -> false iff +0, -0, or NaN.
2306 DwVfpRegister dbl_scratch = double_scratch0(); 2297 DwVfpRegister dbl_scratch = double_scratch0();
2307 Label not_heap_number; 2298 Label not_heap_number;
2308 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 2299 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
2309 __ b(ne, &not_heap_number); 2300 __ b(ne, &not_heap_number);
2310 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 2301 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
2311 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); 2302 __ VFPCompareAndSetFlags(dbl_scratch, 0.0);
2312 __ b(vs, false_label); // NaN -> false. 2303 __ b(vs, false_label); // NaN -> false.
2313 __ b(eq, false_label); // +0, -0 -> false. 2304 __ b(eq, false_label); // +0, -0 -> false.
2314 __ b(true_label); 2305 __ b(true_label);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2374 if (left->IsConstantOperand() && right->IsConstantOperand()) { 2365 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2375 // We can statically evaluate the comparison. 2366 // We can statically evaluate the comparison.
2376 double left_val = ToDouble(LConstantOperand::cast(left)); 2367 double left_val = ToDouble(LConstantOperand::cast(left));
2377 double right_val = ToDouble(LConstantOperand::cast(right)); 2368 double right_val = ToDouble(LConstantOperand::cast(right));
2378 int next_block = 2369 int next_block =
2379 EvalComparison(instr->op(), left_val, right_val) ? true_block 2370 EvalComparison(instr->op(), left_val, right_val) ? true_block
2380 : false_block; 2371 : false_block;
2381 EmitGoto(next_block); 2372 EmitGoto(next_block);
2382 } else { 2373 } else {
2383 if (instr->is_double()) { 2374 if (instr->is_double()) {
2384 CpuFeatureScope scope(masm(), VFP2);
2385 // Compare left and right operands as doubles and load the 2375 // Compare left and right operands as doubles and load the
2386 // resulting flags into the normal status register. 2376 // resulting flags into the normal status register.
2387 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); 2377 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right));
2388 // If a NaN is involved, i.e. the result is unordered (V set), 2378 // If a NaN is involved, i.e. the result is unordered (V set),
2389 // jump to false block label. 2379 // jump to false block label.
2390 __ b(vs, chunk_->GetAssemblyLabel(false_block)); 2380 __ b(vs, chunk_->GetAssemblyLabel(false_block));
2391 } else { 2381 } else {
2392 if (right->IsConstantOperand()) { 2382 if (right->IsConstantOperand()) {
2393 __ cmp(ToRegister(left), 2383 __ cmp(ToRegister(left),
2394 Operand(ToInteger32(LConstantOperand::cast(right)))); 2384 Operand(ToInteger32(LConstantOperand::cast(right))));
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
2929 } 2919 }
2930 2920
2931 2921
2932 void LCodeGen::DoReturn(LReturn* instr) { 2922 void LCodeGen::DoReturn(LReturn* instr) {
2933 if (FLAG_trace && info()->IsOptimizing()) { 2923 if (FLAG_trace && info()->IsOptimizing()) {
2934 // Push the return value on the stack as the parameter. 2924 // Push the return value on the stack as the parameter.
2935 // Runtime::TraceExit returns its parameter in r0. 2925 // Runtime::TraceExit returns its parameter in r0.
2936 __ push(r0); 2926 __ push(r0);
2937 __ CallRuntime(Runtime::kTraceExit, 1); 2927 __ CallRuntime(Runtime::kTraceExit, 1);
2938 } 2928 }
2939 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(VFP2)) { 2929 if (info()->saves_caller_doubles()) {
2940 CpuFeatureScope scope(masm(), VFP2);
2941 ASSERT(NeedsEagerFrame()); 2930 ASSERT(NeedsEagerFrame());
2942 BitVector* doubles = chunk()->allocated_double_registers(); 2931 BitVector* doubles = chunk()->allocated_double_registers();
2943 BitVector::Iterator save_iterator(doubles); 2932 BitVector::Iterator save_iterator(doubles);
2944 int count = 0; 2933 int count = 0;
2945 while (!save_iterator.Done()) { 2934 while (!save_iterator.Done()) {
2946 __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()), 2935 __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()),
2947 MemOperand(sp, count * kDoubleSize)); 2936 MemOperand(sp, count * kDoubleSize));
2948 save_iterator.Advance(); 2937 save_iterator.Advance();
2949 count++; 2938 count++;
2950 } 2939 }
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
3312 ? (element_size_shift - kSmiTagSize) : element_size_shift; 3301 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3313 int additional_offset = instr->additional_index() << element_size_shift; 3302 int additional_offset = instr->additional_index() << element_size_shift;
3314 3303
3315 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3304 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3316 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3305 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3317 DwVfpRegister result = ToDoubleRegister(instr->result()); 3306 DwVfpRegister result = ToDoubleRegister(instr->result());
3318 Operand operand = key_is_constant 3307 Operand operand = key_is_constant
3319 ? Operand(constant_key << element_size_shift) 3308 ? Operand(constant_key << element_size_shift)
3320 : Operand(key, LSL, shift_size); 3309 : Operand(key, LSL, shift_size);
3321 __ add(scratch0(), external_pointer, operand); 3310 __ add(scratch0(), external_pointer, operand);
3322 if (CpuFeatures::IsSupported(VFP2)) { 3311 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3323 CpuFeatureScope scope(masm(), VFP2); 3312 __ vldr(kScratchDoubleReg.low(), scratch0(), additional_offset);
3324 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3313 __ vcvt_f64_f32(result, kScratchDoubleReg.low());
3325 __ vldr(kScratchDoubleReg.low(), scratch0(), additional_offset); 3314 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3326 __ vcvt_f64_f32(result, kScratchDoubleReg.low()); 3315 __ vldr(result, scratch0(), additional_offset);
3327 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3328 __ vldr(result, scratch0(), additional_offset);
3329 }
3330 } else {
3331 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3332 Register value = external_pointer;
3333 __ ldr(value, MemOperand(scratch0(), additional_offset));
3334 __ and_(sfpd_lo, value, Operand(kBinary32MantissaMask));
3335
3336 __ mov(scratch0(), Operand(value, LSR, kBinary32MantissaBits));
3337 __ and_(scratch0(), scratch0(),
3338 Operand(kBinary32ExponentMask >> kBinary32MantissaBits));
3339
3340 Label exponent_rebiased;
3341 __ teq(scratch0(), Operand(0x00));
3342 __ b(eq, &exponent_rebiased);
3343
3344 __ teq(scratch0(), Operand(0xff));
3345 __ mov(scratch0(), Operand(0x7ff), LeaveCC, eq);
3346 __ b(eq, &exponent_rebiased);
3347
3348 // Rebias exponent.
3349 __ add(scratch0(),
3350 scratch0(),
3351 Operand(-kBinary32ExponentBias + HeapNumber::kExponentBias));
3352
3353 __ bind(&exponent_rebiased);
3354 __ and_(sfpd_hi, value, Operand(kBinary32SignMask));
3355 __ orr(sfpd_hi, sfpd_hi,
3356 Operand(scratch0(), LSL, HeapNumber::kMantissaBitsInTopWord));
3357
3358 // Shift mantissa.
3359 static const int kMantissaShiftForHiWord =
3360 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3361
3362 static const int kMantissaShiftForLoWord =
3363 kBitsPerInt - kMantissaShiftForHiWord;
3364
3365 __ orr(sfpd_hi, sfpd_hi,
3366 Operand(sfpd_lo, LSR, kMantissaShiftForHiWord));
3367 __ mov(sfpd_lo, Operand(sfpd_lo, LSL, kMantissaShiftForLoWord));
3368
3369 } else {
3370 __ ldr(sfpd_lo, MemOperand(scratch0(), additional_offset));
3371 __ ldr(sfpd_hi, MemOperand(scratch0(),
3372 additional_offset + kPointerSize));
3373 }
3374 } 3316 }
3375 } else { 3317 } else {
3376 Register result = ToRegister(instr->result()); 3318 Register result = ToRegister(instr->result());
3377 MemOperand mem_operand = PrepareKeyedOperand( 3319 MemOperand mem_operand = PrepareKeyedOperand(
3378 key, external_pointer, key_is_constant, constant_key, 3320 key, external_pointer, key_is_constant, constant_key,
3379 element_size_shift, shift_size, 3321 element_size_shift, shift_size,
3380 instr->additional_index(), additional_offset); 3322 instr->additional_index(), additional_offset);
3381 switch (elements_kind) { 3323 switch (elements_kind) {
3382 case EXTERNAL_BYTE_ELEMENTS: 3324 case EXTERNAL_BYTE_ELEMENTS:
3383 __ ldrsb(result, mem_operand); 3325 __ ldrsb(result, mem_operand);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3437 } 3379 }
3438 } else { 3380 } else {
3439 key = ToRegister(instr->key()); 3381 key = ToRegister(instr->key());
3440 } 3382 }
3441 3383
3442 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + 3384 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
3443 ((constant_key + instr->additional_index()) << element_size_shift); 3385 ((constant_key + instr->additional_index()) << element_size_shift);
3444 if (!key_is_constant) { 3386 if (!key_is_constant) {
3445 __ add(elements, elements, Operand(key, LSL, shift_size)); 3387 __ add(elements, elements, Operand(key, LSL, shift_size));
3446 } 3388 }
3447 if (CpuFeatures::IsSupported(VFP2)) { 3389 __ add(elements, elements, Operand(base_offset));
3448 CpuFeatureScope scope(masm(), VFP2); 3390 __ vldr(result, elements, 0);
3449 __ add(elements, elements, Operand(base_offset)); 3391 if (instr->hydrogen()->RequiresHoleCheck()) {
3450 __ vldr(result, elements, 0); 3392 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
3451 if (instr->hydrogen()->RequiresHoleCheck()) { 3393 __ cmp(scratch, Operand(kHoleNanUpper32));
3452 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 3394 DeoptimizeIf(eq, instr->environment());
3453 __ cmp(scratch, Operand(kHoleNanUpper32));
3454 DeoptimizeIf(eq, instr->environment());
3455 }
3456 } else {
3457 __ ldr(sfpd_hi, MemOperand(elements, base_offset + kPointerSize));
3458 __ ldr(sfpd_lo, MemOperand(elements, base_offset));
3459 if (instr->hydrogen()->RequiresHoleCheck()) {
3460 ASSERT(kPointerSize == sizeof(kHoleNanLower32));
3461 __ cmp(sfpd_hi, Operand(kHoleNanUpper32));
3462 DeoptimizeIf(eq, instr->environment());
3463 }
3464 } 3395 }
3465 } 3396 }
3466 3397
3467 3398
3468 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3399 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3469 Register elements = ToRegister(instr->elements()); 3400 Register elements = ToRegister(instr->elements());
3470 Register result = ToRegister(instr->result()); 3401 Register result = ToRegister(instr->result());
3471 Register scratch = scratch0(); 3402 Register scratch = scratch0();
3472 Register store_base = scratch; 3403 Register store_base = scratch;
3473 int offset = 0; 3404 int offset = 0;
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
3895 // We can make rsb conditional because the previous cmp instruction 3826 // We can make rsb conditional because the previous cmp instruction
3896 // will clear the V (overflow) flag and rsb won't set this flag 3827 // will clear the V (overflow) flag and rsb won't set this flag
3897 // if input is positive. 3828 // if input is positive.
3898 __ rsb(result, input, Operand::Zero(), SetCC, mi); 3829 __ rsb(result, input, Operand::Zero(), SetCC, mi);
3899 // Deoptimize on overflow. 3830 // Deoptimize on overflow.
3900 DeoptimizeIf(vs, instr->environment()); 3831 DeoptimizeIf(vs, instr->environment());
3901 } 3832 }
3902 3833
3903 3834
3904 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3835 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
3905 CpuFeatureScope scope(masm(), VFP2);
3906 // Class for deferred case. 3836 // Class for deferred case.
3907 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3837 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3908 public: 3838 public:
3909 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3839 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
3910 LUnaryMathOperation* instr) 3840 LUnaryMathOperation* instr)
3911 : LDeferredCode(codegen), instr_(instr) { } 3841 : LDeferredCode(codegen), instr_(instr) { }
3912 virtual void Generate() { 3842 virtual void Generate() {
3913 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3843 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3914 } 3844 }
3915 virtual LInstruction* instr() { return instr_; } 3845 virtual LInstruction* instr() { return instr_; }
(...skipping 16 matching lines...) Expand all
3932 // Smi check. 3862 // Smi check.
3933 __ JumpIfNotSmi(input, deferred->entry()); 3863 __ JumpIfNotSmi(input, deferred->entry());
3934 // If smi, handle it directly. 3864 // If smi, handle it directly.
3935 EmitIntegerMathAbs(instr); 3865 EmitIntegerMathAbs(instr);
3936 __ bind(deferred->exit()); 3866 __ bind(deferred->exit());
3937 } 3867 }
3938 } 3868 }
3939 3869
3940 3870
3941 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3871 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
3942 CpuFeatureScope scope(masm(), VFP2);
3943 DwVfpRegister input = ToDoubleRegister(instr->value()); 3872 DwVfpRegister input = ToDoubleRegister(instr->value());
3944 Register result = ToRegister(instr->result()); 3873 Register result = ToRegister(instr->result());
3945 Register input_high = scratch0(); 3874 Register input_high = scratch0();
3946 Label done, exact; 3875 Label done, exact;
3947 3876
3948 __ vmov(input_high, input.high()); 3877 __ vmov(input_high, input.high());
3949 __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact); 3878 __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact);
3950 DeoptimizeIf(al, instr->environment()); 3879 DeoptimizeIf(al, instr->environment());
3951 3880
3952 __ bind(&exact); 3881 __ bind(&exact);
3953 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3882 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3954 // Test for -0. 3883 // Test for -0.
3955 __ cmp(result, Operand::Zero()); 3884 __ cmp(result, Operand::Zero());
3956 __ b(ne, &done); 3885 __ b(ne, &done);
3957 __ cmp(input_high, Operand::Zero()); 3886 __ cmp(input_high, Operand::Zero());
3958 DeoptimizeIf(mi, instr->environment()); 3887 DeoptimizeIf(mi, instr->environment());
3959 } 3888 }
3960 __ bind(&done); 3889 __ bind(&done);
3961 } 3890 }
3962 3891
3963 3892
3964 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3893 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
3965 CpuFeatureScope scope(masm(), VFP2);
3966 DwVfpRegister input = ToDoubleRegister(instr->value()); 3894 DwVfpRegister input = ToDoubleRegister(instr->value());
3967 Register result = ToRegister(instr->result()); 3895 Register result = ToRegister(instr->result());
3968 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); 3896 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp());
3969 DwVfpRegister input_plus_dot_five = double_scratch1; 3897 DwVfpRegister input_plus_dot_five = double_scratch1;
3970 Register input_high = scratch0(); 3898 Register input_high = scratch0();
3971 DwVfpRegister dot_five = double_scratch0(); 3899 DwVfpRegister dot_five = double_scratch0();
3972 Label convert, done; 3900 Label convert, done;
3973 3901
3974 __ Vmov(dot_five, 0.5, scratch0()); 3902 __ Vmov(dot_five, 0.5, scratch0());
3975 __ vabs(double_scratch1, input); 3903 __ vabs(double_scratch1, input);
(...skipping 19 matching lines...) Expand all
3995 __ vmov(input_high, input_plus_dot_five.high()); 3923 __ vmov(input_high, input_plus_dot_five.high());
3996 // Reuse dot_five (double_scratch0) as we no longer need this value. 3924 // Reuse dot_five (double_scratch0) as we no longer need this value.
3997 __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(), 3925 __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(),
3998 &done, &done); 3926 &done, &done);
3999 DeoptimizeIf(al, instr->environment()); 3927 DeoptimizeIf(al, instr->environment());
4000 __ bind(&done); 3928 __ bind(&done);
4001 } 3929 }
4002 3930
4003 3931
4004 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3932 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
4005 CpuFeatureScope scope(masm(), VFP2);
4006 DwVfpRegister input = ToDoubleRegister(instr->value()); 3933 DwVfpRegister input = ToDoubleRegister(instr->value());
4007 DwVfpRegister result = ToDoubleRegister(instr->result()); 3934 DwVfpRegister result = ToDoubleRegister(instr->result());
4008 __ vsqrt(result, input); 3935 __ vsqrt(result, input);
4009 } 3936 }
4010 3937
4011 3938
4012 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3939 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
4013 CpuFeatureScope scope(masm(), VFP2);
4014 DwVfpRegister input = ToDoubleRegister(instr->value()); 3940 DwVfpRegister input = ToDoubleRegister(instr->value());
4015 DwVfpRegister result = ToDoubleRegister(instr->result()); 3941 DwVfpRegister result = ToDoubleRegister(instr->result());
4016 DwVfpRegister temp = ToDoubleRegister(instr->temp()); 3942 DwVfpRegister temp = ToDoubleRegister(instr->temp());
4017 3943
4018 // Note that according to ECMA-262 15.8.2.13: 3944 // Note that according to ECMA-262 15.8.2.13:
4019 // Math.pow(-Infinity, 0.5) == Infinity 3945 // Math.pow(-Infinity, 0.5) == Infinity
4020 // Math.sqrt(-Infinity) == NaN 3946 // Math.sqrt(-Infinity) == NaN
4021 Label done; 3947 Label done;
4022 __ vmov(temp, -V8_INFINITY, scratch0()); 3948 __ vmov(temp, -V8_INFINITY, scratch0());
4023 __ VFPCompareAndSetFlags(input, temp); 3949 __ VFPCompareAndSetFlags(input, temp);
4024 __ vneg(result, temp, eq); 3950 __ vneg(result, temp, eq);
4025 __ b(&done, eq); 3951 __ b(&done, eq);
4026 3952
4027 // Add +0 to convert -0 to +0. 3953 // Add +0 to convert -0 to +0.
4028 __ vadd(result, input, kDoubleRegZero); 3954 __ vadd(result, input, kDoubleRegZero);
4029 __ vsqrt(result, result); 3955 __ vsqrt(result, result);
4030 __ bind(&done); 3956 __ bind(&done);
4031 } 3957 }
4032 3958
4033 3959
4034 void LCodeGen::DoPower(LPower* instr) { 3960 void LCodeGen::DoPower(LPower* instr) {
4035 CpuFeatureScope scope(masm(), VFP2);
4036 Representation exponent_type = instr->hydrogen()->right()->representation(); 3961 Representation exponent_type = instr->hydrogen()->right()->representation();
4037 // Having marked this as a call, we can use any registers. 3962 // Having marked this as a call, we can use any registers.
4038 // Just make sure that the input/output registers are the expected ones. 3963 // Just make sure that the input/output registers are the expected ones.
4039 ASSERT(!instr->right()->IsDoubleRegister() || 3964 ASSERT(!instr->right()->IsDoubleRegister() ||
4040 ToDoubleRegister(instr->right()).is(d2)); 3965 ToDoubleRegister(instr->right()).is(d2));
4041 ASSERT(!instr->right()->IsRegister() || 3966 ASSERT(!instr->right()->IsRegister() ||
4042 ToRegister(instr->right()).is(r2)); 3967 ToRegister(instr->right()).is(r2));
4043 ASSERT(ToDoubleRegister(instr->left()).is(d1)); 3968 ASSERT(ToDoubleRegister(instr->left()).is(d1));
4044 ASSERT(ToDoubleRegister(instr->result()).is(d3)); 3969 ASSERT(ToDoubleRegister(instr->result()).is(d3));
4045 3970
(...skipping 12 matching lines...) Expand all
4058 __ CallStub(&stub); 3983 __ CallStub(&stub);
4059 } else { 3984 } else {
4060 ASSERT(exponent_type.IsDouble()); 3985 ASSERT(exponent_type.IsDouble());
4061 MathPowStub stub(MathPowStub::DOUBLE); 3986 MathPowStub stub(MathPowStub::DOUBLE);
4062 __ CallStub(&stub); 3987 __ CallStub(&stub);
4063 } 3988 }
4064 } 3989 }
4065 3990
4066 3991
4067 void LCodeGen::DoRandom(LRandom* instr) { 3992 void LCodeGen::DoRandom(LRandom* instr) {
4068 CpuFeatureScope scope(masm(), VFP2);
4069 class DeferredDoRandom: public LDeferredCode { 3993 class DeferredDoRandom: public LDeferredCode {
4070 public: 3994 public:
4071 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) 3995 DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
4072 : LDeferredCode(codegen), instr_(instr) { } 3996 : LDeferredCode(codegen), instr_(instr) { }
4073 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 3997 virtual void Generate() { codegen()->DoDeferredRandom(instr_); }
4074 virtual LInstruction* instr() { return instr_; } 3998 virtual LInstruction* instr() { return instr_; }
4075 private: 3999 private:
4076 LRandom* instr_; 4000 LRandom* instr_;
4077 }; 4001 };
4078 4002
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4137 4061
4138 4062
4139 void LCodeGen::DoDeferredRandom(LRandom* instr) { 4063 void LCodeGen::DoDeferredRandom(LRandom* instr) {
4140 __ PrepareCallCFunction(1, scratch0()); 4064 __ PrepareCallCFunction(1, scratch0());
4141 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); 4065 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
4142 // Return value is in r0. 4066 // Return value is in r0.
4143 } 4067 }
4144 4068
4145 4069
4146 void LCodeGen::DoMathExp(LMathExp* instr) { 4070 void LCodeGen::DoMathExp(LMathExp* instr) {
4147 CpuFeatureScope scope(masm(), VFP2);
4148 DwVfpRegister input = ToDoubleRegister(instr->value()); 4071 DwVfpRegister input = ToDoubleRegister(instr->value());
4149 DwVfpRegister result = ToDoubleRegister(instr->result()); 4072 DwVfpRegister result = ToDoubleRegister(instr->result());
4150 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); 4073 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
4151 DwVfpRegister double_scratch2 = double_scratch0(); 4074 DwVfpRegister double_scratch2 = double_scratch0();
4152 Register temp1 = ToRegister(instr->temp1()); 4075 Register temp1 = ToRegister(instr->temp1());
4153 Register temp2 = ToRegister(instr->temp2()); 4076 Register temp2 = ToRegister(instr->temp2());
4154 4077
4155 MathExpGenerator::EmitMathExp( 4078 MathExpGenerator::EmitMathExp(
4156 masm(), input, result, double_scratch1, double_scratch2, 4079 masm(), input, result, double_scratch1, double_scratch2,
4157 temp1, temp2, scratch0()); 4080 temp1, temp2, scratch0());
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
4435 } 4358 }
4436 __ cmp(ip, ToRegister(instr->length())); 4359 __ cmp(ip, ToRegister(instr->length()));
4437 } else { 4360 } else {
4438 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); 4361 __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
4439 } 4362 }
4440 DeoptimizeIf(hs, instr->environment()); 4363 DeoptimizeIf(hs, instr->environment());
4441 } 4364 }
4442 4365
4443 4366
4444 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4367 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4445 CpuFeatureScope scope(masm(), VFP2);
4446 Register external_pointer = ToRegister(instr->elements()); 4368 Register external_pointer = ToRegister(instr->elements());
4447 Register key = no_reg; 4369 Register key = no_reg;
4448 ElementsKind elements_kind = instr->elements_kind(); 4370 ElementsKind elements_kind = instr->elements_kind();
4449 bool key_is_constant = instr->key()->IsConstantOperand(); 4371 bool key_is_constant = instr->key()->IsConstantOperand();
4450 int constant_key = 0; 4372 int constant_key = 0;
4451 if (key_is_constant) { 4373 if (key_is_constant) {
4452 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 4374 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4453 if (constant_key & 0xF0000000) { 4375 if (constant_key & 0xF0000000) {
4454 Abort("array index constant value too big."); 4376 Abort("array index constant value too big.");
4455 } 4377 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4506 case DICTIONARY_ELEMENTS: 4428 case DICTIONARY_ELEMENTS:
4507 case NON_STRICT_ARGUMENTS_ELEMENTS: 4429 case NON_STRICT_ARGUMENTS_ELEMENTS:
4508 UNREACHABLE(); 4430 UNREACHABLE();
4509 break; 4431 break;
4510 } 4432 }
4511 } 4433 }
4512 } 4434 }
4513 4435
4514 4436
4515 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4437 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4516 CpuFeatureScope scope(masm(), VFP2);
4517 DwVfpRegister value = ToDoubleRegister(instr->value()); 4438 DwVfpRegister value = ToDoubleRegister(instr->value());
4518 Register elements = ToRegister(instr->elements()); 4439 Register elements = ToRegister(instr->elements());
4519 Register key = no_reg; 4440 Register key = no_reg;
4520 Register scratch = scratch0(); 4441 Register scratch = scratch0();
4521 bool key_is_constant = instr->key()->IsConstantOperand(); 4442 bool key_is_constant = instr->key()->IsConstantOperand();
4522 int constant_key = 0; 4443 int constant_key = 0;
4523 4444
4524 // Calculate the effective address of the slot in the array to store the 4445 // Calculate the effective address of the slot in the array to store the
4525 // double value. 4446 // double value.
4526 if (key_is_constant) { 4447 if (key_is_constant) {
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
4807 4728
4808 4729
4809 void LCodeGen::DoStringLength(LStringLength* instr) { 4730 void LCodeGen::DoStringLength(LStringLength* instr) {
4810 Register string = ToRegister(instr->string()); 4731 Register string = ToRegister(instr->string());
4811 Register result = ToRegister(instr->result()); 4732 Register result = ToRegister(instr->result());
4812 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); 4733 __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
4813 } 4734 }
4814 4735
4815 4736
4816 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4737 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4817 CpuFeatureScope scope(masm(), VFP2);
4818 LOperand* input = instr->value(); 4738 LOperand* input = instr->value();
4819 ASSERT(input->IsRegister() || input->IsStackSlot()); 4739 ASSERT(input->IsRegister() || input->IsStackSlot());
4820 LOperand* output = instr->result(); 4740 LOperand* output = instr->result();
4821 ASSERT(output->IsDoubleRegister()); 4741 ASSERT(output->IsDoubleRegister());
4822 SwVfpRegister single_scratch = double_scratch0().low(); 4742 SwVfpRegister single_scratch = double_scratch0().low();
4823 if (input->IsStackSlot()) { 4743 if (input->IsStackSlot()) {
4824 Register scratch = scratch0(); 4744 Register scratch = scratch0();
4825 __ ldr(scratch, ToMemOperand(input)); 4745 __ ldr(scratch, ToMemOperand(input));
4826 __ vmov(single_scratch, scratch); 4746 __ vmov(single_scratch, scratch);
4827 } else { 4747 } else {
4828 __ vmov(single_scratch, ToRegister(input)); 4748 __ vmov(single_scratch, ToRegister(input));
4829 } 4749 }
4830 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); 4750 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
4831 } 4751 }
4832 4752
4833 4753
4834 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4754 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4835 CpuFeatureScope scope(masm(), VFP2);
4836 LOperand* input = instr->value(); 4755 LOperand* input = instr->value();
4837 LOperand* output = instr->result(); 4756 LOperand* output = instr->result();
4838 4757
4839 SwVfpRegister flt_scratch = double_scratch0().low(); 4758 SwVfpRegister flt_scratch = double_scratch0().low();
4840 __ vmov(flt_scratch, ToRegister(input)); 4759 __ vmov(flt_scratch, ToRegister(input));
4841 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); 4760 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch);
4842 } 4761 }
4843 4762
4844 4763
4845 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4764 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4887 Register reg = ToRegister(input); 4806 Register reg = ToRegister(input);
4888 4807
4889 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4808 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4890 __ cmp(reg, Operand(Smi::kMaxValue)); 4809 __ cmp(reg, Operand(Smi::kMaxValue));
4891 __ b(hi, deferred->entry()); 4810 __ b(hi, deferred->entry());
4892 __ SmiTag(reg, reg); 4811 __ SmiTag(reg, reg);
4893 __ bind(deferred->exit()); 4812 __ bind(deferred->exit());
4894 } 4813 }
4895 4814
4896 4815
4897 // Convert unsigned integer with specified number of leading zeroes in binary
4898 // representation to IEEE 754 double.
4899 // Integer to convert is passed in register src.
4900 // Resulting double is returned in registers hiword:loword.
4901 // This functions does not work correctly for 0.
4902 static void GenerateUInt2Double(MacroAssembler* masm,
4903 Register src,
4904 Register hiword,
4905 Register loword,
4906 Register scratch,
4907 int leading_zeroes) {
4908 const int meaningful_bits = kBitsPerInt - leading_zeroes - 1;
4909 const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits;
4910
4911 const int mantissa_shift_for_hi_word =
4912 meaningful_bits - HeapNumber::kMantissaBitsInTopWord;
4913 const int mantissa_shift_for_lo_word =
4914 kBitsPerInt - mantissa_shift_for_hi_word;
4915 masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift));
4916 if (mantissa_shift_for_hi_word > 0) {
4917 masm->mov(loword, Operand(src, LSL, mantissa_shift_for_lo_word));
4918 masm->orr(hiword, scratch,
4919 Operand(src, LSR, mantissa_shift_for_hi_word));
4920 } else {
4921 masm->mov(loword, Operand::Zero());
4922 masm->orr(hiword, scratch,
4923 Operand(src, LSL, -mantissa_shift_for_hi_word));
4924 }
4925
4926 // If least significant bit of biased exponent was not 1 it was corrupted
4927 // by most significant bit of mantissa so we should fix that.
4928 if (!(biased_exponent & 1)) {
4929 masm->bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift));
4930 }
4931 }
4932
4933
4934 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 4816 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
4935 LOperand* value, 4817 LOperand* value,
4936 IntegerSignedness signedness) { 4818 IntegerSignedness signedness) {
4937 Label slow; 4819 Label slow;
4938 Register src = ToRegister(value); 4820 Register src = ToRegister(value);
4939 Register dst = ToRegister(instr->result()); 4821 Register dst = ToRegister(instr->result());
4940 DwVfpRegister dbl_scratch = double_scratch0(); 4822 DwVfpRegister dbl_scratch = double_scratch0();
4941 SwVfpRegister flt_scratch = dbl_scratch.low(); 4823 SwVfpRegister flt_scratch = dbl_scratch.low();
4942 4824
4943 // Preserve the value of all registers. 4825 // Preserve the value of all registers.
4944 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4826 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4945 4827
4946 Label done; 4828 Label done;
4947 if (signedness == SIGNED_INT32) { 4829 if (signedness == SIGNED_INT32) {
4948 // There was overflow, so bits 30 and 31 of the original integer 4830 // There was overflow, so bits 30 and 31 of the original integer
4949 // disagree. Try to allocate a heap number in new space and store 4831 // disagree. Try to allocate a heap number in new space and store
4950 // the value in there. If that fails, call the runtime system. 4832 // the value in there. If that fails, call the runtime system.
4951 if (dst.is(src)) { 4833 if (dst.is(src)) {
4952 __ SmiUntag(src, dst); 4834 __ SmiUntag(src, dst);
4953 __ eor(src, src, Operand(0x80000000)); 4835 __ eor(src, src, Operand(0x80000000));
4954 } 4836 }
4955 if (CpuFeatures::IsSupported(VFP2)) { 4837 __ vmov(flt_scratch, src);
4956 CpuFeatureScope scope(masm(), VFP2); 4838 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
4957 __ vmov(flt_scratch, src);
4958 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
4959 } else {
4960 FloatingPointHelper::Destination dest =
4961 FloatingPointHelper::kCoreRegisters;
4962 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, d0,
4963 sfpd_lo, sfpd_hi,
4964 scratch0(), s0);
4965 }
4966 } else { 4839 } else {
4967 if (CpuFeatures::IsSupported(VFP2)) { 4840 __ vmov(flt_scratch, src);
4968 CpuFeatureScope scope(masm(), VFP2); 4841 __ vcvt_f64_u32(dbl_scratch, flt_scratch);
4969 __ vmov(flt_scratch, src);
4970 __ vcvt_f64_u32(dbl_scratch, flt_scratch);
4971 } else {
4972 Label no_leading_zero, convert_done;
4973 __ tst(src, Operand(0x80000000));
4974 __ b(ne, &no_leading_zero);
4975
4976 // Integer has one leading zeros.
4977 GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 1);
4978 __ b(&convert_done);
4979
4980 __ bind(&no_leading_zero);
4981 GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 0);
4982 __ bind(&convert_done);
4983 }
4984 } 4842 }
4985 4843
4986 if (FLAG_inline_new) { 4844 if (FLAG_inline_new) {
4987 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); 4845 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex);
4988 __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT); 4846 __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT);
4989 __ Move(dst, r5); 4847 __ Move(dst, r5);
4990 __ b(&done); 4848 __ b(&done);
4991 } 4849 }
4992 4850
4993 // Slow case: Call the runtime system to do the number allocation. 4851 // Slow case: Call the runtime system to do the number allocation.
4994 __ bind(&slow); 4852 __ bind(&slow);
4995 4853
4996 // TODO(3095996): Put a valid pointer value in the stack slot where the result 4854 // TODO(3095996): Put a valid pointer value in the stack slot where the result
4997 // register is stored, as this register is in the pointer map, but contains an 4855 // register is stored, as this register is in the pointer map, but contains an
4998 // integer value. 4856 // integer value.
4999 if (!CpuFeatures::IsSupported(VFP2)) {
5000 // Preserve sfpd_lo.
5001 __ mov(r9, sfpd_lo);
5002 }
5003 __ mov(ip, Operand::Zero()); 4857 __ mov(ip, Operand::Zero());
5004 __ StoreToSafepointRegisterSlot(ip, dst); 4858 __ StoreToSafepointRegisterSlot(ip, dst);
5005 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 4859 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
5006 __ Move(dst, r0); 4860 __ Move(dst, r0);
5007 if (!CpuFeatures::IsSupported(VFP2)) {
5008 // Restore sfpd_lo.
5009 __ mov(sfpd_lo, r9);
5010 }
5011 __ sub(dst, dst, Operand(kHeapObjectTag)); 4861 __ sub(dst, dst, Operand(kHeapObjectTag));
5012 4862
5013 // Done. Put the value in dbl_scratch into the value of the allocated heap 4863 // Done. Put the value in dbl_scratch into the value of the allocated heap
5014 // number. 4864 // number.
5015 __ bind(&done); 4865 __ bind(&done);
5016 if (CpuFeatures::IsSupported(VFP2)) { 4866 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset);
5017 CpuFeatureScope scope(masm(), VFP2);
5018 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset);
5019 } else {
5020 __ str(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset));
5021 __ str(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset));
5022 }
5023 __ add(dst, dst, Operand(kHeapObjectTag)); 4867 __ add(dst, dst, Operand(kHeapObjectTag));
5024 __ StoreToSafepointRegisterSlot(dst, dst); 4868 __ StoreToSafepointRegisterSlot(dst, dst);
5025 } 4869 }
5026 4870
5027 4871
5028 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4872 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
5029 class DeferredNumberTagD: public LDeferredCode { 4873 class DeferredNumberTagD: public LDeferredCode {
5030 public: 4874 public:
5031 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4875 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
5032 : LDeferredCode(codegen), instr_(instr) { } 4876 : LDeferredCode(codegen), instr_(instr) { }
(...skipping 12 matching lines...) Expand all
5045 bool convert_hole = false; 4889 bool convert_hole = false;
5046 HValue* change_input = instr->hydrogen()->value(); 4890 HValue* change_input = instr->hydrogen()->value();
5047 if (change_input->IsLoadKeyed()) { 4891 if (change_input->IsLoadKeyed()) {
5048 HLoadKeyed* load = HLoadKeyed::cast(change_input); 4892 HLoadKeyed* load = HLoadKeyed::cast(change_input);
5049 convert_hole = load->UsesMustHandleHole(); 4893 convert_hole = load->UsesMustHandleHole();
5050 } 4894 }
5051 4895
5052 Label no_special_nan_handling; 4896 Label no_special_nan_handling;
5053 Label done; 4897 Label done;
5054 if (convert_hole) { 4898 if (convert_hole) {
5055 if (CpuFeatures::IsSupported(VFP2)) { 4899 DwVfpRegister input_reg = ToDoubleRegister(instr->value());
5056 CpuFeatureScope scope(masm(), VFP2); 4900 __ VFPCompareAndSetFlags(input_reg, input_reg);
5057 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); 4901 __ b(vc, &no_special_nan_handling);
5058 __ VFPCompareAndSetFlags(input_reg, input_reg); 4902 __ vmov(reg, scratch0(), input_reg);
5059 __ b(vc, &no_special_nan_handling); 4903 __ cmp(scratch0(), Operand(kHoleNanUpper32));
5060 __ vmov(reg, scratch0(), input_reg); 4904 Label canonicalize;
5061 __ cmp(scratch0(), Operand(kHoleNanUpper32)); 4905 __ b(ne, &canonicalize);
5062 Label canonicalize; 4906 __ Move(reg, factory()->the_hole_value());
5063 __ b(ne, &canonicalize); 4907 __ b(&done);
5064 __ Move(reg, factory()->the_hole_value()); 4908 __ bind(&canonicalize);
5065 __ b(&done); 4909 __ Vmov(input_reg,
5066 __ bind(&canonicalize); 4910 FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
5067 __ Vmov(input_reg, 4911 no_reg);
5068 FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
5069 no_reg);
5070 } else {
5071 Label not_hole;
5072 __ cmp(sfpd_hi, Operand(kHoleNanUpper32));
5073 __ b(ne, &not_hole);
5074 __ Move(reg, factory()->the_hole_value());
5075 __ b(&done);
5076 __ bind(&not_hole);
5077 __ and_(scratch, sfpd_hi, Operand(0x7ff00000));
5078 __ cmp(scratch, Operand(0x7ff00000));
5079 __ b(ne, &no_special_nan_handling);
5080 Label special_nan_handling;
5081 __ tst(sfpd_hi, Operand(0x000FFFFF));
5082 __ b(ne, &special_nan_handling);
5083 __ cmp(sfpd_lo, Operand(0));
5084 __ b(eq, &no_special_nan_handling);
5085 __ bind(&special_nan_handling);
5086 double canonical_nan =
5087 FixedDoubleArray::canonical_not_the_hole_nan_as_double();
5088 uint64_t casted_nan = BitCast<uint64_t>(canonical_nan);
5089 __ mov(sfpd_lo,
5090 Operand(static_cast<uint32_t>(casted_nan & 0xFFFFFFFF)));
5091 __ mov(sfpd_hi,
5092 Operand(static_cast<uint32_t>(casted_nan >> 32)));
5093 }
5094 } 4912 }
5095 4913
5096 __ bind(&no_special_nan_handling); 4914 __ bind(&no_special_nan_handling);
5097 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4915 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
5098 if (FLAG_inline_new) { 4916 if (FLAG_inline_new) {
5099 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4917 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
5100 // We want the untagged address first for performance 4918 // We want the untagged address first for performance
5101 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), 4919 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(),
5102 DONT_TAG_RESULT); 4920 DONT_TAG_RESULT);
5103 } else { 4921 } else {
5104 __ jmp(deferred->entry()); 4922 __ jmp(deferred->entry());
5105 } 4923 }
5106 __ bind(deferred->exit()); 4924 __ bind(deferred->exit());
5107 if (CpuFeatures::IsSupported(VFP2)) { 4925 __ vstr(input_reg, reg, HeapNumber::kValueOffset);
5108 CpuFeatureScope scope(masm(), VFP2);
5109 __ vstr(input_reg, reg, HeapNumber::kValueOffset);
5110 } else {
5111 __ str(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset));
5112 __ str(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize));
5113 }
5114 // Now that we have finished with the object's real address tag it 4926 // Now that we have finished with the object's real address tag it
5115 __ add(reg, reg, Operand(kHeapObjectTag)); 4927 __ add(reg, reg, Operand(kHeapObjectTag));
5116 __ bind(&done); 4928 __ bind(&done);
5117 } 4929 }
5118 4930
5119 4931
5120 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4932 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
5121 // TODO(3095996): Get rid of this. For now, we need to make the 4933 // TODO(3095996): Get rid of this. For now, we need to make the
5122 // result register contain a valid pointer because it is already 4934 // result register contain a valid pointer because it is already
5123 // contained in the register pointer map. 4935 // contained in the register pointer map.
(...skipping 29 matching lines...) Expand all
5153 4965
5154 void LCodeGen::EmitNumberUntagD(Register input_reg, 4966 void LCodeGen::EmitNumberUntagD(Register input_reg,
5155 DwVfpRegister result_reg, 4967 DwVfpRegister result_reg,
5156 bool deoptimize_on_undefined, 4968 bool deoptimize_on_undefined,
5157 bool deoptimize_on_minus_zero, 4969 bool deoptimize_on_minus_zero,
5158 LEnvironment* env, 4970 LEnvironment* env,
5159 NumberUntagDMode mode) { 4971 NumberUntagDMode mode) {
5160 Register scratch = scratch0(); 4972 Register scratch = scratch0();
5161 SwVfpRegister flt_scratch = double_scratch0().low(); 4973 SwVfpRegister flt_scratch = double_scratch0().low();
5162 ASSERT(!result_reg.is(double_scratch0())); 4974 ASSERT(!result_reg.is(double_scratch0()));
5163 CpuFeatureScope scope(masm(), VFP2);
5164 4975
5165 Label load_smi, heap_number, done; 4976 Label load_smi, heap_number, done;
5166 4977
5167 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 4978 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
5168 // Smi check. 4979 // Smi check.
5169 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4980 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
5170 4981
5171 // Heap number map check. 4982 // Heap number map check.
5172 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4983 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
5173 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4984 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
5242 // SmiUntag(heap_object, SetCC) 5053 // SmiUntag(heap_object, SetCC)
5243 STATIC_ASSERT(kHeapObjectTag == 1); 5054 STATIC_ASSERT(kHeapObjectTag == 1);
5244 __ adc(input_reg, input_reg, Operand(input_reg)); 5055 __ adc(input_reg, input_reg, Operand(input_reg));
5245 5056
5246 // Heap number map check. 5057 // Heap number map check.
5247 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 5058 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
5248 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 5059 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
5249 __ cmp(scratch1, Operand(ip)); 5060 __ cmp(scratch1, Operand(ip));
5250 5061
5251 if (instr->truncating()) { 5062 if (instr->truncating()) {
5252 CpuFeatureScope scope(masm(), VFP2);
5253 Register scratch3 = ToRegister(instr->temp2()); 5063 Register scratch3 = ToRegister(instr->temp2());
5254 ASSERT(!scratch3.is(input_reg) && 5064 ASSERT(!scratch3.is(input_reg) &&
5255 !scratch3.is(scratch1) && 5065 !scratch3.is(scratch1) &&
5256 !scratch3.is(scratch2)); 5066 !scratch3.is(scratch2));
5257 // Performs a truncating conversion of a floating point number as used by 5067 // Performs a truncating conversion of a floating point number as used by
5258 // the JS bitwise operations. 5068 // the JS bitwise operations.
5259 Label heap_number; 5069 Label heap_number;
5260 __ b(eq, &heap_number); 5070 __ b(eq, &heap_number);
5261 // Check for undefined. Undefined is converted to zero for truncating 5071 // Check for undefined. Undefined is converted to zero for truncating
5262 // conversions. 5072 // conversions.
5263 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 5073 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
5264 __ cmp(input_reg, Operand(ip)); 5074 __ cmp(input_reg, Operand(ip));
5265 DeoptimizeIf(ne, instr->environment()); 5075 DeoptimizeIf(ne, instr->environment());
5266 __ mov(input_reg, Operand::Zero()); 5076 __ mov(input_reg, Operand::Zero());
5267 __ b(&done); 5077 __ b(&done);
5268 5078
5269 __ bind(&heap_number); 5079 __ bind(&heap_number);
5270 __ sub(scratch1, input_reg, Operand(kHeapObjectTag)); 5080 __ sub(scratch1, input_reg, Operand(kHeapObjectTag));
5271 __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset); 5081 __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset);
5272 5082
5273 __ ECMAToInt32VFP(input_reg, double_scratch2, double_scratch, 5083 __ ECMAToInt32(input_reg, double_scratch2, double_scratch,
5274 scratch1, scratch2, scratch3); 5084 scratch1, scratch2, scratch3);
5275 5085
5276 } else { 5086 } else {
5277 CpuFeatureScope scope(masm(), VFP3); 5087 CpuFeatureScope scope(masm(), VFP3);
5278 // Deoptimize if we don't have a heap number. 5088 // Deoptimize if we don't have a heap number.
5279 DeoptimizeIf(ne, instr->environment()); 5089 DeoptimizeIf(ne, instr->environment());
5280 5090
5281 __ sub(ip, input_reg, Operand(kHeapObjectTag)); 5091 __ sub(ip, input_reg, Operand(kHeapObjectTag));
5282 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); 5092 __ vldr(double_scratch, ip, HeapNumber::kValueOffset);
5283 __ TryDoubleToInt32Exact(input_reg, double_scratch, double_scratch2); 5093 __ TryDoubleToInt32Exact(input_reg, double_scratch, double_scratch2);
5284 DeoptimizeIf(ne, instr->environment()); 5094 DeoptimizeIf(ne, instr->environment());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
5362 Register result_reg = ToRegister(instr->result()); 5172 Register result_reg = ToRegister(instr->result());
5363 Register scratch1 = scratch0(); 5173 Register scratch1 = scratch0();
5364 Register scratch2 = ToRegister(instr->temp()); 5174 Register scratch2 = ToRegister(instr->temp());
5365 DwVfpRegister double_input = ToDoubleRegister(instr->value()); 5175 DwVfpRegister double_input = ToDoubleRegister(instr->value());
5366 DwVfpRegister double_scratch = double_scratch0(); 5176 DwVfpRegister double_scratch = double_scratch0();
5367 5177
5368 Label done; 5178 Label done;
5369 5179
5370 if (instr->truncating()) { 5180 if (instr->truncating()) {
5371 Register scratch3 = ToRegister(instr->temp2()); 5181 Register scratch3 = ToRegister(instr->temp2());
5372 __ ECMAToInt32VFP(result_reg, double_input, double_scratch, 5182 __ ECMAToInt32(result_reg, double_input, double_scratch,
5373 scratch1, scratch2, scratch3); 5183 scratch1, scratch2, scratch3);
5374 } else { 5184 } else {
5375 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); 5185 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
5376 // Deoptimize if the input wasn't a int32 (inside a double). 5186 // Deoptimize if the input wasn't a int32 (inside a double).
5377 DeoptimizeIf(ne, instr->environment()); 5187 DeoptimizeIf(ne, instr->environment());
5378 } 5188 }
5379 __ bind(&done); 5189 __ bind(&done);
5380 } 5190 }
5381 5191
5382 5192
5383 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5193 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
5479 __ CompareMap(map_reg, map, &success, REQUIRE_EXACT_MAP); 5289 __ CompareMap(map_reg, map, &success, REQUIRE_EXACT_MAP);
5480 __ b(eq, &success); 5290 __ b(eq, &success);
5481 } 5291 }
5482 Handle<Map> map = map_set->last(); 5292 Handle<Map> map = map_set->last();
5483 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); 5293 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment());
5484 __ bind(&success); 5294 __ bind(&success);
5485 } 5295 }
5486 5296
5487 5297
5488 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5298 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5489 CpuFeatureScope vfp_scope(masm(), VFP2);
5490 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped()); 5299 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped());
5491 Register result_reg = ToRegister(instr->result()); 5300 Register result_reg = ToRegister(instr->result());
5492 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); 5301 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp());
5493 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); 5302 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
5494 } 5303 }
5495 5304
5496 5305
5497 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5306 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5498 CpuFeatureScope scope(masm(), VFP2);
5499 Register unclamped_reg = ToRegister(instr->unclamped()); 5307 Register unclamped_reg = ToRegister(instr->unclamped());
5500 Register result_reg = ToRegister(instr->result()); 5308 Register result_reg = ToRegister(instr->result());
5501 __ ClampUint8(result_reg, unclamped_reg); 5309 __ ClampUint8(result_reg, unclamped_reg);
5502 } 5310 }
5503 5311
5504 5312
5505 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 5313 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5506 CpuFeatureScope scope(masm(), VFP2);
5507 Register scratch = scratch0(); 5314 Register scratch = scratch0();
5508 Register input_reg = ToRegister(instr->unclamped()); 5315 Register input_reg = ToRegister(instr->unclamped());
5509 Register result_reg = ToRegister(instr->result()); 5316 Register result_reg = ToRegister(instr->result());
5510 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); 5317 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp());
5511 Label is_smi, done, heap_number; 5318 Label is_smi, done, heap_number;
5512 5319
5513 // Both smi and heap number cases are handled. 5320 // Both smi and heap number cases are handled.
5514 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); 5321 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi);
5515 5322
5516 // Check for heap number 5323 // Check for heap number
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
6397 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 6204 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
6398 __ ldr(result, FieldMemOperand(scratch, 6205 __ ldr(result, FieldMemOperand(scratch,
6399 FixedArray::kHeaderSize - kPointerSize)); 6206 FixedArray::kHeaderSize - kPointerSize));
6400 __ bind(&done); 6207 __ bind(&done);
6401 } 6208 }
6402 6209
6403 6210
6404 #undef __ 6211 #undef __
6405 6212
6406 } } // namespace v8::internal 6213 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-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