| 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 | 99 |
| 100 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 100 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 101 MachineType rep = RepresentationOf(store_rep.machine_type); | 101 MachineType rep = RepresentationOf(store_rep.machine_type); |
| 102 if (store_rep.write_barrier_kind == kFullWriteBarrier) { | 102 if (store_rep.write_barrier_kind == kFullWriteBarrier) { |
| 103 DCHECK_EQ(kRepTagged, rep); | 103 DCHECK_EQ(kRepTagged, rep); |
| 104 // TODO(dcarney): refactor RecordWrite function to take temp registers | 104 // TODO(dcarney): refactor RecordWrite function to take temp registers |
| 105 // and pass them here instead of using fixed regs | 105 // and pass them here instead of using fixed regs |
| 106 // TODO(dcarney): handle immediate indices. | 106 // TODO(dcarney): handle immediate indices. |
| 107 InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; | 107 InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; |
| 108 Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx), | 108 Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx), |
| 109 g.UseFixed(index, ecx), g.UseFixed(value, edx), ARRAY_SIZE(temps), | 109 g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps), |
| 110 temps); | 110 temps); |
| 111 return; | 111 return; |
| 112 } | 112 } |
| 113 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); | 113 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); |
| 114 InstructionOperand* val; | 114 InstructionOperand* val; |
| 115 if (g.CanBeImmediate(value)) { | 115 if (g.CanBeImmediate(value)) { |
| 116 val = g.UseImmediate(value); | 116 val = g.UseImmediate(value); |
| 117 } else if (rep == kRepWord8 || rep == kRepBit) { | 117 } else if (rep == kRepWord8 || rep == kRepBit) { |
| 118 val = g.UseByteRegister(value); | 118 val = g.UseByteRegister(value); |
| 119 } else { | 119 } else { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 } | 188 } |
| 189 | 189 |
| 190 outputs[output_count++] = g.DefineSameAsFirst(node); | 190 outputs[output_count++] = g.DefineSameAsFirst(node); |
| 191 if (cont->IsSet()) { | 191 if (cont->IsSet()) { |
| 192 // TODO(turbofan): Use byte register here. | 192 // TODO(turbofan): Use byte register here. |
| 193 outputs[output_count++] = g.DefineAsRegister(cont->result()); | 193 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
| 194 } | 194 } |
| 195 | 195 |
| 196 DCHECK_NE(0, input_count); | 196 DCHECK_NE(0, input_count); |
| 197 DCHECK_NE(0, output_count); | 197 DCHECK_NE(0, output_count); |
| 198 DCHECK_GE(ARRAY_SIZE(inputs), input_count); | 198 DCHECK_GE(arraysize(inputs), input_count); |
| 199 DCHECK_GE(ARRAY_SIZE(outputs), output_count); | 199 DCHECK_GE(arraysize(outputs), output_count); |
| 200 | 200 |
| 201 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, | 201 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, |
| 202 outputs, input_count, inputs); | 202 outputs, input_count, inputs); |
| 203 if (cont->IsBranch()) instr->MarkAsControl(); | 203 if (cont->IsBranch()) instr->MarkAsControl(); |
| 204 } | 204 } |
| 205 | 205 |
| 206 | 206 |
| 207 // Shared routine for multiple binary operations. | 207 // Shared routine for multiple binary operations. |
| 208 static void VisitBinop(InstructionSelector* selector, Node* node, | 208 static void VisitBinop(InstructionSelector* selector, Node* node, |
| 209 InstructionCode opcode) { | 209 InstructionCode opcode) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left), | 309 Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left), |
| 310 g.Use(right)); | 310 g.Use(right)); |
| 311 } | 311 } |
| 312 } | 312 } |
| 313 | 313 |
| 314 | 314 |
| 315 static inline void VisitDiv(InstructionSelector* selector, Node* node, | 315 static inline void VisitDiv(InstructionSelector* selector, Node* node, |
| 316 ArchOpcode opcode) { | 316 ArchOpcode opcode) { |
| 317 IA32OperandGenerator g(selector); | 317 IA32OperandGenerator g(selector); |
| 318 InstructionOperand* temps[] = {g.TempRegister(edx)}; | 318 InstructionOperand* temps[] = {g.TempRegister(edx)}; |
| 319 size_t temp_count = ARRAY_SIZE(temps); | 319 size_t temp_count = arraysize(temps); |
| 320 selector->Emit(opcode, g.DefineAsFixed(node, eax), | 320 selector->Emit(opcode, g.DefineAsFixed(node, eax), |
| 321 g.UseFixed(node->InputAt(0), eax), | 321 g.UseFixed(node->InputAt(0), eax), |
| 322 g.UseUnique(node->InputAt(1)), temp_count, temps); | 322 g.UseUnique(node->InputAt(1)), temp_count, temps); |
| 323 } | 323 } |
| 324 | 324 |
| 325 | 325 |
| 326 void InstructionSelector::VisitInt32Div(Node* node) { | 326 void InstructionSelector::VisitInt32Div(Node* node) { |
| 327 VisitDiv(this, node, kIA32Idiv); | 327 VisitDiv(this, node, kIA32Idiv); |
| 328 } | 328 } |
| 329 | 329 |
| 330 | 330 |
| 331 void InstructionSelector::VisitInt32UDiv(Node* node) { | 331 void InstructionSelector::VisitInt32UDiv(Node* node) { |
| 332 VisitDiv(this, node, kIA32Udiv); | 332 VisitDiv(this, node, kIA32Udiv); |
| 333 } | 333 } |
| 334 | 334 |
| 335 | 335 |
| 336 static inline void VisitMod(InstructionSelector* selector, Node* node, | 336 static inline void VisitMod(InstructionSelector* selector, Node* node, |
| 337 ArchOpcode opcode) { | 337 ArchOpcode opcode) { |
| 338 IA32OperandGenerator g(selector); | 338 IA32OperandGenerator g(selector); |
| 339 InstructionOperand* temps[] = {g.TempRegister(eax), g.TempRegister(edx)}; | 339 InstructionOperand* temps[] = {g.TempRegister(eax), g.TempRegister(edx)}; |
| 340 size_t temp_count = ARRAY_SIZE(temps); | 340 size_t temp_count = arraysize(temps); |
| 341 selector->Emit(opcode, g.DefineAsFixed(node, edx), | 341 selector->Emit(opcode, g.DefineAsFixed(node, edx), |
| 342 g.UseFixed(node->InputAt(0), eax), | 342 g.UseFixed(node->InputAt(0), eax), |
| 343 g.UseUnique(node->InputAt(1)), temp_count, temps); | 343 g.UseUnique(node->InputAt(1)), temp_count, temps); |
| 344 } | 344 } |
| 345 | 345 |
| 346 | 346 |
| 347 void InstructionSelector::VisitInt32Mod(Node* node) { | 347 void InstructionSelector::VisitInt32Mod(Node* node) { |
| 348 VisitMod(this, node, kIA32Idiv); | 348 VisitMod(this, node, kIA32Idiv); |
| 349 } | 349 } |
| 350 | 350 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 if (descriptor->kind() == CallDescriptor::kCallAddress && | 560 if (descriptor->kind() == CallDescriptor::kCallAddress && |
| 561 buffer.pushed_nodes.size() > 0) { | 561 buffer.pushed_nodes.size() > 0) { |
| 562 DCHECK(deoptimization == NULL && continuation == NULL); | 562 DCHECK(deoptimization == NULL && continuation == NULL); |
| 563 Emit(kPopStack | MiscField::encode(buffer.pushed_nodes.size()), NULL); | 563 Emit(kPopStack | MiscField::encode(buffer.pushed_nodes.size()), NULL); |
| 564 } | 564 } |
| 565 } | 565 } |
| 566 | 566 |
| 567 } // namespace compiler | 567 } // namespace compiler |
| 568 } // namespace internal | 568 } // namespace internal |
| 569 } // namespace v8 | 569 } // namespace v8 |
| OLD | NEW |