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:
parent
e268fbdaba
commit
f952df4be1
@ -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
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user