Index: src/compiler/arm/instruction-selector-arm.cc |
diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc |
index 19ba71c4383fb6944b138fa85a34017ce1665584..ed58bbabe634dd9f54cc2275b83885ae5d39832d 100644 |
--- a/src/compiler/arm/instruction-selector-arm.cc |
+++ b/src/compiler/arm/instruction-selector-arm.cc |
@@ -23,6 +23,14 @@ class ArmOperandGenerator : public OperandGenerator { |
return UseRegister(node); |
} |
+ bool CanBeImmediate(int32_t value) const { |
+ return Assembler::ImmediateFitsAddrMode1Instruction(value); |
+ } |
+ |
+ bool CanBeImmediate(uint32_t value) const { |
+ return CanBeImmediate(bit_cast<int32_t>(value)); |
+ } |
+ |
bool CanBeImmediate(Node* node, InstructionCode opcode) { |
Int32Matcher m(node); |
if (!m.HasValue()) return false; |
@@ -32,22 +40,20 @@ class ArmOperandGenerator : public OperandGenerator { |
case kArmMov: |
case kArmMvn: |
case kArmBic: |
- return ImmediateFitsAddrMode1Instruction(value) || |
- ImmediateFitsAddrMode1Instruction(~value); |
+ return CanBeImmediate(value) || CanBeImmediate(~value); |
case kArmAdd: |
case kArmSub: |
case kArmCmp: |
case kArmCmn: |
- return ImmediateFitsAddrMode1Instruction(value) || |
- ImmediateFitsAddrMode1Instruction(-value); |
+ return CanBeImmediate(value) || CanBeImmediate(-value); |
case kArmTst: |
case kArmTeq: |
case kArmOrr: |
case kArmEor: |
case kArmRsb: |
- return ImmediateFitsAddrMode1Instruction(value); |
+ return CanBeImmediate(value); |
case kArmVldrF32: |
case kArmVstrF32: |
@@ -106,11 +112,6 @@ class ArmOperandGenerator : public OperandGenerator { |
UNREACHABLE(); |
return false; |
} |
- |
- private: |
- bool ImmediateFitsAddrMode1Instruction(int32_t imm) const { |
- return Assembler::ImmediateFitsAddrMode1Instruction(imm); |
- } |
}; |
@@ -417,7 +418,8 @@ void InstructionSelector::VisitWord32And(Node* node) { |
} |
} |
if (IsSupported(ARMv7) && m.right().HasValue()) { |
- uint32_t value = m.right().Value(); |
+ // Try to interpret this AND as UBFX. |
+ uint32_t const value = m.right().Value(); |
uint32_t width = base::bits::CountPopulation32(value); |
uint32_t msb = base::bits::CountLeadingZeros32(value); |
if (width != 0 && msb + width == 32) { |
@@ -435,6 +437,15 @@ void InstructionSelector::VisitWord32And(Node* node) { |
g.TempImmediate(0), g.TempImmediate(width)); |
return; |
} |
+ |
+ // Try to interpret this AND as BIC. |
+ if (g.CanBeImmediate(~value)) { |
+ Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I), |
+ g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
+ g.TempImmediate(~value)); |
+ return; |
+ } |
+ |
// Try to interpret this AND as BFC. |
width = 32 - width; |
msb = base::bits::CountLeadingZeros32(~value); |