Chromium Code Reviews| Index: runtime/vm/assembler_x64.cc |
| =================================================================== |
| --- runtime/vm/assembler_x64.cc (revision 16928) |
| +++ runtime/vm/assembler_x64.cc (working copy) |
| @@ -641,6 +641,17 @@ |
| } |
| +void Assembler::andpd(XmmRegister dst, const Address& src) { |
| + ASSERT(dst <= XMM15); |
| + AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| + EmitUint8(0x66); |
| + EmitOperandREX(dst, src, REX_NONE); |
| + EmitUint8(0x0F); |
| + EmitUint8(0x54); |
| + EmitOperand(dst & 7, src); |
| +} |
| + |
| + |
| void Assembler::cvtsi2sd(XmmRegister dst, Register src) { |
| AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| ASSERT(dst <= XMM15); |
| @@ -689,6 +700,33 @@ |
| } |
| +void Assembler::pxor(XmmRegister dst, XmmRegister src) { |
| + ASSERT(src <= XMM15); |
| + ASSERT(dst <= XMM15); |
| + AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| + EmitUint8(0x66); |
| + EmitREX_RB(dst, src); |
| + EmitUint8(0x0F); |
| + EmitUint8(0xEF); |
| + EmitXmmRegisterOperand(dst, src); |
| +} |
| + |
| + |
| +void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { |
| + ASSERT(src <= XMM15); |
| + ASSERT(dst <= XMM15); |
| + AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| + EmitUint8(0x66); |
| + EmitREX_RB(dst, src); |
| + EmitUint8(0x0F); |
| + EmitUint8(0x3A); |
| + EmitUint8(0x0B); |
| + EmitXmmRegisterOperand(dst, src); |
| + // Mask precision exeption. |
| + EmitUint8(static_cast<uint8_t>(mode) | 0x8); |
| +} |
| + |
| + |
| void Assembler::fldl(const Address& src) { |
| AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| EmitUint8(0xDD); |
| @@ -1754,6 +1792,51 @@ |
| } |
| +void Assembler::DoubleAbs(XmmRegister reg) { |
| + static const struct ALIGN16 { |
| + uint64_t a; |
| + uint64_t b; |
| + } double_abs_constant = |
| + {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; |
| + movq(TMP, Immediate(reinterpret_cast<intptr_t>(&double_abs_constant))); |
| + andpd(reg, Address(TMP, 0)); |
| +} |
| + |
| + |
| +void Assembler::DoubleRound(XmmRegister dst, XmmRegister src, XmmRegister tmp) { |
| + ASSERT(tmp != src); |
| + static double kZeroFiveConst = 0.5; |
| + static double kNegZeroFiveConst = -0.5; |
| + Label is_negative, round; |
| + if (src != dst) { |
| + movsd(dst, src); |
| + } |
| + Label below_half, below_equal_neg_half, done; |
| + movq(TMP, Immediate(reinterpret_cast<intptr_t>(&kZeroFiveConst))); |
| + movsd(tmp, Address(TMP, 0)); |
| + comisd(tmp, dst); |
| + // 0.5 > dst ? |
|
Florian Schneider
2013/01/11 09:49:30
Same comments as on ia32.
srdjan
2013/01/11 19:41:08
Done.
|
| + j(ABOVE, &below_half, Assembler::kNearJump); |
| + // floor(val + 0.5). |
| + addsd(dst, tmp); |
| + roundsd(dst, dst, Assembler::kRoundDown); |
| + jmp(&done, Assembler::kNearJump); |
| + Bind(&below_half); |
| + // Return -0.0 for -0.5. |
| + movq(TMP, Immediate(reinterpret_cast<intptr_t>(&kNegZeroFiveConst))); |
| + movsd(tmp, Address(TMP, 0)); |
| + comisd(tmp, dst); |
| + // -0.5 >= dst. |
| + j(ABOVE_EQUAL, &below_equal_neg_half, Assembler::kNearJump); |
| + roundsd(dst, dst, Assembler::kRoundToZero); |
| + jmp(&done, Assembler::kNearJump); |
| + Bind(&below_equal_neg_half); |
| + addsd(dst, tmp); |
| + roundsd(dst, dst, Assembler::kRoundUp); |
| + Bind(&done); |
| +} |
| + |
| + |
| void Assembler::Stop(const char* message) { |
| int64_t message_address = reinterpret_cast<int64_t>(message); |
| if (FLAG_print_stop_message) { |