Author: [email protected]
Date: Mon Jun 29 02:32:06 2009
New Revision: 2292
Modified:
branches/bleeding_edge/src/arm/assembler-arm.cc
branches/bleeding_edge/src/arm/disasm-arm.cc
branches/bleeding_edge/src/ia32/assembler-ia32.cc
branches/bleeding_edge/src/ia32/assembler-ia32.h
branches/bleeding_edge/src/x64/assembler-x64.cc
branches/bleeding_edge/src/x64/assembler-x64.h
branches/bleeding_edge/test/cctest/test-assembler-x64.cc
Log:
* Add missing imul instruction on Intel.
* Fix incorrect signedness in disassembly of umull/mull on ARM.
* Fix incorrect register order in disassembly of umull/mull.
* Fix incorrect assembly of umull on ARM.
* Remove retroactively obsoleted restriction on choice of
registers in mul instructions on ARM.
Review URL: http://codereview.chromium.org/150002
Modified: branches/bleeding_edge/src/arm/assembler-arm.cc
==============================================================================
--- branches/bleeding_edge/src/arm/assembler-arm.cc (original)
+++ branches/bleeding_edge/src/arm/assembler-arm.cc Mon Jun 29 02:32:06 2009
@@ -816,7 +816,6 @@
void Assembler::mla(Register dst, Register src1, Register src2, Register
srcA,
SBit s, Condition cond) {
ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
- ASSERT(!dst.is(src1));
emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 |
src2.code()*B8 | B7 | B4 | src1.code());
}
@@ -825,7 +824,6 @@
void Assembler::mul(Register dst, Register src1, Register src2,
SBit s, Condition cond) {
ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
- ASSERT(!dst.is(src1));
emit(cond | s | dst.code()*B16 | src2.code()*B8 | B7 | B4 | src1.code());
}
@@ -837,7 +835,7 @@
SBit s,
Condition cond) {
ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
- ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL));
+ ASSERT(!dstL.is(dstH));
emit(cond | B23 | B22 | A | s | dstH.code()*B16 | dstL.code()*B12 |
src2.code()*B8 | B7 | B4 | src1.code());
}
@@ -850,7 +848,7 @@
SBit s,
Condition cond) {
ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
- ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL));
+ ASSERT(!dstL.is(dstH));
emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
src2.code()*B8 | B7 | B4 | src1.code());
}
@@ -863,7 +861,7 @@
SBit s,
Condition cond) {
ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
- ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL));
+ ASSERT(!dstL.is(dstH));
emit(cond | B23 | A | s | dstH.code()*B16 | dstL.code()*B12 |
src2.code()*B8 | B7 | B4 | src1.code());
}
@@ -876,8 +874,8 @@
SBit s,
Condition cond) {
ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
- ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL));
- emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 |
+ ASSERT(!dstL.is(dstH));
+ emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
src2.code()*B8 | B7 | B4 | src1.code());
}
Modified: branches/bleeding_edge/src/arm/disasm-arm.cc
==============================================================================
--- branches/bleeding_edge/src/arm/disasm-arm.cc (original)
+++ branches/bleeding_edge/src/arm/disasm-arm.cc Mon Jun 29 02:32:06 2009
@@ -438,7 +438,7 @@
return 6;
}
case 'u': { // 'u: signed or unsigned multiplies
- if (instr->Bit(22) == 0) {
+ if (instr->Bit(22) == 1) {
Print("u");
} else {
Print("s");
@@ -499,7 +499,7 @@
Format(instr, "mla'cond's 'rd, 'rm, 'rs, 'rn");
}
} else {
- Format(instr, "'um'al'cond's 'rn, 'rd, 'rs, 'rm");
+ Format(instr, "'um'al'cond's 'rn, 'rd, 'rm, 'rs");
}
} else {
Unknown(instr); // not used by V8
Modified: branches/bleeding_edge/src/ia32/assembler-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/assembler-ia32.cc (original)
+++ branches/bleeding_edge/src/ia32/assembler-ia32.cc Mon Jun 29 02:32:06
2009
@@ -919,6 +919,14 @@
}
+void Assembler::imul(Register reg) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ EMIT(0xF7);
+ EMIT(0xE8 | reg.code());
+}
+
+
void Assembler::imul(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
Modified: branches/bleeding_edge/src/ia32/assembler-ia32.h
==============================================================================
--- branches/bleeding_edge/src/ia32/assembler-ia32.h (original)
+++ branches/bleeding_edge/src/ia32/assembler-ia32.h Mon Jun 29 02:32:06
2009
@@ -544,15 +544,18 @@
void idiv(Register src);
- void imul(Register dst, const Operand& src);
- void imul(Register dst, Register src, int32_t imm32);
+ // Signed multiply instructions.
+ void imul(Register src); // edx:eax = eax
* src.
+ void imul(Register dst, const Operand& src); // dst = dst *
src.
+ void imul(Register dst, Register src, int32_t imm32); // dst = src *
imm32.
void inc(Register dst);
void inc(const Operand& dst);
void lea(Register dst, const Operand& src);
- void mul(Register src);
+ // Unsigned multiply instruction.
+ void mul(Register src); // edx:eax = eax
* reg.
void neg(Register dst);
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 29 02:32:06 2009
@@ -750,6 +750,15 @@
}
+void Assembler::imul(Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_rex_64(src);
+ emit(0xF7);
+ emit_modrm(0x5, src);
+}
+
+
void Assembler::imul(Register dst, Register src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
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 29 02:32:06 2009
@@ -605,12 +605,13 @@
// Divide rdx:rax by src. Quotient in rax, remainder in rdx.
void idiv(Register src);
- void imul(Register dst, Register src);
- void imul(Register dst, const Operand& src);
- // Performs the operation dst = src * imm.
- void imul(Register dst, Register src, Immediate imm);
+ // Signed multiply instructions.
+ void imul(Register src); // rdx:rax = rax
* src.
+ void imul(Register dst, Register src); // dst = dst *
src.
+ void imul(Register dst, const Operand& src); // dst = dst *
src.
+ void imul(Register dst, Register src, Immediate imm); // dst = src *
imm.
// Multiply 32 bit registers
- void imull(Register dst, Register src);
+ void imull(Register dst, Register src); // dst = dst *
src.
void incq(Register dst);
void incq(const Operand& dst);
Modified: branches/bleeding_edge/test/cctest/test-assembler-x64.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-assembler-x64.cc (original)
+++ branches/bleeding_edge/test/cctest/test-assembler-x64.cc Mon Jun 29
02:32:06 2009
@@ -44,6 +44,7 @@
using v8::internal::rax;
using v8::internal::rsi;
using v8::internal::rdi;
+using v8::internal::rdx;
using v8::internal::rbp;
using v8::internal::rsp;
using v8::internal::FUNCTION_CAST;
@@ -63,8 +64,8 @@
// with GCC. A different convention is used on 64-bit windows.
typedef int (*F0)();
-typedef int (*F1)(int x);
-typedef int (*F2)(int x, int y);
+typedef int (*F1)(int64_t x);
+typedef int (*F2)(int64_t x, int64_t y);
#define __ assm.
@@ -130,7 +131,7 @@
CHECK(buffer);
Assembler assm(buffer, actual_size);
- // Assemble a simple function that copies argument 2 and returns it.
+ // Assemble a simple function that adds arguments returning the sum.
__ movq(rax, rsi);
__ addq(rax, rdi);
__ ret(0);
@@ -140,6 +141,33 @@
// Call the function from C++.
int result = FUNCTION_CAST<F2>(buffer)(3, 2);
CHECK_EQ(5, result);
+}
+
+TEST(AssemblerX64ImulOperation) {
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer =
static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
+ &actual_size,
+ true));
+ CHECK(buffer);
+ Assembler assm(buffer, actual_size);
+
+ // Assemble a simple function that multiplies arguments returning the
high
+ // word.
+ __ movq(rax, rsi);
+ __ imul(rdi);
+ __ movq(rax, rdx);
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ // Call the function from C++.
+ int result = FUNCTION_CAST<F2>(buffer)(3, 2);
+ CHECK_EQ(0, result);
+ result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l);
+ CHECK_EQ(1, result);
+ result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l);
+ CHECK_EQ(-1, result);
}
TEST(AssemblerX64MemoryOperands) {
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---