Chromium Code Reviews| 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/compiler/generic-node-inl.h" | 5 #include "src/compiler/generic-node-inl.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 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 | 357 |
| 358 void InstructionSelector::VisitWord32Ror(Node* node) { | 358 void InstructionSelector::VisitWord32Ror(Node* node) { |
| 359 VisitWord32Shift(this, node, kX64Ror32); | 359 VisitWord32Shift(this, node, kX64Ror32); |
| 360 } | 360 } |
| 361 | 361 |
| 362 | 362 |
| 363 void InstructionSelector::VisitWord64Ror(Node* node) { | 363 void InstructionSelector::VisitWord64Ror(Node* node) { |
| 364 VisitWord64Shift(this, node, kX64Ror); | 364 VisitWord64Shift(this, node, kX64Ror); |
| 365 } | 365 } |
| 366 | 366 |
| 367 namespace { | |
| 368 | |
| 369 static AddressingMode ScaleFactorToAddressingMode( | |
|
titzer
2014/11/06 11:47:06
If you use the scale power of 2, then you can just
danno
2014/11/06 23:34:07
Done.
| |
| 370 int scale_factor, const AddressingMode modes[]) { | |
| 371 switch (scale_factor) { | |
| 372 case 1: | |
| 373 return modes[0]; | |
| 374 break; | |
| 375 case 2: | |
| 376 return modes[1]; | |
| 377 break; | |
| 378 case 4: | |
| 379 return modes[2]; | |
| 380 break; | |
| 381 case 8: | |
| 382 return modes[3]; | |
| 383 break; | |
| 384 default: | |
| 385 break; | |
| 386 } | |
| 387 UNREACHABLE(); | |
| 388 return modes[0]; | |
| 389 } | |
| 390 | |
| 391 AddressingMode GenerateMemoryOperandInputs(X64OperandGenerator* g, Node* scaled, | |
| 392 int scale_factor, Node* offset, | |
| 393 Node* constant, | |
| 394 InstructionOperand* inputs[], | |
| 395 size_t* input_count) { | |
| 396 AddressingMode mode = kMode_MRI; | |
| 397 if (offset != NULL) { | |
| 398 inputs[(*input_count)++] = g->UseRegister(offset); | |
| 399 if (scaled != NULL) { | |
| 400 inputs[(*input_count)++] = g->UseRegister(scaled); | |
| 401 if (constant != NULL) { | |
| 402 inputs[(*input_count)++] = g->UseImmediate(constant); | |
| 403 static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I, | |
| 404 kMode_MR4I, kMode_MR8I}; | |
| 405 mode = ScaleFactorToAddressingMode(scale_factor, kMRnI_modes); | |
| 406 } else { | |
| 407 static const AddressingMode kMRn_modes[] = {kMode_MR1, kMode_MR2, | |
| 408 kMode_MR4, kMode_MR8}; | |
| 409 mode = ScaleFactorToAddressingMode(scale_factor, kMRn_modes); | |
| 410 } | |
| 411 } else { | |
| 412 DCHECK(constant != NULL); | |
| 413 inputs[(*input_count)++] = g->UseImmediate(constant); | |
| 414 mode = kMode_MRI; | |
| 415 } | |
| 416 } else { | |
| 417 DCHECK(scaled != NULL); | |
| 418 inputs[(*input_count)++] = g->UseRegister(scaled); | |
| 419 if (constant != NULL) { | |
| 420 inputs[(*input_count)++] = g->UseImmediate(constant); | |
| 421 static const AddressingMode kMnI_modes[] = {kMode_M1I, kMode_M2I, | |
| 422 kMode_M4I, kMode_M8I}; | |
| 423 mode = ScaleFactorToAddressingMode(scale_factor, kMnI_modes); | |
| 424 } else { | |
| 425 static const AddressingMode kMn_modes[] = {kMode_M1, kMode_M2, kMode_M4, | |
| 426 kMode_M8}; | |
| 427 mode = ScaleFactorToAddressingMode(scale_factor, kMn_modes); | |
| 428 } | |
| 429 } | |
| 430 return mode; | |
| 431 } | |
| 432 | |
| 433 } // namespace | |
| 434 | |
| 367 | 435 |
| 368 void InstructionSelector::VisitInt32Add(Node* node) { | 436 void InstructionSelector::VisitInt32Add(Node* node) { |
| 437 // Try to match the Add to a leal pattern | |
| 438 ScaledWithOffsetMatcher m(node); | |
| 439 X64OperandGenerator g(this); | |
| 440 if (m.Matches() && (m.Constant() == NULL || g.CanBeImmediate(m.Constant()))) { | |
| 441 InstructionOperand* inputs[4]; | |
| 442 size_t input_count = 0; | |
| 443 | |
| 444 AddressingMode mode = | |
| 445 GenerateMemoryOperandInputs(&g, m.Scaled(), m.ScaleFactor(), m.Offset(), | |
| 446 m.Constant(), inputs, &input_count); | |
| 447 | |
| 448 DCHECK_NE(0, static_cast<int>(input_count)); | |
| 449 DCHECK_GE(arraysize(inputs), input_count); | |
| 450 | |
| 451 InstructionOperand* outputs[1]; | |
| 452 outputs[0] = g.DefineAsRegister(node); | |
| 453 | |
| 454 InstructionCode opcode = AddressingModeField::encode(mode) | kX64Lea32; | |
| 455 | |
| 456 Emit(opcode, 1, outputs, input_count, inputs); | |
| 457 return; | |
| 458 } | |
| 459 | |
| 369 VisitBinop(this, node, kX64Add32); | 460 VisitBinop(this, node, kX64Add32); |
| 370 } | 461 } |
| 371 | 462 |
| 372 | 463 |
| 373 void InstructionSelector::VisitInt64Add(Node* node) { | 464 void InstructionSelector::VisitInt64Add(Node* node) { |
| 374 VisitBinop(this, node, kX64Add); | 465 VisitBinop(this, node, kX64Add); |
| 375 } | 466 } |
| 376 | 467 |
| 377 | 468 |
| 378 void InstructionSelector::VisitInt32Sub(Node* node) { | 469 void InstructionSelector::VisitInt32Sub(Node* node) { |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1083 if (CpuFeatures::IsSupported(SSE4_1)) { | 1174 if (CpuFeatures::IsSupported(SSE4_1)) { |
| 1084 return MachineOperatorBuilder::kFloat64Floor | | 1175 return MachineOperatorBuilder::kFloat64Floor | |
| 1085 MachineOperatorBuilder::kFloat64Ceil | | 1176 MachineOperatorBuilder::kFloat64Ceil | |
| 1086 MachineOperatorBuilder::kFloat64RoundTruncate; | 1177 MachineOperatorBuilder::kFloat64RoundTruncate; |
| 1087 } | 1178 } |
| 1088 return MachineOperatorBuilder::kNoFlags; | 1179 return MachineOperatorBuilder::kNoFlags; |
| 1089 } | 1180 } |
| 1090 } // namespace compiler | 1181 } // namespace compiler |
| 1091 } // namespace internal | 1182 } // namespace internal |
| 1092 } // namespace v8 | 1183 } // namespace v8 |
| OLD | NEW |