mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 676287 - IonMonkey: inline some constant doubles in code. r=dvander
This commit is contained in:
parent
049f589808
commit
9e785e924d
@ -287,6 +287,7 @@ private:
|
||||
OP2_XORPD_VpdWpd = 0x57,
|
||||
OP2_MOVD_VdEd = 0x6E,
|
||||
OP2_PSRLDQ_Vd = 0x73,
|
||||
OP2_PCMPEQW = 0x75,
|
||||
OP2_MOVD_EdVd = 0x7E,
|
||||
OP2_JCC_rel32 = 0x80,
|
||||
OP_SETCC = 0x90,
|
||||
@ -2049,6 +2050,15 @@ public:
|
||||
|
||||
// SSE operations:
|
||||
|
||||
void pcmpeqw_rr(XMMRegisterID src, XMMRegisterID dst)
|
||||
{
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
IPFX "pcmpeqw %s, %s\n", MAYBE_PAD,
|
||||
nameFPReg(src), nameFPReg(dst));
|
||||
m_formatter.prefix(PRE_SSE_66);
|
||||
m_formatter.twoByteOp(OP2_PCMPEQW, (RegisterID)dst, (RegisterID)src); /* right order ? */
|
||||
}
|
||||
|
||||
void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
|
||||
{
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
@ -2185,13 +2195,33 @@ public:
|
||||
void psrldq_rr(XMMRegisterID dest, int shift)
|
||||
{
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
IPFX "pslldq %s, %d\n", MAYBE_PAD,
|
||||
IPFX "psrldq %s, %d\n", MAYBE_PAD,
|
||||
nameFPReg(dest), shift);
|
||||
m_formatter.prefix(PRE_SSE_66);
|
||||
m_formatter.twoByteOp(OP2_PSRLDQ_Vd, (RegisterID)3, (RegisterID)dest);
|
||||
m_formatter.immediate8(shift);
|
||||
}
|
||||
|
||||
void psllq_rr(XMMRegisterID dest, int shift)
|
||||
{
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
IPFX "psllq %s, %d\n", MAYBE_PAD,
|
||||
nameFPReg(dest), shift);
|
||||
m_formatter.prefix(PRE_SSE_66);
|
||||
m_formatter.twoByteOp(OP2_PSRLDQ_Vd, (RegisterID)6, (RegisterID)dest);
|
||||
m_formatter.immediate8(shift);
|
||||
}
|
||||
|
||||
void psrlq_rr(XMMRegisterID dest, int shift)
|
||||
{
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
IPFX "psrlq %s, %d\n", MAYBE_PAD,
|
||||
nameFPReg(dest), shift);
|
||||
m_formatter.prefix(PRE_SSE_66);
|
||||
m_formatter.twoByteOp(OP2_PSRLDQ_Vd, (RegisterID)2, (RegisterID)dest);
|
||||
m_formatter.immediate8(shift);
|
||||
}
|
||||
|
||||
void movmskpd_rr(XMMRegisterID src, RegisterID dst)
|
||||
{
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
|
@ -1007,9 +1007,15 @@ class AssemblerX86Shared
|
||||
JS_NOT_REACHED("unexpected operand kind");
|
||||
}
|
||||
}
|
||||
void psrlq(Imm32 shift, const FloatRegister &dest) {
|
||||
void psrldq(Imm32 shift, const FloatRegister &dest) {
|
||||
masm.psrldq_rr(dest.code(), shift.value);
|
||||
}
|
||||
void psllq(Imm32 shift, const FloatRegister &dest) {
|
||||
masm.psllq_rr(dest.code(), shift.value);
|
||||
}
|
||||
void psrlq(Imm32 shift, const FloatRegister &dest) {
|
||||
masm.psrlq_rr(dest.code(), shift.value);
|
||||
}
|
||||
|
||||
void cvtsi2sd(const Operand &src, const FloatRegister &dest) {
|
||||
switch (src.kind()) {
|
||||
@ -1042,6 +1048,9 @@ class AssemblerX86Shared
|
||||
void ucomisd(const FloatRegister &lhs, const FloatRegister &rhs) {
|
||||
masm.ucomisd_rr(rhs.code(), lhs.code());
|
||||
}
|
||||
void pcmpeqw(const FloatRegister &lhs, const FloatRegister &rhs) {
|
||||
masm.pcmpeqw_rr(rhs.code(), lhs.code());
|
||||
}
|
||||
void movd(const Register &src, const FloatRegister &dest) {
|
||||
masm.movd_rr(src.code(), dest.code());
|
||||
}
|
||||
|
@ -323,6 +323,43 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
bool maybeInlineDouble(uint64_t u, const FloatRegister &dest) {
|
||||
// This implements parts of "13.4 Generating constants" of
|
||||
// "2. Optimizing subroutines in assembly language" by Agner Fog.
|
||||
switch (u) {
|
||||
case 0:
|
||||
xorpd(dest, dest);
|
||||
break;
|
||||
case 0x3fe0000000000000: // 0.5
|
||||
pcmpeqw(dest, dest);
|
||||
psllq(Imm32(55), dest);
|
||||
psrlq(Imm32(2), dest);
|
||||
break;
|
||||
case 0x3ff0000000000000: // 1.0
|
||||
pcmpeqw(dest, dest);
|
||||
psllq(Imm32(54), dest);
|
||||
psrlq(Imm32(2), dest);
|
||||
break;
|
||||
case 0x3ff8000000000000: // 1.5
|
||||
pcmpeqw(dest, dest);
|
||||
psllq(Imm32(53), dest);
|
||||
psrlq(Imm32(2), dest);
|
||||
break;
|
||||
case 0x4000000000000000: // 2.0
|
||||
pcmpeqw(dest, dest);
|
||||
psllq(Imm32(63), dest);
|
||||
psrlq(Imm32(1), dest);
|
||||
break;
|
||||
case 0xc000000000000000: // -2.0
|
||||
pcmpeqw(dest, dest);
|
||||
psllq(Imm32(62), dest);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Emit a JMP that can be toggled to a CMP. See ToggleToJmp(), ToggleToCmp().
|
||||
CodeOffsetLabel toggledJump(Label *label) {
|
||||
CodeOffsetLabel offset(size());
|
||||
|
@ -704,9 +704,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
double d;
|
||||
} pun;
|
||||
pun.d = d;
|
||||
if (pun.u == 0) {
|
||||
xorpd(dest, dest);
|
||||
} else {
|
||||
if (!maybeInlineDouble(pun.u, dest)) {
|
||||
movq(ImmWord(pun.u), ScratchReg);
|
||||
movqsd(ScratchReg, dest);
|
||||
}
|
||||
|
@ -199,10 +199,8 @@ CodeGeneratorX86::visitDouble(LDouble *ins)
|
||||
} dpun;
|
||||
dpun.d = v.toDouble();
|
||||
|
||||
if (dpun.u == 0) {
|
||||
masm.xorpd(ToFloatRegister(out), ToFloatRegister(out));
|
||||
if (masm.maybeInlineDouble(dpun.u, ToFloatRegister(out)))
|
||||
return true;
|
||||
}
|
||||
|
||||
DeferredDouble *d = new DeferredDouble(cindex->index());
|
||||
if (!deferredDoubles_.append(d))
|
||||
|
@ -542,7 +542,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
// Note: this function clobbers the source register.
|
||||
void boxDouble(const FloatRegister &src, const ValueOperand &dest) {
|
||||
movd(src, dest.payloadReg());
|
||||
psrlq(Imm32(4), src);
|
||||
psrldq(Imm32(4), src);
|
||||
movd(src, dest.typeReg());
|
||||
}
|
||||
void unboxInt32(const ValueOperand &src, const Register &dest) {
|
||||
|
35
js/src/jit-test/tests/ion/inline-doubles.js
Normal file
35
js/src/jit-test/tests/ion/inline-doubles.js
Normal file
@ -0,0 +1,35 @@
|
||||
function add0_5 (n) {
|
||||
return n + 0.5;
|
||||
}
|
||||
|
||||
function add1_0 (n) {
|
||||
return n + 1;
|
||||
}
|
||||
|
||||
function add1_5 (n) {
|
||||
return n + 1.5;
|
||||
}
|
||||
|
||||
function add2_0 (n) {
|
||||
return n + 2;
|
||||
}
|
||||
|
||||
function sub2_0 (n) {
|
||||
return n - 2;
|
||||
}
|
||||
|
||||
|
||||
var num = 1.5;
|
||||
|
||||
function main () {
|
||||
for (var i = 0; i < 10000; i++) {
|
||||
assertEq(add0_5(num), 2);
|
||||
assertEq(add1_0(num), 2.5);
|
||||
assertEq(add1_5(num), 3);
|
||||
assertEq(add2_0(num), 3.5);
|
||||
assertEq(sub2_0(num), -0.5);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < 1000; i++)
|
||||
main();
|
Loading…
Reference in New Issue
Block a user