Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE
This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.
FPIIM-449
Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc
index f3deae7..14b30b1 100644
--- a/src/compiler/arm/instruction-selector-arm.cc
+++ b/src/compiler/arm/instruction-selector-arm.cc
@@ -327,8 +327,9 @@
case MachineRepresentation::kWord32:
opcode = kArmLdr;
break;
- case MachineRepresentation::kNone: // Fall through.
- case MachineRepresentation::kWord64:
+ case MachineRepresentation::kWord64: // Fall through.
+ case MachineRepresentation::kSimd128: // Fall through.
+ case MachineRepresentation::kNone:
UNREACHABLE();
return;
}
@@ -355,10 +356,19 @@
if (write_barrier_kind != kNoWriteBarrier) {
DCHECK_EQ(MachineRepresentation::kTagged, rep);
+ AddressingMode addressing_mode;
InstructionOperand inputs[3];
size_t input_count = 0;
inputs[input_count++] = g.UseUniqueRegister(base);
- inputs[input_count++] = g.UseUniqueRegister(index);
+ // OutOfLineRecordWrite uses the index in an 'add' instruction as well as
+ // for the store itself, so we must check compatibility with both.
+ if (g.CanBeImmediate(index, kArmAdd) && g.CanBeImmediate(index, kArmStr)) {
+ inputs[input_count++] = g.UseImmediate(index);
+ addressing_mode = kMode_Offset_RI;
+ } else {
+ inputs[input_count++] = g.UseUniqueRegister(index);
+ addressing_mode = kMode_Offset_RR;
+ }
inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
? g.UseRegister(value)
: g.UseUniqueRegister(value);
@@ -380,6 +390,7 @@
InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
size_t const temp_count = arraysize(temps);
InstructionCode code = kArchStoreWithWriteBarrier;
+ code |= AddressingModeField::encode(addressing_mode);
code |= MiscField::encode(static_cast<int>(record_write_mode));
Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
} else {
@@ -402,8 +413,9 @@
case MachineRepresentation::kWord32:
opcode = kArmStr;
break;
- case MachineRepresentation::kNone: // Fall through.
- case MachineRepresentation::kWord64:
+ case MachineRepresentation::kWord64: // Fall through.
+ case MachineRepresentation::kSimd128: // Fall through.
+ case MachineRepresentation::kNone:
UNREACHABLE();
return;
}
@@ -442,9 +454,10 @@
case MachineRepresentation::kFloat64:
opcode = kCheckedLoadFloat64;
break;
- case MachineRepresentation::kBit: // Fall through.
- case MachineRepresentation::kTagged: // Fall through.
- case MachineRepresentation::kWord64: // Fall through.
+ case MachineRepresentation::kBit: // Fall through.
+ case MachineRepresentation::kTagged: // Fall through.
+ case MachineRepresentation::kWord64: // Fall through.
+ case MachineRepresentation::kSimd128: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
return;
@@ -483,9 +496,10 @@
case MachineRepresentation::kFloat64:
opcode = kCheckedStoreFloat64;
break;
- case MachineRepresentation::kBit: // Fall through.
- case MachineRepresentation::kTagged: // Fall through.
- case MachineRepresentation::kWord64: // Fall through.
+ case MachineRepresentation::kBit: // Fall through.
+ case MachineRepresentation::kTagged: // Fall through.
+ case MachineRepresentation::kWord64: // Fall through.
+ case MachineRepresentation::kSimd128: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
return;
@@ -551,43 +565,67 @@
if (m.right().HasValue()) {
uint32_t const value = m.right().Value();
uint32_t width = base::bits::CountPopulation32(value);
- uint32_t msb = base::bits::CountLeadingZeros32(value);
- // Try to interpret this AND as UBFX.
- if (IsSupported(ARMv7) && width != 0 && msb + width == 32) {
- DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value));
- if (m.left().IsWord32Shr()) {
- Int32BinopMatcher mleft(m.left().node());
- if (mleft.right().IsInRange(0, 31)) {
- // UBFX cannot extract bits past the register size, however since
- // shifting the original value would have introduced some zeros we can
- // still use UBFX with a smaller mask and the remaining bits will be
- // zeros.
- uint32_t const lsb = mleft.right().Value();
- return EmitUbfx(this, node, mleft.left().node(), lsb,
- std::min(width, 32 - lsb));
+ uint32_t leading_zeros = base::bits::CountLeadingZeros32(value);
+
+ // Try to merge SHR operations on the left hand input into this AND.
+ if (m.left().IsWord32Shr()) {
+ Int32BinopMatcher mshr(m.left().node());
+ if (mshr.right().HasValue()) {
+ uint32_t const shift = mshr.right().Value();
+
+ if (((shift == 8) || (shift == 16) || (shift == 24)) &&
+ ((value == 0xff) || (value == 0xffff))) {
+ // Merge SHR into AND by emitting a UXTB or UXTH instruction with a
+ // bytewise rotation.
+ Emit((value == 0xff) ? kArmUxtb : kArmUxth,
+ g.DefineAsRegister(m.node()), g.UseRegister(mshr.left().node()),
+ g.TempImmediate(mshr.right().Value()));
+ return;
+ } else if (IsSupported(ARMv7) && (width != 0) &&
+ ((leading_zeros + width) == 32)) {
+ // Merge Shr into And by emitting a UBFX instruction.
+ DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value));
+ if ((1 <= shift) && (shift <= 31)) {
+ // UBFX cannot extract bits past the register size, however since
+ // shifting the original value would have introduced some zeros we
+ // can still use UBFX with a smaller mask and the remaining bits
+ // will be zeros.
+ EmitUbfx(this, node, mshr.left().node(), shift,
+ std::min(width, 32 - shift));
+ return;
+ }
}
}
- return EmitUbfx(this, node, m.left().node(), 0, width);
+ } else if (value == 0xffff) {
+ // Emit UXTH for this AND. We don't bother testing for UXTB, as it's no
+ // better than AND 0xff for this operation.
+ Emit(kArmUxth, g.DefineAsRegister(m.node()),
+ g.UseRegister(m.left().node()), g.TempImmediate(0));
+ return;
}
- // Try to interpret this AND as BIC.
if (g.CanBeImmediate(~value)) {
+ // Emit BIC for this AND by inverting the immediate value first.
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 UXTH.
- if (value == 0xffff) {
- Emit(kArmUxth, g.DefineAsRegister(m.node()),
- g.UseRegister(m.left().node()), g.TempImmediate(0));
- return;
- }
- // Try to interpret this AND as BFC.
- if (IsSupported(ARMv7)) {
+ if (!g.CanBeImmediate(value) && IsSupported(ARMv7)) {
+ // If value has 9 to 23 contiguous set bits, and has the lsb set, we can
+ // replace this AND with UBFX. Other contiguous bit patterns have already
+ // been handled by BIC or will be handled by AND.
+ if ((width != 0) && ((leading_zeros + width) == 32) &&
+ (9 <= leading_zeros) && (leading_zeros <= 23)) {
+ DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value));
+ EmitUbfx(this, node, m.left().node(), 0, width);
+ return;
+ }
+
width = 32 - width;
- msb = base::bits::CountLeadingZeros32(~value);
+ leading_zeros = base::bits::CountLeadingZeros32(~value);
uint32_t lsb = base::bits::CountTrailingZeros32(~value);
- if (msb + width + lsb == 32) {
+ if ((leading_zeros + width + lsb) == 32) {
+ // This AND can be replaced with BFC.
Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
g.TempImmediate(lsb), g.TempImmediate(width));
return;
@@ -699,14 +737,23 @@
Int32BinopMatcher m(node);
if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) {
Int32BinopMatcher mleft(m.left().node());
- if (mleft.right().Is(16) && m.right().Is(16)) {
- Emit(kArmSxth, g.DefineAsRegister(node),
- g.UseRegister(mleft.left().node()), g.TempImmediate(0));
- return;
- } else if (mleft.right().Is(24) && m.right().Is(24)) {
- Emit(kArmSxtb, g.DefineAsRegister(node),
- g.UseRegister(mleft.left().node()), g.TempImmediate(0));
- return;
+ if (m.right().HasValue() && mleft.right().HasValue()) {
+ uint32_t sar = m.right().Value();
+ uint32_t shl = mleft.right().Value();
+ if ((sar == shl) && (sar == 16)) {
+ Emit(kArmSxth, g.DefineAsRegister(node),
+ g.UseRegister(mleft.left().node()), g.TempImmediate(0));
+ return;
+ } else if ((sar == shl) && (sar == 24)) {
+ Emit(kArmSxtb, g.DefineAsRegister(node),
+ g.UseRegister(mleft.left().node()), g.TempImmediate(0));
+ return;
+ } else if (IsSupported(ARMv7) && (sar >= shl)) {
+ Emit(kArmSbfx, g.DefineAsRegister(node),
+ g.UseRegister(mleft.left().node()), g.TempImmediate(sar - shl),
+ g.TempImmediate(32 - sar));
+ return;
+ }
}
}
VisitShift(this, node, TryMatchASR);
@@ -726,6 +773,12 @@
void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
+void InstructionSelector::VisitWord32ReverseBits(Node* node) {
+ DCHECK(IsSupported(ARMv7));
+ VisitRR(this, kArmRbit, node);
+}
+
+
void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
@@ -921,6 +974,16 @@
}
+void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
+ VisitRR(this, kArmVcvtF32S32, node);
+}
+
+
+void InstructionSelector::VisitRoundUint32ToFloat32(Node* node) {
+ VisitRR(this, kArmVcvtF32U32, node);
+}
+
+
void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
VisitRR(this, kArmVcvtF64S32, node);
}
@@ -931,6 +994,16 @@
}
+void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) {
+ VisitRR(this, kArmVcvtS32F32, node);
+}
+
+
+void InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) {
+ VisitRR(this, kArmVcvtU32F32, node);
+}
+
+
void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
VisitRR(this, kArmVcvtS32F64, node);
}
@@ -1591,6 +1664,9 @@
MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::kInt32DivIsSafe |
MachineOperatorBuilder::kUint32DivIsSafe;
+ if (CpuFeatures::IsSupported(ARMv7)) {
+ flags |= MachineOperatorBuilder::kWord32ReverseBits;
+ }
if (CpuFeatures::IsSupported(ARMv8)) {
flags |= MachineOperatorBuilder::kFloat32RoundDown |
MachineOperatorBuilder::kFloat64RoundDown |