[ia32] Better code generation for materialization of float/double constants.
TEST=cctest,mjsunit R=mstarzinger@chromium.org, jarin@chromium.org Review URL: https://codereview.chromium.org/645493002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24485 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
d50ba88bfd
commit
d143beb658
@ -905,26 +905,23 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
|
||||
__ 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);
|
||||
|
@ -2381,6 +2381,26 @@ void Assembler::ptest(XMMRegister dst, XMMRegister 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) {
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0x66);
|
||||
|
@ -1024,6 +1024,8 @@ class Assembler : public AssemblerBase {
|
||||
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);
|
||||
|
@ -1386,6 +1386,15 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -842,7 +842,9 @@ class MacroAssembler: public Assembler {
|
||||
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)); }
|
||||
|
Loading…
Reference in New Issue
Block a user