Author: [email protected]
Date: Mon May 25 07:00:30 2009
New Revision: 2043
Modified:
branches/bleeding_edge/src/x64/assembler-x64.cc
branches/bleeding_edge/src/x64/assembler-x64.h
Log:
Implementation of a few more assembly instructions on x64
Review URL: http://codereview.chromium.org/113767
Modified: branches/bleeding_edge/src/x64/assembler-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.cc (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.cc Mon May 25 07:00:30 2009
@@ -33,6 +33,9 @@
namespace internal {
Register no_reg = { -1 };
+Register rax = { 0 };
+Register rcx = { 1 };
+Register rsi = { 7 };
// Safe default is no features.
@@ -239,10 +242,39 @@
}
-void Assembler::int3() {
+void Assembler::add(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
- EMIT(0xCC);
+ emit_rex_64(dst, src);
+ EMIT(0x03);
+ emit_operand(dst, src);
+}
+
+
+void Assembler::add(Register dst, Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(dst, src);
+ EMIT(0x03);
+ EMIT(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7));
+}
+
+
+void Assembler::dec(Register dst) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(rcx, dst);
+ EMIT(0xFF);
+ EMIT(0xC8 | (dst.code() & 0x7));
+}
+
+
+void Assembler::dec(const Operand& dst) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(rax, dst);
+ EMIT(0xFF);
+ emit_operand(rcx, dst);
}
@@ -253,24 +285,28 @@
}
-void Assembler::nop() {
+void Assembler::inc(Register dst) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
- EMIT(0x90);
+ emit_rex_64(rax, dst);
+ EMIT(0xFF);
+ EMIT(0xC0 | (dst.code() & 0x7));
}
-void Assembler::ret(int imm16) {
+void Assembler::inc(const Operand& dst) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
- ASSERT(is_uint16(imm16));
- if (imm16 == 0) {
- EMIT(0xC3);
- } else {
- EMIT(0xC2);
- EMIT(imm16 & 0xFF);
- EMIT((imm16 >> 8) & 0xFF);
- }
+ emit_rex_64(rax, dst);
+ EMIT(0xFF);
+ emit_operand(rax, dst);
+}
+
+
+void Assembler::int3() {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ EMIT(0xCC);
}
@@ -289,6 +325,64 @@
emit_rex_64(dst, src);
EMIT(0x89);
EMIT(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7));
+}
+
+
+void Assembler::nop() {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ EMIT(0x90);
+}
+
+void Assembler::pop(Register dst) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ if (dst.code() & 0x8) {
+ emit_rex_64(rax, dst);
+ }
+ EMIT(0x58 | (dst.code() & 0x7));
+}
+
+
+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(0x8F);
+ emit_operand(rax, dst);
+}
+
+
+void Assembler::push(Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ if (src.code() & 0x8) {
+ emit_rex_64(rax, src);
+ }
+ EMIT(0x50 | (src.code() & 0x7));
+}
+
+
+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(0xFF);
+ emit_operand(rsi, src);
+}
+
+
+void Assembler::ret(int imm16) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ ASSERT(is_uint16(imm16));
+ if (imm16 == 0) {
+ EMIT(0xC3);
+ } else {
+ EMIT(0xC2);
+ EMIT(imm16 & 0xFF);
+ EMIT((imm16 >> 8) & 0xFF);
+ }
}
} } // namespace v8::internal
Modified: branches/bleeding_edge/src/x64/assembler-x64.h
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.h (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.h Mon May 25 07:00:30 2009
@@ -437,7 +437,8 @@
private:
// The relocation writer's position is kGap bytes below the end of
// the generated instructions. This leaves enough space for the
- // longest possible ia32 instruction (17 bytes as of 9/26/06) and
+ // longest possible x64 instruction (There is a 15 byte limit on
+ // instruction length, ruling out some otherwise valid instructions) and
// allows for a single, fast space check per instruction.
static const int kGap = 32;
@@ -475,22 +476,20 @@
//
---------------------------------------------------------------------------
// Code generation
//
- // - function names correspond one-to-one to ia32 instruction mnemonics
- // - unless specified otherwise, instructions operate on 32bit operands
- // - instructions on 8bit (byte) operands/registers have a trailing '_b'
- // - instructions on 16bit (word) operands/registers have a trailing '_w'
- // - naming conflicts with C++ keywords are resolved via a trailing '_'
-
- // NOTE ON INTERFACE: Currently, the interface is not very consistent
- // in the sense that some operations (e.g. mov()) can be called in more
- // the one way to generate the same instruction: The Register argument
- // can in some cases be replaced with an Operand(Register) argument.
- // This should be cleaned up and made more orthogonal. The questions
- // is: should we always use Operands instead of Registers where an
- // Operand is possible, or should we have a Register (overloaded) form
- // instead? We must be careful to make sure that the selected instruction
- // is obvious from the parameters to avoid hard-to-find code generation
- // bugs.
+ // Function names correspond one-to-one to x64 instruction mnemonics.
+ // Unless specified otherwise, instructions operate on 64-bit operands.
+ //
+ // If we need versions of an assembly instruction that operate on
different
+ // width arguments, we add a single-letter suffix specifying the width.
+ // This is done for the following instructions: mov, cmp.
+ // There are no versions of these instructions without the suffix.
+ // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
+ // - Instructions on 16-bit (word) operands/registers have a
trailing 'w'.
+ // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
+ // - Instructions on 64-bit (quadword) operands/registers use 'q'.
+ //
+ // Some mnemonics, such as "and", are the same as C++ keywords.
+ // Naming conflicts with C++ keywords are resolved by adding a
trailing '_'.
// Insert the smallest number of nop instructions
// possible to align the pc offset to a multiple
@@ -552,6 +551,7 @@
void adc(Register dst, int32_t imm32);
void adc(Register dst, const Operand& src);
+ void add(Register dst, Register src);
void add(Register dst, const Operand& src);
void add(const Operand& dst, const Immediate& x);
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---