| 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 { |
| 11 namespace compiler { | 11 namespace compiler { |
| 12 | 12 |
| 13 // Adds IA32-specific methods for generating operands. | 13 // Adds IA32-specific methods for generating operands. |
| 14 class IA32OperandGenerator FINAL : public OperandGenerator { | 14 class IA32OperandGenerator FINAL : public OperandGenerator { |
| 15 public: | 15 public: |
| 16 explicit IA32OperandGenerator(InstructionSelector* selector) | 16 explicit IA32OperandGenerator(InstructionSelector* selector) |
| 17 : OperandGenerator(selector) {} | 17 : OperandGenerator(selector) {} |
| 18 | 18 |
| 19 InstructionOperand UseByteRegister(Node* node) { | 19 InstructionOperand UseByteRegister(Node* node) { |
| 20 // TODO(dcarney): relax constraint. | 20 // TODO(titzer): encode byte register use constraints. |
| 21 return UseFixed(node, edx); | 21 return UseFixed(node, edx); |
| 22 } | 22 } |
| 23 | 23 |
| 24 InstructionOperand DefineAsByteRegister(Node* node) { |
| 25 // TODO(titzer): encode byte register def constraints. |
| 26 return DefineAsRegister(node); |
| 27 } |
| 28 |
| 24 bool CanBeImmediate(Node* node) { | 29 bool CanBeImmediate(Node* node) { |
| 25 switch (node->opcode()) { | 30 switch (node->opcode()) { |
| 26 case IrOpcode::kInt32Constant: | 31 case IrOpcode::kInt32Constant: |
| 27 case IrOpcode::kNumberConstant: | 32 case IrOpcode::kNumberConstant: |
| 28 case IrOpcode::kExternalConstant: | 33 case IrOpcode::kExternalConstant: |
| 29 return true; | 34 return true; |
| 30 case IrOpcode::kHeapConstant: { | 35 case IrOpcode::kHeapConstant: { |
| 31 // Constants in new space cannot be used as immediates in V8 because | 36 // Constants in new space cannot be used as immediates in V8 because |
| 32 // the GC does not scan code objects when collecting the new generation. | 37 // the GC does not scan code objects when collecting the new generation. |
| 33 Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node); | 38 Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 selector->Emit(opcode, g.DefineAsRegister(node), | 130 selector->Emit(opcode, g.DefineAsRegister(node), |
| 126 g.UseRegister(node->InputAt(0))); | 131 g.UseRegister(node->InputAt(0))); |
| 127 } | 132 } |
| 128 | 133 |
| 129 | 134 |
| 130 void InstructionSelector::VisitLoad(Node* node) { | 135 void InstructionSelector::VisitLoad(Node* node) { |
| 131 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 136 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
| 132 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 137 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
| 133 | 138 |
| 134 ArchOpcode opcode; | 139 ArchOpcode opcode; |
| 135 // TODO(titzer): signed/unsigned small loads | |
| 136 switch (rep) { | 140 switch (rep) { |
| 137 case kRepFloat32: | 141 case kRepFloat32: |
| 138 opcode = kIA32Movss; | 142 opcode = kIA32Movss; |
| 139 break; | 143 break; |
| 140 case kRepFloat64: | 144 case kRepFloat64: |
| 141 opcode = kIA32Movsd; | 145 opcode = kIA32Movsd; |
| 142 break; | 146 break; |
| 143 case kRepBit: // Fall through. | 147 case kRepBit: // Fall through. |
| 144 case kRepWord8: | 148 case kRepWord8: |
| 145 opcode = typ == kTypeInt32 ? kIA32Movsxbl : kIA32Movzxbl; | 149 opcode = typ == kTypeInt32 ? kIA32Movsxbl : kIA32Movzxbl; |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 inputs[input_count++] = g.Use(right); | 363 inputs[input_count++] = g.Use(right); |
| 360 } | 364 } |
| 361 | 365 |
| 362 if (cont->IsBranch()) { | 366 if (cont->IsBranch()) { |
| 363 inputs[input_count++] = g.Label(cont->true_block()); | 367 inputs[input_count++] = g.Label(cont->true_block()); |
| 364 inputs[input_count++] = g.Label(cont->false_block()); | 368 inputs[input_count++] = g.Label(cont->false_block()); |
| 365 } | 369 } |
| 366 | 370 |
| 367 outputs[output_count++] = g.DefineSameAsFirst(node); | 371 outputs[output_count++] = g.DefineSameAsFirst(node); |
| 368 if (cont->IsSet()) { | 372 if (cont->IsSet()) { |
| 369 // TODO(turbofan): Use byte register here. | 373 outputs[output_count++] = g.DefineAsByteRegister(cont->result()); |
| 370 outputs[output_count++] = g.DefineAsRegister(cont->result()); | |
| 371 } | 374 } |
| 372 | 375 |
| 373 DCHECK_NE(0u, input_count); | 376 DCHECK_NE(0u, input_count); |
| 374 DCHECK_NE(0u, output_count); | 377 DCHECK_NE(0u, output_count); |
| 375 DCHECK_GE(arraysize(inputs), input_count); | 378 DCHECK_GE(arraysize(inputs), input_count); |
| 376 DCHECK_GE(arraysize(outputs), output_count); | 379 DCHECK_GE(arraysize(outputs), output_count); |
| 377 | 380 |
| 378 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, | 381 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, |
| 379 outputs, input_count, inputs); | 382 outputs, input_count, inputs); |
| 380 if (cont->IsBranch()) instr->MarkAsControl(); | 383 if (cont->IsBranch()) instr->MarkAsControl(); |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 823 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 821 InstructionOperand left, InstructionOperand right, | 824 InstructionOperand left, InstructionOperand right, |
| 822 FlagsContinuation* cont) { | 825 FlagsContinuation* cont) { |
| 823 IA32OperandGenerator g(selector); | 826 IA32OperandGenerator g(selector); |
| 824 if (cont->IsBranch()) { | 827 if (cont->IsBranch()) { |
| 825 selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, | 828 selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, |
| 826 g.Label(cont->true_block()), | 829 g.Label(cont->true_block()), |
| 827 g.Label(cont->false_block()))->MarkAsControl(); | 830 g.Label(cont->false_block()))->MarkAsControl(); |
| 828 } else { | 831 } else { |
| 829 DCHECK(cont->IsSet()); | 832 DCHECK(cont->IsSet()); |
| 830 // TODO(titzer): Needs byte register. | 833 selector->Emit(cont->Encode(opcode), g.DefineAsByteRegister(cont->result()), |
| 831 selector->Emit(cont->Encode(opcode), g.DefineAsRegister(cont->result()), | |
| 832 left, right); | 834 left, right); |
| 833 } | 835 } |
| 834 } | 836 } |
| 835 | 837 |
| 836 | 838 |
| 837 // Shared routine for multiple compare operations. | 839 // Shared routine for multiple compare operations. |
| 838 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 840 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 839 Node* left, Node* right, FlagsContinuation* cont, | 841 Node* left, Node* right, FlagsContinuation* cont, |
| 840 bool commutative) { | 842 bool commutative) { |
| 841 IA32OperandGenerator g(selector); | 843 IA32OperandGenerator g(selector); |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 if (CpuFeatures::IsSupported(SSE4_1)) { | 1173 if (CpuFeatures::IsSupported(SSE4_1)) { |
| 1172 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1174 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
| 1173 MachineOperatorBuilder::kFloat64RoundTruncate; | 1175 MachineOperatorBuilder::kFloat64RoundTruncate; |
| 1174 } | 1176 } |
| 1175 return flags; | 1177 return flags; |
| 1176 } | 1178 } |
| 1177 | 1179 |
| 1178 } // namespace compiler | 1180 } // namespace compiler |
| 1179 } // namespace internal | 1181 } // namespace internal |
| 1180 } // namespace v8 | 1182 } // namespace v8 |
| OLD | NEW |