| 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/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
| 6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
| 7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 case kShift64Imm: | 60 case kShift64Imm: |
| 61 return 0 <= value && value < 64; | 61 return 0 <= value && value < 64; |
| 62 case kNoImmediate: | 62 case kNoImmediate: |
| 63 return false; | 63 return false; |
| 64 } | 64 } |
| 65 return false; | 65 return false; |
| 66 } | 66 } |
| 67 }; | 67 }; |
| 68 | 68 |
| 69 | 69 |
| 70 static void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode, | 70 namespace { |
| 71 Node* node) { | 71 |
| 72 void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { |
| 72 PPCOperandGenerator g(selector); | 73 PPCOperandGenerator g(selector); |
| 73 selector->Emit(opcode, g.DefineAsRegister(node), | 74 selector->Emit(opcode, g.DefineAsRegister(node), |
| 74 g.UseRegister(node->InputAt(0))); | 75 g.UseRegister(node->InputAt(0))); |
| 75 } | 76 } |
| 76 | 77 |
| 77 | 78 |
| 78 static void VisitRRR(InstructionSelector* selector, Node* node, | 79 void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { |
| 79 ArchOpcode opcode) { | |
| 80 PPCOperandGenerator g(selector); | 80 PPCOperandGenerator g(selector); |
| 81 selector->Emit(opcode, g.DefineAsRegister(node), | 81 selector->Emit(opcode, g.DefineAsRegister(node), |
| 82 g.UseRegister(node->InputAt(0)), | 82 g.UseRegister(node->InputAt(0)), |
| 83 g.UseRegister(node->InputAt(1))); | |
| 84 } | |
| 85 | |
| 86 | |
| 87 static void VisitRRRFloat64(InstructionSelector* selector, Node* node, | |
| 88 ArchOpcode opcode) { | |
| 89 PPCOperandGenerator g(selector); | |
| 90 selector->Emit(opcode, g.DefineAsRegister(node), | |
| 91 g.UseRegister(node->InputAt(0)), | |
| 92 g.UseRegister(node->InputAt(1))); | 83 g.UseRegister(node->InputAt(1))); |
| 93 } | 84 } |
| 94 | 85 |
| 95 | 86 |
| 96 static void VisitRRO(InstructionSelector* selector, Node* node, | 87 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node, |
| 97 ArchOpcode opcode, ImmediateMode operand_mode) { | 88 ImmediateMode operand_mode) { |
| 98 PPCOperandGenerator g(selector); | 89 PPCOperandGenerator g(selector); |
| 99 selector->Emit(opcode, g.DefineAsRegister(node), | 90 selector->Emit(opcode, g.DefineAsRegister(node), |
| 100 g.UseRegister(node->InputAt(0)), | 91 g.UseRegister(node->InputAt(0)), |
| 101 g.UseOperand(node->InputAt(1), operand_mode)); | 92 g.UseOperand(node->InputAt(1), operand_mode)); |
| 102 } | 93 } |
| 103 | 94 |
| 104 | 95 |
| 105 // Shared routine for multiple binary operations. | 96 // Shared routine for multiple binary operations. |
| 106 template <typename Matcher> | 97 template <typename Matcher> |
| 107 static void VisitBinop(InstructionSelector* selector, Node* node, | 98 void VisitBinop(InstructionSelector* selector, Node* node, |
| 108 InstructionCode opcode, ImmediateMode operand_mode, | 99 InstructionCode opcode, ImmediateMode operand_mode, |
| 109 FlagsContinuation* cont) { | 100 FlagsContinuation* cont) { |
| 110 PPCOperandGenerator g(selector); | 101 PPCOperandGenerator g(selector); |
| 111 Matcher m(node); | 102 Matcher m(node); |
| 112 InstructionOperand inputs[4]; | 103 InstructionOperand inputs[4]; |
| 113 size_t input_count = 0; | 104 size_t input_count = 0; |
| 114 InstructionOperand outputs[2]; | 105 InstructionOperand outputs[2]; |
| 115 size_t output_count = 0; | 106 size_t output_count = 0; |
| 116 | 107 |
| 117 inputs[input_count++] = g.UseRegister(m.left().node()); | 108 inputs[input_count++] = g.UseRegister(m.left().node()); |
| 118 inputs[input_count++] = g.UseOperand(m.right().node(), operand_mode); | 109 inputs[input_count++] = g.UseOperand(m.right().node(), operand_mode); |
| 119 | 110 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 132 DCHECK_GE(arraysize(inputs), input_count); | 123 DCHECK_GE(arraysize(inputs), input_count); |
| 133 DCHECK_GE(arraysize(outputs), output_count); | 124 DCHECK_GE(arraysize(outputs), output_count); |
| 134 | 125 |
| 135 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, | 126 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, |
| 136 inputs); | 127 inputs); |
| 137 } | 128 } |
| 138 | 129 |
| 139 | 130 |
| 140 // Shared routine for multiple binary operations. | 131 // Shared routine for multiple binary operations. |
| 141 template <typename Matcher> | 132 template <typename Matcher> |
| 142 static void VisitBinop(InstructionSelector* selector, Node* node, | 133 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, |
| 143 ArchOpcode opcode, ImmediateMode operand_mode) { | 134 ImmediateMode operand_mode) { |
| 144 FlagsContinuation cont; | 135 FlagsContinuation cont; |
| 145 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); | 136 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); |
| 146 } | 137 } |
| 147 | 138 |
| 139 } // namespace |
| 140 |
| 148 | 141 |
| 149 void InstructionSelector::VisitLoad(Node* node) { | 142 void InstructionSelector::VisitLoad(Node* node) { |
| 150 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 143 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
| 151 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 144 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
| 152 PPCOperandGenerator g(this); | 145 PPCOperandGenerator g(this); |
| 153 Node* base = node->InputAt(0); | 146 Node* base = node->InputAt(0); |
| 154 Node* offset = node->InputAt(1); | 147 Node* offset = node->InputAt(1); |
| 155 | 148 |
| 156 ArchOpcode opcode; | 149 ArchOpcode opcode; |
| 157 ImmediateMode mode = kInt16Imm; | 150 ImmediateMode mode = kInt16Imm; |
| 158 switch (rep) { | 151 switch (rep) { |
| 159 case kRepFloat32: | 152 case kRepFloat32: |
| 160 opcode = kPPC_LoadFloat32; | 153 opcode = kPPC_LoadFloat32; |
| 161 break; | 154 break; |
| 162 case kRepFloat64: | 155 case kRepFloat64: |
| 163 opcode = kPPC_LoadFloat64; | 156 opcode = kPPC_LoadDouble; |
| 164 break; | 157 break; |
| 165 case kRepBit: // Fall through. | 158 case kRepBit: // Fall through. |
| 166 case kRepWord8: | 159 case kRepWord8: |
| 167 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS8 : kPPC_LoadWordU8; | 160 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS8 : kPPC_LoadWordU8; |
| 168 break; | 161 break; |
| 169 case kRepWord16: | 162 case kRepWord16: |
| 170 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS16 : kPPC_LoadWordU16; | 163 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS16 : kPPC_LoadWordU16; |
| 171 break; | 164 break; |
| 172 #if !V8_TARGET_ARCH_PPC64 | 165 #if !V8_TARGET_ARCH_PPC64 |
| 173 case kRepTagged: // Fall through. | 166 case kRepTagged: // Fall through. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 return; | 216 return; |
| 224 } | 217 } |
| 225 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); | 218 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); |
| 226 ArchOpcode opcode; | 219 ArchOpcode opcode; |
| 227 ImmediateMode mode = kInt16Imm; | 220 ImmediateMode mode = kInt16Imm; |
| 228 switch (rep) { | 221 switch (rep) { |
| 229 case kRepFloat32: | 222 case kRepFloat32: |
| 230 opcode = kPPC_StoreFloat32; | 223 opcode = kPPC_StoreFloat32; |
| 231 break; | 224 break; |
| 232 case kRepFloat64: | 225 case kRepFloat64: |
| 233 opcode = kPPC_StoreFloat64; | 226 opcode = kPPC_StoreDouble; |
| 234 break; | 227 break; |
| 235 case kRepBit: // Fall through. | 228 case kRepBit: // Fall through. |
| 236 case kRepWord8: | 229 case kRepWord8: |
| 237 opcode = kPPC_StoreWord8; | 230 opcode = kPPC_StoreWord8; |
| 238 break; | 231 break; |
| 239 case kRepWord16: | 232 case kRepWord16: |
| 240 opcode = kPPC_StoreWord16; | 233 opcode = kPPC_StoreWord16; |
| 241 break; | 234 break; |
| 242 #if !V8_TARGET_ARCH_PPC64 | 235 #if !V8_TARGET_ARCH_PPC64 |
| 243 case kRepTagged: // Fall through. | 236 case kRepTagged: // Fall through. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 334 |
| 342 template <typename Matcher> | 335 template <typename Matcher> |
| 343 static void VisitLogical(InstructionSelector* selector, Node* node, Matcher* m, | 336 static void VisitLogical(InstructionSelector* selector, Node* node, Matcher* m, |
| 344 ArchOpcode opcode, bool left_can_cover, | 337 ArchOpcode opcode, bool left_can_cover, |
| 345 bool right_can_cover, ImmediateMode imm_mode) { | 338 bool right_can_cover, ImmediateMode imm_mode) { |
| 346 PPCOperandGenerator g(selector); | 339 PPCOperandGenerator g(selector); |
| 347 | 340 |
| 348 // Map instruction to equivalent operation with inverted right input. | 341 // Map instruction to equivalent operation with inverted right input. |
| 349 ArchOpcode inv_opcode = opcode; | 342 ArchOpcode inv_opcode = opcode; |
| 350 switch (opcode) { | 343 switch (opcode) { |
| 351 case kPPC_And32: | 344 case kPPC_And: |
| 352 inv_opcode = kPPC_AndComplement32; | 345 inv_opcode = kPPC_AndComplement; |
| 353 break; | 346 break; |
| 354 case kPPC_And64: | 347 case kPPC_Or: |
| 355 inv_opcode = kPPC_AndComplement64; | 348 inv_opcode = kPPC_OrComplement; |
| 356 break; | |
| 357 case kPPC_Or32: | |
| 358 inv_opcode = kPPC_OrComplement32; | |
| 359 break; | |
| 360 case kPPC_Or64: | |
| 361 inv_opcode = kPPC_OrComplement64; | |
| 362 break; | 349 break; |
| 363 default: | 350 default: |
| 364 UNREACHABLE(); | 351 UNREACHABLE(); |
| 365 } | 352 } |
| 366 | 353 |
| 367 // Select Logical(y, ~x) for Logical(Xor(x, -1), y). | 354 // Select Logical(y, ~x) for Logical(Xor(x, -1), y). |
| 368 if ((m->left().IsWord32Xor() || m->left().IsWord64Xor()) && left_can_cover) { | 355 if ((m->left().IsWord32Xor() || m->left().IsWord64Xor()) && left_can_cover) { |
| 369 Matcher mleft(m->left().node()); | 356 Matcher mleft(m->left().node()); |
| 370 if (mleft.right().Is(-1)) { | 357 if (mleft.right().Is(-1)) { |
| 371 selector->Emit(inv_opcode, g.DefineAsRegister(node), | 358 selector->Emit(inv_opcode, g.DefineAsRegister(node), |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 } | 431 } |
| 445 } | 432 } |
| 446 } | 433 } |
| 447 if (mb >= me) { | 434 if (mb >= me) { |
| 448 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), g.UseRegister(left), | 435 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), g.UseRegister(left), |
| 449 g.TempImmediate(sh), g.TempImmediate(mb), g.TempImmediate(me)); | 436 g.TempImmediate(sh), g.TempImmediate(mb), g.TempImmediate(me)); |
| 450 return; | 437 return; |
| 451 } | 438 } |
| 452 } | 439 } |
| 453 VisitLogical<Int32BinopMatcher>( | 440 VisitLogical<Int32BinopMatcher>( |
| 454 this, node, &m, kPPC_And32, CanCover(node, m.left().node()), | 441 this, node, &m, kPPC_And, CanCover(node, m.left().node()), |
| 455 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | 442 CanCover(node, m.right().node()), kInt16Imm_Unsigned); |
| 456 } | 443 } |
| 457 | 444 |
| 458 | 445 |
| 459 #if V8_TARGET_ARCH_PPC64 | 446 #if V8_TARGET_ARCH_PPC64 |
| 460 // TODO(mbrandy): Absorb rotate-right into rldic? | 447 // TODO(mbrandy): Absorb rotate-right into rldic? |
| 461 void InstructionSelector::VisitWord64And(Node* node) { | 448 void InstructionSelector::VisitWord64And(Node* node) { |
| 462 PPCOperandGenerator g(this); | 449 PPCOperandGenerator g(this); |
| 463 Int64BinopMatcher m(node); | 450 Int64BinopMatcher m(node); |
| 464 int mb; | 451 int mb; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 mask = mb; | 488 mask = mb; |
| 502 } | 489 } |
| 503 if (match) { | 490 if (match) { |
| 504 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), | 491 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), |
| 505 g.TempImmediate(sh), g.TempImmediate(mask)); | 492 g.TempImmediate(sh), g.TempImmediate(mask)); |
| 506 return; | 493 return; |
| 507 } | 494 } |
| 508 } | 495 } |
| 509 } | 496 } |
| 510 VisitLogical<Int64BinopMatcher>( | 497 VisitLogical<Int64BinopMatcher>( |
| 511 this, node, &m, kPPC_And64, CanCover(node, m.left().node()), | 498 this, node, &m, kPPC_And, CanCover(node, m.left().node()), |
| 512 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | 499 CanCover(node, m.right().node()), kInt16Imm_Unsigned); |
| 513 } | 500 } |
| 514 #endif | 501 #endif |
| 515 | 502 |
| 516 | 503 |
| 517 void InstructionSelector::VisitWord32Or(Node* node) { | 504 void InstructionSelector::VisitWord32Or(Node* node) { |
| 518 Int32BinopMatcher m(node); | 505 Int32BinopMatcher m(node); |
| 519 VisitLogical<Int32BinopMatcher>( | 506 VisitLogical<Int32BinopMatcher>( |
| 520 this, node, &m, kPPC_Or32, CanCover(node, m.left().node()), | 507 this, node, &m, kPPC_Or, CanCover(node, m.left().node()), |
| 521 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | 508 CanCover(node, m.right().node()), kInt16Imm_Unsigned); |
| 522 } | 509 } |
| 523 | 510 |
| 524 | 511 |
| 525 #if V8_TARGET_ARCH_PPC64 | 512 #if V8_TARGET_ARCH_PPC64 |
| 526 void InstructionSelector::VisitWord64Or(Node* node) { | 513 void InstructionSelector::VisitWord64Or(Node* node) { |
| 527 Int64BinopMatcher m(node); | 514 Int64BinopMatcher m(node); |
| 528 VisitLogical<Int64BinopMatcher>( | 515 VisitLogical<Int64BinopMatcher>( |
| 529 this, node, &m, kPPC_Or64, CanCover(node, m.left().node()), | 516 this, node, &m, kPPC_Or, CanCover(node, m.left().node()), |
| 530 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | 517 CanCover(node, m.right().node()), kInt16Imm_Unsigned); |
| 531 } | 518 } |
| 532 #endif | 519 #endif |
| 533 | 520 |
| 534 | 521 |
| 535 void InstructionSelector::VisitWord32Xor(Node* node) { | 522 void InstructionSelector::VisitWord32Xor(Node* node) { |
| 536 PPCOperandGenerator g(this); | 523 PPCOperandGenerator g(this); |
| 537 Int32BinopMatcher m(node); | 524 Int32BinopMatcher m(node); |
| 538 if (m.right().Is(-1)) { | 525 if (m.right().Is(-1)) { |
| 539 Emit(kPPC_Not32, g.DefineAsRegister(node), g.UseRegister(m.left().node())); | 526 Emit(kPPC_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node())); |
| 540 } else { | 527 } else { |
| 541 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Xor32, kInt16Imm_Unsigned); | 528 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Xor, kInt16Imm_Unsigned); |
| 542 } | 529 } |
| 543 } | 530 } |
| 544 | 531 |
| 545 | 532 |
| 546 #if V8_TARGET_ARCH_PPC64 | 533 #if V8_TARGET_ARCH_PPC64 |
| 547 void InstructionSelector::VisitWord64Xor(Node* node) { | 534 void InstructionSelector::VisitWord64Xor(Node* node) { |
| 548 PPCOperandGenerator g(this); | 535 PPCOperandGenerator g(this); |
| 549 Int64BinopMatcher m(node); | 536 Int64BinopMatcher m(node); |
| 550 if (m.right().Is(-1)) { | 537 if (m.right().Is(-1)) { |
| 551 Emit(kPPC_Not64, g.DefineAsRegister(node), g.UseRegister(m.left().node())); | 538 Emit(kPPC_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node())); |
| 552 } else { | 539 } else { |
| 553 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Xor64, kInt16Imm_Unsigned); | 540 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Xor, kInt16Imm_Unsigned); |
| 554 } | 541 } |
| 555 } | 542 } |
| 556 #endif | 543 #endif |
| 557 | 544 |
| 558 | 545 |
| 559 void InstructionSelector::VisitWord32Shl(Node* node) { | 546 void InstructionSelector::VisitWord32Shl(Node* node) { |
| 560 PPCOperandGenerator g(this); | 547 PPCOperandGenerator g(this); |
| 561 Int32BinopMatcher m(node); | 548 Int32BinopMatcher m(node); |
| 562 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { | 549 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { |
| 563 // Try to absorb logical-and into rlwinm | 550 // Try to absorb logical-and into rlwinm |
| 564 Int32BinopMatcher mleft(m.left().node()); | 551 Int32BinopMatcher mleft(m.left().node()); |
| 565 int sh = m.right().Value(); | 552 int sh = m.right().Value(); |
| 566 int mb; | 553 int mb; |
| 567 int me; | 554 int me; |
| 568 if (mleft.right().HasValue() && | 555 if (mleft.right().HasValue() && |
| 569 IsContiguousMask32(mleft.right().Value() << sh, &mb, &me)) { | 556 IsContiguousMask32(mleft.right().Value() << sh, &mb, &me)) { |
| 570 // Adjust the mask such that it doesn't include any rotated bits. | 557 // Adjust the mask such that it doesn't include any rotated bits. |
| 571 if (me < sh) me = sh; | 558 if (me < sh) me = sh; |
| 572 if (mb >= me) { | 559 if (mb >= me) { |
| 573 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), | 560 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), |
| 574 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 561 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
| 575 g.TempImmediate(mb), g.TempImmediate(me)); | 562 g.TempImmediate(mb), g.TempImmediate(me)); |
| 576 return; | 563 return; |
| 577 } | 564 } |
| 578 } | 565 } |
| 579 } | 566 } |
| 580 VisitRRO(this, node, kPPC_ShiftLeft32, kShift32Imm); | 567 VisitRRO(this, kPPC_ShiftLeft32, node, kShift32Imm); |
| 581 } | 568 } |
| 582 | 569 |
| 583 | 570 |
| 584 #if V8_TARGET_ARCH_PPC64 | 571 #if V8_TARGET_ARCH_PPC64 |
| 585 void InstructionSelector::VisitWord64Shl(Node* node) { | 572 void InstructionSelector::VisitWord64Shl(Node* node) { |
| 586 PPCOperandGenerator g(this); | 573 PPCOperandGenerator g(this); |
| 587 Int64BinopMatcher m(node); | 574 Int64BinopMatcher m(node); |
| 588 // TODO(mbrandy): eliminate left sign extension if right >= 32 | 575 // TODO(mbrandy): eliminate left sign extension if right >= 32 |
| 589 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { | 576 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { |
| 590 // Try to absorb logical-and into rldic | 577 // Try to absorb logical-and into rldic |
| (...skipping 24 matching lines...) Expand all Loading... |
| 615 } | 602 } |
| 616 if (match) { | 603 if (match) { |
| 617 Emit(opcode, g.DefineAsRegister(node), | 604 Emit(opcode, g.DefineAsRegister(node), |
| 618 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 605 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
| 619 g.TempImmediate(mask)); | 606 g.TempImmediate(mask)); |
| 620 return; | 607 return; |
| 621 } | 608 } |
| 622 } | 609 } |
| 623 } | 610 } |
| 624 } | 611 } |
| 625 VisitRRO(this, node, kPPC_ShiftLeft64, kShift64Imm); | 612 VisitRRO(this, kPPC_ShiftLeft64, node, kShift64Imm); |
| 626 } | 613 } |
| 627 #endif | 614 #endif |
| 628 | 615 |
| 629 | 616 |
| 630 void InstructionSelector::VisitWord32Shr(Node* node) { | 617 void InstructionSelector::VisitWord32Shr(Node* node) { |
| 631 PPCOperandGenerator g(this); | 618 PPCOperandGenerator g(this); |
| 632 Int32BinopMatcher m(node); | 619 Int32BinopMatcher m(node); |
| 633 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { | 620 if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) { |
| 634 // Try to absorb logical-and into rlwinm | 621 // Try to absorb logical-and into rlwinm |
| 635 Int32BinopMatcher mleft(m.left().node()); | 622 Int32BinopMatcher mleft(m.left().node()); |
| 636 int sh = m.right().Value(); | 623 int sh = m.right().Value(); |
| 637 int mb; | 624 int mb; |
| 638 int me; | 625 int me; |
| 639 if (mleft.right().HasValue() && | 626 if (mleft.right().HasValue() && |
| 640 IsContiguousMask32((uint32_t)(mleft.right().Value()) >> sh, &mb, &me)) { | 627 IsContiguousMask32((uint32_t)(mleft.right().Value()) >> sh, &mb, &me)) { |
| 641 // Adjust the mask such that it doesn't include any rotated bits. | 628 // Adjust the mask such that it doesn't include any rotated bits. |
| 642 if (mb > 31 - sh) mb = 31 - sh; | 629 if (mb > 31 - sh) mb = 31 - sh; |
| 643 sh = (32 - sh) & 0x1f; | 630 sh = (32 - sh) & 0x1f; |
| 644 if (mb >= me) { | 631 if (mb >= me) { |
| 645 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), | 632 Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), |
| 646 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 633 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
| 647 g.TempImmediate(mb), g.TempImmediate(me)); | 634 g.TempImmediate(mb), g.TempImmediate(me)); |
| 648 return; | 635 return; |
| 649 } | 636 } |
| 650 } | 637 } |
| 651 } | 638 } |
| 652 VisitRRO(this, node, kPPC_ShiftRight32, kShift32Imm); | 639 VisitRRO(this, kPPC_ShiftRight32, node, kShift32Imm); |
| 653 } | 640 } |
| 654 | 641 |
| 655 | 642 |
| 656 #if V8_TARGET_ARCH_PPC64 | 643 #if V8_TARGET_ARCH_PPC64 |
| 657 void InstructionSelector::VisitWord64Shr(Node* node) { | 644 void InstructionSelector::VisitWord64Shr(Node* node) { |
| 658 PPCOperandGenerator g(this); | 645 PPCOperandGenerator g(this); |
| 659 Int64BinopMatcher m(node); | 646 Int64BinopMatcher m(node); |
| 660 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { | 647 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { |
| 661 // Try to absorb logical-and into rldic | 648 // Try to absorb logical-and into rldic |
| 662 Int64BinopMatcher mleft(m.left().node()); | 649 Int64BinopMatcher mleft(m.left().node()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 683 } | 670 } |
| 684 if (match) { | 671 if (match) { |
| 685 Emit(opcode, g.DefineAsRegister(node), | 672 Emit(opcode, g.DefineAsRegister(node), |
| 686 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 673 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
| 687 g.TempImmediate(mask)); | 674 g.TempImmediate(mask)); |
| 688 return; | 675 return; |
| 689 } | 676 } |
| 690 } | 677 } |
| 691 } | 678 } |
| 692 } | 679 } |
| 693 VisitRRO(this, node, kPPC_ShiftRight64, kShift64Imm); | 680 VisitRRO(this, kPPC_ShiftRight64, node, kShift64Imm); |
| 694 } | 681 } |
| 695 #endif | 682 #endif |
| 696 | 683 |
| 697 | 684 |
| 698 void InstructionSelector::VisitWord32Sar(Node* node) { | 685 void InstructionSelector::VisitWord32Sar(Node* node) { |
| 699 PPCOperandGenerator g(this); | 686 PPCOperandGenerator g(this); |
| 700 Int32BinopMatcher m(node); | 687 Int32BinopMatcher m(node); |
| 701 // Replace with sign extension for (x << K) >> K where K is 16 or 24. | 688 // Replace with sign extension for (x << K) >> K where K is 16 or 24. |
| 702 if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { | 689 if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { |
| 703 Int32BinopMatcher mleft(m.left().node()); | 690 Int32BinopMatcher mleft(m.left().node()); |
| 704 if (mleft.right().Is(16) && m.right().Is(16)) { | 691 if (mleft.right().Is(16) && m.right().Is(16)) { |
| 705 Emit(kPPC_ExtendSignWord16, g.DefineAsRegister(node), | 692 Emit(kPPC_ExtendSignWord16, g.DefineAsRegister(node), |
| 706 g.UseRegister(mleft.left().node())); | 693 g.UseRegister(mleft.left().node())); |
| 707 return; | 694 return; |
| 708 } else if (mleft.right().Is(24) && m.right().Is(24)) { | 695 } else if (mleft.right().Is(24) && m.right().Is(24)) { |
| 709 Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node), | 696 Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node), |
| 710 g.UseRegister(mleft.left().node())); | 697 g.UseRegister(mleft.left().node())); |
| 711 return; | 698 return; |
| 712 } | 699 } |
| 713 } | 700 } |
| 714 VisitRRO(this, node, kPPC_ShiftRightAlg32, kShift32Imm); | 701 VisitRRO(this, kPPC_ShiftRightAlg32, node, kShift32Imm); |
| 715 } | 702 } |
| 716 | 703 |
| 717 | 704 |
| 718 #if V8_TARGET_ARCH_PPC64 | 705 #if V8_TARGET_ARCH_PPC64 |
| 719 void InstructionSelector::VisitWord64Sar(Node* node) { | 706 void InstructionSelector::VisitWord64Sar(Node* node) { |
| 720 VisitRRO(this, node, kPPC_ShiftRightAlg64, kShift64Imm); | 707 VisitRRO(this, kPPC_ShiftRightAlg64, node, kShift64Imm); |
| 721 } | 708 } |
| 722 #endif | 709 #endif |
| 723 | 710 |
| 724 | 711 |
| 725 // TODO(mbrandy): Absorb logical-and into rlwinm? | 712 // TODO(mbrandy): Absorb logical-and into rlwinm? |
| 726 void InstructionSelector::VisitWord32Ror(Node* node) { | 713 void InstructionSelector::VisitWord32Ror(Node* node) { |
| 727 VisitRRO(this, node, kPPC_RotRight32, kShift32Imm); | 714 VisitRRO(this, kPPC_RotRight32, node, kShift32Imm); |
| 728 } | 715 } |
| 729 | 716 |
| 730 | 717 |
| 731 #if V8_TARGET_ARCH_PPC64 | 718 #if V8_TARGET_ARCH_PPC64 |
| 732 // TODO(mbrandy): Absorb logical-and into rldic? | 719 // TODO(mbrandy): Absorb logical-and into rldic? |
| 733 void InstructionSelector::VisitWord64Ror(Node* node) { | 720 void InstructionSelector::VisitWord64Ror(Node* node) { |
| 734 VisitRRO(this, node, kPPC_RotRight64, kShift64Imm); | 721 VisitRRO(this, kPPC_RotRight64, node, kShift64Imm); |
| 735 } | 722 } |
| 736 #endif | 723 #endif |
| 737 | 724 |
| 738 | 725 |
| 739 void InstructionSelector::VisitWord32Clz(Node* node) { | 726 void InstructionSelector::VisitWord32Clz(Node* node) { |
| 740 PPCOperandGenerator g(this); | 727 PPCOperandGenerator g(this); |
| 741 Emit(kPPC_Cntlz32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); | 728 Emit(kPPC_Cntlz32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); |
| 742 } | 729 } |
| 743 | 730 |
| 744 | 731 |
| 745 void InstructionSelector::VisitInt32Add(Node* node) { | 732 void InstructionSelector::VisitInt32Add(Node* node) { |
| 746 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Add32, kInt16Imm); | 733 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Add, kInt16Imm); |
| 747 } | 734 } |
| 748 | 735 |
| 749 | 736 |
| 750 #if V8_TARGET_ARCH_PPC64 | 737 #if V8_TARGET_ARCH_PPC64 |
| 751 void InstructionSelector::VisitInt64Add(Node* node) { | 738 void InstructionSelector::VisitInt64Add(Node* node) { |
| 752 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add64, kInt16Imm); | 739 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm); |
| 753 } | 740 } |
| 754 #endif | 741 #endif |
| 755 | 742 |
| 756 | 743 |
| 757 void InstructionSelector::VisitInt32Sub(Node* node) { | 744 void InstructionSelector::VisitInt32Sub(Node* node) { |
| 758 PPCOperandGenerator g(this); | 745 PPCOperandGenerator g(this); |
| 759 Int32BinopMatcher m(node); | 746 Int32BinopMatcher m(node); |
| 760 if (m.left().Is(0)) { | 747 if (m.left().Is(0)) { |
| 761 Emit(kPPC_Neg32, g.DefineAsRegister(node), g.UseRegister(m.right().node())); | 748 Emit(kPPC_Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node())); |
| 762 } else { | 749 } else { |
| 763 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Sub32, kInt16Imm_Negate); | 750 VisitBinop<Int32BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate); |
| 764 } | 751 } |
| 765 } | 752 } |
| 766 | 753 |
| 767 | 754 |
| 768 #if V8_TARGET_ARCH_PPC64 | 755 #if V8_TARGET_ARCH_PPC64 |
| 769 void InstructionSelector::VisitInt64Sub(Node* node) { | 756 void InstructionSelector::VisitInt64Sub(Node* node) { |
| 770 PPCOperandGenerator g(this); | 757 PPCOperandGenerator g(this); |
| 771 Int64BinopMatcher m(node); | 758 Int64BinopMatcher m(node); |
| 772 if (m.left().Is(0)) { | 759 if (m.left().Is(0)) { |
| 773 Emit(kPPC_Neg64, g.DefineAsRegister(node), g.UseRegister(m.right().node())); | 760 Emit(kPPC_Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node())); |
| 774 } else { | 761 } else { |
| 775 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub64, kInt16Imm_Negate); | 762 VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate); |
| 776 } | 763 } |
| 777 } | 764 } |
| 778 #endif | 765 #endif |
| 779 | 766 |
| 780 | 767 |
| 781 void InstructionSelector::VisitInt32Mul(Node* node) { | 768 void InstructionSelector::VisitInt32Mul(Node* node) { |
| 782 VisitRRR(this, node, kPPC_Mul32); | 769 VisitRRR(this, kPPC_Mul32, node); |
| 783 } | 770 } |
| 784 | 771 |
| 785 | 772 |
| 786 #if V8_TARGET_ARCH_PPC64 | 773 #if V8_TARGET_ARCH_PPC64 |
| 787 void InstructionSelector::VisitInt64Mul(Node* node) { | 774 void InstructionSelector::VisitInt64Mul(Node* node) { |
| 788 VisitRRR(this, node, kPPC_Mul64); | 775 VisitRRR(this, kPPC_Mul64, node); |
| 789 } | 776 } |
| 790 #endif | 777 #endif |
| 791 | 778 |
| 792 | 779 |
| 793 void InstructionSelector::VisitInt32MulHigh(Node* node) { | 780 void InstructionSelector::VisitInt32MulHigh(Node* node) { |
| 794 PPCOperandGenerator g(this); | 781 PPCOperandGenerator g(this); |
| 795 Emit(kPPC_MulHigh32, g.DefineAsRegister(node), | 782 Emit(kPPC_MulHigh32, g.DefineAsRegister(node), |
| 796 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); | 783 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); |
| 797 } | 784 } |
| 798 | 785 |
| 799 | 786 |
| 800 void InstructionSelector::VisitUint32MulHigh(Node* node) { | 787 void InstructionSelector::VisitUint32MulHigh(Node* node) { |
| 801 PPCOperandGenerator g(this); | 788 PPCOperandGenerator g(this); |
| 802 Emit(kPPC_MulHighU32, g.DefineAsRegister(node), | 789 Emit(kPPC_MulHighU32, g.DefineAsRegister(node), |
| 803 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); | 790 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); |
| 804 } | 791 } |
| 805 | 792 |
| 806 | 793 |
| 807 void InstructionSelector::VisitInt32Div(Node* node) { | 794 void InstructionSelector::VisitInt32Div(Node* node) { |
| 808 VisitRRR(this, node, kPPC_Div32); | 795 VisitRRR(this, kPPC_Div32, node); |
| 809 } | 796 } |
| 810 | 797 |
| 811 | 798 |
| 812 #if V8_TARGET_ARCH_PPC64 | 799 #if V8_TARGET_ARCH_PPC64 |
| 813 void InstructionSelector::VisitInt64Div(Node* node) { | 800 void InstructionSelector::VisitInt64Div(Node* node) { |
| 814 VisitRRR(this, node, kPPC_Div64); | 801 VisitRRR(this, kPPC_Div64, node); |
| 815 } | 802 } |
| 816 #endif | 803 #endif |
| 817 | 804 |
| 818 | 805 |
| 819 void InstructionSelector::VisitUint32Div(Node* node) { | 806 void InstructionSelector::VisitUint32Div(Node* node) { |
| 820 VisitRRR(this, node, kPPC_DivU32); | 807 VisitRRR(this, kPPC_DivU32, node); |
| 821 } | 808 } |
| 822 | 809 |
| 823 | 810 |
| 824 #if V8_TARGET_ARCH_PPC64 | 811 #if V8_TARGET_ARCH_PPC64 |
| 825 void InstructionSelector::VisitUint64Div(Node* node) { | 812 void InstructionSelector::VisitUint64Div(Node* node) { |
| 826 VisitRRR(this, node, kPPC_DivU64); | 813 VisitRRR(this, kPPC_DivU64, node); |
| 827 } | 814 } |
| 828 #endif | 815 #endif |
| 829 | 816 |
| 830 | 817 |
| 831 void InstructionSelector::VisitInt32Mod(Node* node) { | 818 void InstructionSelector::VisitInt32Mod(Node* node) { |
| 832 VisitRRR(this, node, kPPC_Mod32); | 819 VisitRRR(this, kPPC_Mod32, node); |
| 833 } | 820 } |
| 834 | 821 |
| 835 | 822 |
| 836 #if V8_TARGET_ARCH_PPC64 | 823 #if V8_TARGET_ARCH_PPC64 |
| 837 void InstructionSelector::VisitInt64Mod(Node* node) { | 824 void InstructionSelector::VisitInt64Mod(Node* node) { |
| 838 VisitRRR(this, node, kPPC_Mod64); | 825 VisitRRR(this, kPPC_Mod64, node); |
| 839 } | 826 } |
| 840 #endif | 827 #endif |
| 841 | 828 |
| 842 | 829 |
| 843 void InstructionSelector::VisitUint32Mod(Node* node) { | 830 void InstructionSelector::VisitUint32Mod(Node* node) { |
| 844 VisitRRR(this, node, kPPC_ModU32); | 831 VisitRRR(this, kPPC_ModU32, node); |
| 845 } | 832 } |
| 846 | 833 |
| 847 | 834 |
| 848 #if V8_TARGET_ARCH_PPC64 | 835 #if V8_TARGET_ARCH_PPC64 |
| 849 void InstructionSelector::VisitUint64Mod(Node* node) { | 836 void InstructionSelector::VisitUint64Mod(Node* node) { |
| 850 VisitRRR(this, node, kPPC_ModU64); | 837 VisitRRR(this, kPPC_ModU64, node); |
| 851 } | 838 } |
| 852 #endif | 839 #endif |
| 853 | 840 |
| 854 | 841 |
| 855 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { | 842 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
| 856 PPCOperandGenerator g(this); | 843 VisitRR(this, kPPC_Float32ToDouble, node); |
| 857 Emit(kPPC_Float32ToFloat64, g.DefineAsRegister(node), | |
| 858 g.UseRegister(node->InputAt(0))); | |
| 859 } | 844 } |
| 860 | 845 |
| 861 | 846 |
| 862 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { | 847 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
| 863 PPCOperandGenerator g(this); | 848 VisitRR(this, kPPC_Int32ToDouble, node); |
| 864 Emit(kPPC_Int32ToFloat64, g.DefineAsRegister(node), | |
| 865 g.UseRegister(node->InputAt(0))); | |
| 866 } | 849 } |
| 867 | 850 |
| 868 | 851 |
| 869 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { | 852 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { |
| 870 PPCOperandGenerator g(this); | 853 VisitRR(this, kPPC_Uint32ToDouble, node); |
| 871 Emit(kPPC_Uint32ToFloat64, g.DefineAsRegister(node), | |
| 872 g.UseRegister(node->InputAt(0))); | |
| 873 } | 854 } |
| 874 | 855 |
| 875 | 856 |
| 876 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { | 857 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { |
| 877 PPCOperandGenerator g(this); | 858 VisitRR(this, kPPC_DoubleToInt32, node); |
| 878 Emit(kPPC_Float64ToInt32, g.DefineAsRegister(node), | |
| 879 g.UseRegister(node->InputAt(0))); | |
| 880 } | 859 } |
| 881 | 860 |
| 882 | 861 |
| 883 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { | 862 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { |
| 884 PPCOperandGenerator g(this); | 863 VisitRR(this, kPPC_DoubleToUint32, node); |
| 885 Emit(kPPC_Float64ToUint32, g.DefineAsRegister(node), | |
| 886 g.UseRegister(node->InputAt(0))); | |
| 887 } | 864 } |
| 888 | 865 |
| 889 | 866 |
| 890 #if V8_TARGET_ARCH_PPC64 | 867 #if V8_TARGET_ARCH_PPC64 |
| 891 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { | 868 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { |
| 892 // TODO(mbrandy): inspect input to see if nop is appropriate. | 869 // TODO(mbrandy): inspect input to see if nop is appropriate. |
| 893 PPCOperandGenerator g(this); | 870 VisitRR(this, kPPC_ExtendSignWord32, node); |
| 894 Emit(kPPC_ExtendSignWord32, g.DefineAsRegister(node), | |
| 895 g.UseRegister(node->InputAt(0))); | |
| 896 } | 871 } |
| 897 | 872 |
| 898 | 873 |
| 899 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { | 874 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { |
| 900 // TODO(mbrandy): inspect input to see if nop is appropriate. | 875 // TODO(mbrandy): inspect input to see if nop is appropriate. |
| 901 PPCOperandGenerator g(this); | 876 PPCOperandGenerator g(this); |
| 902 Emit(kPPC_Uint32ToUint64, g.DefineAsRegister(node), | 877 Emit(kPPC_Uint32ToUint64, g.DefineAsRegister(node), |
| 903 g.UseRegister(node->InputAt(0))); | 878 g.UseRegister(node->InputAt(0))); |
| 904 } | 879 } |
| 905 #endif | 880 #endif |
| 906 | 881 |
| 907 | 882 |
| 908 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { | 883 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { |
| 909 PPCOperandGenerator g(this); | 884 PPCOperandGenerator g(this); |
| 910 Emit(kPPC_Float64ToFloat32, g.DefineAsRegister(node), | 885 Emit(kPPC_DoubleToFloat32, g.DefineAsRegister(node), |
| 911 g.UseRegister(node->InputAt(0))); | 886 g.UseRegister(node->InputAt(0))); |
| 912 } | 887 } |
| 913 | 888 |
| 914 | 889 |
| 915 #if V8_TARGET_ARCH_PPC64 | 890 #if V8_TARGET_ARCH_PPC64 |
| 916 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { | 891 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { |
| 917 PPCOperandGenerator g(this); | 892 PPCOperandGenerator g(this); |
| 918 // TODO(mbrandy): inspect input to see if nop is appropriate. | 893 // TODO(mbrandy): inspect input to see if nop is appropriate. |
| 919 Emit(kPPC_Int64ToInt32, g.DefineAsRegister(node), | 894 Emit(kPPC_Int64ToInt32, g.DefineAsRegister(node), |
| 920 g.UseRegister(node->InputAt(0))); | 895 g.UseRegister(node->InputAt(0))); |
| 921 } | 896 } |
| 922 #endif | 897 #endif |
| 923 | 898 |
| 924 | 899 |
| 900 void InstructionSelector::VisitFloat32Add(Node* node) { |
| 901 VisitRRR(this, kPPC_AddDouble, node); |
| 902 } |
| 903 |
| 904 |
| 925 void InstructionSelector::VisitFloat64Add(Node* node) { | 905 void InstructionSelector::VisitFloat64Add(Node* node) { |
| 926 // TODO(mbrandy): detect multiply-add | 906 // TODO(mbrandy): detect multiply-add |
| 927 VisitRRRFloat64(this, node, kPPC_AddFloat64); | 907 VisitRRR(this, kPPC_AddDouble, node); |
| 928 } | 908 } |
| 929 | 909 |
| 930 | 910 |
| 911 void InstructionSelector::VisitFloat32Sub(Node* node) { |
| 912 VisitRRR(this, kPPC_SubDouble, node); |
| 913 } |
| 914 |
| 915 |
| 931 void InstructionSelector::VisitFloat64Sub(Node* node) { | 916 void InstructionSelector::VisitFloat64Sub(Node* node) { |
| 932 // TODO(mbrandy): detect multiply-subtract | 917 // TODO(mbrandy): detect multiply-subtract |
| 933 PPCOperandGenerator g(this); | 918 PPCOperandGenerator g(this); |
| 934 Float64BinopMatcher m(node); | 919 Float64BinopMatcher m(node); |
| 935 if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() && | 920 if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() && |
| 936 CanCover(m.node(), m.right().node())) { | 921 CanCover(m.node(), m.right().node())) { |
| 937 if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && | 922 if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && |
| 938 CanCover(m.right().node(), m.right().InputAt(0))) { | 923 CanCover(m.right().node(), m.right().InputAt(0))) { |
| 939 Float64BinopMatcher mright0(m.right().InputAt(0)); | 924 Float64BinopMatcher mright0(m.right().InputAt(0)); |
| 940 if (mright0.left().IsMinusZero()) { | 925 if (mright0.left().IsMinusZero()) { |
| 941 // -floor(-x) = ceil(x) | 926 // -floor(-x) = ceil(x) |
| 942 Emit(kPPC_CeilFloat64, g.DefineAsRegister(node), | 927 Emit(kPPC_CeilDouble, g.DefineAsRegister(node), |
| 943 g.UseRegister(mright0.right().node())); | 928 g.UseRegister(mright0.right().node())); |
| 944 return; | 929 return; |
| 945 } | 930 } |
| 946 } | 931 } |
| 947 } | 932 } |
| 948 VisitRRRFloat64(this, node, kPPC_SubFloat64); | 933 VisitRRR(this, kPPC_SubDouble, node); |
| 934 } |
| 935 |
| 936 |
| 937 void InstructionSelector::VisitFloat32Mul(Node* node) { |
| 938 VisitRRR(this, kPPC_MulDouble, node); |
| 949 } | 939 } |
| 950 | 940 |
| 951 | 941 |
| 952 void InstructionSelector::VisitFloat64Mul(Node* node) { | 942 void InstructionSelector::VisitFloat64Mul(Node* node) { |
| 953 // TODO(mbrandy): detect negate | 943 // TODO(mbrandy): detect negate |
| 954 VisitRRRFloat64(this, node, kPPC_MulFloat64); | 944 VisitRRR(this, kPPC_MulDouble, node); |
| 945 } |
| 946 |
| 947 |
| 948 void InstructionSelector::VisitFloat32Div(Node* node) { |
| 949 VisitRRR(this, kPPC_DivDouble, node); |
| 955 } | 950 } |
| 956 | 951 |
| 957 | 952 |
| 958 void InstructionSelector::VisitFloat64Div(Node* node) { | 953 void InstructionSelector::VisitFloat64Div(Node* node) { |
| 959 VisitRRRFloat64(this, node, kPPC_DivFloat64); | 954 VisitRRR(this, kPPC_DivDouble, node); |
| 960 } | 955 } |
| 961 | 956 |
| 962 | 957 |
| 963 void InstructionSelector::VisitFloat64Mod(Node* node) { | 958 void InstructionSelector::VisitFloat64Mod(Node* node) { |
| 964 PPCOperandGenerator g(this); | 959 PPCOperandGenerator g(this); |
| 965 Emit(kPPC_ModFloat64, g.DefineAsFixed(node, d1), | 960 Emit(kPPC_ModDouble, g.DefineAsFixed(node, d1), |
| 966 g.UseFixed(node->InputAt(0), d1), | 961 g.UseFixed(node->InputAt(0), d1), |
| 967 g.UseFixed(node->InputAt(1), d2))->MarkAsCall(); | 962 g.UseFixed(node->InputAt(1), d2))->MarkAsCall(); |
| 968 } | 963 } |
| 969 | 964 |
| 970 | 965 |
| 966 void InstructionSelector::VisitFloat32Max(Node* node) { |
| 967 VisitRRR(this, kPPC_MaxDouble, node); |
| 968 } |
| 969 |
| 970 |
| 971 void InstructionSelector::VisitFloat64Max(Node* node) { | 971 void InstructionSelector::VisitFloat64Max(Node* node) { |
| 972 VisitRRRFloat64(this, node, kPPC_MaxFloat64); | 972 VisitRRR(this, kPPC_MaxDouble, node); |
| 973 } |
| 974 |
| 975 |
| 976 void InstructionSelector::VisitFloat32Min(Node* node) { |
| 977 VisitRRR(this, kPPC_MinDouble, node); |
| 973 } | 978 } |
| 974 | 979 |
| 975 | 980 |
| 976 void InstructionSelector::VisitFloat64Min(Node* node) { | 981 void InstructionSelector::VisitFloat64Min(Node* node) { |
| 977 VisitRRRFloat64(this, node, kPPC_MinFloat64); | 982 VisitRRR(this, kPPC_MinDouble, node); |
| 983 } |
| 984 |
| 985 |
| 986 void InstructionSelector::VisitFloat32Sqrt(Node* node) { |
| 987 VisitRR(this, kPPC_SqrtDouble, node); |
| 978 } | 988 } |
| 979 | 989 |
| 980 | 990 |
| 981 void InstructionSelector::VisitFloat64Sqrt(Node* node) { | 991 void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
| 982 VisitRRFloat64(this, kPPC_SqrtFloat64, node); | 992 VisitRR(this, kPPC_SqrtDouble, node); |
| 983 } | 993 } |
| 984 | 994 |
| 985 | 995 |
| 986 void InstructionSelector::VisitFloat64RoundDown(Node* node) { | 996 void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
| 987 VisitRRFloat64(this, kPPC_FloorFloat64, node); | 997 VisitRR(this, kPPC_FloorDouble, node); |
| 988 } | 998 } |
| 989 | 999 |
| 990 | 1000 |
| 991 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 1001 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
| 992 VisitRRFloat64(this, kPPC_TruncateFloat64, node); | 1002 VisitRR(this, kPPC_TruncateDouble, node); |
| 993 } | 1003 } |
| 994 | 1004 |
| 995 | 1005 |
| 996 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 1006 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
| 997 VisitRRFloat64(this, kPPC_RoundFloat64, node); | 1007 VisitRR(this, kPPC_RoundDouble, node); |
| 998 } | 1008 } |
| 999 | 1009 |
| 1000 | 1010 |
| 1001 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { | 1011 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
| 1002 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1012 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| 1003 FlagsContinuation cont(kOverflow, ovf); | 1013 FlagsContinuation cont(kOverflow, ovf); |
| 1004 return VisitBinop<Int32BinopMatcher>(this, node, kPPC_AddWithOverflow32, | 1014 return VisitBinop<Int32BinopMatcher>(this, node, kPPC_AddWithOverflow32, |
| 1005 kInt16Imm, &cont); | 1015 kInt16Imm, &cont); |
| 1006 } | 1016 } |
| 1007 FlagsContinuation cont; | 1017 FlagsContinuation cont; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1030 case kUnsignedGreaterThan: | 1040 case kUnsignedGreaterThan: |
| 1031 return true; | 1041 return true; |
| 1032 default: | 1042 default: |
| 1033 return false; | 1043 return false; |
| 1034 } | 1044 } |
| 1035 UNREACHABLE(); | 1045 UNREACHABLE(); |
| 1036 return false; | 1046 return false; |
| 1037 } | 1047 } |
| 1038 | 1048 |
| 1039 | 1049 |
| 1050 namespace { |
| 1051 |
| 1040 // Shared routine for multiple compare operations. | 1052 // Shared routine for multiple compare operations. |
| 1041 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1053 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 1042 InstructionOperand left, InstructionOperand right, | 1054 InstructionOperand left, InstructionOperand right, |
| 1043 FlagsContinuation* cont) { | 1055 FlagsContinuation* cont) { |
| 1044 PPCOperandGenerator g(selector); | 1056 PPCOperandGenerator g(selector); |
| 1045 opcode = cont->Encode(opcode); | 1057 opcode = cont->Encode(opcode); |
| 1046 if (cont->IsBranch()) { | 1058 if (cont->IsBranch()) { |
| 1047 selector->Emit(opcode, g.NoOutput(), left, right, | 1059 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1048 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1060 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1049 } else { | 1061 } else { |
| 1050 DCHECK(cont->IsSet()); | 1062 DCHECK(cont->IsSet()); |
| 1051 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 1063 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
| 1052 } | 1064 } |
| 1053 } | 1065 } |
| 1054 | 1066 |
| 1055 | 1067 |
| 1056 // Shared routine for multiple word compare operations. | 1068 // Shared routine for multiple word compare operations. |
| 1057 static void VisitWordCompare(InstructionSelector* selector, Node* node, | 1069 void VisitWordCompare(InstructionSelector* selector, Node* node, |
| 1058 InstructionCode opcode, FlagsContinuation* cont, | 1070 InstructionCode opcode, FlagsContinuation* cont, |
| 1059 bool commutative, ImmediateMode immediate_mode) { | 1071 bool commutative, ImmediateMode immediate_mode) { |
| 1060 PPCOperandGenerator g(selector); | 1072 PPCOperandGenerator g(selector); |
| 1061 Node* left = node->InputAt(0); | 1073 Node* left = node->InputAt(0); |
| 1062 Node* right = node->InputAt(1); | 1074 Node* right = node->InputAt(1); |
| 1063 | 1075 |
| 1064 // Match immediates on left or right side of comparison. | 1076 // Match immediates on left or right side of comparison. |
| 1065 if (g.CanBeImmediate(right, immediate_mode)) { | 1077 if (g.CanBeImmediate(right, immediate_mode)) { |
| 1066 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), | 1078 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), |
| 1067 cont); | 1079 cont); |
| 1068 } else if (g.CanBeImmediate(left, immediate_mode)) { | 1080 } else if (g.CanBeImmediate(left, immediate_mode)) { |
| 1069 if (!commutative) cont->Commute(); | 1081 if (!commutative) cont->Commute(); |
| 1070 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left), | 1082 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left), |
| 1071 cont); | 1083 cont); |
| 1072 } else { | 1084 } else { |
| 1073 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), | 1085 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), |
| 1074 cont); | 1086 cont); |
| 1075 } | 1087 } |
| 1076 } | 1088 } |
| 1077 | 1089 |
| 1078 | 1090 |
| 1079 static void VisitWord32Compare(InstructionSelector* selector, Node* node, | 1091 void VisitWord32Compare(InstructionSelector* selector, Node* node, |
| 1080 FlagsContinuation* cont) { | 1092 FlagsContinuation* cont) { |
| 1081 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm); | 1093 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm); |
| 1082 VisitWordCompare(selector, node, kPPC_Cmp32, cont, false, mode); | 1094 VisitWordCompare(selector, node, kPPC_Cmp32, cont, false, mode); |
| 1083 } | 1095 } |
| 1084 | 1096 |
| 1085 | 1097 |
| 1086 #if V8_TARGET_ARCH_PPC64 | 1098 #if V8_TARGET_ARCH_PPC64 |
| 1087 static void VisitWord64Compare(InstructionSelector* selector, Node* node, | 1099 void VisitWord64Compare(InstructionSelector* selector, Node* node, |
| 1088 FlagsContinuation* cont) { | 1100 FlagsContinuation* cont) { |
| 1089 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm); | 1101 ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm); |
| 1090 VisitWordCompare(selector, node, kPPC_Cmp64, cont, false, mode); | 1102 VisitWordCompare(selector, node, kPPC_Cmp64, cont, false, mode); |
| 1091 } | 1103 } |
| 1092 #endif | 1104 #endif |
| 1093 | 1105 |
| 1094 | 1106 |
| 1095 // Shared routine for multiple float compare operations. | 1107 // Shared routine for multiple float32 compare operations. |
| 1096 static void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 1108 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
| 1097 FlagsContinuation* cont) { | 1109 FlagsContinuation* cont) { |
| 1098 PPCOperandGenerator g(selector); | 1110 PPCOperandGenerator g(selector); |
| 1099 Node* left = node->InputAt(0); | 1111 Node* left = node->InputAt(0); |
| 1100 Node* right = node->InputAt(1); | 1112 Node* right = node->InputAt(1); |
| 1101 VisitCompare(selector, kPPC_CmpFloat64, g.UseRegister(left), | 1113 VisitCompare(selector, kPPC_CmpDouble, g.UseRegister(left), |
| 1114 g.UseRegister(right), cont); |
| 1115 } |
| 1116 |
| 1117 |
| 1118 // Shared routine for multiple float64 compare operations. |
| 1119 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
| 1120 FlagsContinuation* cont) { |
| 1121 PPCOperandGenerator g(selector); |
| 1122 Node* left = node->InputAt(0); |
| 1123 Node* right = node->InputAt(1); |
| 1124 VisitCompare(selector, kPPC_CmpDouble, g.UseRegister(left), |
| 1102 g.UseRegister(right), cont); | 1125 g.UseRegister(right), cont); |
| 1103 } | 1126 } |
| 1104 | 1127 |
| 1105 | 1128 |
| 1106 // Shared routine for word comparisons against zero. | 1129 // Shared routine for word comparisons against zero. |
| 1107 static void VisitWordCompareZero(InstructionSelector* selector, Node* user, | 1130 void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
| 1108 Node* value, InstructionCode opcode, | 1131 Node* value, InstructionCode opcode, |
| 1109 FlagsContinuation* cont) { | 1132 FlagsContinuation* cont) { |
| 1110 while (selector->CanCover(user, value)) { | 1133 while (selector->CanCover(user, value)) { |
| 1111 switch (value->opcode()) { | 1134 switch (value->opcode()) { |
| 1112 case IrOpcode::kWord32Equal: { | 1135 case IrOpcode::kWord32Equal: { |
| 1113 // Combine with comparisons against 0 by simply inverting the | 1136 // Combine with comparisons against 0 by simply inverting the |
| 1114 // continuation. | 1137 // continuation. |
| 1115 Int32BinopMatcher m(value); | 1138 Int32BinopMatcher m(value); |
| 1116 if (m.right().Is(0)) { | 1139 if (m.right().Is(0)) { |
| 1117 user = value; | 1140 user = value; |
| 1118 value = m.left().node(); | 1141 value = m.left().node(); |
| 1119 cont->Negate(); | 1142 cont->Negate(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1141 case IrOpcode::kInt64LessThan: | 1164 case IrOpcode::kInt64LessThan: |
| 1142 cont->OverwriteAndNegateIfEqual(kSignedLessThan); | 1165 cont->OverwriteAndNegateIfEqual(kSignedLessThan); |
| 1143 return VisitWord64Compare(selector, value, cont); | 1166 return VisitWord64Compare(selector, value, cont); |
| 1144 case IrOpcode::kInt64LessThanOrEqual: | 1167 case IrOpcode::kInt64LessThanOrEqual: |
| 1145 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 1168 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
| 1146 return VisitWord64Compare(selector, value, cont); | 1169 return VisitWord64Compare(selector, value, cont); |
| 1147 case IrOpcode::kUint64LessThan: | 1170 case IrOpcode::kUint64LessThan: |
| 1148 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1171 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1149 return VisitWord64Compare(selector, value, cont); | 1172 return VisitWord64Compare(selector, value, cont); |
| 1150 #endif | 1173 #endif |
| 1174 case IrOpcode::kFloat32Equal: |
| 1175 cont->OverwriteAndNegateIfEqual(kEqual); |
| 1176 return VisitFloat32Compare(selector, value, cont); |
| 1177 case IrOpcode::kFloat32LessThan: |
| 1178 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1179 return VisitFloat32Compare(selector, value, cont); |
| 1180 case IrOpcode::kFloat32LessThanOrEqual: |
| 1181 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
| 1182 return VisitFloat32Compare(selector, value, cont); |
| 1151 case IrOpcode::kFloat64Equal: | 1183 case IrOpcode::kFloat64Equal: |
| 1152 cont->OverwriteAndNegateIfEqual(kEqual); | 1184 cont->OverwriteAndNegateIfEqual(kEqual); |
| 1153 return VisitFloat64Compare(selector, value, cont); | 1185 return VisitFloat64Compare(selector, value, cont); |
| 1154 case IrOpcode::kFloat64LessThan: | 1186 case IrOpcode::kFloat64LessThan: |
| 1155 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1187 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1156 return VisitFloat64Compare(selector, value, cont); | 1188 return VisitFloat64Compare(selector, value, cont); |
| 1157 case IrOpcode::kFloat64LessThanOrEqual: | 1189 case IrOpcode::kFloat64LessThanOrEqual: |
| 1158 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 1190 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
| 1159 return VisitFloat64Compare(selector, value, cont); | 1191 return VisitFloat64Compare(selector, value, cont); |
| 1160 case IrOpcode::kProjection: | 1192 case IrOpcode::kProjection: |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1221 break; | 1253 break; |
| 1222 } | 1254 } |
| 1223 | 1255 |
| 1224 // Branch could not be combined with a compare, emit compare against 0. | 1256 // Branch could not be combined with a compare, emit compare against 0. |
| 1225 PPCOperandGenerator g(selector); | 1257 PPCOperandGenerator g(selector); |
| 1226 VisitCompare(selector, opcode, g.UseRegister(value), g.TempImmediate(0), | 1258 VisitCompare(selector, opcode, g.UseRegister(value), g.TempImmediate(0), |
| 1227 cont); | 1259 cont); |
| 1228 } | 1260 } |
| 1229 | 1261 |
| 1230 | 1262 |
| 1231 static void VisitWord32CompareZero(InstructionSelector* selector, Node* user, | 1263 void VisitWord32CompareZero(InstructionSelector* selector, Node* user, |
| 1232 Node* value, FlagsContinuation* cont) { | 1264 Node* value, FlagsContinuation* cont) { |
| 1233 VisitWordCompareZero(selector, user, value, kPPC_Cmp32, cont); | 1265 VisitWordCompareZero(selector, user, value, kPPC_Cmp32, cont); |
| 1234 } | 1266 } |
| 1235 | 1267 |
| 1236 | 1268 |
| 1237 #if V8_TARGET_ARCH_PPC64 | 1269 #if V8_TARGET_ARCH_PPC64 |
| 1238 static void VisitWord64CompareZero(InstructionSelector* selector, Node* user, | 1270 void VisitWord64CompareZero(InstructionSelector* selector, Node* user, |
| 1239 Node* value, FlagsContinuation* cont) { | 1271 Node* value, FlagsContinuation* cont) { |
| 1240 VisitWordCompareZero(selector, user, value, kPPC_Cmp64, cont); | 1272 VisitWordCompareZero(selector, user, value, kPPC_Cmp64, cont); |
| 1241 } | 1273 } |
| 1242 #endif | 1274 #endif |
| 1243 | 1275 |
| 1276 } // namespace |
| 1277 |
| 1244 | 1278 |
| 1245 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 1279 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
| 1246 BasicBlock* fbranch) { | 1280 BasicBlock* fbranch) { |
| 1247 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 1281 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
| 1248 VisitWord32CompareZero(this, branch, branch->InputAt(0), &cont); | 1282 VisitWord32CompareZero(this, branch, branch->InputAt(0), &cont); |
| 1249 } | 1283 } |
| 1250 | 1284 |
| 1251 | 1285 |
| 1252 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { | 1286 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
| 1253 PPCOperandGenerator g(this); | 1287 PPCOperandGenerator g(this); |
| 1254 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); | 1288 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); |
| 1255 | 1289 |
| 1256 // Emit either ArchTableSwitch or ArchLookupSwitch. | 1290 // Emit either ArchTableSwitch or ArchLookupSwitch. |
| 1257 size_t table_space_cost = 4 + sw.value_range; | 1291 size_t table_space_cost = 4 + sw.value_range; |
| 1258 size_t table_time_cost = 3; | 1292 size_t table_time_cost = 3; |
| 1259 size_t lookup_space_cost = 3 + 2 * sw.case_count; | 1293 size_t lookup_space_cost = 3 + 2 * sw.case_count; |
| 1260 size_t lookup_time_cost = sw.case_count; | 1294 size_t lookup_time_cost = sw.case_count; |
| 1261 if (sw.case_count > 0 && | 1295 if (sw.case_count > 0 && |
| 1262 table_space_cost + 3 * table_time_cost <= | 1296 table_space_cost + 3 * table_time_cost <= |
| 1263 lookup_space_cost + 3 * lookup_time_cost && | 1297 lookup_space_cost + 3 * lookup_time_cost && |
| 1264 sw.min_value > std::numeric_limits<int32_t>::min()) { | 1298 sw.min_value > std::numeric_limits<int32_t>::min()) { |
| 1265 InstructionOperand index_operand = value_operand; | 1299 InstructionOperand index_operand = value_operand; |
| 1266 if (sw.min_value) { | 1300 if (sw.min_value) { |
| 1267 index_operand = g.TempRegister(); | 1301 index_operand = g.TempRegister(); |
| 1268 Emit(kPPC_Sub32, index_operand, value_operand, | 1302 Emit(kPPC_Sub, index_operand, value_operand, |
| 1269 g.TempImmediate(sw.min_value)); | 1303 g.TempImmediate(sw.min_value)); |
| 1270 } | 1304 } |
| 1271 // Generate a table lookup. | 1305 // Generate a table lookup. |
| 1272 return EmitTableSwitch(sw, index_operand); | 1306 return EmitTableSwitch(sw, index_operand); |
| 1273 } | 1307 } |
| 1274 | 1308 |
| 1275 // Generate a sequence of conditional jumps. | 1309 // Generate a sequence of conditional jumps. |
| 1276 return EmitLookupSwitch(sw, value_operand); | 1310 return EmitLookupSwitch(sw, value_operand); |
| 1277 } | 1311 } |
| 1278 | 1312 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 } | 1368 } |
| 1335 | 1369 |
| 1336 | 1370 |
| 1337 void InstructionSelector::VisitUint64LessThan(Node* node) { | 1371 void InstructionSelector::VisitUint64LessThan(Node* node) { |
| 1338 FlagsContinuation cont(kUnsignedLessThan, node); | 1372 FlagsContinuation cont(kUnsignedLessThan, node); |
| 1339 VisitWord64Compare(this, node, &cont); | 1373 VisitWord64Compare(this, node, &cont); |
| 1340 } | 1374 } |
| 1341 #endif | 1375 #endif |
| 1342 | 1376 |
| 1343 | 1377 |
| 1378 void InstructionSelector::VisitFloat32Equal(Node* node) { |
| 1379 FlagsContinuation cont(kEqual, node); |
| 1380 VisitFloat32Compare(this, node, &cont); |
| 1381 } |
| 1382 |
| 1383 |
| 1384 void InstructionSelector::VisitFloat32LessThan(Node* node) { |
| 1385 FlagsContinuation cont(kUnsignedLessThan, node); |
| 1386 VisitFloat32Compare(this, node, &cont); |
| 1387 } |
| 1388 |
| 1389 |
| 1390 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { |
| 1391 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); |
| 1392 VisitFloat32Compare(this, node, &cont); |
| 1393 } |
| 1394 |
| 1395 |
| 1344 void InstructionSelector::VisitFloat64Equal(Node* node) { | 1396 void InstructionSelector::VisitFloat64Equal(Node* node) { |
| 1345 FlagsContinuation cont(kEqual, node); | 1397 FlagsContinuation cont(kEqual, node); |
| 1346 VisitFloat64Compare(this, node, &cont); | 1398 VisitFloat64Compare(this, node, &cont); |
| 1347 } | 1399 } |
| 1348 | 1400 |
| 1349 | 1401 |
| 1350 void InstructionSelector::VisitFloat64LessThan(Node* node) { | 1402 void InstructionSelector::VisitFloat64LessThan(Node* node) { |
| 1351 FlagsContinuation cont(kUnsignedLessThan, node); | 1403 FlagsContinuation cont(kUnsignedLessThan, node); |
| 1352 VisitFloat64Compare(this, node, &cont); | 1404 VisitFloat64Compare(this, node, &cont); |
| 1353 } | 1405 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1412 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; | 1464 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; |
| 1413 Instruction* call_instr = | 1465 Instruction* call_instr = |
| 1414 Emit(opcode, buffer.outputs.size(), first_output, | 1466 Emit(opcode, buffer.outputs.size(), first_output, |
| 1415 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 1467 buffer.instruction_args.size(), &buffer.instruction_args.front()); |
| 1416 call_instr->MarkAsCall(); | 1468 call_instr->MarkAsCall(); |
| 1417 } | 1469 } |
| 1418 | 1470 |
| 1419 | 1471 |
| 1420 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { | 1472 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { |
| 1421 PPCOperandGenerator g(this); | 1473 PPCOperandGenerator g(this); |
| 1422 Emit(kPPC_Float64ExtractLowWord32, g.DefineAsRegister(node), | 1474 Emit(kPPC_DoubleExtractLowWord32, g.DefineAsRegister(node), |
| 1423 g.UseRegister(node->InputAt(0))); | 1475 g.UseRegister(node->InputAt(0))); |
| 1424 } | 1476 } |
| 1425 | 1477 |
| 1426 | 1478 |
| 1427 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { | 1479 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { |
| 1428 PPCOperandGenerator g(this); | 1480 PPCOperandGenerator g(this); |
| 1429 Emit(kPPC_Float64ExtractHighWord32, g.DefineAsRegister(node), | 1481 Emit(kPPC_DoubleExtractHighWord32, g.DefineAsRegister(node), |
| 1430 g.UseRegister(node->InputAt(0))); | 1482 g.UseRegister(node->InputAt(0))); |
| 1431 } | 1483 } |
| 1432 | 1484 |
| 1433 | 1485 |
| 1434 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { | 1486 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { |
| 1435 PPCOperandGenerator g(this); | 1487 PPCOperandGenerator g(this); |
| 1436 Node* left = node->InputAt(0); | 1488 Node* left = node->InputAt(0); |
| 1437 Node* right = node->InputAt(1); | 1489 Node* right = node->InputAt(1); |
| 1438 if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 && | 1490 if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 && |
| 1439 CanCover(node, left)) { | 1491 CanCover(node, left)) { |
| 1440 left = left->InputAt(1); | 1492 left = left->InputAt(1); |
| 1441 Emit(kPPC_Float64Construct, g.DefineAsRegister(node), g.UseRegister(left), | 1493 Emit(kPPC_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(left), |
| 1442 g.UseRegister(right)); | 1494 g.UseRegister(right)); |
| 1443 return; | 1495 return; |
| 1444 } | 1496 } |
| 1445 Emit(kPPC_Float64InsertLowWord32, g.DefineSameAsFirst(node), | 1497 Emit(kPPC_DoubleInsertLowWord32, g.DefineSameAsFirst(node), |
| 1446 g.UseRegister(left), g.UseRegister(right)); | 1498 g.UseRegister(left), g.UseRegister(right)); |
| 1447 } | 1499 } |
| 1448 | 1500 |
| 1449 | 1501 |
| 1450 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { | 1502 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { |
| 1451 PPCOperandGenerator g(this); | 1503 PPCOperandGenerator g(this); |
| 1452 Node* left = node->InputAt(0); | 1504 Node* left = node->InputAt(0); |
| 1453 Node* right = node->InputAt(1); | 1505 Node* right = node->InputAt(1); |
| 1454 if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 && | 1506 if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 && |
| 1455 CanCover(node, left)) { | 1507 CanCover(node, left)) { |
| 1456 left = left->InputAt(1); | 1508 left = left->InputAt(1); |
| 1457 Emit(kPPC_Float64Construct, g.DefineAsRegister(node), g.UseRegister(right), | 1509 Emit(kPPC_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(right), |
| 1458 g.UseRegister(left)); | 1510 g.UseRegister(left)); |
| 1459 return; | 1511 return; |
| 1460 } | 1512 } |
| 1461 Emit(kPPC_Float64InsertHighWord32, g.DefineSameAsFirst(node), | 1513 Emit(kPPC_DoubleInsertHighWord32, g.DefineSameAsFirst(node), |
| 1462 g.UseRegister(left), g.UseRegister(right)); | 1514 g.UseRegister(left), g.UseRegister(right)); |
| 1463 } | 1515 } |
| 1464 | 1516 |
| 1465 | 1517 |
| 1466 // static | 1518 // static |
| 1467 MachineOperatorBuilder::Flags | 1519 MachineOperatorBuilder::Flags |
| 1468 InstructionSelector::SupportedMachineOperatorFlags() { | 1520 InstructionSelector::SupportedMachineOperatorFlags() { |
| 1469 return MachineOperatorBuilder::kFloat64Max | | 1521 return MachineOperatorBuilder::kFloat32Max | |
| 1522 MachineOperatorBuilder::kFloat32Min | |
| 1523 MachineOperatorBuilder::kFloat64Max | |
| 1470 MachineOperatorBuilder::kFloat64Min | | 1524 MachineOperatorBuilder::kFloat64Min | |
| 1471 MachineOperatorBuilder::kFloat64RoundDown | | 1525 MachineOperatorBuilder::kFloat64RoundDown | |
| 1472 MachineOperatorBuilder::kFloat64RoundTruncate | | 1526 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1473 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1527 MachineOperatorBuilder::kFloat64RoundTiesAway; |
| 1474 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. | 1528 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. |
| 1475 } | 1529 } |
| 1476 | 1530 |
| 1477 } // namespace compiler | 1531 } // namespace compiler |
| 1478 } // namespace internal | 1532 } // namespace internal |
| 1479 } // namespace v8 | 1533 } // namespace v8 |
| OLD | NEW |