Chromium Code Reviews| Index: src/x64/macro-assembler-x64.cc |
| diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc |
| index abbcaacf24a8ac1938436eace8adb2ef5bd88307..7bb5dec6b9e6c9059fb1e92bee774cfa0005187b 100644 |
| --- a/src/x64/macro-assembler-x64.cc |
| +++ b/src/x64/macro-assembler-x64.cc |
| @@ -1002,6 +1002,46 @@ void MacroAssembler::Cvttss2siq(Register dst, const Operand& src) { |
| } |
| +void MacroAssembler::Cvtss2siq(Register dst, XMMRegister src) { |
| + if (CpuFeatures::IsSupported(AVX)) { |
| + CpuFeatureScope scope(this, AVX); |
| + vcvtss2siq(dst, src); |
| + } else { |
| + cvtss2siq(dst, src); |
| + } |
| +} |
| + |
| + |
| +void MacroAssembler::Cvtss2siq(Register dst, const Operand& src) { |
| + if (CpuFeatures::IsSupported(AVX)) { |
| + CpuFeatureScope scope(this, AVX); |
| + vcvtss2siq(dst, src); |
| + } else { |
| + cvtss2siq(dst, src); |
| + } |
| +} |
| + |
| + |
| +void MacroAssembler::Cvtsd2siq(Register dst, XMMRegister src) { |
| + if (CpuFeatures::IsSupported(AVX)) { |
| + CpuFeatureScope scope(this, AVX); |
| + vcvtsd2siq(dst, src); |
| + } else { |
| + cvtsd2siq(dst, src); |
| + } |
| +} |
| + |
| + |
| +void MacroAssembler::Cvtsd2siq(Register dst, const Operand& src) { |
| + if (CpuFeatures::IsSupported(AVX)) { |
| + CpuFeatureScope scope(this, AVX); |
| + vcvtsd2siq(dst, src); |
| + } else { |
| + cvtsd2siq(dst, src); |
| + } |
| +} |
| + |
| + |
| void MacroAssembler::Cvttsd2siq(Register dst, XMMRegister src) { |
| if (CpuFeatures::IsSupported(AVX)) { |
| CpuFeatureScope scope(this, AVX); |
| @@ -2816,6 +2856,60 @@ void MacroAssembler::Roundss(XMMRegister dst, XMMRegister src, |
| } |
| +void MacroAssembler::Roundss(XMMRegister dst, XMMRegister src, Register tmp, |
| + XMMRegister xtmp, RoundingMode mode) { |
| + if (CpuFeatures::IsSupported(SSE4_1)) { |
| + CpuFeatureScope scope(this, SSE4_1); |
| + Roundss(dst, src, mode); |
| + } else { |
| + { |
| + // Set the right rounding mode. |
| + subq(rsp, Immediate(kPointerSize * 2)); |
| + stmxcsr(Operand(rsp, 0)); |
| + movl(tmp, Operand(rsp, 0)); |
| + andl(tmp, Immediate(0xffff9fff)); |
| + orl(tmp, Immediate(mode << 13)); |
| + movl(Operand(rsp, kPointerSize), tmp); |
| + ldmxcsr(Operand(rsp, kPointerSize)); |
| + } |
| + |
| + // Do rounding by conversion to int64. |
| + Cvtss2siq(tmp, src); |
| + |
| + Label done; |
| + Label out_of_range; |
| + cmpq(tmp, Immediate(1)); |
| + // If the conversion results in INT64_MIN, then the input is outside |
| + // int64 range, and due to the limited precision of float32 this means |
| + // that the input must have been an integer already. We are therefore |
| + // done already. |
| + j(overflow, &out_of_range); |
| + |
| + // Saving the sign bit. |
|
ahaas
2016/01/19 12:06:00
The idea to support -0 is to store the sign of the
|
| + Pcmpeqd(xtmp, xtmp); |
| + Pslld(xtmp, 31); |
| + Andps(xtmp, src); |
| + // Rounding is done by converting the value back to float. |
| + Cvtqsi2ss(dst, tmp); |
| + // Restore the sign bit. |
| + Orps(dst, xtmp); |
| + if (!dst.is(src)) { |
| + jmp(&done); |
| + } |
| + |
| + bind(&out_of_range); |
| + if (!dst.is(src)) { |
| + movss(dst, src); |
| + } |
| + |
| + bind(&done); |
| + // Restore the original rounding mode. |
| + ldmxcsr(Operand(rsp, 0)); |
| + addq(rsp, Immediate(kPointerSize * 2)); |
| + } |
| +} |
| + |
| + |
| void MacroAssembler::Roundsd(XMMRegister dst, XMMRegister src, |
| RoundingMode mode) { |
| if (CpuFeatures::IsSupported(AVX)) { |
| @@ -2827,6 +2921,60 @@ void MacroAssembler::Roundsd(XMMRegister dst, XMMRegister src, |
| } |
| +void MacroAssembler::Roundsd(XMMRegister dst, XMMRegister src, Register tmp, |
| + XMMRegister xtmp, RoundingMode mode) { |
| + if (CpuFeatures::IsSupported(SSE4_1)) { |
| + CpuFeatureScope scope(this, SSE4_1); |
| + Roundsd(dst, src, mode); |
| + } else { |
| + { |
| + // Set the right rounding mode. |
| + subq(rsp, Immediate(kPointerSize * 2)); |
| + stmxcsr(Operand(rsp, 0)); |
| + movl(tmp, Operand(rsp, 0)); |
| + andl(tmp, Immediate(0xffff9fff)); |
| + orl(tmp, Immediate(mode << 13)); |
| + movl(Operand(rsp, kPointerSize), tmp); |
| + ldmxcsr(Operand(rsp, kPointerSize)); |
| + } |
| + // Do rounding by conversion to int64. |
| + Cvtsd2siq(tmp, src); |
| + |
| + Label out_of_range; |
| + Label done; |
| + cmpq(tmp, Immediate(1)); |
| + // If the conversion results in INT64_MIN, then the input is outside |
| + // int64 range, and due to the limited precision of float64 this means |
| + // that the input must have been an integer already. We are therefore |
| + // done already. |
| + j(overflow, &out_of_range); |
| + // Saving the sign bit. |
| + // Initialize xtmp with 0x8000000000000000. |
| + Pcmpeqd(xtmp, xtmp); |
| + Psllq(xtmp, 63); |
| + Andpd(xtmp, src); |
| + // Rounding is done by converting the value back to float. |
| + Cvtqsi2sd(dst, tmp); |
| + // Restore the sign bit. |
| + Orpd(dst, xtmp); |
| + |
| + if (!dst.is(src)) { |
| + jmp(&done); |
| + } |
| + |
| + bind(&out_of_range); |
| + if (!dst.is(src)) { |
| + movsd(dst, src); |
| + } |
| + |
| + bind(&done); |
| + // Restore the original rounding mode. |
| + ldmxcsr(Operand(rsp, 0)); |
| + addq(rsp, Immediate(kPointerSize * 2)); |
| + } |
| +} |
| + |
| + |
| void MacroAssembler::Sqrtsd(XMMRegister dst, XMMRegister src) { |
| if (CpuFeatures::IsSupported(AVX)) { |
| CpuFeatureScope scope(this, AVX); |