| 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-inl.h" | 7 #include "src/compiler/node-properties-inl.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 | 89 |
| 90 void InstructionSelector::VisitStore(Node* node) { | 90 void InstructionSelector::VisitStore(Node* node) { |
| 91 IA32OperandGenerator g(this); | 91 IA32OperandGenerator g(this); |
| 92 Node* base = node->InputAt(0); | 92 Node* base = node->InputAt(0); |
| 93 Node* index = node->InputAt(1); | 93 Node* index = node->InputAt(1); |
| 94 Node* value = node->InputAt(2); | 94 Node* value = node->InputAt(2); |
| 95 | 95 |
| 96 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 96 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 97 MachineRepresentation rep = store_rep.rep; | 97 MachineRepresentation rep = store_rep.rep; |
| 98 if (store_rep.write_barrier_kind == kFullWriteBarrier) { | 98 if (store_rep.write_barrier_kind == kFullWriteBarrier) { |
| 99 ASSERT_EQ(kMachineTagged, rep); | 99 DCHECK_EQ(kMachineTagged, rep); |
| 100 // TODO(dcarney): refactor RecordWrite function to take temp registers | 100 // TODO(dcarney): refactor RecordWrite function to take temp registers |
| 101 // and pass them here instead of using fixed regs | 101 // and pass them here instead of using fixed regs |
| 102 // TODO(dcarney): handle immediate indices. | 102 // TODO(dcarney): handle immediate indices. |
| 103 InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; | 103 InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; |
| 104 Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx), | 104 Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx), |
| 105 g.UseFixed(index, ecx), g.UseFixed(value, edx), ARRAY_SIZE(temps), | 105 g.UseFixed(index, ecx), g.UseFixed(value, edx), ARRAY_SIZE(temps), |
| 106 temps); | 106 temps); |
| 107 return; | 107 return; |
| 108 } | 108 } |
| 109 ASSERT_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); | 109 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); |
| 110 bool is_immediate = false; | 110 bool is_immediate = false; |
| 111 InstructionOperand* val; | 111 InstructionOperand* val; |
| 112 if (rep == kMachineFloat64) { | 112 if (rep == kMachineFloat64) { |
| 113 val = g.UseDoubleRegister(value); | 113 val = g.UseDoubleRegister(value); |
| 114 } else { | 114 } else { |
| 115 is_immediate = g.CanBeImmediate(value); | 115 is_immediate = g.CanBeImmediate(value); |
| 116 if (is_immediate) { | 116 if (is_immediate) { |
| 117 val = g.UseImmediate(value); | 117 val = g.UseImmediate(value); |
| 118 } else if (rep == kMachineWord8) { | 118 } else if (rep == kMachineWord8) { |
| 119 val = g.UseByteRegister(value); | 119 val = g.UseByteRegister(value); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 inputs[input_count++] = g.Label(cont->true_block()); | 184 inputs[input_count++] = g.Label(cont->true_block()); |
| 185 inputs[input_count++] = g.Label(cont->false_block()); | 185 inputs[input_count++] = g.Label(cont->false_block()); |
| 186 } | 186 } |
| 187 | 187 |
| 188 outputs[output_count++] = g.DefineSameAsFirst(node); | 188 outputs[output_count++] = g.DefineSameAsFirst(node); |
| 189 if (cont->IsSet()) { | 189 if (cont->IsSet()) { |
| 190 // TODO(turbofan): Use byte register here. | 190 // TODO(turbofan): Use byte register here. |
| 191 outputs[output_count++] = g.DefineAsRegister(cont->result()); | 191 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
| 192 } | 192 } |
| 193 | 193 |
| 194 ASSERT_NE(0, input_count); | 194 DCHECK_NE(0, input_count); |
| 195 ASSERT_NE(0, output_count); | 195 DCHECK_NE(0, output_count); |
| 196 ASSERT_GE(ARRAY_SIZE(inputs), input_count); | 196 DCHECK_GE(ARRAY_SIZE(inputs), input_count); |
| 197 ASSERT_GE(ARRAY_SIZE(outputs), output_count); | 197 DCHECK_GE(ARRAY_SIZE(outputs), output_count); |
| 198 | 198 |
| 199 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, | 199 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, |
| 200 outputs, input_count, inputs); | 200 outputs, input_count, inputs); |
| 201 if (cont->IsBranch()) instr->MarkAsControl(); | 201 if (cont->IsBranch()) instr->MarkAsControl(); |
| 202 } | 202 } |
| 203 | 203 |
| 204 | 204 |
| 205 // Shared routine for multiple binary operations. | 205 // Shared routine for multiple binary operations. |
| 206 static void VisitBinop(InstructionSelector* selector, Node* node, | 206 static void VisitBinop(InstructionSelector* selector, Node* node, |
| 207 InstructionCode opcode) { | 207 InstructionCode opcode) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 InstructionCode opcode, | 434 InstructionCode opcode, |
| 435 InstructionOperand* left, | 435 InstructionOperand* left, |
| 436 InstructionOperand* right, | 436 InstructionOperand* right, |
| 437 FlagsContinuation* cont) { | 437 FlagsContinuation* cont) { |
| 438 IA32OperandGenerator g(selector); | 438 IA32OperandGenerator g(selector); |
| 439 if (cont->IsBranch()) { | 439 if (cont->IsBranch()) { |
| 440 selector->Emit(cont->Encode(opcode), NULL, left, right, | 440 selector->Emit(cont->Encode(opcode), NULL, left, right, |
| 441 g.Label(cont->true_block()), | 441 g.Label(cont->true_block()), |
| 442 g.Label(cont->false_block()))->MarkAsControl(); | 442 g.Label(cont->false_block()))->MarkAsControl(); |
| 443 } else { | 443 } else { |
| 444 ASSERT(cont->IsSet()); | 444 DCHECK(cont->IsSet()); |
| 445 // TODO(titzer): Needs byte register. | 445 // TODO(titzer): Needs byte register. |
| 446 selector->Emit(cont->Encode(opcode), g.DefineAsRegister(cont->result()), | 446 selector->Emit(cont->Encode(opcode), g.DefineAsRegister(cont->result()), |
| 447 left, right); | 447 left, right); |
| 448 } | 448 } |
| 449 } | 449 } |
| 450 | 450 |
| 451 | 451 |
| 452 // Shared routine for multiple word compare operations. | 452 // Shared routine for multiple word compare operations. |
| 453 static inline void VisitWordCompare(InstructionSelector* selector, Node* node, | 453 static inline void VisitWordCompare(InstructionSelector* selector, Node* node, |
| 454 InstructionCode opcode, | 454 InstructionCode opcode, |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 return; | 536 return; |
| 537 } | 537 } |
| 538 | 538 |
| 539 // Emit the call instruction. | 539 // Emit the call instruction. |
| 540 Instruction* call_instr = | 540 Instruction* call_instr = |
| 541 Emit(opcode, buffer.output_count, buffer.outputs, | 541 Emit(opcode, buffer.output_count, buffer.outputs, |
| 542 buffer.fixed_and_control_count(), buffer.fixed_and_control_args); | 542 buffer.fixed_and_control_count(), buffer.fixed_and_control_args); |
| 543 | 543 |
| 544 call_instr->MarkAsCall(); | 544 call_instr->MarkAsCall(); |
| 545 if (deoptimization != NULL) { | 545 if (deoptimization != NULL) { |
| 546 ASSERT(continuation != NULL); | 546 DCHECK(continuation != NULL); |
| 547 call_instr->MarkAsControl(); | 547 call_instr->MarkAsControl(); |
| 548 } | 548 } |
| 549 | 549 |
| 550 // Caller clean up of stack for C-style calls. | 550 // Caller clean up of stack for C-style calls. |
| 551 if (descriptor->kind() == CallDescriptor::kCallAddress && | 551 if (descriptor->kind() == CallDescriptor::kCallAddress && |
| 552 buffer.pushed_count > 0) { | 552 buffer.pushed_count > 0) { |
| 553 ASSERT(deoptimization == NULL && continuation == NULL); | 553 DCHECK(deoptimization == NULL && continuation == NULL); |
| 554 Emit(kPopStack | MiscField::encode(buffer.pushed_count), NULL); | 554 Emit(kPopStack | MiscField::encode(buffer.pushed_count), NULL); |
| 555 } | 555 } |
| 556 } | 556 } |
| 557 | 557 |
| 558 } // namespace compiler | 558 } // namespace compiler |
| 559 } // namespace internal | 559 } // namespace internal |
| 560 } // namespace v8 | 560 } // namespace v8 |
| OLD | NEW |