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

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

Issue 2242002: X64: Make smi memory operations work directly on the embedded value. (Closed)
Patch Set: Created 10 years, 7 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
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 3d03949f25633f7cdefbfe1b5de5801b26bee995..8bdce9cb09cd440eab6d0058c62f7d5deb557c4f 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -239,6 +239,49 @@ Operand::Operand(Register index,
}
+Operand::Operand(const Operand& operand, int32_t offset) {
+ ASSERT(operand.len_ >= 1);
+ // Operand encodes REX ModR/M [SIB] [Disp].
+ byte modrm = operand.buf_[0];
+ ASSERT(modrm < 0xC0); // Disallow mode 3 (register target).
+ bool has_sib = ((modrm & 0x07) == 0x04);
+ byte mode = modrm & 0xC0;
+ int disp_offset = has_sib ? 2 : 1;
+ int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
+ // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
+ // displacement.
+ bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base.
+ int32_t disp_value = 0;
+ if (mode == 0x80 || is_baseless) {
+ // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
+ disp_value = *reinterpret_cast<const int32_t*>(&operand.buf_[disp_offset]);
+ } else if (mode == 0x40) {
+ // Mode 1: Byte displacement.
+ disp_value = static_cast<signed char>(operand.buf_[disp_offset]);
+ }
+ // Write new operand with same registers, but with modified displacement.
William Hesse 2010/05/26 08:13:24 Insert blank line after reading and before writing
Lasse Reichstein 2010/05/26 08:34:11 Done.
+ disp_value += offset;
William Hesse 2010/05/26 08:13:24 The assert for no overflow could be added: ASSERT(
Lasse Reichstein 2010/05/26 08:34:11 Assertion added.
+ rex_ = operand.rex_;
+ if (!is_int8(disp_value) || is_baseless) {
+ // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
+ buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
+ len_ = disp_offset + 4;
+ Memory::int32_at(&buf_[disp_offset]) = disp_value;
+ } else if (disp_value != 0 || (base_reg == 0x05)) {
+ // Need 8 bits of displacement.
+ buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1.
+ len_ = disp_offset + 1;
+ buf_[disp_offset] = static_cast<byte>(disp_value);
+ } else {
+ // Need no displacement.
+ buf_[0] = (modrm & 0x3f); // Mode 0.
+ len_ = disp_offset;
+ }
+ if (has_sib) {
+ buf_[1] = operand.buf_[1];
+ }
+}
+
// -----------------------------------------------------------------------------
// Implementation of Assembler.

Powered by Google App Engine
This is Rietveld 408576698