Index: src/arm/assembler-arm.cc |
=================================================================== |
--- src/arm/assembler-arm.cc (revision 6826) |
+++ src/arm/assembler-arm.cc (working copy) |
@@ -1848,14 +1848,35 @@ |
offset = -offset; |
u = 0; |
} |
- ASSERT(offset % 4 == 0); |
- ASSERT((offset / 4) < 256); |
+ |
ASSERT(offset >= 0); |
- emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | |
- 0xB*B8 | ((offset / 4) & 255)); |
+ if ((offset % 4) == 0 && (offset / 4) < 256) { |
+ emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | |
+ 0xB*B8 | ((offset / 4) & 255)); |
+ } else { |
+ // Larger offsets must be handled by computing the correct address |
+ // in the ip register. |
+ ASSERT(!base.is(ip)); |
+ mov(ip, Operand(offset)); |
Rodolph Perfetta
2011/02/16 16:48:54
The offset may be encodable in an add/sub immediat
William Hesse
2011/02/17 11:27:29
Done.
|
+ if (u == 1) { |
+ add(ip, base, ip); |
+ } else { |
+ sub(ip, base, ip); |
+ } |
+ emit(cond | 0xD1*B20 | ip.code()*B16 | dst.code()*B12 | 0xB*B8); |
+ } |
} |
+void Assembler::vldr(const DwVfpRegister dst, |
+ const MemOperand& operand, |
+ const Condition cond) { |
+ ASSERT(!operand.rm().is_valid()); |
+ ASSERT(operand.am_ == Offset); |
+ vldr(dst, operand.rn(), operand.offset(), cond); |
+} |
+ |
+ |
void Assembler::vldr(const SwVfpRegister dst, |
const Register base, |
int offset, |
@@ -1870,16 +1891,37 @@ |
offset = -offset; |
u = 0; |
} |
- ASSERT(offset % 4 == 0); |
- ASSERT((offset / 4) < 256); |
- ASSERT(offset >= 0); |
int sd, d; |
dst.split_code(&sd, &d); |
+ ASSERT(offset >= 0); |
+ |
+ if ((offset % 4) == 0 && (offset / 4) < 256) { |
emit(cond | u*B23 | d*B22 | 0xD1*B20 | base.code()*B16 | sd*B12 | |
0xA*B8 | ((offset / 4) & 255)); |
+ } else { |
+ // Larger offsets must be handled by computing the correct address |
+ // in the ip register. |
+ ASSERT(!base.is(ip)); |
+ mov(ip, Operand(offset)); |
Rodolph Perfetta
2011/02/16 16:48:54
ditto.
|
+ if (u == 1) { |
+ add(ip, ip, base); |
+ } else { |
+ sub(ip, base, ip); |
+ } |
+ emit(cond | d*B22 | 0xD1*B20 | ip.code()*B16 | sd*B12 | 0xA*B8); |
+ } |
} |
+void Assembler::vldr(const SwVfpRegister dst, |
+ const MemOperand& operand, |
+ const Condition cond) { |
+ ASSERT(!operand.rm().is_valid()); |
+ ASSERT(operand.am_ == Offset); |
+ vldr(dst, operand.rn(), operand.offset(), cond); |
+} |
+ |
+ |
void Assembler::vstr(const DwVfpRegister src, |
const Register base, |
int offset, |
@@ -1894,14 +1936,34 @@ |
offset = -offset; |
u = 0; |
} |
- ASSERT(offset % 4 == 0); |
- ASSERT((offset / 4) < 256); |
ASSERT(offset >= 0); |
- emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | |
- 0xB*B8 | ((offset / 4) & 255)); |
+ if ((offset % 4) == 0 && (offset / 4) < 256) { |
+ emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | |
+ 0xB*B8 | ((offset / 4) & 255)); |
+ } else { |
+ // Larger offsets must be handled by computing the correct address |
+ // in the ip register. |
+ ASSERT(!base.is(ip)); |
+ mov(ip, Operand(offset)); |
Rodolph Perfetta
2011/02/16 16:48:54
ditto.
|
+ if (u == 1) { |
+ add(ip, ip, base); |
+ } else { |
+ sub(ip, base, ip); |
+ } |
+ emit(cond | 0xD0*B20 | ip.code()*B16 | src.code()*B12 | 0xB*B8); |
+ } |
} |
+void Assembler::vstr(const DwVfpRegister src, |
+ const MemOperand& operand, |
+ const Condition cond) { |
+ ASSERT(!operand.rm().is_valid()); |
+ ASSERT(operand.am_ == Offset); |
+ vldr(src, operand.rn(), operand.offset(), cond); |
+} |
+ |
+ |
void Assembler::vstr(const SwVfpRegister src, |
const Register base, |
int offset, |
@@ -1916,16 +1978,36 @@ |
offset = -offset; |
u = 0; |
} |
- ASSERT(offset % 4 == 0); |
- ASSERT((offset / 4) < 256); |
- ASSERT(offset >= 0); |
int sd, d; |
src.split_code(&sd, &d); |
- emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | |
- 0xA*B8 | ((offset / 4) & 255)); |
+ ASSERT(offset >= 0); |
+ if ((offset % 4) == 0 && (offset / 4) < 256) { |
+ emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | |
+ 0xA*B8 | ((offset / 4) & 255)); |
+ } else { |
+ // Larger offsets must be handled by computing the correct address |
+ // in the ip register. |
+ ASSERT(!base.is(ip)); |
+ mov(ip, Operand(offset)); |
Rodolph Perfetta
2011/02/16 16:48:54
ditto.
|
+ if (u == 1) { |
+ add(ip, ip, base); |
+ } else { |
+ sub(ip, base, ip); |
+ } |
+ emit(cond | d*B22 | 0xD0*B20 | ip.code()*B16 | sd*B12 | 0xA*B8); |
+ } |
} |
+void Assembler::vstr(const SwVfpRegister src, |
+ const MemOperand& operand, |
+ const Condition cond) { |
+ ASSERT(!operand.rm().is_valid()); |
+ ASSERT(operand.am_ == Offset); |
+ vldr(src, operand.rn(), operand.offset(), cond); |
+} |
+ |
+ |
static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { |
uint64_t i; |
memcpy(&i, &d, 8); |