Revision: 24485
Author: bmeu...@chromium.org
Date: Thu Oct 9 09:32:59 2014 UTC
Log: [ia32] Better code generation for materialization of float/double
constants.
TEST=cctest,mjsunit
R=mstarzin...@chromium.org, ja...@chromium.org
Review URL: https://codereview.chromium.org/645493002
https://code.google.com/p/v8/source/detail?r=24485
Modified:
/branches/bleeding_edge/src/compiler/ia32/code-generator-ia32.cc
/branches/bleeding_edge/src/ia32/assembler-ia32.cc
/branches/bleeding_edge/src/ia32/assembler-ia32.h
/branches/bleeding_edge/src/ia32/disasm-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.h
=======================================
--- /branches/bleeding_edge/src/compiler/ia32/code-generator-ia32.cc Wed
Oct 8 10:44:45 2014 UTC
+++ /branches/bleeding_edge/src/compiler/ia32/code-generator-ia32.cc Thu
Oct 9 09:32:59 2014 UTC
@@ -905,26 +905,23 @@
__ mov(dst, g.ToImmediate(source));
} else if (src_constant.type() == Constant::kFloat32) {
// TODO(turbofan): Can we do better here?
- Immediate src(bit_cast<int32_t>(src_constant.ToFloat32()));
+ uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32());
if (destination->IsDoubleRegister()) {
XMMRegister dst = g.ToDoubleRegister(destination);
- __ push(Immediate(src));
- __ movss(dst, Operand(esp, 0));
- __ add(esp, Immediate(kDoubleSize / 2));
+ __ Move(dst, src);
} else {
DCHECK(destination->IsDoubleStackSlot());
Operand dst = g.ToOperand(destination);
- __ mov(dst, src);
+ __ mov(dst, Immediate(src));
}
} else {
DCHECK_EQ(Constant::kFloat64, src_constant.type());
- double v = src_constant.ToFloat64();
- uint64_t int_val = bit_cast<uint64_t, double>(v);
- int32_t lower = static_cast<int32_t>(int_val);
- int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt);
+ uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64());
+ uint32_t lower = static_cast<uint32_t>(src);
+ uint32_t upper = static_cast<uint32_t>(src >> 32);
if (destination->IsDoubleRegister()) {
XMMRegister dst = g.ToDoubleRegister(destination);
- __ Move(dst, v);
+ __ Move(dst, src);
} else {
DCHECK(destination->IsDoubleStackSlot());
Operand dst0 = g.ToOperand(destination);
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.cc Thu Oct 2 09:04:04
2014 UTC
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.cc Thu Oct 9 09:32:59
2014 UTC
@@ -2379,6 +2379,26 @@
EMIT(0x17);
emit_sse_operand(dst, src);
}
+
+
+void Assembler::pslld(XMMRegister reg, int8_t shift) {
+ EnsureSpace ensure_space(this);
+ EMIT(0x66);
+ EMIT(0x0F);
+ EMIT(0x72);
+ emit_sse_operand(esi, reg); // esi == 6
+ EMIT(shift);
+}
+
+
+void Assembler::psrld(XMMRegister reg, int8_t shift) {
+ EnsureSpace ensure_space(this);
+ EMIT(0x66);
+ EMIT(0x0F);
+ EMIT(0x72);
+ emit_sse_operand(edx, reg); // edx == 2
+ EMIT(shift);
+}
void Assembler::psllq(XMMRegister reg, int8_t shift) {
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.h Thu Oct 2 09:04:04
2014 UTC
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.h Thu Oct 9 09:32:59
2014 UTC
@@ -1024,6 +1024,8 @@
void por(XMMRegister dst, XMMRegister src);
void ptest(XMMRegister dst, XMMRegister src);
+ void pslld(XMMRegister reg, int8_t shift);
+ void psrld(XMMRegister reg, int8_t shift);
void psllq(XMMRegister reg, int8_t shift);
void psllq(XMMRegister dst, XMMRegister src);
void psrlq(XMMRegister reg, int8_t shift);
=======================================
--- /branches/bleeding_edge/src/ia32/disasm-ia32.cc Wed Aug 6 08:19:36
2014 UTC
+++ /branches/bleeding_edge/src/ia32/disasm-ia32.cc Thu Oct 9 09:32:59
2014 UTC
@@ -1386,6 +1386,15 @@
NameOfXMMRegister(regop),
NameOfXMMRegister(rm));
data++;
+ } else if (*data == 0x72) {
+ data++;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ int8_t imm8 = static_cast<int8_t>(data[1]);
+ DCHECK(regop == esi || regop == edx);
+ AppendToBuffer("%s %s,%d", (regop == esi) ? "pslld" : "psrld",
+ NameOfXMMRegister(rm), static_cast<int>(imm8));
+ data += 2;
} else if (*data == 0x73) {
data++;
int mod, regop, rm;
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Tue Sep 30
10:24:11 2014 UTC
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Thu Oct 9
09:32:59 2014 UTC
@@ -2616,18 +2616,66 @@
}
-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);
+ }
}
}
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Tue Sep 30
10:24:11 2014 UTC
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Thu Oct 9
09:32:59 2014 UTC
@@ -842,7 +842,9 @@
void Move(const Operand& dst, const Immediate& x);
// Move an immediate into an XMM register.
- void Move(XMMRegister dst, double val);
+ void Move(XMMRegister dst, uint32_t src);
+ void Move(XMMRegister dst, uint64_t src);
+ void Move(XMMRegister dst, double src) { Move(dst,
bit_cast<uint64_t>(src)); }
// Push a handle value.
void Push(Handle<Object> handle) { push(Immediate(handle)); }
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.