X64: Disassembler updated to using REX, extended registers and some X64 opcodes.

Not all opcodes fixed yet (some should be invalid in 64-bit mode, others should be added).

Review URL: http://codereview.chromium.org/155087


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2375 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
lrn@chromium.org 2009-07-07 12:40:15 +00:00
parent e9580c61ba
commit 9cecee80f1
4 changed files with 1479 additions and 56 deletions

View File

@ -427,6 +427,17 @@ void Assembler::arithmetic_op_32(byte opcode, Register dst, Register src) {
} }
void Assembler::arithmetic_op_32(byte opcode,
const Operand& dst,
Register src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_optional_rex_32(src, dst);
emit(opcode);
emit_operand(src, dst);
}
void Assembler::immediate_arithmetic_op(byte subcode, void Assembler::immediate_arithmetic_op(byte subcode,
Register dst, Register dst,
Immediate src) { Immediate src) {
@ -1068,11 +1079,23 @@ void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) {
void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this); // Non-relocatable values might not need a 64-bit representation.
last_pc_ = pc_; if (rmode == RelocInfo::NONE) {
emit_rex_64(dst); // Sadly, there is no zero or sign extending move for 8-bit immediates.
emit(0xB8 | dst.low_bits()); if (is_int32(value)) {
emitq(value, rmode); movq(dst, Immediate(static_cast<int32_t>(value)));
} else if (is_uint32(value)) {
movl(dst, Immediate(static_cast<int32_t>(value)));
}
// Value cannot be represented by 32 bits, so do a full 64 bit immediate
// value.
} else {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_rex_64(dst);
emit(0xB8 | dst.low_bits());
emitq(value, rmode);
}
} }
@ -1097,16 +1120,24 @@ void Assembler::movq(const Operand& dst, Immediate value) {
void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) { void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
EnsureSpace ensure_space(this); // If there is no relocation info, emit the value of the handle efficiently
last_pc_ = pc_; // (possibly using less that 8 bytes for the value).
ASSERT(!Heap::InNewSpace(*value)); if (mode == RelocInfo::NONE) {
emit_rex_64(dst); // There is no possible reason to store a heap pointer without relocation
emit(0xB8 | dst.low_bits()); // info, so it must be a smi.
if (value->IsHeapObject()) { ASSERT(value->IsSmi());
emitq(reinterpret_cast<uintptr_t>(value.location()), mode); // Smis never have more than 32 significant bits, but they might
// have garbage in the high bits.
movq(dst,
Immediate(static_cast<int32_t>(reinterpret_cast<intptr_t>(*value))));
} else { } else {
ASSERT_EQ(RelocInfo::NONE, mode); EnsureSpace ensure_space(this);
emitq(reinterpret_cast<uintptr_t>(*value), RelocInfo::NONE); last_pc_ = pc_;
ASSERT(value->IsHeapObject());
ASSERT(!Heap::InNewSpace(*value));
emit_rex_64(dst);
emit(0xB8 | dst.low_bits());
emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
} }
} }

View File

@ -566,10 +566,22 @@ class Assembler : public Malloced {
arithmetic_op_32(0x3B, dst, src); arithmetic_op_32(0x3B, dst, src);
} }
void cmpl(Register dst, const Operand& src) {
arithmetic_op_32(0x3B, src, dst);
}
void cmpl(const Operand& dst, Register src) {
arithmetic_op_32(0x39, dst, src);
}
void cmpl(Register dst, Immediate src) { void cmpl(Register dst, Immediate src) {
immediate_arithmetic_op_32(0x7, dst, src); immediate_arithmetic_op_32(0x7, dst, src);
} }
void cmpl(const Operand& dst, Immediate src) {
immediate_arithmetic_op_32(0x7, dst, src);
}
void cmpq(Register dst, Register src) { void cmpq(Register dst, Register src) {
arithmetic_op(0x3B, dst, src); arithmetic_op(0x3B, dst, src);
} }
@ -1091,6 +1103,7 @@ class Assembler : public Malloced {
// ModR/M byte. // ModR/M byte.
void arithmetic_op(byte opcode, Register dst, Register src); void arithmetic_op(byte opcode, Register dst, Register src);
void arithmetic_op_32(byte opcode, Register dst, Register src); void arithmetic_op_32(byte opcode, Register dst, Register src);
void arithmetic_op_32(byte opcode, const Operand& dst, Register src);
void arithmetic_op(byte opcode, Register reg, const Operand& op); void arithmetic_op(byte opcode, Register reg, const Operand& op);
void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);

