From 1ac2603eb76ef8fca0f2e8d6f685d666587aa01a Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Wed, 20 May 2009 14:14:44 +0000 Subject: [PATCH] Add the REX prefix to 64-bit assembly operands. Move some inline functions. Review URL: http://codereview.chromium.org/115568 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2017 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/assembler-ia32-inl.h | 16 ++++++++++++++++ src/ia32/assembler-ia32.cc | 14 -------------- src/x64/assembler-x64-inl.h | 42 ++++++++++++++++++++++++++++++++++++++++++ src/x64/assembler-x64.h | 38 +++++++------------------------------- 4 files changed, 65 insertions(+), 45 deletions(-) diff --git a/src/ia32/assembler-ia32-inl.h b/src/ia32/assembler-ia32-inl.h index c1edd32..8d5e4f2 100644 --- a/src/ia32/assembler-ia32-inl.h +++ b/src/ia32/assembler-ia32-inl.h @@ -277,6 +277,22 @@ void Operand::set_modrm(int mod, Register rm) { } +void Operand::set_sib(ScaleFactor scale, Register index, Register base) { + ASSERT(len_ == 1); + ASSERT((scale & -4) == 0); + // Use SIB with no index register only for base esp. + ASSERT(!index.is(esp) || base.is(esp)); + buf_[1] = scale << 6 | index.code() << 3 | base.code(); + len_ = 2; +} + + +void Operand::set_disp8(int8_t disp) { + ASSERT(len_ == 1 || len_ == 2); + *reinterpret_cast(&buf_[len_++]) = disp; +} + + void Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) { ASSERT(len_ == 1 || len_ == 2); int32_t* p = reinterpret_cast(&buf_[len_]); diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc index e5e9455..ca9a534 100644 --- a/src/ia32/assembler-ia32.cc +++ b/src/ia32/assembler-ia32.cc @@ -256,20 +256,6 @@ Operand::Operand(Register index, } -void Operand::set_sib(ScaleFactor scale, Register index, Register base) { - ASSERT(len_ == 1); - ASSERT((scale & -4) == 0); - buf_[1] = scale << 6 | index.code() << 3 | base.code(); - len_ = 2; -} - - -void Operand::set_disp8(int8_t disp) { - ASSERT(len_ == 1 || len_ == 2); - *reinterpret_cast(&buf_[len_++]) = disp; -} - - bool Operand::is_reg(Register reg) const { return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. && ((buf_[0] & 0x07) == reg.code()); // register codes match. diff --git a/src/x64/assembler-x64-inl.h b/src/x64/assembler-x64-inl.h index b617507..d555eb8 100644 --- a/src/x64/assembler-x64-inl.h +++ b/src/x64/assembler-x64-inl.h @@ -148,6 +148,48 @@ Object** RelocInfo::call_object_address() { return reinterpret_cast(pc_ + 1); } + +void Operand::set_modrm(int mod, Register rm) { + ASSERT((mod & -4) == 0); + buf_[0] = mod << 6 | (rm.code() & 0x7); + // Set REX.B to the high bit of rm.code(). + rex_ |= (rm.code() >> 3); + len_ = 1; +} + + +void Operand::set_sib(ScaleFactor scale, Register index, Register base) { + ASSERT(len_ == 1); + ASSERT((scale & -4) == 0); + // Use SIB with no index register only for base rsp or r12. + ASSERT(!index.is(rsp) || base.is(rsp) || base.is(r12)); + buf_[1] = scale << 6 | (index.code() & 0x7) << 3 | (base.code() & 0x7); + rex_ |= (index.code() >> 3) << 1 | base.code() >> 3; + len_ = 2; +} + + +void Operand::set_disp32(int32_t disp) { + ASSERT(len_ == 1 || len_ == 2); + int32_t* p = reinterpret_cast(&buf_[len_]); + *p = disp; + len_ += sizeof(int32_t); +} + + +void Operand::set_dispr(intptr_t disp, RelocInfo::Mode rmode) { + // This cannot be used in 64-bit mode. A 64-bit displacement + // cannot be encoded, so relocatable 64-bit values must be + // loaded as immediates. + UNIMPLEMENTED(); +} + + +Operand::Operand(Register reg) { + // reg + set_modrm(3, reg); +} + } } // namespace v8::internal #endif // V8_X64_ASSEMBLER_X64_INL_H_ diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h index 7328f07..f64d272 100644 --- a/src/x64/assembler-x64.h +++ b/src/x64/assembler-x64.h @@ -264,34 +264,22 @@ class Operand BASE_EMBEDDED { // disp only must always be relocated // [base + disp/r] - explicit Operand(Register base, intptr_t disp, + explicit Operand(Register base, int32_t disp, RelocInfo::Mode rmode = RelocInfo::NONE); // [base + index*scale + disp/r] explicit Operand(Register base, Register index, ScaleFactor scale, - intptr_t disp, + int32_t disp, RelocInfo::Mode rmode = RelocInfo::NONE); // [index*scale + disp/r] explicit Operand(Register index, ScaleFactor scale, - intptr_t disp, + int32_t disp, RelocInfo::Mode rmode = RelocInfo::NONE); - static Operand StaticVariable(const ExternalReference& ext) { - return Operand(reinterpret_cast(ext.address()), - RelocInfo::EXTERNAL_REFERENCE); - } - - static Operand StaticArray(Register index, - ScaleFactor scale, - const ExternalReference& arr) { - return Operand(index, scale, reinterpret_cast(arr.address()), - RelocInfo::EXTERNAL_REFERENCE); - } - // End of constructors and methods that have been moved to MemOperand. private: @@ -317,40 +305,28 @@ class Operand BASE_EMBEDDED { class MemOperand : public Operand { public: // [disp/r] - INLINE(explicit MemOperand(intptr_t disp, RelocInfo::Mode rmode)) : + INLINE(explicit MemOperand(int32_t disp, RelocInfo::Mode rmode)) : Operand() { UNIMPLEMENTED(); } // disp only must always be relocated // [base + disp/r] - explicit MemOperand(Register base, intptr_t disp, + explicit MemOperand(Register base, int32_t disp, RelocInfo::Mode rmode = RelocInfo::NONE); // [base + index*scale + disp/r] explicit MemOperand(Register base, Register index, ScaleFactor scale, - intptr_t disp, + int32_t disp, RelocInfo::Mode rmode = RelocInfo::NONE); // [index*scale + disp/r] explicit MemOperand(Register index, ScaleFactor scale, - intptr_t disp, + int32_t disp, RelocInfo::Mode rmode = RelocInfo::NONE); - - static MemOperand StaticVariable(const ExternalReference& ext) { - return MemOperand(reinterpret_cast(ext.address()), - RelocInfo::EXTERNAL_REFERENCE); - } - - static MemOperand StaticArray(Register index, - ScaleFactor scale, - const ExternalReference& arr) { - return MemOperand(index, scale, reinterpret_cast(arr.address()), - RelocInfo::EXTERNAL_REFERENCE); - } }; // ----------------------------------------------------------------------------- -- 2.7.4