Index: runtime/vm/assembler_x64.cc |
=================================================================== |
--- runtime/vm/assembler_x64.cc (revision 2205) |
+++ runtime/vm/assembler_x64.cc (working copy) |
@@ -63,6 +63,18 @@ |
} |
+void Assembler::pushq(const Immediate& imm) { |
+ if (imm.is_int32()) { |
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
+ EmitUint8(0x68); |
+ EmitImmediate(imm); |
+ } else { |
+ movq(TMP, imm); |
+ pushq(TMP); |
+ } |
+} |
+ |
+ |
void Assembler::popq(Register reg) { |
AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
EmitRegisterREX(reg, REX_NONE); |
@@ -275,13 +287,17 @@ |
void Assembler::movq(const Address& dst, const Immediate& imm) { |
- AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
- ASSERT(imm.is_int32()); |
- Operand operand(dst); |
- EmitOperandREX(0, operand, REX_W); |
- EmitUint8(0xC7); |
- EmitOperand(0, operand); |
- EmitImmediate(imm); |
+ if (imm.is_int32()) { |
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
+ Operand operand(dst); |
+ EmitOperandREX(0, operand, REX_W); |
+ EmitUint8(0xC7); |
+ EmitOperand(0, operand); |
+ EmitImmediate(imm); |
+ } else { |
+ movq(TMP, imm); |
+ movq(dst, TMP); |
+ } |
} |
@@ -340,7 +356,7 @@ |
EmitUint8(0x66); |
EmitUint8(0x0F); |
EmitUint8(0x6E); |
- EmitOperand(dst, Operand(src)); |
+ EmitOperand(dst & 7, Operand(src)); |
} |
@@ -350,7 +366,7 @@ |
EmitUint8(0x66); |
EmitUint8(0x0F); |
EmitUint8(0x7E); |
- EmitOperand(src, Operand(dst)); |
+ EmitOperand(src & 7, Operand(dst)); |
} |
@@ -536,18 +552,36 @@ |
} |
-void Assembler::cmpq(const Address& address, const Immediate& imm) { |
+void Assembler::cmpq(const Address& address, Register reg) { |
AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
- Operand operand(address); |
- EmitOperandREX(7, operand, REX_W); |
- EmitComplex(7, operand, imm); |
+ EmitOperandREX(reg, address, REX_W); |
+ EmitUint8(0x39); |
+ EmitOperand(reg & 7, address); |
} |
+void Assembler::cmpq(const Address& address, const Immediate& imm) { |
+ if (imm.is_int32()) { |
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
+ Operand operand(address); |
+ EmitOperandREX(7, operand, REX_W); |
+ EmitComplex(7, operand, imm); |
+ } else { |
+ movq(TMP, imm); |
+ cmpq(address, TMP); |
+ } |
+} |
+ |
+ |
void Assembler::cmpq(Register reg, const Immediate& imm) { |
- AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
- EmitRegisterREX(reg, REX_W); |
- EmitComplex(7, Operand(reg), imm); |
+ if (imm.is_int32()) { |
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
+ EmitRegisterREX(reg, REX_W); |
+ EmitComplex(7, Operand(reg), imm); |
+ } else { |
+ movq(TMP, imm); |
+ cmpq(reg, TMP); |
+ } |
} |
@@ -805,16 +839,19 @@ |
void Assembler::imull(Register dst, Register src) { |
AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
+ Operand operand(src); |
+ EmitOperandREX(dst, operand, REX_NONE); |
EmitUint8(0x0F); |
EmitUint8(0xAF); |
- EmitOperand(dst, Operand(src)); |
+ EmitOperand(dst & 7, Operand(src)); |
} |
void Assembler::imull(Register reg, const Immediate& imm) { |
AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
+ EmitRegisterREX(reg, REX_NONE); |
EmitUint8(0x69); |
- EmitOperand(reg, Operand(reg)); |
+ EmitOperand(reg & 7, Operand(reg)); |
EmitImmediate(imm); |
} |
@@ -1124,24 +1161,36 @@ |
void Assembler::LoadObject(Register dst, const Object& object) { |
- ASSERT(object.IsZoneHandle()); |
- AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
- EmitRegisterREX(dst, REX_W); |
- EmitUint8(0xB8 | (dst & 7)); |
- buffer_.EmitObject(object); |
+ if (object.IsSmi()) { |
+ movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
+ } else { |
+ ASSERT(object.IsZoneHandle()); |
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
+ EmitRegisterREX(dst, REX_W); |
+ EmitUint8(0xB8 | (dst & 7)); |
+ buffer_.EmitObject(object); |
+ } |
} |
void Assembler::PushObject(const Object& object) { |
- LoadObject(TMP, object); |
- pushq(TMP); |
+ if (object.IsSmi()) { |
+ pushq(Immediate(reinterpret_cast<int64_t>(object.raw()))); |
+ } else { |
+ LoadObject(TMP, object); |
+ pushq(TMP); |
+ } |
} |
void Assembler::CompareObject(Register reg, const Object& object) { |
- ASSERT(reg != TMP); |
- LoadObject(TMP, object); |
- cmpq(reg, TMP); |
+ if (object.IsSmi()) { |
+ cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
+ } else { |
+ ASSERT(reg != TMP); |
+ LoadObject(TMP, object); |
+ cmpq(reg, TMP); |
+ } |
} |
@@ -1175,6 +1224,35 @@ |
} |
+void Assembler::EnterFrame(intptr_t frame_size) { |
+ if (prolog_offset_ == -1) { |
+ prolog_offset_ = CodeSize(); |
+ } |
+ pushq(RBP); |
+ movq(RBP, RSP); |
+ if (frame_size != 0) { |
+ Immediate frame_space(frame_size); |
+ subq(RSP, frame_space); |
+ } |
+} |
+ |
+ |
+void Assembler::LeaveFrame() { |
+ movq(RSP, RBP); |
+ popq(RBP); |
+} |
+ |
+ |
+void Assembler::CallRuntimeFromDart(const RuntimeEntry& entry) { |
+ entry.CallFromDart(this); |
+} |
+ |
+ |
+void Assembler::CallRuntimeFromStub(const RuntimeEntry& entry) { |
+ entry.CallFromStub(this); |
+} |
+ |
+ |
void Assembler::Align(int alignment, int offset) { |
UNIMPLEMENTED(); |
} |
@@ -1211,8 +1289,8 @@ |
void Assembler::EmitComplex(int rm, |
- const Operand& operand, |
- const Immediate& immediate) { |
+ const Operand& operand, |
+ const Immediate& immediate) { |
ASSERT(rm >= 0 && rm < 8); |
ASSERT(immediate.is_int32()); |
if (immediate.is_int8()) { |