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. |
+ 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); |