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;
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:
UNREACHABLE();
return false;
}
-
- private:
- bool ImmediateFitsAddrMode1Instruction(int32_t imm) const {
- return Assembler::ImmediateFitsAddrMode1Instruction(imm);
- }
};
}
}
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) {
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);
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <limits>
+
#include "test/unittests/compiler/instruction-selector-unittest.h"
namespace v8 {
// Immediates (random subset).
static const int32_t kImmediates[] = {
- -2147483617, -2147483606, -2113929216, -2080374784, -1996488704,
- -1879048192, -1459617792, -1358954496, -1342177265, -1275068414,
- -1073741818, -1073741777, -855638016, -805306368, -402653184,
- -268435444, -16777216, 0, 35, 61,
- 105, 116, 171, 245, 255,
- 692, 1216, 1248, 1520, 1600,
- 1888, 3744, 4080, 5888, 8384,
- 9344, 9472, 9792, 13312, 15040,
- 15360, 20736, 22272, 23296, 32000,
- 33536, 37120, 45824, 47872, 56320,
- 59392, 65280, 72704, 101376, 147456,
- 161792, 164864, 167936, 173056, 195584,
- 209920, 212992, 356352, 655360, 704512,
- 716800, 851968, 901120, 1044480, 1523712,
- 2572288, 3211264, 3588096, 3833856, 3866624,
- 4325376, 5177344, 6488064, 7012352, 7471104,
- 14090240, 16711680, 19398656, 22282240, 28573696,
- 30408704, 30670848, 43253760, 54525952, 55312384,
- 56623104, 68157440, 115343360, 131072000, 187695104,
- 188743680, 195035136, 197132288, 203423744, 218103808,
- 267386880, 268435470, 285212672, 402653185, 415236096,
- 595591168, 603979776, 603979778, 629145600, 1073741835,
- 1073741855, 1073741861, 1073741884, 1157627904, 1476395008,
- 1476395010, 1610612741, 2030043136, 2080374785, 2097152000};
+ std::numeric_limits<int32_t>::min(), -2147483617, -2147483606, -2113929216,
+ -2080374784, -1996488704, -1879048192, -1459617792,
+ -1358954496, -1342177265, -1275068414, -1073741818,
+ -1073741777, -855638016, -805306368, -402653184,
+ -268435444, -16777216, 0, 35,
+ 61, 105, 116, 171,
+ 245, 255, 692, 1216,
+ 1248, 1520, 1600, 1888,
+ 3744, 4080, 5888, 8384,
+ 9344, 9472, 9792, 13312,
+ 15040, 15360, 20736, 22272,
+ 23296, 32000, 33536, 37120,
+ 45824, 47872, 56320, 59392,
+ 65280, 72704, 101376, 147456,
+ 161792, 164864, 167936, 173056,
+ 195584, 209920, 212992, 356352,
+ 655360, 704512, 716800, 851968,
+ 901120, 1044480, 1523712, 2572288,
+ 3211264, 3588096, 3833856, 3866624,
+ 4325376, 5177344, 6488064, 7012352,
+ 7471104, 14090240, 16711680, 19398656,
+ 22282240, 28573696, 30408704, 30670848,
+ 43253760, 54525952, 55312384, 56623104,
+ 68157440, 115343360, 131072000, 187695104,
+ 188743680, 195035136, 197132288, 203423744,
+ 218103808, 267386880, 268435470, 285212672,
+ 402653185, 415236096, 595591168, 603979776,
+ 603979778, 629145600, 1073741835, 1073741855,
+ 1073741861, 1073741884, 1157627904, 1476395008,
+ 1476395010, 1610612741, 2030043136, 2080374785,
+ 2097152000};
} // namespace
TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) {
TRACED_FORRANGE(int32_t, lsb, 0, 31) {
- TRACED_FORRANGE(int32_t, width, 1, (32 - lsb) - 1) {
+ TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) {
StreamBuilder m(this, kMachInt32, kMachInt32);
m.Return(m.Word32And(
m.Parameter(0),
}
}
TRACED_FORRANGE(int32_t, lsb, 0, 31) {
- TRACED_FORRANGE(int32_t, width, 1, (32 - lsb) - 1) {
+ TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) {
StreamBuilder m(this, kMachInt32, kMachInt32);
m.Return(
m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)),