File diff suppressed because it is too large Load Diff

View File

@ -208,7 +208,9 @@ Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
void MacroAssembler::Set(Register dst, int64_t x) { void MacroAssembler::Set(Register dst, int64_t x) {
if (is_int32(x)) { if (x == 0) {
xor_(dst, dst);
} else if (is_int32(x)) {
movq(dst, Immediate(x)); movq(dst, Immediate(x));
} else if (is_uint32(x)) { } else if (is_uint32(x)) {
movl(dst, Immediate(x)); movl(dst, Immediate(x));
@ -219,14 +221,17 @@ void MacroAssembler::Set(Register dst, int64_t x) {
void MacroAssembler::Set(const Operand& dst, int64_t x) { void MacroAssembler::Set(const Operand& dst, int64_t x) {
if (is_int32(x)) { if (x == 0) {
movq(kScratchRegister, Immediate(x)); xor_(kScratchRegister, kScratchRegister);
movq(dst, kScratchRegister);
} else if (is_int32(x)) {
movq(dst, Immediate(x));
} else if (is_uint32(x)) { } else if (is_uint32(x)) {
movl(kScratchRegister, Immediate(x)); movl(dst, Immediate(x));
} else { } else {
movq(kScratchRegister, x, RelocInfo::NONE); movq(kScratchRegister, x, RelocInfo::NONE);
movq(dst, kScratchRegister);
} }
movq(dst, kScratchRegister);
} }
@ -240,11 +245,13 @@ void MacroAssembler::LoadUnsafeSmi(Register dst, Smi* source) {
void MacroAssembler::Move(Register dst, Handle<Object> source) { void MacroAssembler::Move(Register dst, Handle<Object> source) {
ASSERT(!source->IsFailure());
if (source->IsSmi()) { if (source->IsSmi()) {
if (IsUnsafeSmi(source)) { if (IsUnsafeSmi(source)) {
LoadUnsafeSmi(dst, source); LoadUnsafeSmi(dst, source);
} else { } else {
movq(dst, source, RelocInfo::NONE); int32_t smi = static_cast<int32_t>(reinterpret_cast<intptr_t>(*source));
movq(dst, Immediate(smi));
} }
} else { } else {
movq(dst, source, RelocInfo::EMBEDDED_OBJECT); movq(dst, source, RelocInfo::EMBEDDED_OBJECT);
@ -253,8 +260,13 @@ void MacroAssembler::Move(Register dst, Handle<Object> source) {
void MacroAssembler::Move(const Operand& dst, Handle<Object> source) { void MacroAssembler::Move(const Operand& dst, Handle<Object> source) {
Move(kScratchRegister, source); if (source->IsSmi()) {
movq(dst, kScratchRegister); int32_t smi = static_cast<int32_t>(reinterpret_cast<intptr_t>(*source));
movq(dst, Immediate(smi));
} else {
movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT);
movq(dst, kScratchRegister);
}
} }
@ -265,14 +277,37 @@ void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
void MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) { void MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) {
Move(kScratchRegister, source); if (source->IsSmi()) {
cmpq(dst, kScratchRegister); if (IsUnsafeSmi(source)) {
LoadUnsafeSmi(kScratchRegister, source);
cmpl(dst, kScratchRegister);
} else {
// For smi-comparison, it suffices to compare the low 32 bits.
int32_t smi = static_cast<int32_t>(reinterpret_cast<intptr_t>(*source));
cmpl(dst, Immediate(smi));
}
} else {
ASSERT(source->IsHeapObject());
movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT);
cmpq(dst, kScratchRegister);
}
} }
void MacroAssembler::Push(Handle<Object> source) { void MacroAssembler::Push(Handle<Object> source) {
Move(kScratchRegister, source); if (source->IsSmi()) {
push(kScratchRegister); if (IsUnsafeSmi(source)) {
LoadUnsafeSmi(kScratchRegister, source);
push(kScratchRegister);
} else {
int32_t smi = static_cast<int32_t>(reinterpret_cast<intptr_t>(*source));
push(Immediate(smi));
}
} else {
ASSERT(source->IsHeapObject());
movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT);
push(kScratchRegister);
}
} }