| Index: src/x64/assembler-x64.cc
|
| ===================================================================
|
| --- src/x64/assembler-x64.cc (revision 2072)
|
| +++ src/x64/assembler-x64.cc (working copy)
|
| @@ -28,6 +28,7 @@
|
| #include "v8.h"
|
|
|
| #include "macro-assembler.h"
|
| +#include "serialize.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -173,19 +174,7 @@
|
| }
|
| }
|
|
|
| -void Assembler::RecordComment(char const* a) {
|
| - UNIMPLEMENTED();
|
| -}
|
|
|
| -void Assembler::RecordPosition(int a) {
|
| - UNIMPLEMENTED();
|
| -}
|
| -
|
| -void Assembler::RecordStatementPosition(int a) {
|
| - UNIMPLEMENTED();
|
| -}
|
| -
|
| -
|
| void Assembler::bind_to(Label* L, int pos) {
|
| ASSERT(!L->is_bound()); // Label may only be bound once.
|
| last_pc_ = NULL;
|
| @@ -319,11 +308,14 @@
|
| Immediate src) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rax, dst);
|
| + emit_rex_64(dst);
|
| if (is_int8(src.value_)) {
|
| emit(0x83);
|
| emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
|
| emit(src.value_);
|
| + } else if (dst.is(rax)) {
|
| + emit(0x05 | (subcode << 3));
|
| + emitl(src.value_);
|
| } else {
|
| emit(0x81);
|
| emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
|
| @@ -336,7 +328,7 @@
|
| Immediate src) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rax, dst);
|
| + emit_rex_64(dst);
|
| if (is_int8(src.value_)) {
|
| emit(0x83);
|
| emit_operand(Register::toRegister(subcode), dst);
|
| @@ -373,7 +365,7 @@
|
| void Assembler::dec(Register dst) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rcx, dst);
|
| + emit_rex_64(dst);
|
| emit(0xFF);
|
| emit(0xC8 | (dst.code() & 0x7));
|
| }
|
| @@ -382,9 +374,9 @@
|
| void Assembler::dec(const Operand& dst) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rax, dst);
|
| + emit_rex_64(dst);
|
| emit(0xFF);
|
| - emit_operand(rcx, dst);
|
| + emit_operand(1, dst);
|
| }
|
|
|
|
|
| @@ -398,7 +390,7 @@
|
| void Assembler::inc(Register dst) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rax, dst);
|
| + emit_rex_64(dst);
|
| emit(0xFF);
|
| emit(0xC0 | (dst.code() & 0x7));
|
| }
|
| @@ -407,9 +399,9 @@
|
| void Assembler::inc(const Operand& dst) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rax, dst);
|
| + emit_rex_64(dst);
|
| emit(0xFF);
|
| - emit_operand(rax, dst);
|
| + emit_operand(0, dst);
|
| }
|
|
|
|
|
| @@ -508,7 +500,7 @@
|
| void Assembler::movq(Register dst, Immediate value) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rax, dst);
|
| + emit_rex_64(dst);
|
| emit(0xC7);
|
| emit(0xC0 | (dst.code() & 0x7));
|
| emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
|
| @@ -518,12 +510,30 @@
|
| void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rax, dst);
|
| + emit_rex_64(dst);
|
| emit(0xB8 | (dst.code() & 0x7));
|
| emitq(value, rmode);
|
| }
|
|
|
|
|
| +void Assembler::neg(Register dst) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit_rex_64(dst);
|
| + emit(0xF7);
|
| + emit(0xC0 | (0x3 << 3) | (dst.code() & 0x7));
|
| +}
|
| +
|
| +
|
| +void Assembler::neg(const Operand& dst) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit_rex_64(dst);
|
| + emit(0xF7);
|
| + emit_operand(3, dst);
|
| +}
|
| +
|
| +
|
| void Assembler::nop() {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| @@ -531,11 +541,29 @@
|
| }
|
|
|
|
|
| +void Assembler::not_(Register dst) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit_rex_64(dst);
|
| + emit(0xF7);
|
| + emit(0xC0 | (0x2 << 3) | (dst.code() & 0x7));
|
| +}
|
| +
|
| +
|
| +void Assembler::not_(const Operand& dst) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit_rex_64(dst);
|
| + emit(0xF7);
|
| + emit_operand(2, dst);
|
| +}
|
| +
|
| +
|
| void Assembler::pop(Register dst) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| if (dst.code() & 0x8) {
|
| - emit_rex_64(rax, dst);
|
| + emit_rex_64(dst);
|
| }
|
| emit(0x58 | (dst.code() & 0x7));
|
| }
|
| @@ -544,9 +572,9 @@
|
| void Assembler::pop(const Operand& dst) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rax, dst); // Could be omitted in some cases.
|
| + emit_rex_64(dst); // Could be omitted in some cases.
|
| emit(0x8F);
|
| - emit_operand(rax, dst);
|
| + emit_operand(0, dst);
|
| }
|
|
|
|
|
| @@ -554,7 +582,7 @@
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| if (src.code() & 0x8) {
|
| - emit_rex_64(rax, src);
|
| + emit_rex_64(src);
|
| }
|
| emit(0x50 | (src.code() & 0x7));
|
| }
|
| @@ -563,9 +591,9 @@
|
| void Assembler::push(const Operand& src) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| - emit_rex_64(rsi, src); // Could be omitted in some cases.
|
| + emit_rex_64(src); // Could be omitted in some cases.
|
| emit(0xFF);
|
| - emit_operand(rsi, src);
|
| + emit_operand(6, src);
|
| }
|
|
|
|
|
| @@ -582,6 +610,127 @@
|
| }
|
| }
|
|
|
| +
|
| +void Assembler::testb(Register reg, Immediate mask) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + if (reg.is(rax)) {
|
| + emit(0xA8);
|
| + emit(mask);
|
| + } else {
|
| + if (reg.code() & 0x8) {
|
| + emit_rex_32(rax, reg);
|
| + }
|
| + emit(0xF6);
|
| + emit(0xC0 | (reg.code() & 0x3));
|
| + emit(mask.value_); // Low byte emitted.
|
| + }
|
| +}
|
| +
|
| +
|
| +void Assembler::testb(const Operand& op, Immediate mask) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit_optional_rex_32(rax, op);
|
| + emit(0xF6);
|
| + emit_operand(rax, op); // Operation code 0
|
| + emit(mask.value_); // Low byte emitted.
|
| +}
|
| +
|
| +
|
| +void Assembler::testl(Register reg, Immediate mask) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + if (reg.is(rax)) {
|
| + emit(0xA9);
|
| + emit(mask);
|
| + } else {
|
| + emit_optional_rex_32(rax, reg);
|
| + emit(0xF7);
|
| + emit(0xC0 | (reg.code() & 0x3));
|
| + emit(mask);
|
| + }
|
| +}
|
| +
|
| +
|
| +void Assembler::testl(const Operand& op, Immediate mask) {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + emit_optional_rex_32(rax, op);
|
| + emit(0xF7);
|
| + emit_operand(rax, op); // Operation code 0
|
| + emit(mask);
|
| +}
|
| +
|
| +
|
| +// Relocation information implementations
|
| +
|
| +void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
|
| + ASSERT(rmode != RelocInfo::NONE);
|
| + // Don't record external references unless the heap will be serialized.
|
| + if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
|
| + !Serializer::enabled() &&
|
| + !FLAG_debug_code) {
|
| + return;
|
| + }
|
| + RelocInfo rinfo(pc_, rmode, data);
|
| + reloc_info_writer.Write(&rinfo);
|
| +}
|
| +
|
| +void Assembler::RecordJSReturn() {
|
| + WriteRecordedPositions();
|
| + EnsureSpace ensure_space(this);
|
| + RecordRelocInfo(RelocInfo::JS_RETURN);
|
| +}
|
| +
|
| +
|
| +void Assembler::RecordComment(const char* msg) {
|
| + if (FLAG_debug_code) {
|
| + EnsureSpace ensure_space(this);
|
| + RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
|
| + }
|
| +}
|
| +
|
| +
|
| +void Assembler::RecordPosition(int pos) {
|
| + ASSERT(pos != RelocInfo::kNoPosition);
|
| + ASSERT(pos >= 0);
|
| + current_position_ = pos;
|
| +}
|
| +
|
| +
|
| +void Assembler::RecordStatementPosition(int pos) {
|
| + ASSERT(pos != RelocInfo::kNoPosition);
|
| + ASSERT(pos >= 0);
|
| + current_statement_position_ = pos;
|
| +}
|
| +
|
| +
|
| +void Assembler::WriteRecordedPositions() {
|
| + // Write the statement position if it is different from what was written last
|
| + // time.
|
| + if (current_statement_position_ != written_statement_position_) {
|
| + EnsureSpace ensure_space(this);
|
| + RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_);
|
| + written_statement_position_ = current_statement_position_;
|
| + }
|
| +
|
| + // Write the position if it is different from what was written last time and
|
| + // also different from the written statement position.
|
| + if (current_position_ != written_position_ &&
|
| + current_position_ != written_statement_position_) {
|
| + EnsureSpace ensure_space(this);
|
| + RecordRelocInfo(RelocInfo::POSITION, current_position_);
|
| + written_position_ = current_position_;
|
| + }
|
| +}
|
| +
|
| +
|
| +const int RelocInfo::kApplyMask =
|
| + RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
|
| + 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE;
|
| +
|
| +
|
| } } // namespace v8::internal
|
|
|
|
|
| @@ -732,8 +881,6 @@
|
| return NULL;
|
| }
|
|
|
| -const int RelocInfo::kApplyMask = -1;
|
| -
|
| StackFrame::Type StackFrame::ComputeType(StackFrame::State* a) {
|
| UNIMPLEMENTED();
|
| return NONE;
|
|
|