Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h (198952 => 198953)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h 2016-04-01 19:15:05 UTC (rev 198952)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h 2016-04-01 19:20:08 UTC (rev 198953)
@@ -1245,35 +1245,89 @@
void subDouble(FPRegisterID src, FPRegisterID dest)
{
- ASSERT(isSSE2Present());
- m_assembler.subsd_rr(src, dest);
+ subDouble(dest, src, dest);
}
void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
{
- // B := A - B is invalid.
- ASSERT(op1 == dest || op2 != dest);
+ if (supportsAVX())
+ m_assembler.vsubsd_rr(op1, op2, dest);
+ else {
+ ASSERT(isSSE2Present());
- moveDouble(op1, dest);
- subDouble(op2, dest);
+ // B := A - B is invalid.
+ ASSERT(op1 == dest || op2 != dest);
+ moveDouble(op1, dest);
+ m_assembler.subsd_rr(op2, dest);
+ }
}
+ void subDouble(FPRegisterID op1, Address op2, FPRegisterID dest)
+ {
+ if (supportsAVX())
+ m_assembler.vsubsd_mr(op1, op2.offset, op2.base, dest);
+ else {
+ moveDouble(op1, dest);
+ m_assembler.subsd_mr(op2.offset, op2.base, dest);
+ }
+ }
+
+ void subDouble(FPRegisterID op1, BaseIndex op2, FPRegisterID dest)
+ {
+ if (supportsAVX())
+ m_assembler.vsubsd_mr(op1, op2.offset, op2.base, op2.index, op2.scale, dest);
+ else {
+ moveDouble(op1, dest);
+ m_assembler.subsd_mr(op2.offset, op2.base, op2.index, op2.scale, dest);
+ }
+ }
+
void subDouble(Address src, FPRegisterID dest)
{
- ASSERT(isSSE2Present());
- m_assembler.subsd_mr(src.offset, src.base, dest);
+ subDouble(dest, src, dest);
}
void subFloat(FPRegisterID src, FPRegisterID dest)
{
- ASSERT(isSSE2Present());
- m_assembler.subss_rr(src, dest);
+ subFloat(dest, src, dest);
}
+ void subFloat(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
+ {
+ if (supportsAVX())
+ m_assembler.vsubss_rr(op1, op2, dest);
+ else {
+ ASSERT(isSSE2Present());
+ // B := A - B is invalid.
+ ASSERT(op1 == dest || op2 != dest);
+ moveDouble(op1, dest);
+ m_assembler.subss_rr(op2, dest);
+ }
+ }
+
+ void subFloat(FPRegisterID op1, Address op2, FPRegisterID dest)
+ {
+ if (supportsAVX())
+ m_assembler.vsubss_mr(op1, op2.offset, op2.base, dest);
+ else {
+ moveDouble(op1, dest);
+ m_assembler.subss_mr(op2.offset, op2.base, dest);
+ }
+ }
+
+ void subFloat(FPRegisterID op1, BaseIndex op2, FPRegisterID dest)
+ {
+ if (supportsAVX())
+ m_assembler.vsubss_mr(op1, op2.offset, op2.base, op2.index, op2.scale, dest);
+ else {
+ moveDouble(op1, dest);
+ m_assembler.subss_mr(op2.offset, op2.base, op2.index, op2.scale, dest);
+ }
+ }
+
void subFloat(Address src, FPRegisterID dest)
{
- ASSERT(isSSE2Present());
- m_assembler.subss_mr(src.offset, src.base, dest);
+ subFloat(dest, src, dest);
}
void mulDouble(FPRegisterID src, FPRegisterID dest)
Modified: trunk/Source/_javascript_Core/assembler/X86Assembler.h (198952 => 198953)
--- trunk/Source/_javascript_Core/assembler/X86Assembler.h 2016-04-01 19:15:05 UTC (rev 198952)
+++ trunk/Source/_javascript_Core/assembler/X86Assembler.h 2016-04-01 19:20:08 UTC (rev 198953)
@@ -2441,24 +2441,66 @@
m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
}
+ void vsubsd_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
+ {
+ m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
+ }
+
void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F2);
m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
}
+ void subsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, dst, base, index, scale, offset);
+ }
+
+ void vsubsd_mr(XMMRegisterID b, int offset, RegisterID base, XMMRegisterID dst)
+ {
+ m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
+ }
+
+ void vsubsd_mr(XMMRegisterID b, int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
+ {
+ m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
+ }
+
void subss_rr(XMMRegisterID src, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F3);
m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
}
+ void vsubss_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
+ {
+ m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
+ }
+
void subss_mr(int offset, RegisterID base, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F3);
m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
}
+ void subss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F3);
+ m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, dst, base, index, scale, offset);
+ }
+
+ void vsubss_mr(XMMRegisterID b, int offset, RegisterID base, XMMRegisterID dst)
+ {
+ m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
+ }
+
+ void vsubss_mr(XMMRegisterID b, int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
+ {
+ m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
+ }
+
void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_66);
@@ -3339,15 +3381,10 @@
writer.memoryModRM(reg, address);
}
#endif
- void vexNdsLigWigCommutativeTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, RegisterID b)
+ void vexNdsLigWigTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, RegisterID b)
{
SingleInstructionBufferWriter writer(m_buffer);
-
- // Since this is a commutative operation, we can try switching the arguments.
if (regRequiresRex(b))
- std::swap(a, b);
-
- if (regRequiresRex(b))
writer.threeBytesVexNds(simdPrefix, VexImpliedBytes::TwoBytesOp, dest, a, b);
else
writer.twoBytesVex(simdPrefix, a, dest);
@@ -3355,6 +3392,14 @@
writer.registerModRM(dest, b);
}
+ void vexNdsLigWigCommutativeTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, RegisterID b)
+ {
+ // Since this is a commutative operation, we can try switching the arguments.
+ if (regRequiresRex(b))
+ std::swap(a, b);
+ vexNdsLigWigTwoByteOp(simdPrefix, opcode, dest, a, b);
+ }
+
void vexNdsLigWigTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, RegisterID base, int offset)
{
SingleInstructionBufferWriter writer(m_buffer);
Modified: trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes (198952 => 198953)
--- trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes 2016-04-01 19:15:05 UTC (rev 198952)
+++ trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes 2016-04-01 19:20:08 UTC (rev 198953)
@@ -177,15 +177,19 @@
x86: Addr, Tmp
x86: Tmp, Addr
-arm64: SubDouble U:F:64, U:F:64, D:F:64
- Tmp, Tmp, Tmp
+SubDouble U:F:64, U:F:64, D:F:64
+ arm64: Tmp, Tmp, Tmp
+ x86: Tmp, Addr, Tmp
+ x86: Tmp, Index, Tmp
x86: SubDouble U:F:64, UD:F:64
Tmp, Tmp
Addr, Tmp
-arm64: SubFloat U:F:32, U:F:32, D:F:32
- Tmp, Tmp, Tmp
+SubFloat U:F:32, U:F:32, D:F:32
+ arm64: Tmp, Tmp, Tmp
+ x86: Tmp, Addr, Tmp
+ x86: Tmp, Index, Tmp
x86: SubFloat U:F:32, UD:F:32
Tmp, Tmp