Index: src/compiler/s390/instruction-selector-s390.cc |
diff --git a/src/compiler/s390/instruction-selector-s390.cc b/src/compiler/s390/instruction-selector-s390.cc |
index dacf2d8fb9e43739e88b5a04198626f5ffefc3dc..4b70e41ffdab884eb5ee8aae7fe74652c4cc9a54 100644 |
--- a/src/compiler/s390/instruction-selector-s390.cc |
+++ b/src/compiler/s390/instruction-selector-s390.cc |
@@ -330,6 +330,8 @@ ArchOpcode SelectLoadOpcode(Node* node) { |
/* Word32 unary op */ \ |
V(Word32Clz) \ |
V(Word32Popcnt) \ |
+ V(Float64ExtractLowWord32) \ |
+ V(Float64ExtractHighWord32) \ |
/* Word32 bin op */ \ |
V(Int32Add) \ |
V(Int32Sub) \ |
@@ -1379,13 +1381,44 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector, |
} |
#endif |
+static inline bool TryMatchDoubleConstructFromInsert( |
+ InstructionSelector* selector, Node* node) { |
+ S390OperandGenerator g(selector); |
+ Node* left = node->InputAt(0); |
+ Node* right = node->InputAt(1); |
+ Node* lo32 = NULL; |
+ Node* hi32 = NULL; |
+ |
+ if (node->opcode() == IrOpcode::kFloat64InsertLowWord32) { |
+ lo32 = right; |
+ } else if (node->opcode() == IrOpcode::kFloat64InsertHighWord32) { |
+ hi32 = right; |
+ } else { |
+ return false; // doesn't match |
+ } |
+ |
+ if (left->opcode() == IrOpcode::kFloat64InsertLowWord32) { |
+ lo32 = left->InputAt(1); |
+ } else if (left->opcode() == IrOpcode::kFloat64InsertHighWord32) { |
+ hi32 = left->InputAt(1); |
+ } else { |
+ return false; // doesn't match |
+ } |
+ |
+ if (!lo32 || !hi32) return false; // doesn't match |
+ |
+ selector->Emit(kS390_DoubleConstruct, g.DefineAsRegister(node), |
+ g.UseRegister(hi32), g.UseRegister(lo32)); |
+ return true; |
+} |
+ |
#define null ([]() { return false; }) |
// TODO(john.yan): place kAllowRM where available |
#define FLOAT_UNARY_OP_LIST_32(V) \ |
V(Float32, ChangeFloat32ToFloat64, kS390_Float32ToDouble, \ |
OperandMode::kAllowRM, null) \ |
V(Float32, BitcastFloat32ToInt32, kS390_BitcastFloat32ToInt32, \ |
- OperandMode::kNone, null) \ |
+ OperandMode::kAllowRM, null) \ |
V(Float64, TruncateFloat64ToFloat32, kS390_DoubleToFloat32, \ |
OperandMode::kNone, null) \ |
V(Float64, TruncateFloat64ToWord32, kArchTruncateDoubleToI, \ |
@@ -1419,7 +1452,12 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector, |
V(Float64, Float64RoundTiesAway, kS390_RoundDouble, OperandMode::kNone, \ |
null) \ |
V(Float32, Float32Neg, kS390_NegFloat, OperandMode::kNone, null) \ |
- V(Float64, Float64Neg, kS390_NegDouble, OperandMode::kNone, null) |
+ V(Float64, Float64Neg, kS390_NegDouble, OperandMode::kNone, null) \ |
+ /* TODO(john.yan): can use kAllowRM */ \ |
+ V(Word32, Float64ExtractLowWord32, kS390_DoubleExtractLowWord32, \ |
+ OperandMode::kNone, null) \ |
+ V(Word32, Float64ExtractHighWord32, kS390_DoubleExtractHighWord32, \ |
+ OperandMode::kNone, null) |
#define FLOAT_BIN_OP_LIST(V) \ |
V(Float32, Float32Add, kS390_AddFloat, OperandMode::kAllowRM, null) \ |
@@ -1511,7 +1549,13 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector, |
V(Word32, Word32Shl, kS390_ShiftLeft32, Shift32OperandMode, null) \ |
V(Word32, Word32Shr, kS390_ShiftRight32, Shift32OperandMode, null) \ |
V(Word32, Word32Sar, kS390_ShiftRightArith32, Shift32OperandMode, \ |
- [&]() { return TryMatchSignExtInt16OrInt8FromWord32Sar(this, node); }) |
+ [&]() { return TryMatchSignExtInt16OrInt8FromWord32Sar(this, node); }) \ |
+ V(Word32, Float64InsertLowWord32, kS390_DoubleInsertLowWord32, \ |
+ OperandMode::kAllowRRR, \ |
+ [&]() -> bool { return TryMatchDoubleConstructFromInsert(this, node); }) \ |
+ V(Word32, Float64InsertHighWord32, kS390_DoubleInsertHighWord32, \ |
+ OperandMode::kAllowRRR, \ |
+ [&]() -> bool { return TryMatchDoubleConstructFromInsert(this, node); }) |
#define WORD64_UNARY_OP_LIST(V) \ |
V(Word64, Word64Popcnt, kS390_Popcnt64, OperandMode::kNone, null) \ |
@@ -2300,48 +2344,6 @@ bool InstructionSelector::IsTailCallAddressImmediate() { return false; } |
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } |
-void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { |
- S390OperandGenerator g(this); |
- Emit(kS390_DoubleExtractLowWord32, g.DefineAsRegister(node), |
- g.UseRegister(node->InputAt(0))); |
-} |
- |
-void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { |
- S390OperandGenerator g(this); |
- Emit(kS390_DoubleExtractHighWord32, g.DefineAsRegister(node), |
- g.UseRegister(node->InputAt(0))); |
-} |
- |
-void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { |
- S390OperandGenerator g(this); |
- Node* left = node->InputAt(0); |
- Node* right = node->InputAt(1); |
- if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 && |
- CanCover(node, left)) { |
- left = left->InputAt(1); |
- Emit(kS390_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(left), |
- g.UseRegister(right)); |
- return; |
- } |
- Emit(kS390_DoubleInsertLowWord32, g.DefineSameAsFirst(node), |
- g.UseRegister(left), g.UseRegister(right)); |
-} |
- |
-void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { |
- S390OperandGenerator g(this); |
- Node* left = node->InputAt(0); |
- Node* right = node->InputAt(1); |
- if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 && |
- CanCover(node, left)) { |
- left = left->InputAt(1); |
- Emit(kS390_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(right), |
- g.UseRegister(left)); |
- return; |
- } |
- Emit(kS390_DoubleInsertHighWord32, g.DefineSameAsFirst(node), |
- g.UseRegister(left), g.UseRegister(right)); |
-} |
- |
void InstructionSelector::VisitAtomicLoad(Node* node) { |
LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
S390OperandGenerator g(this); |