Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1105)

Unified Diff: runtime/vm/assembler_x64.cc

Issue 12207117: SSE Assembler and Disassembler support (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Review fixes Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_x64.cc
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 1b270aa310ca1481c42d22864fbf1bb5a80fbe66..a872ac5ba94fa259d6d1e219eb346fdb3d860fea 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -529,6 +529,24 @@ void Assembler::movaps(XmmRegister dst, XmmRegister src) {
}
+void Assembler::movups(XmmRegister dst, const Address& src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x10);
+ EmitOperand(dst & 7, src);
+}
+
+
+void Assembler::movups(const Address& dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(src, dst);
+ EmitUint8(0x0F);
+ EmitUint8(0x11);
+ EmitOperand(src & 7, dst);
+}
+
+
void Assembler::addsd(XmmRegister dst, XmmRegister src) {
ASSERT(src <= XMM15);
ASSERT(dst <= XMM15);
@@ -576,6 +594,245 @@ void Assembler::divsd(XmmRegister dst, XmmRegister src) {
EmitXmmRegisterOperand(dst & 7, src);
}
+void Assembler::addps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x58);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
+
+void Assembler::subps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x5C);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
+
+void Assembler::divps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x5E);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
+
+void Assembler::mulps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x59);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
+
+void Assembler::minps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x5D);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
+
+void Assembler::maxps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x5F);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
+
+void Assembler::andps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x54);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
+
+void Assembler::andps(XmmRegister dst, const Address& src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x54);
+ EmitOperand(dst & 7, src);
+}
+
+
+void Assembler::orps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x56);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
+void Assembler::notps(XmmRegister dst) {
+ static const struct ALIGN16 {
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+ uint32_t d;
+ } float_not_constant =
+ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant)));
+ xorps(dst, Address(TMP, 0));
+}
+
+
+void Assembler::negateps(XmmRegister dst) {
+ static const struct ALIGN16 {
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+ uint32_t d;
+ } float_negate_constant =
+ { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
+ movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant)));
+ xorps(dst, Address(TMP, 0));
+}
+
+
+void Assembler::absps(XmmRegister dst) {
+ static const struct ALIGN16 {
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+ uint32_t d;
+ } float_absolute_constant =
+ { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
+ movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant)));
+ andps(dst, Address(TMP, 0));
+}
+
+
+void Assembler::zerowps(XmmRegister dst) {
+ static const struct ALIGN16 {
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+ uint32_t d;
+ } float_zerow_constant =
+ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 };
+ movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant)));
+ andps(dst, Address(TMP, 0));
+}
+
+
+void Assembler::cmppseq(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0xC2);
+ EmitXmmRegisterOperand(dst & 7, src);
+ EmitUint8(0x0);
+}
+
+
+void Assembler::cmppsneq(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0xC2);
+ EmitXmmRegisterOperand(dst & 7, src);
+ EmitUint8(0x4);
+}
+
+
+void Assembler::cmppslt(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0xC2);
+ EmitXmmRegisterOperand(dst & 7, src);
+ EmitUint8(0x1);
+}
+
+
+void Assembler::cmppsle(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0xC2);
+ EmitXmmRegisterOperand(dst & 7, src);
+ EmitUint8(0x2);
+}
+
+
+void Assembler::cmppsnlt(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0xC2);
+ EmitXmmRegisterOperand(dst & 7, src);
+ EmitUint8(0x5);
+}
+
+
+void Assembler::cmppsnle(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0xC2);
+ EmitXmmRegisterOperand(dst & 7, src);
+ EmitUint8(0x6);
+}
+
+
+void Assembler::sqrtps(XmmRegister dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, dst);
+ EmitUint8(0x0F);
+ EmitUint8(0x51);
+ EmitXmmRegisterOperand(dst & 7, dst);
+}
+
+
+void Assembler::rsqrtps(XmmRegister dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, dst);
+ EmitUint8(0x0F);
+ EmitUint8(0x52);
+ EmitXmmRegisterOperand(dst & 7, dst);
+}
+
+
+void Assembler::reciprocalps(XmmRegister dst) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, dst);
+ EmitUint8(0x0F);
+ EmitUint8(0x53);
+ EmitXmmRegisterOperand(dst & 7, dst);
+}
+
+
+void Assembler::set1ps(XmmRegister dst, Register tmp1, const Immediate& imm) {
+ // Load 32-bit immediate value into tmp1.
+ movl(tmp1, imm);
+ // Move value from tmp1 into dst.
+ movd(dst, tmp1);
+ // Broadcast low lane into other three lanes.
+ shufps(dst, dst, Immediate(0x0));
+}
+
+
+void Assembler::shufps(XmmRegister dst, XmmRegister src, const Immediate& imm) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0xC6);
+ EmitXmmRegisterOperand(dst & 7, src);
+ ASSERT(imm.is_uint8());
+ EmitUint8(imm.value());
+}
+
void Assembler::comisd(XmmRegister a, XmmRegister b) {
ASSERT(a <= XMM15);
@@ -600,6 +857,16 @@ void Assembler::movmskpd(Register dst, XmmRegister src) {
}
+void Assembler::movmskps(Register dst, XmmRegister src) {
+ ASSERT(src <= XMM15);
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x50);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
+
void Assembler::sqrtsd(XmmRegister dst, XmmRegister src) {
ASSERT(dst <= XMM15);
ASSERT(src <= XMM15);
@@ -635,6 +902,23 @@ void Assembler::xorpd(XmmRegister dst, XmmRegister src) {
}
+void Assembler::xorps(XmmRegister dst, const Address& src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x57);
+ EmitOperand(dst & 7, src);
+}
+
+
+void Assembler::xorps(XmmRegister dst, XmmRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitREX_RB(dst, src);
+ EmitUint8(0x0F);
+ EmitUint8(0x57);
+ EmitXmmRegisterOperand(dst & 7, src);
+}
+
void Assembler::andpd(XmmRegister dst, const Address& src) {
ASSERT(dst <= XMM15);
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
@@ -1923,14 +2207,14 @@ void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
}
// Preserve all XMM registers except XMM0
- subq(RSP, Immediate((kNumberOfXmmRegisters - 1) * kDoubleSize));
+ subq(RSP, Immediate((kNumberOfXmmRegisters - 1) * kFpuRegisterSize));
// Store XMM registers with the lowest register number at the lowest
// address.
intptr_t offset = 0;
for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
- movsd(Address(RSP, offset), xmm_reg);
- offset += kDoubleSize;
+ movups(Address(RSP, offset), xmm_reg);
+ offset += kFpuRegisterSize;
}
ReserveAlignedFrameSpace(frame_space);
@@ -1943,7 +2227,7 @@ void Assembler::LeaveCallRuntimeFrame() {
// We need to restore it before restoring registers.
const intptr_t kPushedRegistersSize =
kNumberOfVolatileCpuRegisters * kWordSize +
- kNumberOfVolatileXmmRegisters * kDoubleSize;
+ kNumberOfVolatileXmmRegisters * kFpuRegisterSize;
leaq(RSP, Address(RBP, -kPushedRegistersSize));
// Restore all XMM registers except XMM0
@@ -1951,8 +2235,8 @@ void Assembler::LeaveCallRuntimeFrame() {
intptr_t offset = 0;
for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
- movsd(xmm_reg, Address(RSP, offset));
- offset += kDoubleSize;
+ movups(xmm_reg, Address(RSP, offset));
+ offset += kFpuRegisterSize;
}
addq(RSP, Immediate(offset));
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698