| OLD | NEW | 
|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 3586 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3597 | 3597 | 
| 3598     __ bind(&done); | 3598     __ bind(&done); | 
| 3599   } | 3599   } | 
| 3600 } | 3600 } | 
| 3601 | 3601 | 
| 3602 | 3602 | 
| 3603 void LCodeGen::DoMathRound(LMathRound* instr) { | 3603 void LCodeGen::DoMathRound(LMathRound* instr) { | 
| 3604   const XMMRegister xmm_scratch = double_scratch0(); | 3604   const XMMRegister xmm_scratch = double_scratch0(); | 
| 3605   Register output_reg = ToRegister(instr->result()); | 3605   Register output_reg = ToRegister(instr->result()); | 
| 3606   XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3606   XMMRegister input_reg = ToDoubleRegister(instr->value()); | 
|  | 3607   XMMRegister input_temp = ToDoubleRegister(instr->temp()); | 
| 3607   static int64_t one_half = V8_INT64_C(0x3FE0000000000000);  // 0.5 | 3608   static int64_t one_half = V8_INT64_C(0x3FE0000000000000);  // 0.5 | 
| 3608   static int64_t minus_one_half = V8_INT64_C(0xBFE0000000000000);  // -0.5 | 3609   static int64_t minus_one_half = V8_INT64_C(0xBFE0000000000000);  // -0.5 | 
| 3609 | 3610 | 
| 3610   Label done, round_to_zero, below_one_half, do_not_compensate, restore; | 3611   Label done, round_to_zero, below_one_half; | 
| 3611   Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; | 3612   Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; | 
| 3612   __ movq(kScratchRegister, one_half); | 3613   __ movq(kScratchRegister, one_half); | 
| 3613   __ movq(xmm_scratch, kScratchRegister); | 3614   __ movq(xmm_scratch, kScratchRegister); | 
| 3614   __ ucomisd(xmm_scratch, input_reg); | 3615   __ ucomisd(xmm_scratch, input_reg); | 
| 3615   __ j(above, &below_one_half, Label::kNear); | 3616   __ j(above, &below_one_half, Label::kNear); | 
| 3616 | 3617 | 
| 3617   // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). | 3618   // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). | 
| 3618   __ addsd(xmm_scratch, input_reg); | 3619   __ addsd(xmm_scratch, input_reg); | 
| 3619   __ cvttsd2si(output_reg, xmm_scratch); | 3620   __ cvttsd2si(output_reg, xmm_scratch); | 
| 3620   // Overflow is signalled with minint. | 3621   // Overflow is signalled with minint. | 
| 3621   __ cmpl(output_reg, Immediate(0x80000000)); | 3622   __ cmpl(output_reg, Immediate(0x80000000)); | 
| 3622   __ RecordComment("D2I conversion overflow"); | 3623   __ RecordComment("D2I conversion overflow"); | 
| 3623   DeoptimizeIf(equal, instr->environment()); | 3624   DeoptimizeIf(equal, instr->environment()); | 
| 3624   __ jmp(&done, dist); | 3625   __ jmp(&done, dist); | 
| 3625 | 3626 | 
| 3626   __ bind(&below_one_half); | 3627   __ bind(&below_one_half); | 
| 3627   __ movq(kScratchRegister, minus_one_half); | 3628   __ movq(kScratchRegister, minus_one_half); | 
| 3628   __ movq(xmm_scratch, kScratchRegister); | 3629   __ movq(xmm_scratch, kScratchRegister); | 
| 3629   __ ucomisd(xmm_scratch, input_reg); | 3630   __ ucomisd(xmm_scratch, input_reg); | 
| 3630   __ j(below_equal, &round_to_zero, Label::kNear); | 3631   __ j(below_equal, &round_to_zero, Label::kNear); | 
| 3631 | 3632 | 
| 3632   // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then | 3633   // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then | 
| 3633   // compare and compensate. | 3634   // compare and compensate. | 
| 3634   __ movq(kScratchRegister, input_reg);  // Back up input_reg. | 3635   __ movq(input_temp, input_reg);  // Do not alter input_reg. | 
| 3635   __ subsd(input_reg, xmm_scratch); | 3636   __ subsd(input_temp, xmm_scratch); | 
| 3636   __ cvttsd2si(output_reg, input_reg); | 3637   __ cvttsd2si(output_reg, input_temp); | 
| 3637   // Catch minint due to overflow, and to prevent overflow when compensating. | 3638   // Catch minint due to overflow, and to prevent overflow when compensating. | 
| 3638   __ cmpl(output_reg, Immediate(0x80000000)); | 3639   __ cmpl(output_reg, Immediate(0x80000000)); | 
| 3639   __ RecordComment("D2I conversion overflow"); | 3640   __ RecordComment("D2I conversion overflow"); | 
| 3640   DeoptimizeIf(equal, instr->environment()); | 3641   DeoptimizeIf(equal, instr->environment()); | 
| 3641 | 3642 | 
| 3642   __ Cvtlsi2sd(xmm_scratch, output_reg); | 3643   __ Cvtlsi2sd(xmm_scratch, output_reg); | 
| 3643   __ ucomisd(input_reg, xmm_scratch); | 3644   __ ucomisd(xmm_scratch, input_temp); | 
| 3644   __ j(equal, &restore, Label::kNear); | 3645   __ j(equal, &done, dist); | 
| 3645   __ subl(output_reg, Immediate(1)); | 3646   __ subl(output_reg, Immediate(1)); | 
| 3646   // No overflow because we already ruled out minint. | 3647   // No overflow because we already ruled out minint. | 
| 3647   __ bind(&restore); |  | 
| 3648   __ movq(input_reg, kScratchRegister);  // Restore input_reg. |  | 
| 3649   __ jmp(&done, dist); | 3648   __ jmp(&done, dist); | 
| 3650 | 3649 | 
| 3651   __ bind(&round_to_zero); | 3650   __ bind(&round_to_zero); | 
| 3652   // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if | 3651   // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if | 
| 3653   // we can ignore the difference between a result of -0 and +0. | 3652   // we can ignore the difference between a result of -0 and +0. | 
| 3654   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3653   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 3655     __ movq(output_reg, input_reg); | 3654     __ movq(output_reg, input_reg); | 
| 3656     __ testq(output_reg, output_reg); | 3655     __ testq(output_reg, output_reg); | 
| 3657     __ RecordComment("Minus zero"); | 3656     __ RecordComment("Minus zero"); | 
| 3658     DeoptimizeIf(negative, instr->environment()); | 3657     DeoptimizeIf(negative, instr->environment()); | 
| (...skipping 1980 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5639                                FixedArray::kHeaderSize - kPointerSize)); | 5638                                FixedArray::kHeaderSize - kPointerSize)); | 
| 5640   __ bind(&done); | 5639   __ bind(&done); | 
| 5641 } | 5640 } | 
| 5642 | 5641 | 
| 5643 | 5642 | 
| 5644 #undef __ | 5643 #undef __ | 
| 5645 | 5644 | 
| 5646 } }  // namespace v8::internal | 5645 } }  // namespace v8::internal | 
| 5647 | 5646 | 
| 5648 #endif  // V8_TARGET_ARCH_X64 | 5647 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|