| OLD | NEW | 
|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/base/adapters.h" | 5 #include "src/base/adapters.h" | 
| 6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" | 
| 7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" | 
| 8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" | 
| 9 | 9 | 
| 10 namespace v8 { | 10 namespace v8 { | 
| (...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 982     } | 982     } | 
| 983   } | 983   } | 
| 984 } | 984 } | 
| 985 | 985 | 
| 986 | 986 | 
| 987 bool InstructionSelector::IsTailCallAddressImmediate() { return true; } | 987 bool InstructionSelector::IsTailCallAddressImmediate() { return true; } | 
| 988 | 988 | 
| 989 | 989 | 
| 990 namespace { | 990 namespace { | 
| 991 | 991 | 
|  | 992 void VisitCompareWithMemoryOperand(InstructionSelector* selector, | 
|  | 993                                    InstructionCode opcode, Node* left, | 
|  | 994                                    InstructionOperand right, | 
|  | 995                                    FlagsContinuation* cont) { | 
|  | 996   DCHECK(left->opcode() == IrOpcode::kLoad); | 
|  | 997   IA32OperandGenerator g(selector); | 
|  | 998   size_t input_count = 0; | 
|  | 999   InstructionOperand inputs[6]; | 
|  | 1000   AddressingMode addressing_mode = | 
|  | 1001       g.GetEffectiveAddressMemoryOperand(left, inputs, &input_count); | 
|  | 1002   opcode |= AddressingModeField::encode(addressing_mode); | 
|  | 1003   opcode = cont->Encode(opcode); | 
|  | 1004   inputs[input_count++] = right; | 
|  | 1005 | 
|  | 1006   if (cont->IsBranch()) { | 
|  | 1007     inputs[input_count++] = g.Label(cont->true_block()); | 
|  | 1008     inputs[input_count++] = g.Label(cont->false_block()); | 
|  | 1009     selector->Emit(opcode, 0, nullptr, input_count, inputs); | 
|  | 1010   } else { | 
|  | 1011     DCHECK(cont->IsSet()); | 
|  | 1012     InstructionOperand output = g.DefineAsRegister(cont->result()); | 
|  | 1013     selector->Emit(opcode, 1, &output, input_count, inputs); | 
|  | 1014   } | 
|  | 1015 } | 
|  | 1016 | 
|  | 1017 // Determines if {input} of {node} can be replaced by a memory operand. | 
|  | 1018 bool CanUseMemoryOperand(InstructionSelector* selector, InstructionCode opcode, | 
|  | 1019                          Node* node, Node* input) { | 
|  | 1020   if (input->opcode() != IrOpcode::kLoad || !selector->CanCover(node, input)) { | 
|  | 1021     return false; | 
|  | 1022   } | 
|  | 1023   if (LoadRepresentationOf(input->op()).representation() == | 
|  | 1024       MachineRepresentation::kWord32) { | 
|  | 1025     return opcode == kIA32Cmp || opcode == kIA32Test; | 
|  | 1026   } | 
|  | 1027   return false; | 
|  | 1028 } | 
|  | 1029 | 
| 992 // Shared routine for multiple compare operations. | 1030 // Shared routine for multiple compare operations. | 
| 993 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1031 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 
| 994                   InstructionOperand left, InstructionOperand right, | 1032                   InstructionOperand left, InstructionOperand right, | 
| 995                   FlagsContinuation* cont) { | 1033                   FlagsContinuation* cont) { | 
| 996   IA32OperandGenerator g(selector); | 1034   IA32OperandGenerator g(selector); | 
| 997   if (cont->IsBranch()) { | 1035   if (cont->IsBranch()) { | 
| 998     selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, | 1036     selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, | 
| 999                    g.Label(cont->true_block()), g.Label(cont->false_block())); | 1037                    g.Label(cont->true_block()), g.Label(cont->false_block())); | 
| 1000   } else { | 1038   } else { | 
| 1001     DCHECK(cont->IsSet()); | 1039     DCHECK(cont->IsSet()); | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1037 | 1075 | 
| 1038 // Shared routine for multiple word compare operations. | 1076 // Shared routine for multiple word compare operations. | 
| 1039 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1077 void VisitWordCompare(InstructionSelector* selector, Node* node, | 
| 1040                       InstructionCode opcode, FlagsContinuation* cont) { | 1078                       InstructionCode opcode, FlagsContinuation* cont) { | 
| 1041   IA32OperandGenerator g(selector); | 1079   IA32OperandGenerator g(selector); | 
| 1042   Node* const left = node->InputAt(0); | 1080   Node* const left = node->InputAt(0); | 
| 1043   Node* const right = node->InputAt(1); | 1081   Node* const right = node->InputAt(1); | 
| 1044 | 1082 | 
| 1045   // Match immediates on left or right side of comparison. | 1083   // Match immediates on left or right side of comparison. | 
| 1046   if (g.CanBeImmediate(right)) { | 1084   if (g.CanBeImmediate(right)) { | 
| 1047     VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont); | 1085     return VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), | 
|  | 1086                         cont); | 
| 1048   } else if (g.CanBeImmediate(left)) { | 1087   } else if (g.CanBeImmediate(left)) { | 
| 1049     if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); | 1088     if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); | 
| 1050     VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont); | 1089     return VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), | 
| 1051   } else { | 1090                         cont); | 
| 1052     VisitCompare(selector, opcode, left, right, cont, |  | 
| 1053                  node->op()->HasProperty(Operator::kCommutative)); |  | 
| 1054   } | 1091   } | 
|  | 1092   // TODO(epertoso): emit memory operands for comparisons againt immediates as | 
|  | 1093   // well. | 
|  | 1094   if (CanUseMemoryOperand(selector, opcode, node, left)) { | 
|  | 1095     return VisitCompareWithMemoryOperand(selector, opcode, left, | 
|  | 1096                                          g.UseRegister(right), cont); | 
|  | 1097   } | 
|  | 1098   return VisitCompare(selector, opcode, left, right, cont, | 
|  | 1099                       node->op()->HasProperty(Operator::kCommutative)); | 
| 1055 } | 1100 } | 
| 1056 | 1101 | 
| 1057 |  | 
| 1058 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1102 void VisitWordCompare(InstructionSelector* selector, Node* node, | 
| 1059                       FlagsContinuation* cont) { | 1103                       FlagsContinuation* cont) { | 
| 1060   IA32OperandGenerator g(selector); | 1104   IA32OperandGenerator g(selector); | 
| 1061   Int32BinopMatcher m(node); | 1105   Int32BinopMatcher m(node); | 
| 1062   if (m.left().IsLoad() && m.right().IsLoadStackPointer()) { | 1106   if (m.left().IsLoad() && m.right().IsLoadStackPointer()) { | 
| 1063     LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); | 1107     LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); | 
| 1064     ExternalReference js_stack_limit = | 1108     ExternalReference js_stack_limit = | 
| 1065         ExternalReference::address_of_stack_limit(selector->isolate()); | 1109         ExternalReference::address_of_stack_limit(selector->isolate()); | 
| 1066     if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { | 1110     if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { | 
| 1067       // Compare(Load(js_stack_limit), LoadStackPointer) | 1111       // Compare(Load(js_stack_limit), LoadStackPointer) | 
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1357              MachineOperatorBuilder::kFloat64RoundTruncate | | 1401              MachineOperatorBuilder::kFloat64RoundTruncate | | 
| 1358              MachineOperatorBuilder::kFloat32RoundTiesEven | | 1402              MachineOperatorBuilder::kFloat32RoundTiesEven | | 
| 1359              MachineOperatorBuilder::kFloat64RoundTiesEven; | 1403              MachineOperatorBuilder::kFloat64RoundTiesEven; | 
| 1360   } | 1404   } | 
| 1361   return flags; | 1405   return flags; | 
| 1362 } | 1406 } | 
| 1363 | 1407 | 
| 1364 }  // namespace compiler | 1408 }  // namespace compiler | 
| 1365 }  // namespace internal | 1409 }  // namespace internal | 
| 1366 }  // namespace v8 | 1410 }  // namespace v8 | 
| OLD | NEW | 
|---|