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