Chromium Code Reviews| Index: src/compiler/mips64/instruction-selector-mips64.cc |
| diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc |
| index 6e937e20d7ae9fdc4c48245b4bf3f8e760504a8a..d4491d7b08c3af79f0d67f97184633cef928b995 100644 |
| --- a/src/compiler/mips64/instruction-selector-mips64.cc |
| +++ b/src/compiler/mips64/instruction-selector-mips64.cc |
| @@ -1840,10 +1840,60 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, |
| } |
| } |
| +bool IsNodeUnsigned(Node* n) { |
| + NodeMatcher m(n); |
| + |
| + if (m.IsLoad()) { |
| + LoadRepresentation load_rep = LoadRepresentationOf(n->op()); |
| + return load_rep.IsUnsigned(); |
| + } else if (m.IsUnalignedLoad()) { |
| + UnalignedLoadRepresentation load_rep = |
| + UnalignedLoadRepresentationOf(n->op()); |
| + return load_rep.IsUnsigned(); |
| + } else { |
|
ahaas
2016/10/13 08:10:54
I think you also have to deal with parameter and p
ivica.bogosavljevic
2016/10/14 08:16:40
Hi Ahaas!
I looked at the code: the Phi and Selec
titzer
2016/10/15 10:45:33
Is it possible to add some extra --debug-code chec
|
| + return m.IsUint32Div() || m.IsUint32LessThan() || |
| + m.IsUint32LessThanOrEqual() || m.IsUint32Mod() || |
| + m.IsUint32MulHigh() || m.IsChangeFloat64ToUint32() || |
| + m.IsTruncateFloat64ToUint32() || m.IsTruncateFloat32ToUint32(); |
| + } |
| +} |
| + |
| +// Shared routine for multiple word compare operations. |
| +void VisitSimulateWord32Compare(InstructionSelector* selector, Node* node, |
| + InstructionCode opcode, FlagsContinuation* cont, |
| + bool commutative) { |
| + Mips64OperandGenerator g(selector); |
| + Node* left = node->InputAt(0); |
| + Node* right = node->InputAt(1); |
| + InstructionOperand leftOp = g.TempRegister(); |
| + InstructionOperand rightOp = g.TempRegister(); |
| + |
| + selector->Emit(kMips64Dshl, leftOp, g.UseRegister(left), g.TempImmediate(32)); |
| + selector->Emit(kMips64Dshl, rightOp, g.UseRegister(right), |
| + g.TempImmediate(32)); |
| + |
| + VisitCompare(selector, opcode, leftOp, rightOp, cont); |
| +} |
| void VisitWord32Compare(InstructionSelector* selector, Node* node, |
| FlagsContinuation* cont) { |
| - VisitWordCompare(selector, node, kMips64Cmp, cont, false); |
| + // MIPS64 doesn't support Word32 compare instructions. Instead it relies |
| + // that the values in registers are correctly sign-extended and uses |
| + // Word64 comparison instead. This behavior is correct in most cases, |
| + // but doesn't work when comparing signed with unsigned operands. |
| + // We could simulate Word32 compare in all cases but this would create |
| + // an unnecessary overhead since unsigned integers are rarely used |
| + // in JavaScript. |
| + // The solution proposed here tries to match a comparison of signed |
| + // with unsigned operand, and perform Word32Compare simulation only |
| + // in those cases. Unfortunately, the solution is not complete because |
| + // it might skip cases where Word32 compare simulation is needed, so |
| + // basically it is a hack. |
| + if (IsNodeUnsigned(node->InputAt(0)) != IsNodeUnsigned(node->InputAt(1))) { |
| + VisitSimulateWord32Compare(selector, node, kMips64Cmp, cont, false); |
| + } else { |
| + VisitWordCompare(selector, node, kMips64Cmp, cont, false); |
| + } |
| } |