Index: src/ia32/macro-assembler-ia32.cc |
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc |
index 43043e5b27d4cfc922a245ba8711a2078f583463..8616848e8a5ba2f93fe0779e9b7b4f025d00770f 100644 |
--- a/src/ia32/macro-assembler-ia32.cc |
+++ b/src/ia32/macro-assembler-ia32.cc |
@@ -2616,18 +2616,66 @@ void MacroAssembler::Move(const Operand& dst, const Immediate& x) { |
} |
-void MacroAssembler::Move(XMMRegister dst, double val) { |
- // TODO(titzer): recognize double constants with ExternalReferences. |
- uint64_t int_val = bit_cast<uint64_t, double>(val); |
- if (int_val == 0) { |
- xorps(dst, dst); |
+void MacroAssembler::Move(XMMRegister dst, uint32_t src) { |
+ if (src == 0) { |
+ pxor(dst, dst); |
} else { |
- int32_t lower = static_cast<int32_t>(int_val); |
- int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt); |
- push(Immediate(upper)); |
- push(Immediate(lower)); |
- movsd(dst, Operand(esp, 0)); |
- add(esp, Immediate(kDoubleSize)); |
+ unsigned cnt = base::bits::CountPopulation32(src); |
+ unsigned nlz = base::bits::CountLeadingZeros32(src); |
+ unsigned ntz = base::bits::CountTrailingZeros32(src); |
+ if (nlz + cnt + ntz == 32) { |
+ pcmpeqd(dst, dst); |
+ if (ntz == 0) { |
+ psrld(dst, 32 - cnt); |
+ } else { |
+ pslld(dst, 32 - cnt); |
+ if (nlz != 0) psrld(dst, nlz); |
+ } |
+ } else { |
+ push(eax); |
+ mov(eax, Immediate(src)); |
+ movd(dst, Operand(eax)); |
+ pop(eax); |
+ } |
+ } |
+} |
+ |
+ |
+void MacroAssembler::Move(XMMRegister dst, uint64_t src) { |
+ uint32_t lower = static_cast<uint32_t>(src); |
+ uint32_t upper = static_cast<uint32_t>(src >> 32); |
+ if (upper == 0) { |
+ Move(dst, lower); |
+ } else { |
+ unsigned cnt = base::bits::CountPopulation64(src); |
+ unsigned nlz = base::bits::CountLeadingZeros64(src); |
+ unsigned ntz = base::bits::CountTrailingZeros64(src); |
+ if (nlz + cnt + ntz == 64) { |
+ pcmpeqd(dst, dst); |
+ if (ntz == 0) { |
+ psrlq(dst, 64 - cnt); |
+ } else { |
+ psllq(dst, 64 - cnt); |
+ if (nlz != 0) psrlq(dst, nlz); |
+ } |
+ } else if (lower == 0) { |
+ Move(dst, upper); |
+ psllq(dst, 32); |
+ } else { |
+ push(eax); |
+ Move(eax, Immediate(lower)); |
+ movd(dst, Operand(eax)); |
+ Move(eax, Immediate(upper)); |
+ if (CpuFeatures::IsSupported(SSE4_1)) { |
+ CpuFeatureScope scope(this, SSE4_1); |
+ pinsrd(dst, Operand(eax), 1); |
+ } else { |
+ psllq(dst, 32); |
+ movd(xmm0, Operand(eax)); |
+ orpd(dst, xmm0); |
+ } |
+ pop(eax); |
+ } |
} |
} |