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

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

Issue 19560003: [v8-dev] ARM: Make double registers low/high safe (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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
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 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 Register left_reg = ToRegister(instr->left()); 1171 Register left_reg = ToRegister(instr->left());
1172 Register right_reg = ToRegister(instr->right()); 1172 Register right_reg = ToRegister(instr->right());
1173 Register result_reg = ToRegister(instr->result()); 1173 Register result_reg = ToRegister(instr->result());
1174 Register scratch = scratch0(); 1174 Register scratch = scratch0();
1175 ASSERT(!scratch.is(left_reg)); 1175 ASSERT(!scratch.is(left_reg));
1176 ASSERT(!scratch.is(right_reg)); 1176 ASSERT(!scratch.is(right_reg));
1177 ASSERT(!scratch.is(result_reg)); 1177 ASSERT(!scratch.is(result_reg));
1178 DwVfpRegister dividend = ToDoubleRegister(instr->temp()); 1178 DwVfpRegister dividend = ToDoubleRegister(instr->temp());
1179 DwVfpRegister divisor = ToDoubleRegister(instr->temp2()); 1179 DwVfpRegister divisor = ToDoubleRegister(instr->temp2());
1180 ASSERT(!divisor.is(dividend)); 1180 ASSERT(!divisor.is(dividend));
1181 DwVfpRegister quotient = double_scratch0(); 1181 LowDwVfpRegister quotient = double_scratch0();
1182 ASSERT(!quotient.is(dividend)); 1182 ASSERT(!quotient.is(dividend));
1183 ASSERT(!quotient.is(divisor)); 1183 ASSERT(!quotient.is(divisor));
1184 1184
1185 Label done; 1185 Label done;
1186 // Check for x % 0, we have to deopt in this case because we can't return a 1186 // Check for x % 0, we have to deopt in this case because we can't return a
1187 // NaN. 1187 // NaN.
1188 if (right->CanBeZero()) { 1188 if (right->CanBeZero()) {
1189 __ cmp(right_reg, Operand::Zero()); 1189 __ cmp(right_reg, Operand::Zero());
1190 DeoptimizeIf(eq, instr->environment()); 1190 DeoptimizeIf(eq, instr->environment());
1191 } 1191 }
1192 1192
1193 __ Move(result_reg, left_reg); 1193 __ Move(result_reg, left_reg);
1194 // Load the arguments in VFP registers. The divisor value is preloaded 1194 // Load the arguments in VFP registers. The divisor value is preloaded
1195 // before. Be careful that 'right_reg' is only live on entry. 1195 // before. Be careful that 'right_reg' is only live on entry.
1196 // TODO(svenpanne) The last comments seems to be wrong nowadays. 1196 // TODO(svenpanne) The last comments seems to be wrong nowadays.
1197 __ vmov(dividend.low(), left_reg); 1197 __ vmov(double_scratch0().low(), left_reg);
1198 __ vmov(divisor.low(), right_reg); 1198 __ vcvt_f64_s32(dividend, double_scratch0().low());
1199 1199 __ vmov(double_scratch0().low(), right_reg);
1200 __ vcvt_f64_s32(dividend, dividend.low()); 1200 __ vcvt_f64_s32(divisor, double_scratch0().low());
1201 __ vcvt_f64_s32(divisor, divisor.low());
1202 1201
1203 // We do not care about the sign of the divisor. Note that we still handle 1202 // We do not care about the sign of the divisor. Note that we still handle
1204 // the kMinInt % -1 case correctly, though. 1203 // the kMinInt % -1 case correctly, though.
1205 __ vabs(divisor, divisor); 1204 __ vabs(divisor, divisor);
1206 // Compute the quotient and round it to a 32bit integer. 1205 // Compute the quotient and round it to a 32bit integer.
1207 __ vdiv(quotient, dividend, divisor); 1206 __ vdiv(quotient, dividend, divisor);
1208 __ vcvt_s32_f64(quotient.low(), quotient); 1207 __ vcvt_s32_f64(quotient.low(), quotient);
1209 __ vcvt_f64_s32(quotient, quotient.low()); 1208 __ vcvt_f64_s32(quotient, quotient.low());
1210 1209
1211 // Compute the remainder in result. 1210 // Compute the remainder in result.
1212 DwVfpRegister double_scratch = dividend; 1211 __ vmul(double_scratch0(), divisor, quotient);
1213 __ vmul(double_scratch, divisor, quotient); 1212 __ vcvt_s32_f64(double_scratch0().low(), double_scratch0());
1214 __ vcvt_s32_f64(double_scratch.low(), double_scratch); 1213 __ vmov(scratch, double_scratch0().low());
1215 __ vmov(scratch, double_scratch.low());
1216 __ sub(result_reg, left_reg, scratch, SetCC); 1214 __ sub(result_reg, left_reg, scratch, SetCC);
1217 1215
1218 // If we care about -0, test if the dividend is <0 and the result is 0. 1216 // If we care about -0, test if the dividend is <0 and the result is 0.
1219 if (left->CanBeNegative() && 1217 if (left->CanBeNegative() &&
1220 hmod->CanBeZero() && 1218 hmod->CanBeZero() &&
1221 hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1219 hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1222 __ b(ne, &done); 1220 __ b(ne, &done);
1223 __ cmp(left_reg, Operand::Zero()); 1221 __ cmp(left_reg, Operand::Zero());
1224 DeoptimizeIf(mi, instr->environment()); 1222 DeoptimizeIf(mi, instr->environment());
1225 } 1223 }
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 HInstruction::kAllUsesTruncatingToInt32)) { 1403 HInstruction::kAllUsesTruncatingToInt32)) {
1406 // Compute remainder and deopt if it's not zero. 1404 // Compute remainder and deopt if it's not zero.
1407 const Register remainder = scratch0(); 1405 const Register remainder = scratch0();
1408 __ mls(remainder, result, right, left); 1406 __ mls(remainder, result, right, left);
1409 __ cmp(remainder, Operand::Zero()); 1407 __ cmp(remainder, Operand::Zero());
1410 DeoptimizeIf(ne, instr->environment()); 1408 DeoptimizeIf(ne, instr->environment());
1411 } 1409 }
1412 } else { 1410 } else {
1413 const DoubleRegister vleft = ToDoubleRegister(instr->temp()); 1411 const DoubleRegister vleft = ToDoubleRegister(instr->temp());
1414 const DoubleRegister vright = double_scratch0(); 1412 const DoubleRegister vright = double_scratch0();
1415 __ vmov(vleft.low(), left); 1413 __ vmov(double_scratch0().low(), left);
1416 __ vmov(vright.low(), right); 1414 __ vcvt_f64_s32(vleft, double_scratch0().low());
1417 __ vcvt_f64_s32(vleft, vleft.low()); 1415 __ vmov(double_scratch0().low(), right);
1418 __ vcvt_f64_s32(vright, vright.low()); 1416 __ vcvt_f64_s32(vright, double_scratch0().low());
1419 __ vdiv(vleft, vleft, vright); // vleft now contains the result. 1417 __ vdiv(vleft, vleft, vright); // vleft now contains the result.
1420 __ vcvt_s32_f64(vright.low(), vleft); 1418 __ vcvt_s32_f64(double_scratch0().low(), vleft);
1421 __ vmov(result, vright.low()); 1419 __ vmov(result, double_scratch0().low());
1422 1420
1423 if (!instr->hydrogen()->CheckFlag( 1421 if (!instr->hydrogen()->CheckFlag(
1424 HInstruction::kAllUsesTruncatingToInt32)) { 1422 HInstruction::kAllUsesTruncatingToInt32)) {
1425 // Deopt if exact conversion to integer was not possible. 1423 // Deopt if exact conversion to integer was not possible.
1426 // Use vright as scratch register. 1424 // Use vright as scratch register.
1427 __ vcvt_f64_s32(vright, vright.low()); 1425 __ vcvt_f64_s32(double_scratch0(), double_scratch0().low());
1428 __ VFPCompareAndSetFlags(vleft, vright); 1426 __ VFPCompareAndSetFlags(vleft, double_scratch0());
1429 DeoptimizeIf(ne, instr->environment()); 1427 DeoptimizeIf(ne, instr->environment());
1430 } 1428 }
1431 } 1429 }
1432 } 1430 }
1433 1431
1434 1432
1435 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { 1433 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
1436 DwVfpRegister addend = ToDoubleRegister(instr->addend()); 1434 DwVfpRegister addend = ToDoubleRegister(instr->addend());
1437 DwVfpRegister multiplier = ToDoubleRegister(instr->multiplier()); 1435 DwVfpRegister multiplier = ToDoubleRegister(instr->multiplier());
1438 DwVfpRegister multiplicand = ToDoubleRegister(instr->multiplicand()); 1436 DwVfpRegister multiplicand = ToDoubleRegister(instr->multiplicand());
(...skipping 1740 matching lines...) Expand 10 before | Expand all | Expand 10 after
3179 int additional_offset = instr->additional_index() << element_size_shift; 3177 int additional_offset = instr->additional_index() << element_size_shift;
3180 3178
3181 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3179 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3182 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3180 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3183 DwVfpRegister result = ToDoubleRegister(instr->result()); 3181 DwVfpRegister result = ToDoubleRegister(instr->result());
3184 Operand operand = key_is_constant 3182 Operand operand = key_is_constant
3185 ? Operand(constant_key << element_size_shift) 3183 ? Operand(constant_key << element_size_shift)
3186 : Operand(key, LSL, shift_size); 3184 : Operand(key, LSL, shift_size);
3187 __ add(scratch0(), external_pointer, operand); 3185 __ add(scratch0(), external_pointer, operand);
3188 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3186 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3189 __ vldr(kScratchDoubleReg.low(), scratch0(), additional_offset); 3187 __ vldr(double_scratch0().low(), scratch0(), additional_offset);
3190 __ vcvt_f64_f32(result, kScratchDoubleReg.low()); 3188 __ vcvt_f64_f32(result, double_scratch0().low());
3191 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 3189 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3192 __ vldr(result, scratch0(), additional_offset); 3190 __ vldr(result, scratch0(), additional_offset);
3193 } 3191 }
3194 } else { 3192 } else {
3195 Register result = ToRegister(instr->result()); 3193 Register result = ToRegister(instr->result());
3196 MemOperand mem_operand = PrepareKeyedOperand( 3194 MemOperand mem_operand = PrepareKeyedOperand(
3197 key, external_pointer, key_is_constant, constant_key, 3195 key, external_pointer, key_is_constant, constant_key,
3198 element_size_shift, shift_size, 3196 element_size_shift, shift_size,
3199 instr->additional_index(), additional_offset); 3197 instr->additional_index(), additional_offset);
3200 switch (elements_kind) { 3198 switch (elements_kind) {
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
3748 } 3746 }
3749 } 3747 }
3750 3748
3751 3749
3752 void LCodeGen::DoMathFloor(LMathFloor* instr) { 3750 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3753 DwVfpRegister input = ToDoubleRegister(instr->value()); 3751 DwVfpRegister input = ToDoubleRegister(instr->value());
3754 Register result = ToRegister(instr->result()); 3752 Register result = ToRegister(instr->result());
3755 Register input_high = scratch0(); 3753 Register input_high = scratch0();
3756 Label done, exact; 3754 Label done, exact;
3757 3755
3758 __ vmov(input_high, input.high());
3759 __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact); 3756 __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact);
3760 DeoptimizeIf(al, instr->environment()); 3757 DeoptimizeIf(al, instr->environment());
3761 3758
3762 __ bind(&exact); 3759 __ bind(&exact);
3763 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3760 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3764 // Test for -0. 3761 // Test for -0.
3765 __ cmp(result, Operand::Zero()); 3762 __ cmp(result, Operand::Zero());
3766 __ b(ne, &done); 3763 __ b(ne, &done);
3767 __ cmp(input_high, Operand::Zero()); 3764 __ cmp(input_high, Operand::Zero());
3768 DeoptimizeIf(mi, instr->environment()); 3765 DeoptimizeIf(mi, instr->environment());
(...skipping 12 matching lines...) Expand all
3781 Label convert, done; 3778 Label convert, done;
3782 3779
3783 __ Vmov(dot_five, 0.5, scratch0()); 3780 __ Vmov(dot_five, 0.5, scratch0());
3784 __ vabs(double_scratch1, input); 3781 __ vabs(double_scratch1, input);
3785 __ VFPCompareAndSetFlags(double_scratch1, dot_five); 3782 __ VFPCompareAndSetFlags(double_scratch1, dot_five);
3786 // If input is in [-0.5, -0], the result is -0. 3783 // If input is in [-0.5, -0], the result is -0.
3787 // If input is in [+0, +0.5[, the result is +0. 3784 // If input is in [+0, +0.5[, the result is +0.
3788 // If the input is +0.5, the result is 1. 3785 // If the input is +0.5, the result is 1.
3789 __ b(hi, &convert); // Out of [-0.5, +0.5]. 3786 __ b(hi, &convert); // Out of [-0.5, +0.5].
3790 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3787 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3791 __ vmov(input_high, input.high()); 3788 __ VmovHigh(input_high, input);
3792 __ cmp(input_high, Operand::Zero()); 3789 __ cmp(input_high, Operand::Zero());
3793 DeoptimizeIf(mi, instr->environment()); // [-0.5, -0]. 3790 DeoptimizeIf(mi, instr->environment()); // [-0.5, -0].
3794 } 3791 }
3795 __ VFPCompareAndSetFlags(input, dot_five); 3792 __ VFPCompareAndSetFlags(input, dot_five);
3796 __ mov(result, Operand(1), LeaveCC, eq); // +0.5. 3793 __ mov(result, Operand(1), LeaveCC, eq); // +0.5.
3797 // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on 3794 // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on
3798 // flag kBailoutOnMinusZero. 3795 // flag kBailoutOnMinusZero.
3799 __ mov(result, Operand::Zero(), LeaveCC, ne); 3796 __ mov(result, Operand::Zero(), LeaveCC, ne);
3800 __ b(&done); 3797 __ b(&done);
3801 3798
3802 __ bind(&convert); 3799 __ bind(&convert);
3803 __ vadd(input_plus_dot_five, input, dot_five); 3800 __ vadd(input_plus_dot_five, input, dot_five);
3804 __ vmov(input_high, input_plus_dot_five.high());
3805 // Reuse dot_five (double_scratch0) as we no longer need this value. 3801 // Reuse dot_five (double_scratch0) as we no longer need this value.
3806 __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(), 3802 __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(),
3807 &done, &done); 3803 &done, &done);
3808 DeoptimizeIf(al, instr->environment()); 3804 DeoptimizeIf(al, instr->environment());
3809 __ bind(&done); 3805 __ bind(&done);
3810 } 3806 }
3811 3807
3812 3808
3813 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { 3809 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3814 DwVfpRegister input = ToDoubleRegister(instr->value()); 3810 DwVfpRegister input = ToDoubleRegister(instr->value());
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
4717 __ bind(deferred->exit()); 4713 __ bind(deferred->exit());
4718 } 4714 }
4719 4715
4720 4716
4721 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 4717 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
4722 LOperand* value, 4718 LOperand* value,
4723 IntegerSignedness signedness) { 4719 IntegerSignedness signedness) {
4724 Label slow; 4720 Label slow;
4725 Register src = ToRegister(value); 4721 Register src = ToRegister(value);
4726 Register dst = ToRegister(instr->result()); 4722 Register dst = ToRegister(instr->result());
4727 DwVfpRegister dbl_scratch = double_scratch0(); 4723 LowDwVfpRegister dbl_scratch = double_scratch0();
4728 SwVfpRegister flt_scratch = dbl_scratch.low();
4729 4724
4730 // Preserve the value of all registers. 4725 // Preserve the value of all registers.
4731 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4726 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4732 4727
4733 Label done; 4728 Label done;
4734 if (signedness == SIGNED_INT32) { 4729 if (signedness == SIGNED_INT32) {
4735 // There was overflow, so bits 30 and 31 of the original integer 4730 // There was overflow, so bits 30 and 31 of the original integer
4736 // disagree. Try to allocate a heap number in new space and store 4731 // disagree. Try to allocate a heap number in new space and store
4737 // the value in there. If that fails, call the runtime system. 4732 // the value in there. If that fails, call the runtime system.
4738 if (dst.is(src)) { 4733 if (dst.is(src)) {
4739 __ SmiUntag(src, dst); 4734 __ SmiUntag(src, dst);
4740 __ eor(src, src, Operand(0x80000000)); 4735 __ eor(src, src, Operand(0x80000000));
4741 } 4736 }
4742 __ vmov(flt_scratch, src); 4737 __ vmov(dbl_scratch.low(), src);
4743 __ vcvt_f64_s32(dbl_scratch, flt_scratch); 4738 __ vcvt_f64_s32(dbl_scratch, dbl_scratch.low());
4744 } else { 4739 } else {
4745 __ vmov(flt_scratch, src); 4740 __ vmov(dbl_scratch.low(), src);
4746 __ vcvt_f64_u32(dbl_scratch, flt_scratch); 4741 __ vcvt_f64_u32(dbl_scratch, dbl_scratch.low());
4747 } 4742 }
4748 4743
4749 if (FLAG_inline_new) { 4744 if (FLAG_inline_new) {
4750 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); 4745 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex);
4751 __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT); 4746 __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT);
4752 __ Move(dst, r5); 4747 __ Move(dst, r5);
4753 __ b(&done); 4748 __ b(&done);
4754 } 4749 }
4755 4750
4756 // Slow case: Call the runtime system to do the number allocation. 4751 // Slow case: Call the runtime system to do the number allocation.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4797 HLoadKeyed* load = HLoadKeyed::cast(change_input); 4792 HLoadKeyed* load = HLoadKeyed::cast(change_input);
4798 convert_hole = load->UsesMustHandleHole(); 4793 convert_hole = load->UsesMustHandleHole();
4799 } 4794 }
4800 4795
4801 Label no_special_nan_handling; 4796 Label no_special_nan_handling;
4802 Label done; 4797 Label done;
4803 if (convert_hole) { 4798 if (convert_hole) {
4804 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); 4799 DwVfpRegister input_reg = ToDoubleRegister(instr->value());
4805 __ VFPCompareAndSetFlags(input_reg, input_reg); 4800 __ VFPCompareAndSetFlags(input_reg, input_reg);
4806 __ b(vc, &no_special_nan_handling); 4801 __ b(vc, &no_special_nan_handling);
4807 __ vmov(scratch, input_reg.high()); 4802 __ VmovHigh(scratch, input_reg);
4808 __ cmp(scratch, Operand(kHoleNanUpper32)); 4803 __ cmp(scratch, Operand(kHoleNanUpper32));
4809 // If not the hole NaN, force the NaN to be canonical. 4804 // If not the hole NaN, force the NaN to be canonical.
4810 __ VFPCanonicalizeNaN(input_reg, ne); 4805 __ VFPCanonicalizeNaN(input_reg, ne);
4811 __ b(ne, &no_special_nan_handling); 4806 __ b(ne, &no_special_nan_handling);
4812 __ Move(reg, factory()->the_hole_value()); 4807 __ Move(reg, factory()->the_hole_value());
4813 __ b(&done); 4808 __ b(&done);
4814 } 4809 }
4815 4810
4816 __ bind(&no_special_nan_handling); 4811 __ bind(&no_special_nan_handling);
4817 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4812 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4897 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 4892 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
4898 __ cmp(input_reg, Operand(ip)); 4893 __ cmp(input_reg, Operand(ip));
4899 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) { 4894 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) {
4900 __ b(eq, &convert); 4895 __ b(eq, &convert);
4901 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 4896 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
4902 __ cmp(input_reg, Operand(ip)); 4897 __ cmp(input_reg, Operand(ip));
4903 } 4898 }
4904 DeoptimizeIf(ne, env); 4899 DeoptimizeIf(ne, env);
4905 4900
4906 __ bind(&convert); 4901 __ bind(&convert);
4907 __ LoadRoot(ip, Heap::kNanValueRootIndex); 4902 __ LoadRoot(scratch, Heap::kNanValueRootIndex);
4908 __ sub(ip, ip, Operand(kHeapObjectTag)); 4903 __ vldr(result_reg, scratch, HeapNumber::kValueOffset - kHeapObjectTag);
4909 __ vldr(result_reg, ip, HeapNumber::kValueOffset);
4910 __ jmp(&done); 4904 __ jmp(&done);
4911 4905
4912 __ bind(&heap_number); 4906 __ bind(&heap_number);
4913 } 4907 }
4914 // Heap number to double register conversion. 4908 // Heap number to double register conversion.
4915 __ sub(ip, input_reg, Operand(kHeapObjectTag)); 4909 __ vldr(result_reg, input_reg, HeapNumber::kValueOffset - kHeapObjectTag);
4916 __ vldr(result_reg, ip, HeapNumber::kValueOffset);
4917 if (deoptimize_on_minus_zero) { 4910 if (deoptimize_on_minus_zero) {
4918 __ vmov(ip, result_reg.low()); 4911 __ VmovLow(scratch, result_reg);
4919 __ cmp(ip, Operand::Zero()); 4912 __ cmp(scratch, Operand::Zero());
4920 __ b(ne, &done); 4913 __ b(ne, &done);
4921 __ vmov(ip, result_reg.high()); 4914 __ VmovHigh(scratch, result_reg);
4922 __ cmp(ip, Operand(HeapNumber::kSignMask)); 4915 __ cmp(scratch, Operand(HeapNumber::kSignMask));
4923 DeoptimizeIf(eq, env); 4916 DeoptimizeIf(eq, env);
4924 } 4917 }
4925 __ jmp(&done); 4918 __ jmp(&done);
4926 } else { 4919 } else {
4927 __ SmiUntag(scratch, input_reg); 4920 __ SmiUntag(scratch, input_reg);
4928 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 4921 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
4929 } 4922 }
4930 4923
4931 // Smi to double register conversion 4924 // Smi to double register conversion
4932 __ bind(&load_smi); 4925 __ bind(&load_smi);
4933 // scratch: untagged value of input_reg 4926 // scratch: untagged value of input_reg
4934 __ vmov(flt_scratch, scratch); 4927 __ vmov(flt_scratch, scratch);
4935 __ vcvt_f64_s32(result_reg, flt_scratch); 4928 __ vcvt_f64_s32(result_reg, flt_scratch);
4936 __ bind(&done); 4929 __ bind(&done);
4937 } 4930 }
4938 4931
4939 4932
4940 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 4933 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4941 Register input_reg = ToRegister(instr->value()); 4934 Register input_reg = ToRegister(instr->value());
4942 Register scratch1 = scratch0(); 4935 Register scratch1 = scratch0();
4943 Register scratch2 = ToRegister(instr->temp()); 4936 Register scratch2 = ToRegister(instr->temp());
4944 DwVfpRegister double_scratch = double_scratch0(); 4937 LowDwVfpRegister double_scratch = double_scratch0();
4945 DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp3()); 4938 DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp3());
4946 4939
4947 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); 4940 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
4948 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); 4941 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
4949 4942
4950 Label done; 4943 Label done;
4951 4944
4952 // The input was optimistically untagged; revert it. 4945 // The input was optimistically untagged; revert it.
4953 // The carry flag is set when we reach this deferred code as we just executed 4946 // The carry flag is set when we reach this deferred code as we just executed
4954 // SmiUntag(heap_object, SetCC) 4947 // SmiUntag(heap_object, SetCC)
(...skipping 27 matching lines...) Expand all
4982 __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset); 4975 __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset);
4983 4976
4984 __ ECMAToInt32(input_reg, double_scratch2, 4977 __ ECMAToInt32(input_reg, double_scratch2,
4985 scratch1, scratch2, scratch3, double_scratch); 4978 scratch1, scratch2, scratch3, double_scratch);
4986 4979
4987 } else { 4980 } else {
4988 // Deoptimize if we don't have a heap number. 4981 // Deoptimize if we don't have a heap number.
4989 DeoptimizeIf(ne, instr->environment()); 4982 DeoptimizeIf(ne, instr->environment());
4990 4983
4991 __ sub(ip, input_reg, Operand(kHeapObjectTag)); 4984 __ sub(ip, input_reg, Operand(kHeapObjectTag));
4992 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); 4985 __ vldr(double_scratch2, ip, HeapNumber::kValueOffset);
4993 __ TryDoubleToInt32Exact(input_reg, double_scratch, double_scratch2); 4986 __ TryDoubleToInt32Exact(input_reg, double_scratch2, double_scratch);
4994 DeoptimizeIf(ne, instr->environment()); 4987 DeoptimizeIf(ne, instr->environment());
4995 4988
4996 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 4989 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4997 __ cmp(input_reg, Operand::Zero()); 4990 __ cmp(input_reg, Operand::Zero());
4998 __ b(ne, &done); 4991 __ b(ne, &done);
4999 __ vmov(scratch1, double_scratch.high()); 4992 __ VmovHigh(scratch1, double_scratch2);
5000 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 4993 __ tst(scratch1, Operand(HeapNumber::kSignMask));
5001 DeoptimizeIf(ne, instr->environment()); 4994 DeoptimizeIf(ne, instr->environment());
5002 } 4995 }
5003 } 4996 }
5004 __ bind(&done); 4997 __ bind(&done);
5005 } 4998 }
5006 4999
5007 5000
5008 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 5001 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
5009 class DeferredTaggedToI: public LDeferredCode { 5002 class DeferredTaggedToI: public LDeferredCode {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
5062 instr->environment(), 5055 instr->environment(),
5063 mode); 5056 mode);
5064 } 5057 }
5065 5058
5066 5059
5067 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 5060 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5068 Register result_reg = ToRegister(instr->result()); 5061 Register result_reg = ToRegister(instr->result());
5069 Register scratch1 = scratch0(); 5062 Register scratch1 = scratch0();
5070 Register scratch2 = ToRegister(instr->temp()); 5063 Register scratch2 = ToRegister(instr->temp());
5071 DwVfpRegister double_input = ToDoubleRegister(instr->value()); 5064 DwVfpRegister double_input = ToDoubleRegister(instr->value());
5072 DwVfpRegister double_scratch = double_scratch0(); 5065 LowDwVfpRegister double_scratch = double_scratch0();
5073 5066
5074 if (instr->truncating()) { 5067 if (instr->truncating()) {
5075 Register scratch3 = ToRegister(instr->temp2()); 5068 Register scratch3 = ToRegister(instr->temp2());
5076 __ ECMAToInt32(result_reg, double_input, 5069 __ ECMAToInt32(result_reg, double_input,
5077 scratch1, scratch2, scratch3, double_scratch); 5070 scratch1, scratch2, scratch3, double_scratch);
5078 } else { 5071 } else {
5079 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); 5072 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
5080 // Deoptimize if the input wasn't a int32 (inside a double). 5073 // Deoptimize if the input wasn't a int32 (inside a double).
5081 DeoptimizeIf(ne, instr->environment()); 5074 DeoptimizeIf(ne, instr->environment());
5082 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5075 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5083 Label done; 5076 Label done;
5084 __ cmp(result_reg, Operand::Zero()); 5077 __ cmp(result_reg, Operand::Zero());
5085 __ b(ne, &done); 5078 __ b(ne, &done);
5086 __ vmov(scratch1, double_input.high()); 5079 __ VmovHigh(scratch1, double_input);
5087 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 5080 __ tst(scratch1, Operand(HeapNumber::kSignMask));
5088 DeoptimizeIf(ne, instr->environment()); 5081 DeoptimizeIf(ne, instr->environment());
5089 __ bind(&done); 5082 __ bind(&done);
5090 } 5083 }
5091 } 5084 }
5092 } 5085 }
5093 5086
5094 5087
5095 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5088 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5096 Register result_reg = ToRegister(instr->result()); 5089 Register result_reg = ToRegister(instr->result());
5097 Register scratch1 = scratch0(); 5090 Register scratch1 = scratch0();
5098 Register scratch2 = ToRegister(instr->temp()); 5091 Register scratch2 = ToRegister(instr->temp());
5099 DwVfpRegister double_input = ToDoubleRegister(instr->value()); 5092 DwVfpRegister double_input = ToDoubleRegister(instr->value());
5100 DwVfpRegister double_scratch = double_scratch0(); 5093 LowDwVfpRegister double_scratch = double_scratch0();
5101 5094
5102 if (instr->truncating()) { 5095 if (instr->truncating()) {
5103 Register scratch3 = ToRegister(instr->temp2()); 5096 Register scratch3 = ToRegister(instr->temp2());
5104 __ ECMAToInt32(result_reg, double_input, 5097 __ ECMAToInt32(result_reg, double_input,
5105 scratch1, scratch2, scratch3, double_scratch); 5098 scratch1, scratch2, scratch3, double_scratch);
5106 } else { 5099 } else {
5107 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); 5100 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
5108 // Deoptimize if the input wasn't a int32 (inside a double). 5101 // Deoptimize if the input wasn't a int32 (inside a double).
5109 DeoptimizeIf(ne, instr->environment()); 5102 DeoptimizeIf(ne, instr->environment());
5110 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5103 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5111 Label done; 5104 Label done;
5112 __ cmp(result_reg, Operand::Zero()); 5105 __ cmp(result_reg, Operand::Zero());
5113 __ b(ne, &done); 5106 __ b(ne, &done);
5114 __ vmov(scratch1, double_input.high()); 5107 __ VmovHigh(scratch1, double_input);
5115 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 5108 __ tst(scratch1, Operand(HeapNumber::kSignMask));
5116 DeoptimizeIf(ne, instr->environment()); 5109 DeoptimizeIf(ne, instr->environment());
5117 __ bind(&done); 5110 __ bind(&done);
5118 } 5111 }
5119 } 5112 }
5120 __ SmiTag(result_reg, SetCC); 5113 __ SmiTag(result_reg, SetCC);
5121 DeoptimizeIf(vs, instr->environment()); 5114 DeoptimizeIf(vs, instr->environment());
5122 } 5115 }
5123 5116
5124 5117
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
5225 } 5218 }
5226 Handle<Map> map = map_set->last(); 5219 Handle<Map> map = map_set->last();
5227 DoCheckMapCommon(map_reg, map, instr->environment()); 5220 DoCheckMapCommon(map_reg, map, instr->environment());
5228 __ bind(&success); 5221 __ bind(&success);
5229 } 5222 }
5230 5223
5231 5224
5232 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5225 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5233 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped()); 5226 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped());
5234 Register result_reg = ToRegister(instr->result()); 5227 Register result_reg = ToRegister(instr->result());
5235 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); 5228 __ ClampDoubleToUint8(result_reg, value_reg, double_scratch0());
5236 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
5237 } 5229 }
5238 5230
5239 5231
5240 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5232 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5241 Register unclamped_reg = ToRegister(instr->unclamped()); 5233 Register unclamped_reg = ToRegister(instr->unclamped());
5242 Register result_reg = ToRegister(instr->result()); 5234 Register result_reg = ToRegister(instr->result());
5243 __ ClampUint8(result_reg, unclamped_reg); 5235 __ ClampUint8(result_reg, unclamped_reg);
5244 } 5236 }
5245 5237
5246 5238
(...skipping 14 matching lines...) Expand all
5261 5253
5262 // Check for undefined. Undefined is converted to zero for clamping 5254 // Check for undefined. Undefined is converted to zero for clamping
5263 // conversions. 5255 // conversions.
5264 __ cmp(input_reg, Operand(factory()->undefined_value())); 5256 __ cmp(input_reg, Operand(factory()->undefined_value()));
5265 DeoptimizeIf(ne, instr->environment()); 5257 DeoptimizeIf(ne, instr->environment());
5266 __ mov(result_reg, Operand::Zero()); 5258 __ mov(result_reg, Operand::Zero());
5267 __ jmp(&done); 5259 __ jmp(&done);
5268 5260
5269 // Heap number 5261 // Heap number
5270 __ bind(&heap_number); 5262 __ bind(&heap_number);
5271 __ vldr(double_scratch0(), FieldMemOperand(input_reg, 5263 __ vldr(temp_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
5272 HeapNumber::kValueOffset)); 5264 __ ClampDoubleToUint8(result_reg, temp_reg, double_scratch0());
5273 __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg);
5274 __ jmp(&done); 5265 __ jmp(&done);
5275 5266
5276 // smi 5267 // smi
5277 __ bind(&is_smi); 5268 __ bind(&is_smi);
5278 __ ClampUint8(result_reg, result_reg); 5269 __ ClampUint8(result_reg, result_reg);
5279 5270
5280 __ bind(&done); 5271 __ bind(&done);
5281 } 5272 }
5282 5273
5283 5274
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
5436 __ jmp(&allocated); 5427 __ jmp(&allocated);
5437 5428
5438 __ bind(&runtime_allocate); 5429 __ bind(&runtime_allocate);
5439 __ mov(r0, Operand(Smi::FromInt(size))); 5430 __ mov(r0, Operand(Smi::FromInt(size)));
5440 __ Push(r1, r0); 5431 __ Push(r1, r0);
5441 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); 5432 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5442 __ pop(r1); 5433 __ pop(r1);
5443 5434
5444 __ bind(&allocated); 5435 __ bind(&allocated);
5445 // Copy the content into the newly allocated memory. 5436 // Copy the content into the newly allocated memory.
5446 __ CopyFields(r0, r1, double_scratch0(), double_scratch0().low(), 5437 __ CopyFields(r0, r1, double_scratch0(), size / kPointerSize);
5447 size / kPointerSize);
5448 } 5438 }
5449 5439
5450 5440
5451 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 5441 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5452 // Use the fast case closure allocation code that allocates in new 5442 // Use the fast case closure allocation code that allocates in new
5453 // space for nested functions that don't need literals cloning. 5443 // space for nested functions that don't need literals cloning.
5454 bool pretenure = instr->hydrogen()->pretenure(); 5444 bool pretenure = instr->hydrogen()->pretenure();
5455 if (!pretenure && instr->hydrogen()->has_no_literals()) { 5445 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5456 FastNewClosureStub stub(instr->hydrogen()->language_mode(), 5446 FastNewClosureStub stub(instr->hydrogen()->language_mode(),
5457 instr->hydrogen()->is_generator()); 5447 instr->hydrogen()->is_generator());
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
5807 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5797 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5808 __ ldr(result, FieldMemOperand(scratch, 5798 __ ldr(result, FieldMemOperand(scratch,
5809 FixedArray::kHeaderSize - kPointerSize)); 5799 FixedArray::kHeaderSize - kPointerSize));
5810 __ bind(&done); 5800 __ bind(&done);
5811 } 5801 }
5812 5802
5813 5803
5814 #undef __ 5804 #undef __
5815 5805
5816 } } // namespace v8::internal 5806 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698