Index: src/x64/assembler-x64.cc |
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc |
index 2f757a81b7aa1f95f77cc2b07d344e5512da116f..989a748933467c1bbbb7915ed57d2bedf78b899b 100644 |
--- a/src/x64/assembler-x64.cc |
+++ b/src/x64/assembler-x64.cc |
@@ -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,11 +1079,23 @@ void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) { |
void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { |
- EnsureSpace ensure_space(this); |
- last_pc_ = pc_; |
- emit_rex_64(dst); |
- emit(0xB8 | dst.low_bits()); |
- emitq(value, 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); |
+ } |
} |
@@ -1097,16 +1120,24 @@ void Assembler::movq(const Operand& dst, Immediate value) { |
void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) { |
- EnsureSpace ensure_space(this); |
- last_pc_ = pc_; |
- ASSERT(!Heap::InNewSpace(*value)); |
- emit_rex_64(dst); |
- emit(0xB8 | dst.low_bits()); |
- if (value->IsHeapObject()) { |
- emitq(reinterpret_cast<uintptr_t>(value.location()), 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 { |
- ASSERT_EQ(RelocInfo::NONE, mode); |
- emitq(reinterpret_cast<uintptr_t>(*value), RelocInfo::NONE); |
+ EnsureSpace ensure_space(this); |
+ 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); |
} |
} |