| 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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 358 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 359 offset_operand, length_operand, value_operand, offset_operand, | 359 offset_operand, length_operand, value_operand, offset_operand, |
| 360 g.UseImmediate(buffer)); | 360 g.UseImmediate(buffer)); |
| 361 } else { | 361 } else { |
| 362 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), | 362 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), |
| 363 offset_operand, length_operand, value_operand, g.UseRegister(buffer), | 363 offset_operand, length_operand, value_operand, g.UseRegister(buffer), |
| 364 offset_operand); | 364 offset_operand); |
| 365 } | 365 } |
| 366 } | 366 } |
| 367 | 367 |
| 368 namespace { |
| 368 | 369 |
| 369 // Shared routine for multiple binary operations. | 370 // Shared routine for multiple binary operations. |
| 370 static void VisitBinop(InstructionSelector* selector, Node* node, | 371 void VisitBinop(InstructionSelector* selector, Node* node, |
| 371 InstructionCode opcode, FlagsContinuation* cont) { | 372 InstructionCode opcode, FlagsContinuation* cont) { |
| 372 X87OperandGenerator g(selector); | 373 X87OperandGenerator g(selector); |
| 373 Int32BinopMatcher m(node); | 374 Int32BinopMatcher m(node); |
| 374 Node* left = m.left().node(); | 375 Node* left = m.left().node(); |
| 375 Node* right = m.right().node(); | 376 Node* right = m.right().node(); |
| 376 InstructionOperand inputs[4]; | 377 InstructionOperand inputs[4]; |
| 377 size_t input_count = 0; | 378 size_t input_count = 0; |
| 378 InstructionOperand outputs[2]; | 379 InstructionOperand outputs[2]; |
| 379 size_t output_count = 0; | 380 size_t output_count = 0; |
| 380 | 381 |
| 381 // TODO(turbofan): match complex addressing modes. | 382 // TODO(turbofan): match complex addressing modes. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 410 outputs[output_count++] = g.DefineSameAsFirst(node); | 411 outputs[output_count++] = g.DefineSameAsFirst(node); |
| 411 if (cont->IsSet()) { | 412 if (cont->IsSet()) { |
| 412 outputs[output_count++] = g.DefineAsRegister(cont->result()); | 413 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
| 413 } | 414 } |
| 414 | 415 |
| 415 DCHECK_NE(0u, input_count); | 416 DCHECK_NE(0u, input_count); |
| 416 DCHECK_NE(0u, output_count); | 417 DCHECK_NE(0u, output_count); |
| 417 DCHECK_GE(arraysize(inputs), input_count); | 418 DCHECK_GE(arraysize(inputs), input_count); |
| 418 DCHECK_GE(arraysize(outputs), output_count); | 419 DCHECK_GE(arraysize(outputs), output_count); |
| 419 | 420 |
| 420 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, | 421 opcode = cont->Encode(opcode); |
| 421 inputs); | 422 if (cont->IsDeoptimize()) { |
| 423 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, |
| 424 cont->frame_state()); |
| 425 } else { |
| 426 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
| 427 } |
| 422 } | 428 } |
| 423 | 429 |
| 424 | 430 |
| 425 // Shared routine for multiple binary operations. | 431 // Shared routine for multiple binary operations. |
| 426 static void VisitBinop(InstructionSelector* selector, Node* node, | 432 void VisitBinop(InstructionSelector* selector, Node* node, |
| 427 InstructionCode opcode) { | 433 InstructionCode opcode) { |
| 428 FlagsContinuation cont; | 434 FlagsContinuation cont; |
| 429 VisitBinop(selector, node, opcode, &cont); | 435 VisitBinop(selector, node, opcode, &cont); |
| 430 } | 436 } |
| 431 | 437 |
| 438 } // namespace |
| 432 | 439 |
| 433 void InstructionSelector::VisitWord32And(Node* node) { | 440 void InstructionSelector::VisitWord32And(Node* node) { |
| 434 VisitBinop(this, node, kX87And); | 441 VisitBinop(this, node, kX87And); |
| 435 } | 442 } |
| 436 | 443 |
| 437 | 444 |
| 438 void InstructionSelector::VisitWord32Or(Node* node) { | 445 void InstructionSelector::VisitWord32Or(Node* node) { |
| 439 VisitBinop(this, node, kX87Or); | 446 VisitBinop(this, node, kX87Or); |
| 440 } | 447 } |
| 441 | 448 |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 AddressingMode addressing_mode = | 1011 AddressingMode addressing_mode = |
| 1005 g.GetEffectiveAddressMemoryOperand(left, inputs, &input_count); | 1012 g.GetEffectiveAddressMemoryOperand(left, inputs, &input_count); |
| 1006 opcode |= AddressingModeField::encode(addressing_mode); | 1013 opcode |= AddressingModeField::encode(addressing_mode); |
| 1007 opcode = cont->Encode(opcode); | 1014 opcode = cont->Encode(opcode); |
| 1008 inputs[input_count++] = right; | 1015 inputs[input_count++] = right; |
| 1009 | 1016 |
| 1010 if (cont->IsBranch()) { | 1017 if (cont->IsBranch()) { |
| 1011 inputs[input_count++] = g.Label(cont->true_block()); | 1018 inputs[input_count++] = g.Label(cont->true_block()); |
| 1012 inputs[input_count++] = g.Label(cont->false_block()); | 1019 inputs[input_count++] = g.Label(cont->false_block()); |
| 1013 selector->Emit(opcode, 0, nullptr, input_count, inputs); | 1020 selector->Emit(opcode, 0, nullptr, input_count, inputs); |
| 1021 } else if (cont->IsDeoptimize()) { |
| 1022 selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, |
| 1023 cont->frame_state()); |
| 1014 } else { | 1024 } else { |
| 1015 DCHECK(cont->IsSet()); | 1025 DCHECK(cont->IsSet()); |
| 1016 InstructionOperand output = g.DefineAsRegister(cont->result()); | 1026 InstructionOperand output = g.DefineAsRegister(cont->result()); |
| 1017 selector->Emit(opcode, 1, &output, input_count, inputs); | 1027 selector->Emit(opcode, 1, &output, input_count, inputs); |
| 1018 } | 1028 } |
| 1019 } | 1029 } |
| 1020 | 1030 |
| 1021 // Determines if {input} of {node} can be replaced by a memory operand. | 1031 // Determines if {input} of {node} can be replaced by a memory operand. |
| 1022 bool CanUseMemoryOperand(InstructionSelector* selector, InstructionCode opcode, | 1032 bool CanUseMemoryOperand(InstructionSelector* selector, InstructionCode opcode, |
| 1023 Node* node, Node* input) { | 1033 Node* node, Node* input) { |
| 1024 if (input->opcode() != IrOpcode::kLoad || !selector->CanCover(node, input)) { | 1034 if (input->opcode() != IrOpcode::kLoad || !selector->CanCover(node, input)) { |
| 1025 return false; | 1035 return false; |
| 1026 } | 1036 } |
| 1027 MachineRepresentation load_representation = | 1037 MachineRepresentation load_representation = |
| 1028 LoadRepresentationOf(input->op()).representation(); | 1038 LoadRepresentationOf(input->op()).representation(); |
| 1029 if (load_representation == MachineRepresentation::kWord32 || | 1039 if (load_representation == MachineRepresentation::kWord32 || |
| 1030 load_representation == MachineRepresentation::kTagged) { | 1040 load_representation == MachineRepresentation::kTagged) { |
| 1031 return opcode == kX87Cmp || opcode == kX87Test; | 1041 return opcode == kX87Cmp || opcode == kX87Test; |
| 1032 } | 1042 } |
| 1033 return false; | 1043 return false; |
| 1034 } | 1044 } |
| 1035 | 1045 |
| 1036 // Shared routine for multiple compare operations. | 1046 // Shared routine for multiple compare operations. |
| 1037 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1047 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 1038 InstructionOperand left, InstructionOperand right, | 1048 InstructionOperand left, InstructionOperand right, |
| 1039 FlagsContinuation* cont) { | 1049 FlagsContinuation* cont) { |
| 1040 X87OperandGenerator g(selector); | 1050 X87OperandGenerator g(selector); |
| 1051 opcode = cont->Encode(opcode); |
| 1041 if (cont->IsBranch()) { | 1052 if (cont->IsBranch()) { |
| 1042 selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, | 1053 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1043 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1054 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1055 } else if (cont->IsDeoptimize()) { |
| 1056 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, |
| 1057 cont->frame_state()); |
| 1044 } else { | 1058 } else { |
| 1045 DCHECK(cont->IsSet()); | 1059 DCHECK(cont->IsSet()); |
| 1046 selector->Emit(cont->Encode(opcode), g.DefineAsByteRegister(cont->result()), | 1060 selector->Emit(opcode, g.DefineAsByteRegister(cont->result()), left, right); |
| 1047 left, right); | |
| 1048 } | 1061 } |
| 1049 } | 1062 } |
| 1050 | 1063 |
| 1051 | 1064 |
| 1052 // Shared routine for multiple compare operations. | 1065 // Shared routine for multiple compare operations. |
| 1053 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1066 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 1054 Node* left, Node* right, FlagsContinuation* cont, | 1067 Node* left, Node* right, FlagsContinuation* cont, |
| 1055 bool commutative) { | 1068 bool commutative) { |
| 1056 X87OperandGenerator g(selector); | 1069 X87OperandGenerator g(selector); |
| 1057 if (commutative && g.CanBeBetterLeftOperand(right)) { | 1070 if (commutative && g.CanBeBetterLeftOperand(right)) { |
| 1058 std::swap(left, right); | 1071 std::swap(left, right); |
| 1059 } | 1072 } |
| 1060 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); | 1073 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); |
| 1061 } | 1074 } |
| 1062 | 1075 |
| 1063 | 1076 |
| 1064 // Shared routine for multiple float32 compare operations (inputs commuted). | 1077 // Shared routine for multiple float32 compare operations (inputs commuted). |
| 1065 void VisitFloat32Compare(InstructionSelector* selector, Node* node, | 1078 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
| 1066 FlagsContinuation* cont) { | 1079 FlagsContinuation* cont) { |
| 1067 X87OperandGenerator g(selector); | 1080 X87OperandGenerator g(selector); |
| 1068 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); | 1081 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| 1069 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); | 1082 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| 1070 if (cont->IsBranch()) { | 1083 if (cont->IsBranch()) { |
| 1071 selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), | 1084 selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), |
| 1072 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1085 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1086 } else if (cont->IsDeoptimize()) { |
| 1087 selector->EmitDeoptimize(cont->Encode(kX87Float32Cmp), g.NoOutput(), |
| 1088 g.Use(node->InputAt(0)), g.Use(node->InputAt(1)), |
| 1089 cont->frame_state()); |
| 1073 } else { | 1090 } else { |
| 1074 DCHECK(cont->IsSet()); | 1091 DCHECK(cont->IsSet()); |
| 1075 selector->Emit(cont->Encode(kX87Float32Cmp), | 1092 selector->Emit(cont->Encode(kX87Float32Cmp), |
| 1076 g.DefineAsByteRegister(cont->result())); | 1093 g.DefineAsByteRegister(cont->result())); |
| 1077 } | 1094 } |
| 1078 } | 1095 } |
| 1079 | 1096 |
| 1080 | 1097 |
| 1081 // Shared routine for multiple float64 compare operations (inputs commuted). | 1098 // Shared routine for multiple float64 compare operations (inputs commuted). |
| 1082 void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 1099 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
| 1083 FlagsContinuation* cont) { | 1100 FlagsContinuation* cont) { |
| 1084 X87OperandGenerator g(selector); | 1101 X87OperandGenerator g(selector); |
| 1085 selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); | 1102 selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| 1086 selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); | 1103 selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| 1087 if (cont->IsBranch()) { | 1104 if (cont->IsBranch()) { |
| 1088 selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(), | 1105 selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(), |
| 1089 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1106 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1107 } else if (cont->IsDeoptimize()) { |
| 1108 selector->EmitDeoptimize(cont->Encode(kX87Float64Cmp), g.NoOutput(), |
| 1109 g.Use(node->InputAt(0)), g.Use(node->InputAt(1)), |
| 1110 cont->frame_state()); |
| 1090 } else { | 1111 } else { |
| 1091 DCHECK(cont->IsSet()); | 1112 DCHECK(cont->IsSet()); |
| 1092 selector->Emit(cont->Encode(kX87Float64Cmp), | 1113 selector->Emit(cont->Encode(kX87Float64Cmp), |
| 1093 g.DefineAsByteRegister(cont->result())); | 1114 g.DefineAsByteRegister(cont->result())); |
| 1094 } | 1115 } |
| 1095 } | 1116 } |
| 1096 | 1117 |
| 1097 // Shared routine for multiple word compare operations. | 1118 // Shared routine for multiple word compare operations. |
| 1098 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1119 void VisitWordCompare(InstructionSelector* selector, Node* node, |
| 1099 InstructionCode opcode, FlagsContinuation* cont) { | 1120 InstructionCode opcode, FlagsContinuation* cont) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1138 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); | 1159 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); |
| 1139 ExternalReference js_stack_limit = | 1160 ExternalReference js_stack_limit = |
| 1140 ExternalReference::address_of_stack_limit(selector->isolate()); | 1161 ExternalReference::address_of_stack_limit(selector->isolate()); |
| 1141 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { | 1162 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { |
| 1142 // Compare(Load(js_stack_limit), LoadStackPointer) | 1163 // Compare(Load(js_stack_limit), LoadStackPointer) |
| 1143 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); | 1164 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); |
| 1144 InstructionCode opcode = cont->Encode(kX87StackCheck); | 1165 InstructionCode opcode = cont->Encode(kX87StackCheck); |
| 1145 if (cont->IsBranch()) { | 1166 if (cont->IsBranch()) { |
| 1146 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), | 1167 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), |
| 1147 g.Label(cont->false_block())); | 1168 g.Label(cont->false_block())); |
| 1169 } else if (cont->IsDeoptimize()) { |
| 1170 selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, |
| 1171 cont->frame_state()); |
| 1148 } else { | 1172 } else { |
| 1149 DCHECK(cont->IsSet()); | 1173 DCHECK(cont->IsSet()); |
| 1150 selector->Emit(opcode, g.DefineAsRegister(cont->result())); | 1174 selector->Emit(opcode, g.DefineAsRegister(cont->result())); |
| 1151 } | 1175 } |
| 1152 return; | 1176 return; |
| 1153 } | 1177 } |
| 1154 } | 1178 } |
| 1155 VisitWordCompare(selector, node, kX87Cmp, cont); | 1179 VisitWordCompare(selector, node, kX87Cmp, cont); |
| 1156 } | 1180 } |
| 1157 | 1181 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 | 1271 |
| 1248 } // namespace | 1272 } // namespace |
| 1249 | 1273 |
| 1250 | 1274 |
| 1251 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 1275 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
| 1252 BasicBlock* fbranch) { | 1276 BasicBlock* fbranch) { |
| 1253 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 1277 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
| 1254 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); | 1278 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); |
| 1255 } | 1279 } |
| 1256 | 1280 |
| 1281 void InstructionSelector::VisitDeoptimizeIf(Node* node) { |
| 1282 FlagsContinuation cont = |
| 1283 FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1)); |
| 1284 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 1285 } |
| 1286 |
| 1287 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { |
| 1288 FlagsContinuation cont = |
| 1289 FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1)); |
| 1290 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 1291 } |
| 1257 | 1292 |
| 1258 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { | 1293 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
| 1259 X87OperandGenerator g(this); | 1294 X87OperandGenerator g(this); |
| 1260 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); | 1295 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); |
| 1261 | 1296 |
| 1262 // Emit either ArchTableSwitch or ArchLookupSwitch. | 1297 // Emit either ArchTableSwitch or ArchLookupSwitch. |
| 1263 size_t table_space_cost = 4 + sw.value_range; | 1298 size_t table_space_cost = 4 + sw.value_range; |
| 1264 size_t table_time_cost = 3; | 1299 size_t table_time_cost = 3; |
| 1265 size_t lookup_space_cost = 3 + 2 * sw.case_count; | 1300 size_t lookup_space_cost = 3 + 2 * sw.case_count; |
| 1266 size_t lookup_time_cost = sw.case_count; | 1301 size_t lookup_time_cost = sw.case_count; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1277 // Generate a table lookup. | 1312 // Generate a table lookup. |
| 1278 return EmitTableSwitch(sw, index_operand); | 1313 return EmitTableSwitch(sw, index_operand); |
| 1279 } | 1314 } |
| 1280 | 1315 |
| 1281 // Generate a sequence of conditional jumps. | 1316 // Generate a sequence of conditional jumps. |
| 1282 return EmitLookupSwitch(sw, value_operand); | 1317 return EmitLookupSwitch(sw, value_operand); |
| 1283 } | 1318 } |
| 1284 | 1319 |
| 1285 | 1320 |
| 1286 void InstructionSelector::VisitWord32Equal(Node* const node) { | 1321 void InstructionSelector::VisitWord32Equal(Node* const node) { |
| 1287 FlagsContinuation cont(kEqual, node); | 1322 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); |
| 1288 Int32BinopMatcher m(node); | 1323 Int32BinopMatcher m(node); |
| 1289 if (m.right().Is(0)) { | 1324 if (m.right().Is(0)) { |
| 1290 return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); | 1325 return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); |
| 1291 } | 1326 } |
| 1292 VisitWordCompare(this, node, &cont); | 1327 VisitWordCompare(this, node, &cont); |
| 1293 } | 1328 } |
| 1294 | 1329 |
| 1295 | 1330 |
| 1296 void InstructionSelector::VisitInt32LessThan(Node* node) { | 1331 void InstructionSelector::VisitInt32LessThan(Node* node) { |
| 1297 FlagsContinuation cont(kSignedLessThan, node); | 1332 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); |
| 1298 VisitWordCompare(this, node, &cont); | 1333 VisitWordCompare(this, node, &cont); |
| 1299 } | 1334 } |
| 1300 | 1335 |
| 1301 | 1336 |
| 1302 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { | 1337 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { |
| 1303 FlagsContinuation cont(kSignedLessThanOrEqual, node); | 1338 FlagsContinuation cont = |
| 1339 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); |
| 1304 VisitWordCompare(this, node, &cont); | 1340 VisitWordCompare(this, node, &cont); |
| 1305 } | 1341 } |
| 1306 | 1342 |
| 1307 | 1343 |
| 1308 void InstructionSelector::VisitUint32LessThan(Node* node) { | 1344 void InstructionSelector::VisitUint32LessThan(Node* node) { |
| 1309 FlagsContinuation cont(kUnsignedLessThan, node); | 1345 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); |
| 1310 VisitWordCompare(this, node, &cont); | 1346 VisitWordCompare(this, node, &cont); |
| 1311 } | 1347 } |
| 1312 | 1348 |
| 1313 | 1349 |
| 1314 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { | 1350 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { |
| 1315 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); | 1351 FlagsContinuation cont = |
| 1352 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); |
| 1316 VisitWordCompare(this, node, &cont); | 1353 VisitWordCompare(this, node, &cont); |
| 1317 } | 1354 } |
| 1318 | 1355 |
| 1319 | 1356 |
| 1320 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { | 1357 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
| 1321 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1358 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| 1322 FlagsContinuation cont(kOverflow, ovf); | 1359 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
| 1323 return VisitBinop(this, node, kX87Add, &cont); | 1360 return VisitBinop(this, node, kX87Add, &cont); |
| 1324 } | 1361 } |
| 1325 FlagsContinuation cont; | 1362 FlagsContinuation cont; |
| 1326 VisitBinop(this, node, kX87Add, &cont); | 1363 VisitBinop(this, node, kX87Add, &cont); |
| 1327 } | 1364 } |
| 1328 | 1365 |
| 1329 | 1366 |
| 1330 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { | 1367 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
| 1331 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1368 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| 1332 FlagsContinuation cont(kOverflow, ovf); | 1369 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
| 1333 return VisitBinop(this, node, kX87Sub, &cont); | 1370 return VisitBinop(this, node, kX87Sub, &cont); |
| 1334 } | 1371 } |
| 1335 FlagsContinuation cont; | 1372 FlagsContinuation cont; |
| 1336 VisitBinop(this, node, kX87Sub, &cont); | 1373 VisitBinop(this, node, kX87Sub, &cont); |
| 1337 } | 1374 } |
| 1338 | 1375 |
| 1339 | 1376 |
| 1340 void InstructionSelector::VisitFloat32Equal(Node* node) { | 1377 void InstructionSelector::VisitFloat32Equal(Node* node) { |
| 1341 FlagsContinuation cont(kUnorderedEqual, node); | 1378 FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node); |
| 1342 VisitFloat32Compare(this, node, &cont); | 1379 VisitFloat32Compare(this, node, &cont); |
| 1343 } | 1380 } |
| 1344 | 1381 |
| 1345 | 1382 |
| 1346 void InstructionSelector::VisitFloat32LessThan(Node* node) { | 1383 void InstructionSelector::VisitFloat32LessThan(Node* node) { |
| 1347 FlagsContinuation cont(kUnsignedGreaterThan, node); | 1384 FlagsContinuation cont = |
| 1385 FlagsContinuation::ForSet(kUnsignedGreaterThan, node); |
| 1348 VisitFloat32Compare(this, node, &cont); | 1386 VisitFloat32Compare(this, node, &cont); |
| 1349 } | 1387 } |
| 1350 | 1388 |
| 1351 | 1389 |
| 1352 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { | 1390 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { |
| 1353 FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node); | 1391 FlagsContinuation cont = |
| 1392 FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node); |
| 1354 VisitFloat32Compare(this, node, &cont); | 1393 VisitFloat32Compare(this, node, &cont); |
| 1355 } | 1394 } |
| 1356 | 1395 |
| 1357 | 1396 |
| 1358 void InstructionSelector::VisitFloat64Equal(Node* node) { | 1397 void InstructionSelector::VisitFloat64Equal(Node* node) { |
| 1359 FlagsContinuation cont(kUnorderedEqual, node); | 1398 FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node); |
| 1360 VisitFloat64Compare(this, node, &cont); | 1399 VisitFloat64Compare(this, node, &cont); |
| 1361 } | 1400 } |
| 1362 | 1401 |
| 1363 | 1402 |
| 1364 void InstructionSelector::VisitFloat64LessThan(Node* node) { | 1403 void InstructionSelector::VisitFloat64LessThan(Node* node) { |
| 1365 FlagsContinuation cont(kUnsignedGreaterThan, node); | 1404 FlagsContinuation cont = |
| 1405 FlagsContinuation::ForSet(kUnsignedGreaterThan, node); |
| 1366 VisitFloat64Compare(this, node, &cont); | 1406 VisitFloat64Compare(this, node, &cont); |
| 1367 } | 1407 } |
| 1368 | 1408 |
| 1369 | 1409 |
| 1370 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { | 1410 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { |
| 1371 FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node); | 1411 FlagsContinuation cont = |
| 1412 FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node); |
| 1372 VisitFloat64Compare(this, node, &cont); | 1413 VisitFloat64Compare(this, node, &cont); |
| 1373 } | 1414 } |
| 1374 | 1415 |
| 1375 | 1416 |
| 1376 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { | 1417 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { |
| 1377 X87OperandGenerator g(this); | 1418 X87OperandGenerator g(this); |
| 1378 Emit(kX87Float64ExtractLowWord32, g.DefineAsRegister(node), | 1419 Emit(kX87Float64ExtractLowWord32, g.DefineAsRegister(node), |
| 1379 g.Use(node->InputAt(0))); | 1420 g.Use(node->InputAt(0))); |
| 1380 } | 1421 } |
| 1381 | 1422 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1425 MachineOperatorBuilder::kFloat32RoundTruncate | | 1466 MachineOperatorBuilder::kFloat32RoundTruncate | |
| 1426 MachineOperatorBuilder::kFloat64RoundTruncate | | 1467 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1427 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1468 MachineOperatorBuilder::kFloat32RoundTiesEven | |
| 1428 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1469 MachineOperatorBuilder::kFloat64RoundTiesEven; |
| 1429 return flags; | 1470 return flags; |
| 1430 } | 1471 } |
| 1431 | 1472 |
| 1432 } // namespace compiler | 1473 } // namespace compiler |
| 1433 } // namespace internal | 1474 } // namespace internal |
| 1434 } // namespace v8 | 1475 } // namespace v8 |
| OLD | NEW |