| Index: src/arm/assembler-arm.cc
|
| ===================================================================
|
| --- src/arm/assembler-arm.cc (revision 7161)
|
| +++ src/arm/assembler-arm.cc (working copy)
|
| @@ -767,11 +767,35 @@
|
| }
|
|
|
|
|
| -bool Operand::is_single_instruction() const {
|
| +bool Operand::is_single_instruction(Instr instr) const {
|
| if (rm_.is_valid()) return true;
|
| - if (must_use_constant_pool()) return false;
|
| uint32_t dummy1, dummy2;
|
| - return fits_shifter(imm32_, &dummy1, &dummy2, NULL);
|
| + if (must_use_constant_pool() ||
|
| + !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
|
| + // The immediate operand cannot be encoded as a shifter operand, or use of
|
| + // constant pool is required. For a mov instruction not setting the
|
| + // condition code additional instruction conventions can be used.
|
| + if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
|
| + if (must_use_constant_pool() || !CpuFeatures::IsSupported(ARMv7)) {
|
| + // mov instruction will be an ldr from constant pool (one instruction).
|
| + return true;
|
| + } else {
|
| + // mov instruction will be a mov or movw followed by movt (two
|
| + // instructions).
|
| + return false;
|
| + }
|
| + } else {
|
| + // If this is not a mov or mvn instruction there will always an additional
|
| + // instructions - either mov or ldr. The mov might actually be two
|
| + // instructions mov or movw followed by movt so including the actual
|
| + // instruction two or three instructions will be generated.
|
| + return false;
|
| + }
|
| + } else {
|
| + // No use of constant pool and the immediate operand can be encoded as a
|
| + // shifter operand.
|
| + return true;
|
| + }
|
| }
|
|
|
|
|
|
|