Chromium Code Reviews| 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); |