Author: [email protected]
Date: Mon Jun 22 01:17:44 2009
New Revision: 2231
Modified:
branches/bleeding_edge/src/x64/assembler-x64-inl.h
branches/bleeding_edge/src/x64/assembler-x64.cc
branches/bleeding_edge/src/x64/assembler-x64.h
Log:
X64 implementation: Add high_bit() and low_bits() to register methods.
Review URL: http://codereview.chromium.org/141032
Modified: branches/bleeding_edge/src/x64/assembler-x64-inl.h
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64-inl.h (original)
+++ branches/bleeding_edge/src/x64/assembler-x64-inl.h Mon Jun 22 01:17:44
2009
@@ -70,18 +70,18 @@
void Assembler::emit_rex_64(Register reg, Register rm_reg) {
- emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
+ emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit());
}
void Assembler::emit_rex_64(Register reg, const Operand& op) {
- emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_);
+ emit(0x48 | reg.high_bit() << 2 | op.rex_);
}
void Assembler::emit_rex_64(Register rm_reg) {
ASSERT_EQ(rm_reg.code() & 0xf, rm_reg.code());
- emit(0x48 | (rm_reg.code() >> 3));
+ emit(0x48 | rm_reg.high_bit());
}
@@ -91,17 +91,17 @@
void Assembler::emit_rex_32(Register reg, Register rm_reg) {
- emit(0x40 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
+ emit(0x40 | reg.high_bit() << 2 | rm_reg.high_bit());
}
void Assembler::emit_rex_32(Register reg, const Operand& op) {
- emit(0x40 | (reg.code() & 0x8) >> 1 | op.rex_);
+ emit(0x40 | reg.high_bit() << 2 | op.rex_);
}
void Assembler::emit_rex_32(Register rm_reg) {
- emit(0x40 | (rm_reg.code() & 0x8) >> 3);
+ emit(0x40 | rm_reg.high_bit());
}
@@ -111,19 +111,19 @@
void Assembler::emit_optional_rex_32(Register reg, Register rm_reg) {
- byte rex_bits = (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3;
+ byte rex_bits = reg.high_bit() << 2 | rm_reg.high_bit();
if (rex_bits != 0) emit(0x40 | rex_bits);
}
void Assembler::emit_optional_rex_32(Register reg, const Operand& op) {
- byte rex_bits = (reg.code() & 0x8) >> 1 | op.rex_;
+ byte rex_bits = reg.high_bit() << 2 | op.rex_;
if (rex_bits != 0) emit(0x40 | rex_bits);
}
void Assembler::emit_optional_rex_32(Register rm_reg) {
- if (rm_reg.code() > 0x7) emit(0x41);
+ if (rm_reg.high_bit()) emit(0x41);
}
@@ -244,11 +244,11 @@
//
-----------------------------------------------------------------------------
// Implementation of Operand
-void Operand::set_modrm(int mod, Register rm) {
- ASSERT((mod & -4) == 0);
- buf_[0] = (mod << 6) | (rm.code() & 0x7);
+void Operand::set_modrm(int mod, Register rm_reg) {
+ ASSERT(is_uint2(mod));
+ buf_[0] = mod << 6 | rm_reg.low_bits();
// Set REX.B to the high bit of rm.code().
- rex_ |= (rm.code() >> 3);
+ rex_ |= rm_reg.high_bit();
}
@@ -258,8 +258,8 @@
// Use SIB with no index register only for base rsp or r12. Otherwise we
// would skip the SIB byte entirely.
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;
+ buf_[1] = scale << 6 | index.low_bits() << 3 | base.low_bits();
+ rex_ |= index.high_bit() << 1 | base.high_bit();
len_ = 2;
}
Modified: branches/bleeding_edge/src/x64/assembler-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.cc (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.cc Mon Jun 22 01:17:44 2009
@@ -380,13 +380,14 @@
}
-void Assembler::emit_operand(int rm, const Operand& adr) {
- ASSERT_EQ(rm & 0x07, rm);
+void Assembler::emit_operand(int code, const Operand& adr) {
+ ASSERT(is_uint3(code));
const unsigned length = adr.len_;
ASSERT(length > 0);
// Emit updated ModR/M byte containing the given register.
- pc_[0] = (adr.buf_[0] & ~0x38) | (rm << 3);
+ ASSERT((adr.buf_[0] & 0x38) == 0);
+ pc_[0] = adr.buf_[0] | code << 3;
// Emit the rest of the encoded operand.
for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
@@ -593,7 +594,7 @@
EnsureSpace ensure_space(this);
last_pc_ = pc_;
// Opcode: FF /2 r64
- if (adr.code() > 7) {
+ if (adr.high_bit()) {
emit_rex_64(adr);
}
emit(0xFF);
@@ -763,7 +764,7 @@
void Assembler::j(Condition cc, Label* L) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
- ASSERT(0 <= cc && cc < 16);
+ ASSERT(is_uint4(cc));
if (L->is_bound()) {
const int short_size = 2;
const int long_size = 6;
@@ -831,7 +832,7 @@
EnsureSpace ensure_space(this);
last_pc_ = pc_;
// Opcode FF/4 r64
- if (target.code() > 7) {
+ if (target.high_bit()) {
emit_rex_64(target);
}
emit(0xFF);
@@ -982,7 +983,7 @@
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_rex_64(dst);
- emit(0xB8 | (dst.code() & 0x7));
+ emit(0xB8 | dst.low_bits());
emitq(reinterpret_cast<uintptr_t>(value), rmode);
}
@@ -991,7 +992,7 @@
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_rex_64(dst);
- emit(0xB8 | (dst.code() & 0x7)); // Not a ModR/M byte.
+ emit(0xB8 | dst.low_bits());
emitq(value, rmode);
}
@@ -1000,7 +1001,7 @@
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_rex_64(dst);
- emit(0xB8 | (dst.code() & 0x7));
+ emit(0xB8 | dst.low_bits());
emitq(reinterpret_cast<uintptr_t>(ref.address()),
RelocInfo::EXTERNAL_REFERENCE);
}
@@ -1021,7 +1022,7 @@
last_pc_ = pc_;
ASSERT(!Heap::InNewSpace(*value));
emit_rex_64(dst);
- emit(0xB8 | (dst.code() & 0x7));
+ emit(0xB8 | dst.low_bits());
if (value->IsHeapObject()) {
emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
} else {
@@ -1192,10 +1193,10 @@
void Assembler::pop(Register dst) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
- if (dst.code() > 7) {
+ if (dst.high_bit()) {
emit_rex_64(dst);
}
- emit(0x58 | (dst.code() & 0x7));
+ emit(0x58 | dst.low_bits());
}
@@ -1218,10 +1219,10 @@
void Assembler::push(Register src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
- if (src.code() > 7) {
+ if (src.high_bit()) {
emit_rex_64(src);
}
- emit(0x50 | (src.code() & 0x7));
+ emit(0x50 | src.low_bits());
}
@@ -1295,7 +1296,7 @@
void Assembler::setcc(Condition cc, Register reg) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
- ASSERT(0 <= cc && cc < 16);
+ ASSERT(is_uint4(cc));
if (reg.code() > 3) { // Use x64 byte registers, where different.
emit_rex_32(reg);
}
@@ -1331,7 +1332,7 @@
if (src.is(rax) || dst.is(rax)) { // Single-byte encoding
Register other = src.is(rax) ? dst : src;
emit_rex_64(other);
- emit(0x90 | (other.code() & 0x7));
+ emit(0x90 | other.low_bits());
} else {
emit_rex_64(src, dst);
emit(0x87);
@@ -1755,7 +1756,7 @@
void Assembler::emit_farith(int b1, int b2, int i) {
ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
- ASSERT(0 <= i && i < 8); // illegal stack offset
+ ASSERT(is_uint3(i)); // illegal stack offset
emit(b1);
emit(b2 + i);
}
Modified: branches/bleeding_edge/src/x64/assembler-x64.h
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.h (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.h Mon Jun 22 01:17:44 2009
@@ -92,6 +92,17 @@
return 1 << code_;
}
+ // Return the high bit of the register code as a 0 or 1. Used often
+ // when constructing the REX prefix byte.
+ int high_bit() const {
+ return code_ >> 3;
+ }
+ // Return the 3 low bits of the register code. Used when encoding
registers
+ // in modR/M, SIB, and opcode bytes.
+ int low_bits() const {
+ return code_ & 0x7;
+ }
+
// (unfortunately we can't make this private in a struct when
initializing
// by assignment.)
int code_;
@@ -983,7 +994,7 @@
// the second operand of the operation, a register or operation
// subcode, into the reg field of the ModR/M byte.
void emit_operand(Register reg, const Operand& adr) {
- emit_operand(reg.code() & 0x07, adr);
+ emit_operand(reg.low_bits(), adr);
}
// Emit the ModR/M byte, and optionally the SIB byte and
@@ -993,14 +1004,14 @@
// Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
void emit_modrm(Register reg, Register rm_reg) {
- emit(0xC0 | (reg.code() & 0x7) << 3 | (rm_reg.code() & 0x7));
+ emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
}
// Emit a ModR/M byte with an operation subcode in the reg field and
// a register in the rm_reg field.
void emit_modrm(int code, Register rm_reg) {
- ASSERT((code & ~0x7) == 0);
- emit(0xC0 | (code & 0x7) << 3 | (rm_reg.code() & 0x7));
+ ASSERT(is_uint3(code));
+ emit(0xC0 | code << 3 | rm_reg.low_bits());
}
// Emit the code-object-relative offset of the label's position
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---