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 |