Author: [email protected]
Date: Wed Jun 3 03:30:50 2009
New Revision: 2091
Modified:
branches/bleeding_edge/src/assembler.h
branches/bleeding_edge/src/x64/assembler-x64-inl.h
branches/bleeding_edge/src/x64/assembler-x64.cc
branches/bleeding_edge/src/x64/assembler-x64.h
branches/bleeding_edge/src/x64/macro-assembler-x64.cc
branches/bleeding_edge/src/x64/macro-assembler-x64.h
Log:
X64: Added implementations of Set(..., Immediate) to macro assembler.
Removed duplicates comments in assembler-x64.cc.
Review URL: http://codereview.chromium.org/119035
Modified: branches/bleeding_edge/src/assembler.h
==============================================================================
--- branches/bleeding_edge/src/assembler.h (original)
+++ branches/bleeding_edge/src/assembler.h Wed Jun 3 03:30:50 2009
@@ -424,8 +424,6 @@
//
-----------------------------------------------------------------------------
// Utility functions
-// Move these into inline file?
-
static inline bool is_intn(int x, int n) {
return -(1 << (n-1)) <= x && x < (1 << (n-1));
}
Modified: branches/bleeding_edge/src/x64/assembler-x64-inl.h
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64-inl.h (original)
+++ branches/bleeding_edge/src/x64/assembler-x64-inl.h Wed Jun 3 03:30:50
2009
@@ -61,66 +61,66 @@
}
-// High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
-// REX.W is set. REX.X is cleared.
void Assembler::emit_rex_64(Register reg, Register rm_reg) {
emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
}
-// The high bit of reg is used for REX.R, the high bit of op's base
-// register is used for REX.B, and the high bit of op's index register
-// is used for REX.X. REX.W is set.
void Assembler::emit_rex_64(Register reg, const Operand& op) {
emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_);
}
-// The high bit of the register is used for REX.B.
-// REX.W is set and REX.R and REX.X are clear.
void Assembler::emit_rex_64(Register rm_reg) {
- ASSERT_EQ(rm_reg.code() & 0x0f, rm_reg.code());
+ ASSERT_EQ(rm_reg.code() & 0xf, rm_reg.code());
emit(0x48 | (rm_reg.code() >> 3));
}
-// The high bit of op's base register is used for REX.B, and the high
-// bit of op's index register is used for REX.X. REX.W is set and REX.R
clear.
void Assembler::emit_rex_64(const Operand& op) {
emit(0x48 | op.rex_);
}
-// High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
-// REX.W and REX.X are clear.
void Assembler::emit_rex_32(Register reg, Register rm_reg) {
emit(0x40 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
}
-// The high bit of reg is used for REX.R, the high bit of op's base
-// register is used for REX.B, and the high bit of op's index register
-// is used for REX.X. REX.W is cleared.
void Assembler::emit_rex_32(Register reg, const Operand& op) {
emit(0x40 | (reg.code() & 0x8) >> 1 | op.rex_);
}
-// High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
-// REX.W and REX.X are cleared. If no REX bits are set, no byte is
emitted.
+void Assembler::emit_rex_32(Register rm_reg) {
+ emit(0x40 | (rm_reg.code() & 0x8) >> 3);
+}
+
+
+void Assembler::emit_rex_32(const Operand& op) {
+ emit(0x40 | op.rex_);
+}
+
+
void Assembler::emit_optional_rex_32(Register reg, Register rm_reg) {
byte rex_bits = (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3;
- if (rex_bits) emit(0x40 | rex_bits);
+ if (rex_bits != 0) emit(0x40 | rex_bits);
}
-// The high bit of reg is used for REX.R, the high bit of op's base
-// register is used for REX.B, and the high bit of op's index register
-// is used for REX.X. REX.W is cleared. If no REX bits are set, nothing
-// is emitted.
void Assembler::emit_optional_rex_32(Register reg, const Operand& op) {
byte rex_bits = (reg.code() & 0x8) >> 1 | op.rex_;
- if (rex_bits) emit(0x40 | rex_bits);
+ if (rex_bits != 0) emit(0x40 | rex_bits);
+}
+
+
+void Assembler::emit_optional_rex_32(Register rm_reg) {
+ if (rm_reg.code() & 0x8 != 0) emit(0x41);
+}
+
+
+void Assembler::emit_optional_rex_32(const Operand& op) {
+ if (op.rex_ != 0) emit(0x40 | op.rex_);
}
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 Wed Jun 3 03:30:50 2009
@@ -685,6 +685,16 @@
}
+void Assembler::movl(Register dst, Immediate value) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_optional_rex_32(dst);
+ emit(0xC7);
+ emit(0xC0 | (dst.code() & 0x7));
+ emit(value); // Only 32-bit immediates are possible, not 8-bit
immediates.
+}
+
+
void Assembler::movq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
@@ -703,15 +713,6 @@
}
-void Assembler::movq(const Operand& dst, Register src) {
- EnsureSpace ensure_space(this);
- last_pc_ = pc_;
- emit_rex_64(src, dst);
- emit(0x89);
- emit_operand(src, dst);
-}
-
-
void Assembler::movq(Register dst, Immediate value) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
@@ -728,6 +729,15 @@
emit_rex_64(dst);
emit(0xB8 | (dst.code() & 0x7));
emitq(value, rmode);
+}
+
+
+void Assembler::movq(const Operand& dst, Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(src, dst);
+ emit(0x89);
+ emit_operand(src, dst);
}
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 Wed Jun 3 03:30:50 2009
@@ -40,6 +40,19 @@
namespace v8 {
namespace internal {
+// Utility functions
+
+// Test whether a 64-bit value is in a specific range.
+static inline bool is_uint32(int64_t x) {
+ const int64_t kUInt32Mask = V8_INT64_C(0xffffffff);
+ return x == x & kUInt32Mask;
+}
+
+static inline bool is_int32(int64_t x) {
+ const int64_t kMinIntValue = V8_INT64_C(-0x80000000);
+ return is_uint32(x - kMinIntValue);
+}
+
// CPU Registers.
//
// 1) We would prefer to use an enum, but enum values are assignment-
@@ -410,12 +423,16 @@
void movl(Register dst, Register src);
void movl(Register dst, const Operand& src);
void movl(const Operand& dst, Register src);
+ // Load a 32-bit immediate value, zero-extended to 64 bits.
+ void movl(Register dst, Immediate imm32);
void movq(Register dst, int32_t imm32);
- void movq(Register dst, Immediate x);
void movq(Register dst, const Operand& src);
+ // Sign extends immediate 32-bit value to 64 bits.
+ void movq(Register dst, Immediate x);
void movq(Register dst, Register src);
- void movq(const Operand& dst, const Immediate& x);
+
+ // Move 64 bit register value to 64-bit memory location.
void movq(const Operand& dst, Register src);
// New x64 instructions to load a 64-bit immediate into a register.
@@ -426,6 +443,7 @@
void movq(Register dst, const ExternalReference& ext, RelocInfo::Mode
rmode);
void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode);
+
// New x64 instruction to load from an immediate 64-bit pointer into RAX.
void load_rax(void* ptr, RelocInfo::Mode rmode);
@@ -874,6 +892,14 @@
// is used for REX.X. REX.W is cleared.
inline void emit_rex_32(Register reg, const Operand& op);
+ // High bit of rm_reg goes to REX.B.
+ // REX.W, REX.R and REX.X are clear.
+ inline void emit_rex_32(Register rm_reg);
+
+ // High bit of base goes to REX.B and high bit of index to REX.X.
+ // REX.W and REX.R are clear.
+ inline void emit_rex_32(const Operand &);
+
// High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
// REX.W is cleared. If no REX bits are set, no byte is emitted.
inline void emit_optional_rex_32(Register reg, Register rm_reg);
@@ -883,6 +909,15 @@
// is used for REX.X. REX.W is cleared. If no REX bits are set, nothing
// is emitted.
inline void emit_optional_rex_32(Register reg, const Operand& op);
+
+ // Optionally do as emit_rex_32(Register) if the register number has
+ // the high bit set.
+ inline void emit_optional_rex_32(Register rm_reg);
+
+ // Optionally do as emit_rex_32(const Operand&) if the operand register
+ // numbers have a high bit set.
+ inline void emit_optional_rex_32(const Operand& op);
+
// Emit the Mod/RM byte, and optionally the SIB byte and
// 1- or 4-byte offset for a memory operand. Also encodes
Modified: branches/bleeding_edge/src/x64/macro-assembler-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/macro-assembler-x64.cc (original)
+++ branches/bleeding_edge/src/x64/macro-assembler-x64.cc Wed Jun 3
03:30:50 2009
@@ -29,6 +29,7 @@
#include "bootstrapper.h"
#include "codegen-inl.h"
+#include "macro-assembler-x64.h"
namespace v8 {
namespace internal {
@@ -44,5 +45,29 @@
void MacroAssembler::TailCallRuntime(ExternalReference const& a, int b) {
UNIMPLEMENTED();
}
+
+
+void MacroAssembler::Set(Register dst, int64_t x) {
+ if (is_int32(x)) {
+ movq(dst, Immediate(x));
+ } else if (is_uint32(x)) {
+ movl(dst, Immediate(x));
+ } else {
+ movq(dst, x, RelocInfo::NONE);
+ }
+}
+
+
+void MacroAssembler::Set(const Operand& dst, int64_t x) {
+ if (is_int32(x)) {
+ movq(kScratchRegister, Immediate(x));
+ } else if (is_uint32(x)) {
+ movl(kScratchRegister, Immediate(x));
+ } else {
+ movq(kScratchRegister, x, RelocInfo::NONE);
+ }
+ movq(dst, kScratchRegister);
+}
+
} } // namespace v8::internal
Modified: branches/bleeding_edge/src/x64/macro-assembler-x64.h
==============================================================================
--- branches/bleeding_edge/src/x64/macro-assembler-x64.h (original)
+++ branches/bleeding_edge/src/x64/macro-assembler-x64.h Wed Jun 3
03:30:50 2009
@@ -33,6 +33,8 @@
namespace v8 {
namespace internal {
+static const Register kScratchRegister = r10;
+
// Forward declaration.
class JumpTarget;
@@ -137,8 +139,8 @@
void GetBuiltinEntry(Register target, Builtins::JavaScript id);
// Expression support
- void Set(Register dst, const Immediate& x);
- void Set(const Operand& dst, const Immediate& x);
+ void Set(Register dst, int64_t x);
+ void Set(const Operand& dst, int64_t x);
// Compare object type for heap object.
// Incoming register is heap_object and outgoing register is map.
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---