Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Unified Diff: src/x64/assembler-x64.cc

Issue 18014003: Add X32 port into V8 (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/x64/assembler-x64.cc
===================================================================
--- src/x64/assembler-x64.cc (revision 15486)
+++ src/x64/assembler-x64.cc (working copy)
@@ -166,7 +166,11 @@
void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
// Load register with immediate 64 and call through a register instructions
// takes up 13 bytes and int3 takes up one byte.
+#ifndef V8_TARGET_ARCH_X32
static const int kCallCodeSize = 13;
+#else
+ static const int kCallCodeSize = 9;
+#endif
int code_size = kCallCodeSize + guard_bytes;
// Create a code patcher.
@@ -179,7 +183,11 @@
#endif
// Patch the code.
+#ifndef V8_TARGET_ARCH_X32
patcher.masm()->movq(r10, target, RelocInfo::NONE64);
+#else
+ patcher.masm()->movl(r10, target, RelocInfo::NONE32);
+#endif
patcher.masm()->call(r10);
// Check that the size of the code generated is as expected.
@@ -1373,9 +1381,19 @@
void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
EnsureSpace ensure_space(this);
+#ifndef V8_TARGET_ARCH_X32
emit(0x48); // REX.W
+#endif
emit(0xA1);
+#ifndef V8_TARGET_ARCH_X32
emitq(reinterpret_cast<uintptr_t>(value), mode);
+#else
+ // In 64-bit mode, need to zero extend the operand to 8 bytes.
+ // See 2.2.1.4 in Intel64 and IA32 Architectures Software
+ // Developer's Manual Volume 2.
+ emitl(reinterpret_cast<uintptr_t>(value), mode);
+ emitl(0);
+#endif
}
@@ -1481,6 +1499,21 @@
}
+#ifdef V8_TARGET_ARCH_X32
+void Assembler::movl(Register dst, int32_t value, RelocInfo::Mode rmode) {
+ // Non-relocatable values might not need a 64-bit representation.
+ if (RelocInfo::IsNone(rmode)) {
+ movl(dst, Immediate(value));
+ return;
+ }
+ EnsureSpace ensure_space(this);
+ emit_optional_rex_32(dst);
+ emit(0xB8 | dst.low_bits());
+ emitl(value, rmode);
+}
+#endif
+
+
void Assembler::movq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
emit_rex_64(dst, src);
@@ -1520,6 +1553,7 @@
}
+#ifndef V8_TARGET_ARCH_X32
void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) {
// This method must not be used with heap object references. The stored
// address is not GC safe. Use the handle version instead.
@@ -1529,9 +1563,21 @@
emit(0xB8 | dst.low_bits());
emitq(reinterpret_cast<uintptr_t>(value), rmode);
}
+#else
+void Assembler::movl(Register dst, void* value, RelocInfo::Mode rmode) {
+ // This method must not be used with heap object references. The stored
+ // address is not GC safe. Use the handle version instead.
+ ASSERT(rmode > RelocInfo::LAST_GCED_ENUM);
+ EnsureSpace ensure_space(this);
+ emit_optional_rex_32(dst);
+ emit(0xB8 | dst.low_bits());
+ emitl(reinterpret_cast<uintptr_t>(value), rmode);
+}
+#endif
void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
+#ifndef V8_TARGET_ARCH_X32
// Non-relocatable values might not need a 64-bit representation.
if (RelocInfo::IsNone(rmode)) {
if (is_uint32(value)) {
@@ -1544,6 +1590,18 @@
// Value cannot be represented by 32 bits, so do a full 64 bit immediate
// value.
}
+#else
+ ASSERT(RelocInfo::IsNone(rmode));
+ if (is_uint32(value)) {
+ movl(dst, Immediate(static_cast<int32_t>(value)));
+ return;
+ } else if (is_int32(value)) {
+ movq(dst, Immediate(static_cast<int32_t>(value)));
+ return;
+ }
+ // Value cannot be represented by 32 bits, so do a full 64 bit immediate
+ // value.
+#endif
EnsureSpace ensure_space(this);
emit_rex_64(dst);
emit(0xB8 | dst.low_bits());
@@ -1551,10 +1609,17 @@
}
+#ifndef V8_TARGET_ARCH_X32
void Assembler::movq(Register dst, ExternalReference ref) {
int64_t value = reinterpret_cast<int64_t>(ref.address());
movq(dst, value, RelocInfo::EXTERNAL_REFERENCE);
}
+#else
+void Assembler::movl(Register dst, ExternalReference ref) {
+ int32_t value = reinterpret_cast<int32_t>(ref.address());
+ movl(dst, value, RelocInfo::EXTERNAL_REFERENCE);
+}
+#endif
void Assembler::movq(const Operand& dst, Immediate value) {
@@ -1589,6 +1654,7 @@
}
+#ifndef V8_TARGET_ARCH_X32
void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
AllowDeferredHandleDereference using_raw_address;
// If there is no relocation info, emit the value of the handle efficiently
@@ -1607,8 +1673,29 @@
emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
}
}
+#else
+void Assembler::movl(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
+ AllowDeferredHandleDereference using_raw_address;
+ // If there is no relocation info, emit the value of the handle efficiently
+ // (possibly using less that 8 bytes for the value).
+ if (RelocInfo::IsNone(mode)) {
+ // There is no possible reason to store a heap pointer without relocation
+ // info, so it must be a smi.
+ ASSERT(value->IsSmi());
+ movl(dst, reinterpret_cast<int32_t>(*value), RelocInfo::NONE32);
+ } else {
+ EnsureSpace ensure_space(this);
+ ASSERT(value->IsHeapObject());
+ ASSERT(!HEAP->InNewSpace(*value));
+ emit_optional_rex_32(dst);
+ emit(0xB8 | dst.low_bits());
+ emitl(reinterpret_cast<uintptr_t>(value.location()), mode);
+ }
+}
+#endif
+
void Assembler::movsxbq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
emit_rex_64(dst, src);
@@ -1992,11 +2079,38 @@
}
+#ifdef V8_TARGET_ARCH_X32
+void Assembler::xchgl(Register dst, Register src) {
+ EnsureSpace ensure_space(this);
+ if (src.is(rax) || dst.is(rax)) { // Single-byte encoding
+ Register other = src.is(rax) ? dst : src;
+ emit_optional_rex_32(other);
+ emit(0x90 | other.low_bits());
+ } else if (dst.low_bits() == 4) {
+ emit_optional_rex_32(dst, src);
+ emit(0x87);
+ emit_modrm(dst, src);
+ } else {
+ emit_optional_rex_32(src, dst);
+ emit(0x87);
+ emit_modrm(src, dst);
+ }
+}
+#endif
+
+
void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
EnsureSpace ensure_space(this);
+#ifndef V8_TARGET_ARCH_X32
emit(0x48); // REX.W
+#endif
emit(0xA3);
+#ifndef V8_TARGET_ARCH_X32
emitq(reinterpret_cast<uintptr_t>(dst), mode);
+#else
+ emitl(reinterpret_cast<uintptr_t>(dst), mode);
+ emitl(0);
+#endif
}
@@ -2110,6 +2224,16 @@
}
+#ifdef V8_TARGET_ARCH_X32
+void Assembler::testl(const Operand& op, Register reg) {
+ EnsureSpace ensure_space(this);
+ emit_optional_rex_32(reg, op);
+ emit(0x85);
+ emit_operand(reg, op);
+}
+#endif
+
+
void Assembler::testq(const Operand& op, Register reg) {
EnsureSpace ensure_space(this);
emit_rex_64(reg, op);
@@ -3025,6 +3149,17 @@
}
+#ifdef V8_TARGET_ARCH_X32
+void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
+ EnsureSpace ensure_space(this);
+ emit(0x66);
+ emit(0x0f);
+ emit(0x76);
+ emit_sse_operand(dst, src);
+}
+#endif
+
+
void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
Register ireg = { reg.code() };
emit_operand(ireg, adr);

Powered by Google App Engine
This is Rietveld 408576698