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 |