| 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);
|
|
|