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:
parent
e9580c61ba
commit
9cecee80f1
@ -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,
|
||||
Register dst,
|
||||
Immediate src) {
|
||||
@ -1068,12 +1079,24 @@ void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) {
|
||||
|
||||
|
||||
void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
|
||||
// Non-relocatable values might not need a 64-bit representation.
|
||||
if (rmode == RelocInfo::NONE) {
|
||||
// Sadly, there is no zero or sign extending move for 8-bit immediates.
|
||||
if (is_int32(value)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Assembler::movq(Register dst, ExternalReference ref) {
|
||||
@ -1097,16 +1120,24 @@ void Assembler::movq(const Operand& dst, Immediate value) {
|
||||
|
||||
|
||||
void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
|
||||
// If there is no relocation info, emit the value of the handle efficiently
|
||||
// (possibly using less that 8 bytes for the value).
|
||||
if (mode == RelocInfo::NONE) {
|
||||
// There is no possible reason to store a heap pointer without relocation
|
||||
// info, so it must be a smi.
|
||||
ASSERT(value->IsSmi());
|
||||
// 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 {
|
||||
EnsureSpace ensure_space(this);
|
||||
last_pc_ = pc_;
|
||||
ASSERT(value->IsHeapObject());
|
||||
ASSERT(!Heap::InNewSpace(*value));
|
||||
emit_rex_64(dst);
|
||||
emit(0xB8 | dst.low_bits());
|
||||
if (value->IsHeapObject()) {
|
||||
emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
|
||||
} else {
|
||||
ASSERT_EQ(RelocInfo::NONE, mode);
|
||||
emitq(reinterpret_cast<uintptr_t>(*value), RelocInfo::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -566,10 +566,22 @@ class Assembler : public Malloced {
|
||||
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) {
|
||||
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) {
|
||||
arithmetic_op(0x3B, dst, src);
|
||||
}
|
||||
@ -1091,6 +1103,7 @@ class Assembler : public Malloced {
|
||||
// ModR/M byte.
|
||||
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, const Operand& dst, Register src);
|
||||
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, const Operand& dst, Immediate src);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -208,7 +208,9 @@ Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
|
||||
|
||||
|
||||
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));
|
||||
} else if (is_uint32(x)) {
|
||||
movl(dst, Immediate(x));
|
||||
@ -219,15 +221,18 @@ void MacroAssembler::Set(Register dst, int64_t x) {
|
||||
|
||||
|
||||
void MacroAssembler::Set(const Operand& dst, int64_t x) {
|
||||
if (is_int32(x)) {
|
||||
movq(kScratchRegister, Immediate(x));
|
||||
if (x == 0) {
|
||||
xor_(kScratchRegister, kScratchRegister);
|
||||
movq(dst, kScratchRegister);
|
||||
} else if (is_int32(x)) {
|
||||
movq(dst, Immediate(x));
|
||||
} else if (is_uint32(x)) {
|
||||
movl(kScratchRegister, Immediate(x));
|
||||
movl(dst, Immediate(x));
|
||||
} else {
|
||||
movq(kScratchRegister, x, RelocInfo::NONE);
|
||||
}
|
||||
movq(dst, kScratchRegister);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool MacroAssembler::IsUnsafeSmi(Smi* value) {
|
||||
@ -240,11 +245,13 @@ void MacroAssembler::LoadUnsafeSmi(Register dst, Smi* source) {
|
||||
|
||||
|
||||
void MacroAssembler::Move(Register dst, Handle<Object> source) {
|
||||
ASSERT(!source->IsFailure());
|
||||
if (source->IsSmi()) {
|
||||
if (IsUnsafeSmi(source)) {
|
||||
LoadUnsafeSmi(dst, source);
|
||||
} else {
|
||||
movq(dst, source, RelocInfo::NONE);
|
||||
int32_t smi = static_cast<int32_t>(reinterpret_cast<intptr_t>(*source));
|
||||
movq(dst, Immediate(smi));
|
||||
}
|
||||
} else {
|
||||
movq(dst, source, RelocInfo::EMBEDDED_OBJECT);
|
||||
@ -253,9 +260,14 @@ void MacroAssembler::Move(Register dst, Handle<Object> source) {
|
||||
|
||||
|
||||
void MacroAssembler::Move(const Operand& dst, Handle<Object> source) {
|
||||
Move(kScratchRegister, source);
|
||||
if (source->IsSmi()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
|
||||
@ -265,14 +277,37 @@ void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
|
||||
|
||||
|
||||
void MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) {
|
||||
Move(kScratchRegister, source);
|
||||
if (source->IsSmi()) {
|
||||
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) {
|
||||
Move(kScratchRegister, source);
|
||||
if (source->IsSmi()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user