Commit 02ca5fd8 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

ARM: Fix generating two ldr instructions in place of ldrd.

When ldrd is not available two ldr instructions are generated. This fixes these in the case where the register used in the memory operand is the same as the first register in the register pair receiving the values.

All tests now run on ARM with the flag --special-command="@ --noenable-vfp3". Running without VFP3 support in the simulator causes more ldrd instructions to be used, and the default build configuration does not utilize ldrd, but generated tow ldr instructions.
Review URL: http://codereview.chromium.org/2078013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4667 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e9b5d785
...@@ -1359,12 +1359,18 @@ void Assembler::ldrd(Register dst, const MemOperand& src, Condition cond) { ...@@ -1359,12 +1359,18 @@ void Assembler::ldrd(Register dst, const MemOperand& src, Condition cond) {
#ifdef CAN_USE_ARMV7_INSTRUCTIONS #ifdef CAN_USE_ARMV7_INSTRUCTIONS
addrmod3(cond | B7 | B6 | B4, dst, src); addrmod3(cond | B7 | B6 | B4, dst, src);
#else #else
ldr(dst, src, cond); // Generate two ldr instructions if ldrd is not available.
MemOperand src1(src); MemOperand src1(src);
src1.set_offset(src1.offset() + 4); src1.set_offset(src1.offset() + 4);
Register dst1(dst); Register dst1(dst);
dst1.code_ = dst1.code_ + 1; dst1.set_code(dst1.code() + 1);
ldr(dst1, src1, cond); if (dst.is(src.rn())) {
ldr(dst1, src1, cond);
ldr(dst, src, cond);
} else {
ldr(dst, src, cond);
ldr(dst1, src1, cond);
}
#endif #endif
} }
...@@ -1374,11 +1380,12 @@ void Assembler::strd(Register src, const MemOperand& dst, Condition cond) { ...@@ -1374,11 +1380,12 @@ void Assembler::strd(Register src, const MemOperand& dst, Condition cond) {
#ifdef CAN_USE_ARMV7_INSTRUCTIONS #ifdef CAN_USE_ARMV7_INSTRUCTIONS
addrmod3(cond | B7 | B6 | B5 | B4, src, dst); addrmod3(cond | B7 | B6 | B5 | B4, src, dst);
#else #else
str(src, dst, cond); // Generate two str instructions if strd is not available.
MemOperand dst1(dst); MemOperand dst1(dst);
dst1.set_offset(dst1.offset() + 4); dst1.set_offset(dst1.offset() + 4);
Register src1(src); Register src1(src);
src1.code_ = src1.code_ + 1; src1.set_code(src1.code() + 1);
str(src, dst, cond);
str(src1, dst1, cond); str(src1, dst1, cond);
#endif #endif
} }
......
...@@ -80,6 +80,11 @@ struct Register { ...@@ -80,6 +80,11 @@ struct Register {
return 1 << code_; return 1 << code_;
} }
void set_code(int code) {
code_ = code;
ASSERT(is_valid());
}
// Unfortunately we can't make this private in a struct. // Unfortunately we can't make this private in a struct.
int code_; int code_;
}; };
...@@ -458,7 +463,8 @@ class MemOperand BASE_EMBEDDED { ...@@ -458,7 +463,8 @@ class MemOperand BASE_EMBEDDED {
return offset_; return offset_;
} }
Register rm() const {return rm_;} Register rn() const { return rn_; }
Register rm() const { return rm_; }
private: private:
Register rn_; // base Register rn_; // base
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment