}
-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
}
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);
// 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);
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);
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);
}
} 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);
__ 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);
}
__ 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);
__ 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);
__ 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.