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

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

Issue 119078: Add multiplication and division to x64 assembler. Add emit_modrm() function. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 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
« no previous file with comments | « src/x64/assembler-x64.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/assembler-x64.cc
===================================================================
--- src/x64/assembler-x64.cc (revision 2097)
+++ src/x64/assembler-x64.cc (working copy)
@@ -342,7 +342,7 @@
const unsigned length = adr.len_;
ASSERT(length > 0);
- // Emit updated ModRM byte containing the given register.
+ // Emit updated ModR/M byte containing the given register.
pc_[0] = (adr.buf_[0] & ~0x38) | (rm << 3);
// Emit the rest of the encoded operand.
@@ -367,7 +367,7 @@
last_pc_ = pc_;
emit_rex_64(dst, src);
emit(opcode);
- emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7));
+ emit_modrm(dst, src);
}
void Assembler::immediate_arithmetic_op(byte subcode,
@@ -378,14 +378,14 @@
emit_rex_64(dst);
if (is_int8(src.value_)) {
emit(0x83);
- emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
+ emit_modrm(subcode, dst);
emit(src.value_);
} else if (dst.is(rax)) {
emit(0x05 | (subcode << 3));
emitl(src.value_);
} else {
emit(0x81);
- emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
+ emit_modrm(subcode, dst);
emitl(src.value_);
}
}
@@ -415,11 +415,11 @@
if (shift_amount.value_ == 1) {
emit_rex_64(dst);
emit(0xD1);
- emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
+ emit_modrm(subcode, dst);
} else {
emit_rex_64(dst);
emit(0xC1);
- emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
+ emit_modrm(subcode, dst);
emit(shift_amount.value_);
}
}
@@ -430,7 +430,7 @@
last_pc_ = pc_;
emit_rex_64(dst);
emit(0xD3);
- emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
+ emit_modrm(subcode, dst);
}
@@ -479,11 +479,11 @@
EnsureSpace ensure_space(this);
last_pc_ = pc_;
// Opcode: FF /2 r64
- if (!is_uint3(adr.code())) {
+ if (adr.code() > 7) {
emit_rex_64(adr);
}
emit(0xFF);
- emit(0xD0 | (adr.code() & 0x07));
+ emit_modrm(0x2, adr);
}
@@ -509,7 +509,7 @@
last_pc_ = pc_;
emit_rex_64(dst);
emit(0xFF);
- emit(0xC8 | (dst.code() & 0x7));
+ emit_modrm(0x1, dst);
}
@@ -538,12 +538,47 @@
}
+void Assembler::idiv(Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(src);
+ emit(0xF7);
+ emit_modrm(0x7, src);
+}
+
+
+void Assembler::imul(Register dst, const Operand& src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(dst, src);
+ emit(0x0F);
+ emit(0xAF);
+ emit_operand(dst, src);
+}
+
+
+void Assembler::imul(Register dst, Register src, Immediate imm) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(dst, src);
+ if (is_int8(imm.value_)) {
+ emit(0x6B);
+ emit_modrm(dst, src);
+ emit(imm.value_);
+ } else {
+ emit(0x69);
+ emit_modrm(dst, src);
+ emitl(imm.value_);
+ }
+}
+
+
void Assembler::inc(Register dst) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_rex_64(dst);
emit(0xFF);
- emit(0xC0 | (dst.code() & 0x7));
+ emit_modrm(0x0, dst);
}
@@ -634,11 +669,11 @@
EnsureSpace ensure_space(this);
last_pc_ = pc_;
// Opcode FF/4 r64
- if (!is_uint3(target.code())) {
+ if (target.code() > 7) {
emit_rex_64(target);
}
emit(0xFF);
- emit(0xE0 | target.code() & 0x07);
+ emit_modrm(0x4, target);
}
@@ -658,6 +693,31 @@
}
+void Assembler::movb(Register dst, const Operand& src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_32(dst, src);
+ emit(0x8A);
+ emit_operand(dst, src);
+}
+
+void Assembler::movb(Register dst, Immediate imm) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_32(dst);
+ emit(0xC6);
+ emit_modrm(0x0, dst);
+ emit(imm.value_);
+}
+
+void Assembler::movb(const Operand& dst, Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_32(src, dst);
+ emit(0x88);
+ emit_operand(src, dst);
+}
+
void Assembler::movl(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
@@ -672,7 +732,7 @@
last_pc_ = pc_;
emit_optional_rex_32(dst, src);
emit(0x8B);
- emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7));
+ emit_modrm(dst, src);
}
@@ -690,7 +750,7 @@
last_pc_ = pc_;
emit_optional_rex_32(dst);
emit(0xC7);
- emit(0xC0 | (dst.code() & 0x7));
+ emit_modrm(0x0, dst);
emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
}
@@ -709,7 +769,7 @@
last_pc_ = pc_;
emit_rex_64(dst, src);
emit(0x8B);
- emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7));
+ emit_modrm(dst, src);
}
@@ -718,7 +778,7 @@
last_pc_ = pc_;
emit_rex_64(dst);
emit(0xC7);
- emit(0xC0 | (dst.code() & 0x7));
+ emit_modrm(0x0, dst);
emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
}
@@ -727,7 +787,7 @@
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_rex_64(dst);
- emit(0xB8 | (dst.code() & 0x7));
+ emit(0xB8 | (dst.code() & 0x7)); // Not a ModR/M byte.
emitq(value, rmode);
}
@@ -741,12 +801,21 @@
}
+void Assembler::mul(Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(src);
+ emit(0xF7);
+ emit_modrm(0x4, src);
+}
+
+
void Assembler::neg(Register dst) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_rex_64(dst);
emit(0xF7);
- emit(0xC0 | (0x3 << 3) | (dst.code() & 0x7));
+ emit_modrm(0x3, dst);
}
@@ -771,7 +840,7 @@
last_pc_ = pc_;
emit_rex_64(dst);
emit(0xF7);
- emit(0xC0 | (0x2 << 3) | (dst.code() & 0x7));
+ emit_modrm(0x2, dst);
}
@@ -874,7 +943,7 @@
void Assembler::pop(Register dst) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
- if (dst.code() & 0x8) {
+ if (dst.code() > 7) {
emit_rex_64(dst);
}
emit(0x58 | (dst.code() & 0x7));
@@ -900,7 +969,7 @@
void Assembler::push(Register src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
- if (src.code() & 0x8) {
+ if (src.code() > 7) {
emit_rex_64(src);
}
emit(0x50 | (src.code() & 0x7));
@@ -943,11 +1012,11 @@
if (imm8 == 1) {
emit_rex_64(dst);
emit(0xD1);
- emit(0xD0 | (dst.code() & 0x7));
+ emit_modrm(0x2, dst);
} else {
emit_rex_64(dst);
emit(0xC1);
- emit(0xD0 | (dst.code() & 0x7));
+ emit_modrm(0x2, dst);
emit(imm8);
}
}
@@ -967,6 +1036,26 @@
}
+void Assembler::shld(Register dst, Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(src, dst);
+ emit(0x0F);
+ emit(0xA5);
+ emit_modrm(src, dst);
+}
+
+
+void Assembler::shrd(Register dst, Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(src, dst);
+ emit(0x0F);
+ emit(0xAD);
+ emit_modrm(src, dst);
+}
+
+
void Assembler::xchg(Register dst, Register src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
@@ -977,7 +1066,7 @@
} else {
emit_rex_64(src, dst);
emit(0x87);
- emit(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7));
+ emit_modrm(src, dst);
}
}
@@ -989,11 +1078,12 @@
emit(0xA8);
emit(mask);
} else {
- if (reg.code() & 0x8) {
- emit_rex_32(rax, reg);
+ if (reg.code() > 3) {
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(reg);
}
emit(0xF6);
- emit(0xC0 | (reg.code() & 0x3));
+ emit_modrm(0x0, reg);
emit(mask.value_); // Low byte emitted.
}
}
@@ -1018,7 +1108,7 @@
} else {
emit_optional_rex_32(rax, reg);
emit(0xF7);
- emit(0xC0 | (reg.code() & 0x3));
+ emit_modrm(0x0, reg);
emit(mask);
}
}
@@ -1034,6 +1124,24 @@
}
+void Assembler::testq(const Operand& op, Register reg) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(reg, op);
+ emit(0x85);
+ emit_operand(reg, op);
+}
+
+
+void Assembler::testq(Register dst, Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(dst, src);
+ emit(0x85);
+ emit_modrm(dst, src);
+}
+
+
// Relocation information implementations
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
« no previous file with comments | « src/x64/assembler-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698