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
This commit is contained in:
whesse@chromium.org 2009-05-20 14:14:44 +00:00
parent 19d279f815
commit 1ac2603eb7
4 changed files with 65 additions and 45 deletions

View File

@ -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<int8_t*>(&buf_[len_++]) = disp;
}
void Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) {
ASSERT(len_ == 1 || len_ == 2);
int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);

View File

@ -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<int8_t*>(&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.

View File

@ -148,6 +148,48 @@ Object** RelocInfo::call_object_address() {
return reinterpret_cast<Object**>(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<int32_t*>(&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_

View File

@ -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<intptr_t>(ext.address()),
RelocInfo::EXTERNAL_REFERENCE);
}
static Operand StaticArray(Register index,
ScaleFactor scale,
const ExternalReference& arr) {
return Operand(index, scale, reinterpret_cast<intptr_t>(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<intptr_t>(ext.address()),
RelocInfo::EXTERNAL_REFERENCE);
}
static MemOperand StaticArray(Register index,
ScaleFactor scale,
const ExternalReference& arr) {
return MemOperand(index, scale, reinterpret_cast<intptr_t>(arr.address()),
RelocInfo::EXTERNAL_REFERENCE);
}
};
// -----------------------------------------------------------------------------