Make ldrd and strd instructions take two register arguments

Review URL: http://codereview.chromium.org/2122021

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4724 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
sgjesse@chromium.org 2010-05-26 09:43:54 +00:00
parent e268fbdaba
commit f952df4be1
4 changed files with 41 additions and 31 deletions

View File

@ -1363,39 +1363,45 @@ void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) {
}
void Assembler::ldrd(Register dst, const MemOperand& src, Condition cond) {
void Assembler::ldrd(Register dst1,
Register dst2,
const MemOperand& src, Condition cond) {
ASSERT(src.rm().is(no_reg));
ASSERT(!dst1.is(lr)); // r14.
ASSERT_EQ(0, dst1.code() % 2);
ASSERT_EQ(dst1.code() + 1, dst2.code());
#ifdef CAN_USE_ARMV7_INSTRUCTIONS
addrmod3(cond | B7 | B6 | B4, dst, src);
addrmod3(cond | B7 | B6 | B4, dst1, src);
#else
// Generate two ldr instructions if ldrd is not available.
MemOperand src1(src);
src1.set_offset(src1.offset() + 4);
Register dst1(dst);
dst1.set_code(dst1.code() + 1);
if (dst.is(src.rn())) {
ldr(dst1, src1, cond);
ldr(dst, src, cond);
MemOperand src2(src);
src2.set_offset(src2.offset() + 4);
if (dst1.is(src.rn())) {
ldr(dst2, src2, cond);
ldr(dst1, src, cond);
} else {
ldr(dst, src, cond);
ldr(dst1, src1, cond);
ldr(dst1, src, cond);
ldr(dst2, src2, cond);
}
#endif
}
void Assembler::strd(Register src, const MemOperand& dst, Condition cond) {
void Assembler::strd(Register src1,
Register src2,
const MemOperand& dst, Condition cond) {
ASSERT(dst.rm().is(no_reg));
ASSERT(!src1.is(lr)); // r14.
ASSERT_EQ(0, src1.code() % 2);
ASSERT_EQ(src1.code() + 1, src2.code());
#ifdef CAN_USE_ARMV7_INSTRUCTIONS
addrmod3(cond | B7 | B6 | B5 | B4, src, dst);
addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
#else
// Generate two str instructions if strd is not available.
MemOperand dst1(dst);
dst1.set_offset(dst1.offset() + 4);
Register src1(src);
src1.set_code(src1.code() + 1);
str(src, dst, cond);
str(src1, dst1, cond);
MemOperand dst2(dst);
dst2.set_offset(dst2.offset() + 4);
str(src1, dst, cond);
str(src2, dst2, cond);
#endif
}

View File

@ -773,8 +773,12 @@ class Assembler : public Malloced {
void strh(Register src, const MemOperand& dst, Condition cond = al);
void ldrsb(Register dst, const MemOperand& src, Condition cond = al);
void ldrsh(Register dst, const MemOperand& src, Condition cond = al);
void ldrd(Register dst, const MemOperand& src, Condition cond = al);
void strd(Register src, const MemOperand& dst, Condition cond = al);
void ldrd(Register dst1,
Register dst2,
const MemOperand& src, Condition cond = al);
void strd(Register src1,
Register src2,
const MemOperand& dst, Condition cond = al);
// Load/Store multiple instructions
void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);

View File

@ -1514,7 +1514,7 @@ void CodeGenerator::CallApplyLazy(Expression* applicand,
// Then process it as a normal function call.
__ ldr(r0, MemOperand(sp, 3 * kPointerSize));
__ ldr(r1, MemOperand(sp, 2 * kPointerSize));
__ strd(r0, MemOperand(sp, 2 * kPointerSize));
__ strd(r0, r1, MemOperand(sp, 2 * kPointerSize));
CallFunctionStub call_function(2, NOT_IN_LOOP, NO_CALL_FUNCTION_FLAGS);
frame_->CallStub(&call_function, 3);
@ -2307,7 +2307,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
node->continue_target()->SetExpectedHeight();
// Load the current count to r0, load the length to r1.
__ ldrd(r0, frame_->ElementAt(0));
__ ldrd(r0, r1, frame_->ElementAt(0));
__ cmp(r0, r1); // compare to the array length
node->break_target()->Branch(hs);
@ -6379,7 +6379,7 @@ static void EmitSmiNonsmiComparison(MacroAssembler* masm,
ConvertToDoubleStub stub1(r3, r2, r7, r6);
__ Call(stub1.GetCode(), RelocInfo::CODE_TARGET);
// Load rhs to a double in r0, r1.
__ ldrd(r0, FieldMemOperand(r0, HeapNumber::kValueOffset));
__ ldrd(r0, r1, FieldMemOperand(r0, HeapNumber::kValueOffset));
__ pop(lr);
}
@ -6414,7 +6414,7 @@ static void EmitSmiNonsmiComparison(MacroAssembler* masm,
} else {
__ push(lr);
// Load lhs to a double in r2, r3.
__ ldrd(r2, FieldMemOperand(r1, HeapNumber::kValueOffset));
__ ldrd(r2, r3, FieldMemOperand(r1, HeapNumber::kValueOffset));
// Convert rhs to a double in r0, r1.
__ mov(r7, Operand(r0));
ConvertToDoubleStub stub2(r1, r0, r7, r6);
@ -6578,8 +6578,8 @@ static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm,
__ sub(r7, r1, Operand(kHeapObjectTag));
__ vldr(d7, r7, HeapNumber::kValueOffset);
} else {
__ ldrd(r2, FieldMemOperand(r1, HeapNumber::kValueOffset));
__ ldrd(r0, FieldMemOperand(r0, HeapNumber::kValueOffset));
__ ldrd(r2, r3, FieldMemOperand(r1, HeapNumber::kValueOffset));
__ ldrd(r0, r1, FieldMemOperand(r0, HeapNumber::kValueOffset));
}
__ jmp(both_loaded_as_doubles);
}
@ -6956,7 +6956,7 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases(
__ vldr(d7, r7, HeapNumber::kValueOffset);
} else {
// Calling convention says that second double is in r2 and r3.
__ ldrd(r2, FieldMemOperand(r0, HeapNumber::kValueOffset));
__ ldrd(r2, r3, FieldMemOperand(r0, HeapNumber::kValueOffset));
}
__ jmp(&finished_loading_r0);
__ bind(&r0_is_smi);
@ -7008,7 +7008,7 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases(
__ vldr(d6, r7, HeapNumber::kValueOffset);
} else {
// Calling convention says that first double is in r0 and r1.
__ ldrd(r0, FieldMemOperand(r1, HeapNumber::kValueOffset));
__ ldrd(r0, r1, FieldMemOperand(r1, HeapNumber::kValueOffset));
}
__ jmp(&finished_loading_r1);
__ bind(&r1_is_smi);
@ -7079,7 +7079,7 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases(
__ stc(p1, cr8, MemOperand(r4, HeapNumber::kValueOffset));
#else
// Double returned in registers 0 and 1.
__ strd(r0, FieldMemOperand(r5, HeapNumber::kValueOffset));
__ strd(r0, r1, FieldMemOperand(r5, HeapNumber::kValueOffset));
#endif
__ mov(r0, Operand(r5));
// And we are done.

View File

@ -935,7 +935,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Generate code for doing the condition check.
__ bind(&loop);
// Load the current count to r0, load the length to r1.
__ ldrd(r0, MemOperand(sp, 0 * kPointerSize));
__ ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize));
__ cmp(r0, r1); // Compare to the array length.
__ b(hs, loop_statement.break_target());