Chromium Code Reviews| Index: runtime/vm/assembler_x64.cc |
| =================================================================== |
| --- runtime/vm/assembler_x64.cc (revision 2143) |
| +++ 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)); |
|
Ivan Posva
2011/12/07 08:34:51
Why is this necessary if you assert for dst <= XMM
regis
2011/12/07 19:37:36
The first argument of EmitOperand is the 3-bit rm
|
| } |
| @@ -350,7 +366,7 @@ |
| EmitUint8(0x66); |
| EmitUint8(0x0F); |
| EmitUint8(0x7E); |
| - EmitOperand(src, Operand(dst)); |
| + EmitOperand(src & 7, Operand(dst)); |
|
Ivan Posva
2011/12/07 08:34:51
ditto
regis
2011/12/07 19:37:36
ditto
|
| } |
| @@ -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); |
| + } |
| } |
| @@ -807,14 +841,14 @@ |
| AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| EmitUint8(0x0F); |
| EmitUint8(0xAF); |
| - EmitOperand(dst, Operand(src)); |
| + EmitOperand(dst & 7, Operand(src)); |
|
Ivan Posva
2011/12/07 08:34:51
What happens for registers greater than 8?
regis
2011/12/07 19:37:36
Good catch. Emit of the REX byte was missing. Adde
|
| } |
| void Assembler::imull(Register reg, const Immediate& imm) { |
| AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| EmitUint8(0x69); |
| - EmitOperand(reg, Operand(reg)); |
| + EmitOperand(reg & 7, Operand(reg)); |
|
Ivan Posva
2011/12/07 08:34:51
ditto.
regis
2011/12/07 19:37:36
ditto
|
| EmitImmediate(imm); |
| } |
| @@ -1124,24 +1158,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 +1221,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 +1286,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()) { |